xlib_playground1.html (6059B)
1 <!DOCTYPE html> 2 <html> 3 <head> 4 <meta charset="utf-8"> 5 <meta name="viewport" content="width=device-width,initial-scale=1"> 6 <link rel="stylesheet" type="text/css" href="/style.css"> 7 <link rel="icon" type="image/x-icon" href="/pics/favicon.ico"> 8 <title>Xlibで遊んでみる1</title> 9 </head> 10 <body> 11 <header> 12 <a href="/">主頁</a> | 13 <a href="/about.html">自己紹介</a> | 14 <a href="/journal">日記</a> | 15 <a href="/farm">農業</a> | 16 <a href="/kitchen">台所</a> | 17 <a href="/computer">電算機</a> | 18 <a href="/poetry">詩</a> | 19 <a href="/books">本棚</a> | 20 <a href="/gallery">絵</a> | 21 <a href="/plant">植物</a> | 22 <a href="https://git.mtkn.jp">Git</a> 23 </header> 24 <main> 25 <article> 26 <h1>Xlibで遊んでみる1</h1> 27 <time>2022-12-21</time> 28 29 <h2>はじめに</h2> 30 <p>X11でGUIのプログラミングをしてみようと思い、してみた。X11用の低レベルのライブラリはXlibとxcbの二つがあるようだ。x.orgのウェブページを見てみると、Xlibは古く、xcbに置きかわりつつあるという。そのため、新しくなにかを作る場合はxcbを使うようにとのことである。ところがこのxcbはドキュメンテーションに乏しく、X11を触るのが初めての人間にはなにをどうすればいいのかほとんど分からなかった。知らない関数や構造体やらがでてきても(殆ど全部知らないものだが)、その関数なり構造体なりの説明がどこにも見当たらない。manページもない。あるのはdoxygenなるものでソースコードのコメントから自動生成したいい加減なものだけで、使いものにならない。</p> 31 <p>とりあえずX11のことを少しは理解してからでないと初められそうもないと思い、もう少しましな情報があるXlibから始めることにした。</p> 32 <p>言語はC言語である。ソースコードは<a href="https://git.mtkn.jp/xlib_playground">ここ</a>にある。 33 </p> 34 35 <h2>初期設定</h2> 36 <p>ディスプレイを開き、ウィンドウを作成する。変数はとりあえずグローバルに宣言することにした。<code>main</code>関数はできるだけ小さくして実際の処理はそれぞれの関数にさせてみる:</p> 37 <pre><code> 38 #include <stdio.h> 39 #include <stdlib.h> 40 #include <X11/Xlib.h> 41 42 /* macros */ 43 #define INIT_WIDTH 800 44 #define INIT_HEIGHT 600 45 46 /* variables */ 47 Display *display; 48 Window window; 49 unsigned int win_width = INIT_WIDTH, win_height = INIT_HEIGHT; 50 GC gc; 51 Atom wm_delete_window; 52 53 void 54 setup(void) 55 { 56 // Open a display. 57 if ((display = XOpenDisplay(NULL)) == NULL){ 58 fprintf(stderr, "ERROR: could not open display\n"); 59 exit(1); 60 } 61 // Create a window. 62 window = XCreateSimpleWindow( 63 display, 64 XDefaultRootWindow(display), 65 0, 0, 66 win_width, win_height, 67 0, 0, // border properties 68 0); // background color: black 69 XStoreName(display, window, "UNKO"); 70 71 // Setup a graphical context. 72 gc = XCreateGC(display, window, 0, NULL); 73 XSetForeground(display, gc, 0x0000FF); 74 75 // Kill the application when the window is destroyed. 76 wm_delete_window = XInternAtom(display, 77 "WM_DELETE_WINDOW", False); 78 XSetWMProtocols(display, window, &wm_delete_window, 1); 79 80 // Setup which input to process. 81 XSelectInput(display, window, 82 ExposureMask|KeyPressMask|KeyReleaseMask); 83 84 // Actually draw the window. 85 XMapWindow(display, window); 86 } 87 88 void 89 clean_up(void) 90 { 91 XCloseDisplay(display); 92 } 93 </code></pre> 94 95 <p>適当な四角形のものを表示し、その位置を時間の関数として動かしてみる。</p> 96 <pre><code>#include <time.h> 97 #include <math.h> 98 99 int 100 main(void) 101 { 102 int px, py; 103 int quit; 104 struct timespec ts; 105 XEvent event; 106 107 setup(); 108 quit = 0; 109 110 while (!quit){ 111 while(XPending(display) > 0){ 112 XNextEvent(display, &event); 113 switch (event.type){ 114 case KeyPress: { 115 switch (XLookupKeysym(&event.xkey, 0)){ 116 case 'q': 117 quit = 1; 118 break; 119 default: 120 break; 121 } 122 } break; 123 case ClientMessage: { 124 if ((Atom) event.xclient.data.l[0] == wm_delete_window) { 125 quit = 1; 126 } 127 } break; 128 default: 129 break; 130 } 131 } 132 clock_gettime(CLOCK_MONOTONIC, &ts); 133 px = 200 + (int) (100 * sinf(ts.tv_sec + ts.tv_nsec / 1000.0 / 1000 / 1000)); 134 py = 200 + (int) (100 * cosf(ts.tv_sec + ts.tv_nsec / 1000.0 / 1000 / 1000)); 135 XClearArea(display, window, 136 0, 0, // position 137 win_width, win_height, // width and height 138 False); 139 XFillRectangle(display, window, gc, 140 px, py, // position 141 100, 100); // width and height 142 143 ts.tv_sec = 0; 144 ts.tv_nsec = 10 * 1000 * 1000; 145 nanosleep(&ts, NULL); 146 } 147 148 cleanup(); 149 return 0; 150 } 151 </code></pre> 152 153 <p>ここまでのコードはgitリポジトリの<a href="https://git.mtkn.jp/xlib_playground/file/ex1/ex1.c.html">ex1/ex1.c</a>にある。</p> 154 <h2>完成品:</h2> 155 <video controls> 156 <source src="videos/ex1.webm" type="video/webm"> 157 </video> 158 159 <h2>参考</h2> 160 <ul> 161 <li><a href="https://tronche.com/gui/x/xlib/">The Xlib Manual(html conversion)</a></li> 162 <li><a href="https://www.youtube.com/watch?v=764fnfEb1_c">X11 App in C with Xlib(youtube video by tsoding)</a></li> 163 </ul> 164 165 <a href="xlib_playground2.html">次の記事</a> 166 </article> 167 168 </main> 169 <footer> 170 <address>info(at)mtkn(dot)jp</address> 171 <a href="http://creativecommons.org/publicdomain/zero/1.0?ref=chooser-v1" rel="license noopener noreferrer">CC0 1.0</a> 172 </footer> 173 </body> 174 </html>