commit b9b33a9f58286b4d2c2ec6856daf069a6f3ffb2e
parent 8630a517f1976db29a320e87ec3a14f646ab7afd
Author: Matsuda Kenji <info@mtkn.jp>
Date: Sat, 20 Dec 2025 11:48:24 +0900
add x11 program
Diffstat:
9 files changed, 568 insertions(+), 6 deletions(-)
diff --git a/data/weblog b/data/weblog
@@ -129,3 +129,23 @@
1764428400 /journal/index.html
1764428400 /journal/posts/20251122.html
1764428400 /index.html
+1766156400 /computer/x11_32bit_window.html
+1766156400 /computer/x11_32bit_window.html
+1766156400 /computer/x11_32bit_window.html
+1766156400 /computer/x11_32bit_window.html
+1766156400 /computer/x11_32bit_window.html
+1766156400 /computer/x11_32bit_window.html
+1766156400 /computer/x11_32bit_window.html
+1766156400 /computer/x11_32bit_window.html
+1766156400 /computer/x11_32bit_window.html
+1766156400 /computer/x11_32bit_window.html
+1766156400 /computer/x11_32bit_window.html
+1766156400 /computer/index.html
+1766156400 /computer/x11_32bit_window.html
+1766156400 /index.html
+1766156400 /computer/x11_32bit_window.html
+1766156400 /computer/x11_32bit_window.html
+1766156400 /computer/x11_32bit_window.html
+1766156400 /computer/x11_32bit_window.html
+1766156400 /computer/x11_32bit_window.html
+1766156400 /computer/x11_32bit_window.html
diff --git a/man/computer/index.html b/man/computer/index.html
@@ -15,8 +15,9 @@ Small is beautiful.
<li><a href="rp2040_3_interrupt.html">RP2040 SDKなし3 割り込み</a></li>
</ul>
-<h2>Xlib</h2>
+<h2>X Window System</h2>
<ul>
+<li><a href="x11_32bit_window.html">X11で深さが32bitのwindowを作成する</a></li>
<li><a href="xlib_playground1.html">Xlibで遊んでみる1</a></li>
<li><a href="xlib_playground2.html">Xlibで遊んでみる2</a></li>
<li><a href="xlib_playground3.html">Xlibで遊んでみる3</a></li>
diff --git a/man/computer/x11_32bit_window.html b/man/computer/x11_32bit_window.html
@@ -0,0 +1,178 @@
+<h1>X11で深さが32bitのwindowを作成する</h1>
+<time>2025-12-20</time>
+
+<h2>結論</h2>
+<p>
+X11のrender拡張機能で半透明な画像を合成(composite)する際に深さが32bitのウィンドウを作成する必要がある。\
+その際ドキュメントにも書いてなさそうな操作が必要だった。\
+ウィンドウを作成する際に<code>border pixel</code>の値を設定する必要がある(言語はC):
+</p>
+
+<pre><code>\
+// Xlibの場合
+XSetWindowAttributes attr32 = {
+ .border_pixel = 0, // 値はなんでもよさそう
+ .colormap = colormap32,
+}
+Window window32 = XCreateWindow(display, DefaultRootWindow(display),
+ 0, 0, 1, 1, 0,
+ 32, // depth
+ InputOutput,
+ visual32,
+ CWBorderPixel|CWColormap, // CWBorderPixelを指定
+ &attr32);
+</code></pre>
+
+<pre><code>\
+// xcbの場合
+uint32_t attr32[2] = { 0, colormap32 }; // 値はなんでもよさそう。
+xcb_create_window(conn, 32, window32, screen->root,
+ 0, 0, 1, 1, 0,
+ XCB_WINDOW_CLASS_INPUT_OUTPUT,
+ visual32,
+ XCB_CW_BORDER_PIXEL|XCB_CW_COLORMAP, // XCB_CW_BORDER_PIXELを指定
+ &attr32);
+</code></pre>
+
+<h2>出典</h2>
+<p>
+Go言語の<a href="https://cs.opensource.google/go/x/exp/+/8475f288:shiny/driver/x11driver/screen.go;drc=7b9b53b0aca47495e3a71d360c959fe1f14b5756;l=622">golang.org/x/exp/shiny/driver/x11driver/screen.go:622</a>に、
+</p>
+<blockquote cite="https://cs.opensource.google/go/x/exp/+/8475f288:shiny/driver/x11driver/screen.go;drc=7b9b53b0aca47495e3a71d360c959fe1f14b5756;l=622">\
+<pre><code> // The CwBorderPixel attribute seems necessary for depth == 32. See
+ // http://stackoverflow.com/questions/3645632/how-to-create-a-window-with-a-bit-depth-of-32
+</code></pre>
+</blockquote>
+<p>
+と書いていた。\
+引用元を見るとXサーバーのソースコードを参照しており、\
+そのコードでは親のウィンドウの深さと異なる深さのウィンドウを作成する場合、\
+<code>CWBorderPixmap</code>又は<code>CWBorderPixel</code>を指定しないと<code>BadMatch</code>\
+というエラーが返ってくるようになっている。\
+理由はよく分からない:
+</p>
+<blockquote cite="https://cgit.freedesktop.org/xorg/xserver/tree/dix/window.c?h=xorg-server-21.1.21#n818">
+<pre><code> if (((vmask & (CWBorderPixmap | CWBorderPixel)) == 0) &&
+ (class != InputOnly) && (depth != pParent->drawable.depth)) {
+ *error = BadMatch;
+ return NullWindow;
+ }
+</code></pre>
+</blockquote>
+
+<h2>深さ32bitのウィンドウの作成手順</h2>
+<h3>深さ32bitのヴィジュアルを取得</h3>
+<p>ウィンドウ作成の関数(<code>XCreateWindow</code>または<code>xcb_create_window</code>)に渡す32bitのヴィジュアルを\
+取得する:
+</p>
+<pre><code>\
+// xlibの場合
+int findVisual32(Display *display, XVisualInfo *return_visual_info);
+/* ... */
+int main(void) {
+ /* ... */
+ XVisualInfo vi32;
+ if (findVisual32(display, &vi32) < 0) {
+ fatal("32bit-deep visual info not found");
+ }
+ /* ... */
+}
+/* ... */
+int findVisual32(Display *display, XVisualInfo *return_visual_info) {
+ long mask = VisualDepthMask|VisualRedMaskMask|VisualGreenMaskMask|VisualBlueMaskMask;
+ XVisualInfo template = {
+ .depth = 32,
+ .red_mask = 0xff0000,
+ .green_mask = 0x00ff00,
+ .blue_mask = 0x0000ff,
+ };
+ int n;
+ XVisualInfo *vinfos = XGetVisualInfo(display, mask, &template, &n);
+ if (n == 0) {
+ return -1;
+ }
+ *return_visual_info = vinfos[0];
+ XFree(vinfos);
+ return 0;
+}
+</pre></code>
+
+<pre><code>\
+// xcbの場合
+int findVisual32(xcb_screen_t *screen, xcb_visualtype_t *return_visualtype);
+/* ... */
+int main(void) {
+ /* ... */
+ xcb_visualtype_t visual32;
+ if (findVisual32(screen, &visual32) < 0) {
+ fatal("32bit visual not found");
+ }
+ /* ... */
+}
+/* ... */
+int findVisual32(xcb_screen_t *screen, xcb_visualtype_t *return_visualtype) {
+ xcb_depth_iterator_t depth_iter = xcb_screen_allowed_depths_iterator(screen);
+ for (;depth_iter.rem > 0; xcb_depth_next(&depth_iter)) {
+ xcb_depth_t *d = depth_iter.data;
+ if (d->depth != 32) {
+ continue;
+ }
+ xcb_visualtype_iterator_t visual_iter = xcb_depth_visuals_iterator(d);
+ while (visual_iter.rem > 0) {
+ xcb_visualtype_t *v = visual_iter.data;
+ if (v->red_mask == 0xff0000 && v->green_mask == 0x00ff00 && v->blue_mask == 0x0000ff) {
+ *return_visualtype = *v;
+ return 0;
+ }
+ xcb_visualtype_next(&visual_iter);
+ }
+ }
+ return -1;
+}
+</code></pre>
+
+<h3>深さ32bitのカラーマップを作成</h3>
+<p>ウィンドウ作成の関数(<code>XCreateWindow</code>または<code>xcb_create_window</code>)に渡す32bitのカラーマップを\
+作成する。
+</p>
+<pre><code>\
+// xlibの場合
+ Colormap colormap32 = XCreateColormap(display, DefaultRootWindow(display), vi32.visual, AllocNone);
+</code></pre>
+<pre><code>\
+// xcbの場合
+ xcb_colormap_t colormap32 = xcb_generate_id(conn);
+ xcb_create_colormap(conn, XCB_COLORMAP_ALLOC_NONE, colormap32, screen->root, visual32.visual_id);
+</code></pre>
+
+<h3>深さ32bitのウィンドウを作成</h3>
+<p>最後にウィンドウを作成する:</p>
+<pre><code>\
+// xlibの場合
+ Window window32 = XCreateWindow(display, DefaultRootWindow(display),
+ 0, 0, 1, 1, 0,
+ 32,
+ InputOutput,
+ vi32.visual,
+ CWBorderPixel|CWColormap,
+ &attr32);
+</code></pre>
+<pre><code>\
+// xcbの場合
+ uint32_t attr32[2] = { 0, colormap32 };
+ xcb_create_window(conn, 32, window32, screen->root,
+ 0, 0, 1, 1, 0,
+ XCB_WINDOW_CLASS_INPUT_OUTPUT,
+ visual32.visual_id,
+ XCB_CW_BORDER_PIXEL|XCB_CW_COLORMAP, &attr32);
+</code></pre>
+
+<h2>サンプルコード</h2>
+32bitのウィンドウを作成し、そこからrender拡張機能を使って半透明な四角形を描画するプログラムを作った。\
+OpenBSDで動作確認した。他のUnixでも多分動くと思う:<br>
+<a href="https://git.mtkn.jp/win32">git.mtkn.jp/win32</a>
+
+<h2>参考文献</h2>
+<ol>
+<li><a href="https://azelpg.gitlab.io/azsky2/note/prog/x11/03_visual.html">X11: ビジュアル</a></li>
+</ol>
diff --git a/man/index.html b/man/index.html
@@ -9,6 +9,7 @@
<h2>更新履歴</h2>
<a href="/rss.xml">RSS</a>
<ul>
+<li>2025-12-20 <a href="/computer/x11_32bit_window.html">X11で深さが32bitのwindowを作成する</a></li>
<li>2025-11-22 <a href="/journal/posts/20251122.html">ひさしぶりに合気道した</a></li>
<li>2025-08-27 <a href="/computer/rp2040_3_interrupt.html">RP2040 SDKなし3 割り込み</a></li>
<li>2025-07-17 <a href="/gallery/20250717.html">自画像</a></li>
diff --git a/pub/computer/index.html b/pub/computer/index.html
@@ -40,8 +40,9 @@ Small is beautiful.
<li><a href="rp2040_3_interrupt.html">RP2040 SDKなし3 割り込み</a></li>
</ul>
-<h2>Xlib</h2>
+<h2>X Window System</h2>
<ul>
+<li><a href="x11_32bit_window.html">X11で深さが32bitのwindowを作成する</a></li>
<li><a href="xlib_playground1.html">Xlibで遊んでみる1</a></li>
<li><a href="xlib_playground2.html">Xlibで遊んでみる2</a></li>
<li><a href="xlib_playground3.html">Xlibで遊んでみる3</a></li>
diff --git a/pub/computer/x11_32bit_window.html b/pub/computer/x11_32bit_window.html
@@ -0,0 +1,193 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <meta charset="utf-8">
+ <meta name="viewport" content="width=device-width,initial-scale=1">
+ <link rel="stylesheet" type="text/css" href="/style.css">
+ <link rel="icon" type="image/x-icon" href="/pics/favicon.ico">
+ <title>X11で深さが32bitのwindowを作成する</title>
+</head>
+<body>
+ <header>
+ <a href="/">主頁</a> |
+ <a href="/about.html">自己紹介</a> |
+ <a href="/journal">日記</a> |
+ <a href="/farm">農業</a> |
+ <a href="/kitchen">台所</a> |
+ <a href="/computer">電算機</a> |
+ <a href="/poetry">詩</a> |
+ <a href="/books">本棚</a> |
+ <a href="/gallery">絵</a> |
+ <a href="/plant">植物</a> |
+ <a href="https://git.mtkn.jp">Git</a>
+ </header>
+ <main>
+ <article>
+<h1>X11で深さが32bitのwindowを作成する</h1>
+<time>2025-12-20</time>
+
+<h2>結論</h2>
+<p>
+X11のrender拡張機能で半透明な画像を合成(composite)する際に深さが32bitのウィンドウを作成する必要がある。その際ドキュメントにも書いてなさそうな操作が必要だった。ウィンドウを作成する際に<code>border pixel</code>の値を設定する必要がある(言語はC):
+</p>
+
+<pre><code>// Xlibの場合
+XSetWindowAttributes attr32 = {
+ .border_pixel = 0, // 値はなんでもよさそう
+ .colormap = colormap32,
+}
+Window window32 = XCreateWindow(display, DefaultRootWindow(display),
+ 0, 0, 1, 1, 0,
+ 32, // depth
+ InputOutput,
+ visual32,
+ CWBorderPixel|CWColormap, // CWBorderPixelを指定
+ &attr32);
+</code></pre>
+
+<pre><code>// xcbの場合
+uint32_t attr32[2] = { 0, colormap32 }; // 値はなんでもよさそう。
+xcb_create_window(conn, 32, window32, screen->root,
+ 0, 0, 1, 1, 0,
+ XCB_WINDOW_CLASS_INPUT_OUTPUT,
+ visual32,
+ XCB_CW_BORDER_PIXEL|XCB_CW_COLORMAP, // XCB_CW_BORDER_PIXELを指定
+ &attr32);
+</code></pre>
+
+<h2>出典</h2>
+<p>
+Go言語の<a href="https://cs.opensource.google/go/x/exp/+/8475f288:shiny/driver/x11driver/screen.go;drc=7b9b53b0aca47495e3a71d360c959fe1f14b5756;l=622">golang.org/x/exp/shiny/driver/x11driver/screen.go:622</a>に、
+</p>
+<blockquote cite="https://cs.opensource.google/go/x/exp/+/8475f288:shiny/driver/x11driver/screen.go;drc=7b9b53b0aca47495e3a71d360c959fe1f14b5756;l=622"><pre><code> // The CwBorderPixel attribute seems necessary for depth == 32. See
+ // http://stackoverflow.com/questions/3645632/how-to-create-a-window-with-a-bit-depth-of-32
+</code></pre>
+</blockquote>
+<p>
+と書いていた。引用元を見るとXサーバーのソースコードを参照しており、そのコードでは親のウィンドウの深さと異なる深さのウィンドウを作成する場合、<code>CWBorderPixmap</code>又は<code>CWBorderPixel</code>を指定しないと<code>BadMatch</code>というエラーが返ってくるようになっている。理由はよく分からない:
+</p>
+<blockquote cite="https://cgit.freedesktop.org/xorg/xserver/tree/dix/window.c?h=xorg-server-21.1.21#n818">
+<pre><code> if (((vmask & (CWBorderPixmap | CWBorderPixel)) == 0) &&
+ (class != InputOnly) && (depth != pParent->drawable.depth)) {
+ *error = BadMatch;
+ return NullWindow;
+ }
+</code></pre>
+</blockquote>
+
+<h2>深さ32bitのウィンドウの作成手順</h2>
+<h3>深さ32bitのヴィジュアルを取得</h3>
+<p>ウィンドウ作成の関数(<code>XCreateWindow</code>または<code>xcb_create_window</code>)に渡す32bitのヴィジュアルを取得する:
+</p>
+<pre><code>// xlibの場合
+int findVisual32(Display *display, XVisualInfo *return_visual_info);
+/* ... */
+int main(void) {
+ /* ... */
+ XVisualInfo vi32;
+ if (findVisual32(display, &vi32) < 0) {
+ fatal("32bit-deep visual info not found");
+ }
+ /* ... */
+}
+/* ... */
+int findVisual32(Display *display, XVisualInfo *return_visual_info) {
+ long mask = VisualDepthMask|VisualRedMaskMask|VisualGreenMaskMask|VisualBlueMaskMask;
+ XVisualInfo template = {
+ .depth = 32,
+ .red_mask = 0xff0000,
+ .green_mask = 0x00ff00,
+ .blue_mask = 0x0000ff,
+ };
+ int n;
+ XVisualInfo *vinfos = XGetVisualInfo(display, mask, &template, &n);
+ if (n == 0) {
+ return -1;
+ }
+ *return_visual_info = vinfos[0];
+ XFree(vinfos);
+ return 0;
+}
+</pre></code>
+
+<pre><code>// xcbの場合
+int findVisual32(xcb_screen_t *screen, xcb_visualtype_t *return_visualtype);
+/* ... */
+int main(void) {
+ /* ... */
+ xcb_visualtype_t visual32;
+ if (findVisual32(screen, &visual32) < 0) {
+ fatal("32bit visual not found");
+ }
+ /* ... */
+}
+/* ... */
+int findVisual32(xcb_screen_t *screen, xcb_visualtype_t *return_visualtype) {
+ xcb_depth_iterator_t depth_iter = xcb_screen_allowed_depths_iterator(screen);
+ for (;depth_iter.rem > 0; xcb_depth_next(&depth_iter)) {
+ xcb_depth_t *d = depth_iter.data;
+ if (d->depth != 32) {
+ continue;
+ }
+ xcb_visualtype_iterator_t visual_iter = xcb_depth_visuals_iterator(d);
+ while (visual_iter.rem > 0) {
+ xcb_visualtype_t *v = visual_iter.data;
+ if (v->red_mask == 0xff0000 && v->green_mask == 0x00ff00 && v->blue_mask == 0x0000ff) {
+ *return_visualtype = *v;
+ return 0;
+ }
+ xcb_visualtype_next(&visual_iter);
+ }
+ }
+ return -1;
+}
+</code></pre>
+
+<h3>深さ32bitのカラーマップを作成</h3>
+<p>ウィンドウ作成の関数(<code>XCreateWindow</code>または<code>xcb_create_window</code>)に渡す32bitのカラーマップを作成する。
+</p>
+<pre><code>// xlibの場合
+ Colormap colormap32 = XCreateColormap(display, DefaultRootWindow(display), vi32.visual, AllocNone);
+</code></pre>
+<pre><code>// xcbの場合
+ xcb_colormap_t colormap32 = xcb_generate_id(conn);
+ xcb_create_colormap(conn, XCB_COLORMAP_ALLOC_NONE, colormap32, screen->root, visual32.visual_id);
+</code></pre>
+
+<h3>深さ32bitのウィンドウを作成</h3>
+<p>最後にウィンドウを作成する:</p>
+<pre><code>// xlibの場合
+ Window window32 = XCreateWindow(display, DefaultRootWindow(display),
+ 0, 0, 1, 1, 0,
+ 32,
+ InputOutput,
+ vi32.visual,
+ CWBorderPixel|CWColormap,
+ &attr32);
+</code></pre>
+<pre><code>// xcbの場合
+ uint32_t attr32[2] = { 0, colormap32 };
+ xcb_create_window(conn, 32, window32, screen->root,
+ 0, 0, 1, 1, 0,
+ XCB_WINDOW_CLASS_INPUT_OUTPUT,
+ visual32.visual_id,
+ XCB_CW_BORDER_PIXEL|XCB_CW_COLORMAP, &attr32);
+</code></pre>
+
+<h2>サンプルコード</h2>
+32bitのウィンドウを作成し、そこからrender拡張機能を使って半透明な四角形を描画するプログラムを作った。OpenBSDで動作確認した。他のUnixでも多分動くと思う:<br>
+<a href="https://git.mtkn.jp/win32">git.mtkn.jp/win32</a>
+
+<h2>参考文献</h2>
+<ol>
+<li><a href="https://azelpg.gitlab.io/azsky2/note/prog/x11/03_visual.html">X11: ビジュアル</a></li>
+</ol>
+ </article>
+
+ </main>
+ <footer>
+ <address>info(at)mtkn(dot)jp</address>
+ <a href="http://creativecommons.org/publicdomain/zero/1.0?ref=chooser-v1" rel="license noopener noreferrer">CC0 1.0</a>
+ </footer>
+</body>
+</html>
diff --git a/pub/index.html b/pub/index.html
@@ -34,6 +34,7 @@
<h2>更新履歴</h2>
<a href="/rss.xml">RSS</a>
<ul>
+<li>2025-12-20 <a href="/computer/x11_32bit_window.html">X11で深さが32bitのwindowを作成する</a></li>
<li>2025-11-22 <a href="/journal/posts/20251122.html">ひさしぶりに合気道した</a></li>
<li>2025-08-27 <a href="/computer/rp2040_3_interrupt.html">RP2040 SDKなし3 割り込み</a></li>
<li>2025-07-17 <a href="/gallery/20250717.html">自画像</a></li>
diff --git a/pub/rss.xml b/pub/rss.xml
@@ -5,10 +5,176 @@
<description>ウェブページの更新履歴</description>
<language>ja-jp</language>
<link>https://www.mtkn.jp</link>
-<lastBuildDate>Sun, 30 Nov 2025 09:51:40 +0900</lastBuildDate>
-<pubDate>Sun, 30 Nov 2025 09:51:40 +0900</pubDate>
+<lastBuildDate>Sat, 20 Dec 2025 11:47:06 +0900</lastBuildDate>
+<pubDate>Sat, 20 Dec 2025 11:47:06 +0900</pubDate>
<docs>https://www.rssboard.org/rss-specification</docs>
<item>
+<title>X11で深さが32bitのwindowを作成する</title>
+<link>https://www.mtkn.jp/computer/x11_32bit_window.html</link>
+<guid>https://www.mtkn.jp/computer/x11_32bit_window.html</guid>
+<pubDate>Sat, 20 Dec 2025 00:00:00 +0900</pubDate>
+<description><![CDATA[<h1>X11で深さが32bitのwindowを作成する</h1>
+<time>2025-12-20</time>
+
+<h2>結論</h2>
+<p>
+X11のrender拡張機能で半透明な画像を合成(composite)する際に深さが32bitのウィンドウを作成する必要がある。その際ドキュメントにも書いてなさそうな操作が必要だった。ウィンドウを作成する際に<code>border pixel</code>の値を設定する必要がある(言語はC):
+</p>
+
+<pre><code>// Xlibの場合
+XSetWindowAttributes attr32 = {
+ .border_pixel = 0, // 値はなんでもよさそう
+ .colormap = colormap32,
+}
+Window window32 = XCreateWindow(display, DefaultRootWindow(display),
+ 0, 0, 1, 1, 0,
+ 32, // depth
+ InputOutput,
+ visual32,
+ CWBorderPixel|CWColormap, // CWBorderPixelを指定
+ &attr32);
+</code></pre>
+
+<pre><code>// xcbの場合
+uint32_t attr32[2] = { 0, colormap32 }; // 値はなんでもよさそう。
+xcb_create_window(conn, 32, window32, screen->root,
+ 0, 0, 1, 1, 0,
+ XCB_WINDOW_CLASS_INPUT_OUTPUT,
+ visual32,
+ XCB_CW_BORDER_PIXEL|XCB_CW_COLORMAP, // XCB_CW_BORDER_PIXELを指定
+ &attr32);
+</code></pre>
+
+<h2>出典</h2>
+<p>
+Go言語の<a href="https://cs.opensource.google/go/x/exp/+/8475f288:shiny/driver/x11driver/screen.go;drc=7b9b53b0aca47495e3a71d360c959fe1f14b5756;l=622">golang.org/x/exp/shiny/driver/x11driver/screen.go:622</a>に、
+</p>
+<blockquote cite="https://cs.opensource.google/go/x/exp/+/8475f288:shiny/driver/x11driver/screen.go;drc=7b9b53b0aca47495e3a71d360c959fe1f14b5756;l=622"><pre><code> // The CwBorderPixel attribute seems necessary for depth == 32. See
+ // http://stackoverflow.com/questions/3645632/how-to-create-a-window-with-a-bit-depth-of-32
+</code></pre>
+</blockquote>
+<p>
+と書いていた。引用元を見るとXサーバーのソースコードを参照しており、そのコードでは親のウィンドウの深さと異なる深さのウィンドウを作成する場合、<code>CWBorderPixmap</code>又は<code>CWBorderPixel</code>を指定しないと<code>BadMatch</code>というエラーが返ってくるようになっている。理由はよく分からない:
+</p>
+<blockquote cite="https://cgit.freedesktop.org/xorg/xserver/tree/dix/window.c?h=xorg-server-21.1.21#n818">
+<pre><code> if (((vmask & (CWBorderPixmap | CWBorderPixel)) == 0) &&
+ (class != InputOnly) && (depth != pParent->drawable.depth)) {
+ *error = BadMatch;
+ return NullWindow;
+ }
+</code></pre>
+</blockquote>
+
+<h2>深さ32bitのウィンドウの作成手順</h2>
+<h3>深さ32bitのヴィジュアルを取得</h3>
+<p>ウィンドウ作成の関数(<code>XCreateWindow</code>または<code>xcb_create_window</code>)に渡す32bitのヴィジュアルを取得する:
+</p>
+<pre><code>// xlibの場合
+int findVisual32(Display *display, XVisualInfo *return_visual_info);
+/* ... */
+int main(void) {
+ /* ... */
+ XVisualInfo vi32;
+ if (findVisual32(display, &vi32) < 0) {
+ fatal("32bit-deep visual info not found");
+ }
+ /* ... */
+}
+/* ... */
+int findVisual32(Display *display, XVisualInfo *return_visual_info) {
+ long mask = VisualDepthMask|VisualRedMaskMask|VisualGreenMaskMask|VisualBlueMaskMask;
+ XVisualInfo template = {
+ .depth = 32,
+ .red_mask = 0xff0000,
+ .green_mask = 0x00ff00,
+ .blue_mask = 0x0000ff,
+ };
+ int n;
+ XVisualInfo *vinfos = XGetVisualInfo(display, mask, &template, &n);
+ if (n == 0) {
+ return -1;
+ }
+ *return_visual_info = vinfos[0];
+ XFree(vinfos);
+ return 0;
+}
+</pre></code>
+
+<pre><code>// xcbの場合
+int findVisual32(xcb_screen_t *screen, xcb_visualtype_t *return_visualtype);
+/* ... */
+int main(void) {
+ /* ... */
+ xcb_visualtype_t visual32;
+ if (findVisual32(screen, &visual32) < 0) {
+ fatal("32bit visual not found");
+ }
+ /* ... */
+}
+/* ... */
+int findVisual32(xcb_screen_t *screen, xcb_visualtype_t *return_visualtype) {
+ xcb_depth_iterator_t depth_iter = xcb_screen_allowed_depths_iterator(screen);
+ for (;depth_iter.rem > 0; xcb_depth_next(&depth_iter)) {
+ xcb_depth_t *d = depth_iter.data;
+ if (d->depth != 32) {
+ continue;
+ }
+ xcb_visualtype_iterator_t visual_iter = xcb_depth_visuals_iterator(d);
+ while (visual_iter.rem > 0) {
+ xcb_visualtype_t *v = visual_iter.data;
+ if (v->red_mask == 0xff0000 && v->green_mask == 0x00ff00 && v->blue_mask == 0x0000ff) {
+ *return_visualtype = *v;
+ return 0;
+ }
+ xcb_visualtype_next(&visual_iter);
+ }
+ }
+ return -1;
+}
+</code></pre>
+
+<h3>深さ32bitのカラーマップを作成</h3>
+<p>ウィンドウ作成の関数(<code>XCreateWindow</code>または<code>xcb_create_window</code>)に渡す32bitのカラーマップを作成する。
+</p>
+<pre><code>// xlibの場合
+ Colormap colormap32 = XCreateColormap(display, DefaultRootWindow(display), vi32.visual, AllocNone);
+</code></pre>
+<pre><code>// xcbの場合
+ xcb_colormap_t colormap32 = xcb_generate_id(conn);
+ xcb_create_colormap(conn, XCB_COLORMAP_ALLOC_NONE, colormap32, screen->root, visual32.visual_id);
+</code></pre>
+
+<h3>深さ32bitのウィンドウを作成</h3>
+<p>最後にウィンドウを作成する:</p>
+<pre><code>// xlibの場合
+ Window window32 = XCreateWindow(display, DefaultRootWindow(display),
+ 0, 0, 1, 1, 0,
+ 32,
+ InputOutput,
+ vi32.visual,
+ CWBorderPixel|CWColormap,
+ &attr32);
+</code></pre>
+<pre><code>// xcbの場合
+ uint32_t attr32[2] = { 0, colormap32 };
+ xcb_create_window(conn, 32, window32, screen->root,
+ 0, 0, 1, 1, 0,
+ XCB_WINDOW_CLASS_INPUT_OUTPUT,
+ visual32.visual_id,
+ XCB_CW_BORDER_PIXEL|XCB_CW_COLORMAP, &attr32);
+</code></pre>
+
+<h2>サンプルコード</h2>
+32bitのウィンドウを作成し、そこからrender拡張機能を使って半透明な四角形を描画するプログラムを作った。OpenBSDで動作確認した。他のUnixでも多分動くと思う:<br>
+<a href="https://git.mtkn.jp/win32">git.mtkn.jp/win32</a>
+
+<h2>参考文献</h2>
+<ol>
+<li><a href="https://azelpg.gitlab.io/azsky2/note/prog/x11/03_visual.html">X11: ビジュアル</a></li>
+</ol>
+]]></description>
+</item>
+<item>
<title>9P</title>
<link>https://www.mtkn.jp/computer/9p.html</link>
<guid>https://www.mtkn.jp/computer/9p.html</guid>
diff --git a/pub/sitemap.xml b/pub/sitemap.xml
@@ -1,14 +1,15 @@
<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
+<url><loc>https://www.mtkn.jp/</loc><lastmod>2025-12-20</lastmod></url>
+<url><loc>https://www.mtkn.jp/computer/x11_32bit_window.html</loc><lastmod>2025-12-20</lastmod></url>
+<url><loc>https://www.mtkn.jp/computer/</loc><lastmod>2025-12-20</lastmod></url>
<url><loc>https://www.mtkn.jp/computer/9p.html</loc><lastmod>2025-12-19</lastmod></url>
<url><loc>https://www.mtkn.jp/journal/posts/20241211.html</loc><lastmod>2025-12-11</lastmod></url>
<url><loc>https://www.mtkn.jp/journal/posts/20241202.html</loc><lastmod>2025-12-02</lastmod></url>
<url><loc>https://www.mtkn.jp/journal/posts/20251122.html</loc><lastmod>2025-11-30</lastmod></url>
<url><loc>https://www.mtkn.jp/journal/</loc><lastmod>2025-11-30</lastmod></url>
-<url><loc>https://www.mtkn.jp/</loc><lastmod>2025-11-30</lastmod></url>
<url><loc>https://www.mtkn.jp/computer/mailserver.html</loc><lastmod>2025-11-03</lastmod></url>
<url><loc>https://www.mtkn.jp/computer/rp2040_3_interrupt.html</loc><lastmod>2025-08-27</lastmod></url>
-<url><loc>https://www.mtkn.jp/computer/</loc><lastmod>2025-08-27</lastmod></url>
<url><loc>https://www.mtkn.jp/gallery/</loc><lastmod>2025-07-17</lastmod></url>
<url><loc>https://www.mtkn.jp/gallery/20250717.html</loc><lastmod>2025-07-17</lastmod></url>
<url><loc>https://www.mtkn.jp/journal/posts/20250519.html</loc><lastmod>2025-05-19</lastmod></url>