X Window
addon of firefox
firefoxの画面サイズを変更するアドオン。中身を取り出して調べてみる。拡張って所に変なファイル名で入っていた。
sakae@deb:/tmp/extensions$ file \{52c2fc44-27f2-40a0-a8fb-fd01690f81fe\}.xpi {52c2fc44-27f2-40a0-a8fb-fd01690f81fe}.xpi: Zip archive data, at least v2.0 to extract
変な(オイラーの知らない)拡張子だけど、どうって事なかった。unzipで展開。
sakae@deb:/tmp/extensions$ ls data/ lib/ manifest.json META-INF/
manifest.jsonって言うのをまずは見る。
{ "version": "0.1.3", "manifest_version": 2, "offline_enabled": true, "name": "Window Resizer", "short_name": "window-resizer", "permissions": ["storage", "system.display"], "homepage_url": "https://mybrowseraddon.com/window-resizer.html", "description": "Easily set the layout (size & position) of your browser window", :
こいつが動くには、保存と、表示の権限が必要とな。設定値をどこかに保存。それを何かのタイミングで反映するんだな。
"layouts": [ {"id": 1, "width": 800, "height": 1200, "left":0, "top": 0}, {"id": 2, "width": 800, "height": 1200, "left": 300, "top": 0}, {"id": 3, "width": 800, "height": 1200, "left": 600, "top": 0}, :
保存の形式は、あれ(geometory)と同一じゃん。
sakae@deb:/tmp/extensions$ grep system -rIl . ./data/popup/popup.js ./manifest.json
微妙な使われ方をしてる所。
"monitor": function (callback) { config.active.window(function (win) { var flag = chrome.system && chrome.system.display && chrome.system.display.getInfo; if (flag) { chrome.system.display.getInfo(function (displays) { for (var i = 0; i < displays.length; i++) { var monitor = {}, current = {}; var area = displays[i].workArea; /* */ current.left = win.left; monitor.left = area.left; current.right = win.left + win.width; monitor.right = area.left + area.width;
ざっと見だけど、このあたりだろうね。
libxcb
前回の続きで、xbacklightする。するってのは、コンパイルの事ね。普通にconfigureしてからmakeすれば良い。X関係者だからと言って特段と違った事をする訳でもない。
vbox$ make make all-recursive Making all in man GEN xbacklight.1 CC xbacklight.o xbacklight.c:48:1: warning: function 'usage' could be declared with attribute 'noreturn' [-Wmissing-noreturn] { ^ 1 warning generated. CCLD xbacklight
誰だ、こういう風に大事な事を隠す奴は。オイラーは、どんなライブラリィーをリンクしてるか、知りたいぞ。そんなのレシピであるMakefileを見れ。
XRANDR_CFLAGS = -I/usr/X11R6/include XRANDR_LIBS = -L/usr/X11R6/lib -lxcb-randr -lxcb-util -lxcb
この設定が
vbox$ ldd xbacklight xbacklight: Start End Type Open Ref GrpRef Name 14b57000 34b59000 exe 1 0 0 xbacklight 0d91f000 2d921000 rlib 0 1 0 /usr/X11R6/lib/libxcb-randr.so.2.3 00d75000 20d77000 rlib 0 1 0 /usr/X11R6/lib/libxcb-util.so.0.0 085c2000 285c4000 rlib 0 3 0 /usr/X11R6/lib/libxcb.so.4.1 09a8e000 29a9f000 rlib 0 1 0 /usr/lib/libc.so.96.0 04f16000 24f18000 rlib 0 1 0 /usr/X11R6/lib/libXau.so.10.0 01d10000 21d12000 rlib 0 1 0 /usr/X11R6/lib/libXdmcp.so.11.0 0b14e000 0b14e000 ld.so 0 1 0 /usr/libexec/ld.so
こんな風に適用された。指定してない奴もリンクされてるけど、そんなものなのか。
内部で使われている関数のmanが無い。あ、うんの呼吸で使えってか。だから、GUI系は好きになれないのよ。嘆いていてもしょうがないので、関数の仕様書であるヘッダーファイルを閲覧する。
conn = xcb_connect (dpy_name, NULL);
文中に出て来た一番簡単そうな関数。この第二引数は何? xcb.hにあった。
xcb_connection_t *xcb_connect(const char *displayname, int *screenp); /** * @brief Connects to the X server, using an authorization information. * @param display The name of the display. * @param auth The authorization information. * @param screen A pointer to a preferred screen number. * @return A newly allocated xcb_connection_t structure. * * Connects to the X server specified by @p displayname, using the * authorization @p auth. If a particular screen on that server is * preferred, the int pointed to by @p screenp (if not @c NULL) will * be set to that screen; otherwise @p screenp will be set to 0. * * Always returns a non-NULL pointer to a xcb_connection_t, even on failure. * Callers need to use xcb_connection_has_error() to check for failure. * When finished, use xcb_disconnect() to close the connection and free * the structure. */
こうやって、調べて行くの面倒だな。
Basic Graphics Programming With The XCB Library
世の中には、こういう便利な説明書が公開されてた。
xeyes
JR東日本、先月から顔認証で犯罪者や仮釈放者を照合していた なんて話が話題になってた。ギョロ目で挙動不審者を撮影。AIでヤバイ事をやりそうな人を炙り出し。乗客の皆様の安全の為ですとか、言うんだろうね。これが正しいのか否かは、判断に迷う所。
Xな環境でもマウスの位置をギョロ目で追うアプリがある。これもmakeしてみた。
vbox$ make make all-recursive Making all in man GEN xeyes.1 CC Eyes.o CC transform.o CC xeyes.o CCLD xeyes
やっぱり大事な所は隠しているね。
XEYES_CFLAGS = -I/usr/X11R6/include XEYES_LIBS = -L/usr/X11R6/lib -lXext -lXmu -lXt -lX11
リンクしてる物が違っているね。一筋縄ではいきそうに無いですな。まあ、そんなものと諦めるしかないんだろうね。
こいつもmanを見ると
-geometry geometry define the initial window geometry; see X(7).
たらい回しだな。
One of the advantages of using window systems instead of hardwired terminals is that applications don't have to be restricted to a particular size or location on the screen. Although the layout of windows on a display is controlled by the window manager that the user is running (described below), most X programs accept a command line argument of the form -geometry WIDTHxHEIGHT+XOFF+YOFF (where WIDTH, HEIGHT, XOFF, and YOFF are numbers) for specifying a preferred size and location for this application's main window.
firefoxなんかは、この習慣を無視してる新種のアプリです。アプリの初期配置を指定するんだな。LCD画面が1024x768のサイズなら、左上を原点として、どの位置にどれだけのサイズのアプリ用窓を出すか。これを実際にやるのは、twmとかLXDE等のウィンドウ・マネージャーの仕事か。
と考えると、昔やったお絵描きソフトpostscriptと一緒じゃん。あちらは最終ターゲットが、A4サイズとかの用紙って違いしかない。Xは画面制御の他にマウスやらキーボードなんてのも扱えるとな(フォントを無視するなんてフォントに悲しいと、親父ギャク炸裂)。
あれ、そんなののコンソール版があるぞ。OpenBSD wscons(4)
wscons is made of a number of cooperating modules, in particular • Hardware support for display adapters, keyboards and mice; see wsdisplay(4), wskbd(4), and wsmouse(4). • Input event multiplexor; see wsmux(4). • Terminal emulation modules (see below).
話が剃れた。ジオメトリィーに戻ると、
vbox$ grep geometry *.c Eyes.c: /* query_geometry */ XtInheritQueryGeometry, xeyes.c: " [-geometry [{width}][x{height}][{+-}{xoff}[{+-}{yoff}]]]\n"
当たり前の機能なので、X側でサポートするようになってるっぽいな。個別に深入りしても良い事なさそうなので、もっと大局的に調べてみるかな。
X Window
Xlib sample
そして、サンプルは何時もハロワです。
X Window System編 - ツールキットごとに異なるプログラム
続・X Window System編 - あえてメジャーではないツールキットを使う
色々なツールキットが有るんだな。
下記は、勉強の為の叩き台。
#include <stdio.h> #include <X11/Xlib.h> #include <X11/Xutil.h> // Compile: cc gui.c -lX11 // Window: ウィンドウへのハンドル(識別子) // Display: ディスプレイへのハンドル(識別子) // GC: グラッフィクコンテキスト[描画属性]へのハンドル(識別子) // Xevent: イベント void main() { Window window; Display *display; int screen; GC gc; XEvent event; // ディスプレイの指定 display = XOpenDisplay(""); screen = DefaultScreen(display); // ウィンドウの生成・表示・GC作成、イベント指定 window = XCreateSimpleWindow (display, RootWindow(display, screen), 100, 100, 256, 256, 4, BlackPixel(display, screen), WhitePixel(display, screen) ); XMapWindow(display, window); gc = XCreateGC(display, window, 0, 0); XSelectInput(display, window, ExposureMask | ButtonPressMask); // イベント待ち無限ループ while(1) { XNextEvent(display, &event); switch( event.type ) { case ButtonPress: printf("button pressed\n"); XDrawString(display, window, gc, 100, 100, "Hello World", 11); break; } } return; }
ruby/Tk
ちょいとXlibを扱かうには、ruby/Tkが最適らしい。みんな、あんな古いものを使うなんてと馬鹿にするけど、昭和の香が漂っていて、若い人にも新鮮に映るだろう。
何でも有ると自慢のdebianでも、apt一発でruby/Tkは入らない。パッケージが無いんだ。 そこで、gemの出番になる。
sudo gem install tk で行けるはずなんだけど、自前でインストールしたrubyには、opensslが入っていなくて、gemが起動しなかった。インストール時に警告が出てきてたのは知ってたけど、よもやgemが足を引っ張るなんて、想像もつかなかったよ。
んな訳で、libssl-devを入れてからrubyを作り直した。そして再トライしたら、今度はtcltkのライブラリィーが見付からないとな。ちゃんと、tk-devは入れてるのにね。全く困ったものだとググレですよ。32Bitマシン用に変更して、やっとインストール出来た。
sudo gem install tk -- --with-tcltkversion=8.6 \ --with-tcl-lib=/usr/lib/i386-linux-gnu \ --with-tk-lib=/usr/lib/i386-linux-gnu \ --with-tcl-include=/usr/include/tcl8.6 \ --with-tk-include=/usr/include/tcl8.6 \ --enable-pthread
ついでに、FreeBSDにも入れた。こちらは面倒無いように、pkg install rubygem-tk で、一発導入出来た。どうやら、FreeBSDのそれは、何から何まで、rubygem-xxx になってるみたい。irbなんて標準添付かと思ったら、rubygem-irb みたいにする必要があった。パッケージを作る人のポリシーが、色濃く出ているね。
こちらが網羅的に一番詳しく解説されてた。ちょっといじるには最適な取合せと思うぞ。どれぐらい楽かと言うと、
[sakae@fb ~]$ wc tk-clock.rb 112 392 2241 tk-clock.rb
これ、超入門に載ってた、素敵なアナログ時計です。一方、Xに備付のoclockは
vbox$ wc *.c 570 1941 16177 Clock.c 168 563 5207 oclock.c 104 464 2828 transform.c 842 2968 24212 total
でした。もう圧倒的に楽ですよ。
xlib in scm
xlibなんて言うGUI系の権家のような本は、残念ながら持っていない。まて、昔のscheme本にxscmの紹介が載っていたような。調べてみたらxscmは既にディスコン。DLしようにも、探し出せなかった。悔しいので、 The SCM Implementation of Schemeな本家へ行ってみた。何とXlibScmをサポートしてるじゃないですか。これはもう試してみるしか。
debianのaptから入れた。一見動きそうだったけどダメだった。 しょうがないので自前でコンパイルして入れたよ。
下記は、サーバーと通信出来るかの試験スクリプト。
(require 'Xlib) (define d (x:open-display #f)) d (x:server-vendor d) (x:protocol-version d) (x:vendor-release d) (x:screen-count d) (x:default-screen d) (x:close d)
それぞれのS式をC-x C-e で、一つづつ評価してみた。
> ;linking /usr/local/lib/scm/x.so ;done linking /usr/local/lib/scm/x.so #<unspecified> > #<unspecified> > #<X display ":0"> > "The X.Org Foundation" > (11 . 0) > 12011000 > 1 > 0 > #<unspecified>
何となく動いてるっぽい。
ports of FreeBSD
気をよくしたオイラーは、FreeBSDではどうよとportsを調べてみた。portsにはなってるけど、残念ながら、X11は無しでコンパイルされてた。
.if ${PORT_OPTIONS:MX11} SCM_MODULES+= ${SCM_MODULES_X11} SCM_DATA+= ${SCM_DATA_X11} .endif
scmの作成仕様書Makefileを見ると上記のようになってた。はて、このオプションをどう指定するんだったかな? 昔、こういうのを散々やったんだけど、すっかり忘却の彼方になってる。最近は、努力のうちに入らないググレが幅を効かせているので、
ああ、思い出したよ。情無い。情無いと言えば、自分用のカーネルを作るのもさぼっているな。ええ、カーネルのアップデートをお任せにするには、標準品が(ほぼ)要求されますからね。
ports of OpenBSD
portslistを入れておくと、portsに対してキーワード検索が出来るようになる。FreeBSDでは入れなくても検索出来るんだけどね。リナで言う、apt-cache search xxx相当かな。
vbox$ cd /usr/ports/ vbox$ make search key=scm | less : Port: scm-5f1p2 Path: lang/scm Info: scheme r5 interpreter Maint: Marc Espie <espie@openbsd.org> Index: lang L-deps: B-deps: archivers/unzip devel/slib R-deps: devel/slib Archs: any Port: scm-5f1p2-no_x11 Path: lang/scm,no_x11 Info: scheme r5 interpreter Maint: Marc Espie <espie@openbsd.org> Index: lang L-deps: B-deps: archivers/unzip devel/slib R-deps: devel/slib Archs: any
余計な文字列に対してもヒットするので、lessの検索を使って絞り込のがお得だ。scmはデフォでXサポート済ってのが、メンテナの気持を表しているな。同じ調子で、ruby-tkを検索。2.6, 2.7, 3.0系のruby用が有ったぞ。選び放題だな。
scmを入れたので、上で出て来たチェック・スクリプトを走らせてみた。
> #t > #<unspecified> > #<X display "aa.bb.cc.5:0"> > "HC-Consult" > (11 . 0) > 12000000 > 1 > 0 > #<unspecified>
Xサーバーは、Windows10に入れているvcXsrvを環境変数DISPLAYで指定した。ベンダー名が、見慣れないものになっている。WSL上にXサーバをインストールしてGUIを実現する(VcXsrv編)
mobaTermは自前のXを持っているので、それでも試してみた。既に設定されてる環境変数は、unset DISPLAYして、削除しておき、movaTermを起動する事。設定されてると、そちらを優先してしまうようだ。
> #t > #<unspecified> > #<X display "localhost:10.0"> > "Moba/X" > (11 . 0) > 11603000 > 1 > 0 > #<unspecified>
ちゃんと自前のサーバー名を名乗っているね。
最後にX関係のリンク情報をあげておく。
vbox$ ldd /usr/local/bin/scm /usr/local/bin/scm: Start End Type Open Ref GrpRef Name 15760000 35769000 exe 1 0 0 /usr/local/bin/scm 02edd000 22ee1000 rlib 0 1 0 /usr/X11R6/lib/libX11.so.17.1 0422a000 2422f000 rlib 0 1 0 /usr/lib/libreadline.so.4.0 07b56000 27b5a000 rlib 0 2 0 /usr/lib/libcurses.so.14.0 06eef000 26ef1000 rlib 0 1 0 /usr/lib/libm.so.10.1 04d98000 24da9000 rlib 0 1 0 /usr/lib/libc.so.96.0 0fd22000 2fd24000 rlib 0 1 0 /usr/X11R6/lib/libxcb.so.4.1 00569000 2056b000 rlib 0 1 0 /usr/X11R6/lib/libXau.so.10.0 05fe8000 25fea000 rlib 0 1 0 /usr/X11R6/lib/libXdmcp.so.11.0 07406000 07406000 ld.so 0 1 0 /usr/libexec/ld.so