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