commit ddb13870655b4177cff87e2d1d9e4ea8d35e522e
parent e6038dad5efd229279931bec2d739c0427a2a939
Author: Matsuda Kenji <info@mtkn.jp>
Date: Thu, 18 Dec 2025 08:31:23 +0900
change name, free pictures
Diffstat:
| A | xlib.c | | | 181 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
1 file changed, 181 insertions(+), 0 deletions(-)
diff --git a/xlib.c b/xlib.c
@@ -0,0 +1,181 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+#include <X11/extensions/Xrender.h>
+
+void fatal(char *msg);
+int findVisual32(Display *display, XVisualInfo *return_visual_info);
+int findPictFormat(Display *display, int depth, XRenderPictFormat *return_pictformat);
+
+int main(void) {
+ Display *display = XOpenDisplay(NULL);
+ if (!display) {
+ fatal("can't open display");
+ }
+ int screen = DefaultScreen(display);
+
+ XSetWindowAttributes attr = {.event_mask = KeyPressMask | ExposureMask};
+ int width = 800, height = 600;
+ Window window = XCreateWindow(display, DefaultRootWindow(display),
+ 0, 0, width, height, 0,
+ DefaultDepth(display, screen),
+ InputOutput,
+ DefaultVisual(display, screen),
+ CWEventMask,
+ &attr);
+ XMapWindow(display, window);
+
+ XRenderPictFormat pictformat, pictformat24, pictformat32;
+ if (findPictFormat(display, 24, &pictformat24) < 0) {
+ fatal("24bit-deep pictformat not found");
+ }
+ if (findPictFormat(display, 32, &pictformat32) < 0) {
+ fatal("32bit-deep pictformat not found");
+ }
+ switch (DefaultDepth(display, screen)) {
+ case 24:
+ pictformat = pictformat24;
+ break;
+ case 32:
+ pictformat = pictformat32;
+ break;
+ default:
+ fatal("unsupported screen depth");
+ }
+
+ Picture picture = XRenderCreatePicture(display, window, &pictformat, 0, NULL);
+ XRenderColor color = { .red = 0xffff, .green = 0xffff, .blue = 0xeaea, .alpha = 0xffff };
+ XRectangle rectangle = { .x = 0, .y = 0, .width = width, .height = height };
+ XRenderFillRectangles(display, PictOpSrc, picture, &color, &rectangle, 1);
+
+ XVisualInfo vi32;
+ if (findVisual32(display, &vi32) < 0) {
+ fatal("32bit-deep visual info not found");
+ }
+ Colormap colormap32 = XCreateColormap(display, DefaultRootWindow(display), vi32.visual, AllocNone);
+ XSetWindowAttributes attr32 = {
+ .border_pixel = 0,
+ .colormap = colormap32,
+ };
+ Window window32 = XCreateWindow(display, DefaultRootWindow(display),
+ 0, 0, 1, 1, 0,
+ 32,
+ InputOutput,
+ vi32.visual,
+ CWBorderPixel|CWColormap,
+ &attr32);
+
+ int width1 = 300, height1 = 300;
+ Pixmap pixmap32_1 = XCreatePixmap(display, window32, width1, height1, 32);
+ Picture picture32_1 = XRenderCreatePicture(display, pixmap32_1, &pictformat32, 0, NULL);
+ XRenderColor color1 = { .red = 0xffff, .green = 0, .blue = 0, .alpha = 0x3fff };
+ XRectangle rectangle1 = { .x = 0, .y = 0, .width = width1, .height = height1 };
+ XRenderFillRectangles(display, PictOpSrc, picture32_1, &color1, &rectangle1, 1);
+
+ int width2 = 300, height2 = 200;
+ Pixmap pixmap32_2 = XCreatePixmap(display, window32, width2, height2, 32);
+ Picture picture32_2 = XRenderCreatePicture(display, pixmap32_2, &pictformat32, 0, NULL);
+ XRenderColor color2 = { .red = 0, .green = 0xffff, .blue = 0, .alpha = 0x3fff };
+ XRectangle rectangle2 = { .x = 0, .y = 0, .width = width2, .height = height2 };
+ XRenderFillRectangles(display, PictOpSrc, picture32_2, &color2, &rectangle2, 1);
+
+ int width3 = 300, height3 = 300;
+ Pixmap pixmap32_3 = XCreatePixmap(display, window32, width3, height3, 32);
+ Picture picture32_3 = XRenderCreatePicture(display, pixmap32_3, &pictformat32, 0, NULL);
+ XRenderColor color3 = { .red = 0, .green = 0, .blue = 0xffff, .alpha = 0x3fff };
+ XRectangle rectangle3 = { .x = 0, .y = 0, .width = width3, .height = height3 };
+ XRenderFillRectangles(display, PictOpSrc, picture32_3, &color3, &rectangle3, 1);
+
+ XSync(display, 0);
+ int quit = 0;
+ XEvent event;
+ while (!quit) {
+ XRenderFillRectangles(display, PictOpSrc, picture, &color, &rectangle, 1);
+ XRenderComposite(display, PictOpOver, picture32_1, 0, picture, 0, 0, 0, 0, 100, 100, width1, height1);
+ XRenderComposite(display, PictOpOver, picture32_2, 0, picture, 0, 0, 0, 0, 200, 150, width2, height2);
+ XRenderComposite(display, PictOpOver, picture32_3, 0, picture, 0, 0, 0, 0, 150, 200, width3, height3);
+
+ XNextEvent(display, &event);
+ if (event.type == KeyPress && event.xkey.keycode == 49) {
+ quit = 1;
+ }
+ }
+
+ XFreePixmap(display, pixmap32_3);
+ XRenderFreePicture(display, picture32_3);
+ XFreePixmap(display, pixmap32_2);
+ XRenderFreePicture(display, picture32_2);
+ XFreePixmap(display, pixmap32_1);
+ XRenderFreePicture(display, picture32_1);
+ XRenderFreePicture(display, picture);
+ XCloseDisplay(display);
+
+ return 0;
+}
+
+void fatal(char *msg) {
+ fprintf(stderr, "%s\n", msg);
+ exit(1);
+}
+
+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;
+}
+
+int findPictFormat(Display *display, int depth, XRenderPictFormat *return_pictformat) {
+ long mask = PictFormatType | PictFormatDepth |
+ PictFormatRed | PictFormatRedMask |
+ PictFormatGreen | PictFormatGreenMask |
+ PictFormatBlue | PictFormatBlueMask;
+ XRenderDirectFormat directformat24 = {
+ .red = 16,
+ .redMask = 0xff,
+ .green = 8,
+ .greenMask = 0xff,
+ .blue = 0,
+ .blueMask = 0xff,
+ };
+ XRenderDirectFormat directformat32 = {
+ .alpha = 24,
+ .alphaMask = 0xff,
+ .red = 16,
+ .redMask = 0xff,
+ .green = 8,
+ .greenMask = 0xff,
+ .blue = 0,
+ .blueMask = 0xff,
+ };
+ XRenderPictFormat template = {
+ .type = PictTypeDirect,
+ .depth = depth,
+ };
+ if (depth == 32) {
+ mask |= PictFormatAlpha | PictFormatAlphaMask;
+ template.direct = directformat32;
+ } else if (depth == 24) {
+ template.direct = directformat24;
+ } else {
+ fatal("unsupported depth");
+ }
+ XRenderPictFormat *f = XRenderFindFormat(display, mask, &template, 0);
+ if (!f) {
+ return -1;
+ }
+ *return_pictformat = *f;
+ return 0;
+}