xlib.c (5986B)
1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <X11/Xlib.h> 4 #include <X11/Xutil.h> 5 #include <X11/extensions/Xrender.h> 6 7 void fatal(char *msg); 8 int findVisual32(Display *display, XVisualInfo *return_visual_info); 9 int findPictFormat(Display *display, int depth, XRenderPictFormat *return_pictformat); 10 11 int main(void) { 12 Display *display = XOpenDisplay(NULL); 13 if (!display) { 14 fatal("can't open display"); 15 } 16 int screen = DefaultScreen(display); 17 18 XSetWindowAttributes attr = {.event_mask = KeyPressMask | ExposureMask}; 19 int width = 800, height = 600; 20 Window window = XCreateWindow(display, DefaultRootWindow(display), 21 0, 0, width, height, 0, 22 DefaultDepth(display, screen), 23 InputOutput, 24 DefaultVisual(display, screen), 25 CWEventMask, 26 &attr); 27 XMapWindow(display, window); 28 29 XTextProperty xtext; 30 char *title = "xlib"; 31 XStringListToTextProperty(&title, 1, &xtext); 32 XSetWMName(display, window, &xtext); 33 34 XRenderPictFormat pictformat, pictformat24, pictformat32; 35 if (findPictFormat(display, 24, &pictformat24) < 0) { 36 fatal("24bit-deep pictformat not found"); 37 } 38 if (findPictFormat(display, 32, &pictformat32) < 0) { 39 fatal("32bit-deep pictformat not found"); 40 } 41 switch (DefaultDepth(display, screen)) { 42 case 24: 43 pictformat = pictformat24; 44 break; 45 case 32: 46 pictformat = pictformat32; 47 break; 48 default: 49 fatal("unsupported screen depth"); 50 } 51 52 Picture picture = XRenderCreatePicture(display, window, &pictformat, 0, NULL); 53 XRenderColor color = { .red = 0xffff, .green = 0xffff, .blue = 0xeaea, .alpha = 0xffff }; 54 XRectangle rectangle = { .x = 0, .y = 0, .width = width, .height = height }; 55 XRenderFillRectangles(display, PictOpSrc, picture, &color, &rectangle, 1); 56 57 XVisualInfo vi32; 58 if (findVisual32(display, &vi32) < 0) { 59 fatal("32bit-deep visual info not found"); 60 } 61 Colormap colormap32 = XCreateColormap(display, DefaultRootWindow(display), vi32.visual, AllocNone); 62 XSetWindowAttributes attr32 = { 63 .border_pixel = 114514, 64 .colormap = colormap32, 65 }; 66 Window window32 = XCreateWindow(display, DefaultRootWindow(display), 67 0, 0, 1, 1, 0, 68 32, 69 InputOutput, 70 vi32.visual, 71 CWBorderPixel|CWColormap, 72 &attr32); 73 74 int width1 = 300, height1 = 300; 75 Pixmap pixmap32_1 = XCreatePixmap(display, window32, width1, height1, 32); 76 Picture picture32_1 = XRenderCreatePicture(display, pixmap32_1, &pictformat32, 0, NULL); 77 XRenderColor color1 = { .red = 0xffff, .green = 0, .blue = 0, .alpha = 0x3fff }; 78 XRectangle rectangle1 = { .x = 0, .y = 0, .width = width1, .height = height1 }; 79 XRenderFillRectangles(display, PictOpSrc, picture32_1, &color1, &rectangle1, 1); 80 81 int width2 = 300, height2 = 200; 82 Pixmap pixmap32_2 = XCreatePixmap(display, window32, width2, height2, 32); 83 Picture picture32_2 = XRenderCreatePicture(display, pixmap32_2, &pictformat32, 0, NULL); 84 XRenderColor color2 = { .red = 0, .green = 0xffff, .blue = 0, .alpha = 0x3fff }; 85 XRectangle rectangle2 = { .x = 0, .y = 0, .width = width2, .height = height2 }; 86 XRenderFillRectangles(display, PictOpSrc, picture32_2, &color2, &rectangle2, 1); 87 88 int width3 = 300, height3 = 300; 89 Pixmap pixmap32_3 = XCreatePixmap(display, window32, width3, height3, 32); 90 Picture picture32_3 = XRenderCreatePicture(display, pixmap32_3, &pictformat32, 0, NULL); 91 XRenderColor color3 = { .red = 0, .green = 0, .blue = 0xffff, .alpha = 0x3fff }; 92 XRectangle rectangle3 = { .x = 0, .y = 0, .width = width3, .height = height3 }; 93 XRenderFillRectangles(display, PictOpSrc, picture32_3, &color3, &rectangle3, 1); 94 95 XSync(display, 0); 96 int quit = 0; 97 XEvent event; 98 while (!quit) { 99 XRenderFillRectangles(display, PictOpSrc, picture, &color, &rectangle, 1); 100 XRenderComposite(display, PictOpOver, picture32_1, 0, picture, 0, 0, 0, 0, 100, 100, width1, height1); 101 XRenderComposite(display, PictOpOver, picture32_2, 0, picture, 0, 0, 0, 0, 200, 150, width2, height2); 102 XRenderComposite(display, PictOpOver, picture32_3, 0, picture, 0, 0, 0, 0, 150, 200, width3, height3); 103 104 XNextEvent(display, &event); 105 if (event.type == KeyPress && event.xkey.keycode == 49) { 106 quit = 1; 107 } 108 } 109 110 XFreePixmap(display, pixmap32_3); 111 XRenderFreePicture(display, picture32_3); 112 XFreePixmap(display, pixmap32_2); 113 XRenderFreePicture(display, picture32_2); 114 XFreePixmap(display, pixmap32_1); 115 XRenderFreePicture(display, picture32_1); 116 XDestroyWindow(display, window32); 117 118 XRenderFreePicture(display, picture); 119 XDestroyWindow(display, window); 120 121 XCloseDisplay(display); 122 123 return 0; 124 } 125 126 void fatal(char *msg) { 127 fprintf(stderr, "%s\n", msg); 128 exit(1); 129 } 130 131 int findVisual32(Display *display, XVisualInfo *return_visual_info) { 132 long mask = VisualDepthMask|VisualRedMaskMask|VisualGreenMaskMask|VisualBlueMaskMask; 133 XVisualInfo template = { 134 .depth = 32, 135 .red_mask = 0xff0000, 136 .green_mask = 0x00ff00, 137 .blue_mask = 0x0000ff, 138 }; 139 int n; 140 XVisualInfo *vinfos = XGetVisualInfo(display, mask, &template, &n); 141 if (n == 0) { 142 return -1; 143 } 144 *return_visual_info = vinfos[0]; 145 XFree(vinfos); 146 return 0; 147 } 148 149 int findPictFormat(Display *display, int depth, XRenderPictFormat *return_pictformat) { 150 long mask = PictFormatType | PictFormatDepth | 151 PictFormatRed | PictFormatRedMask | 152 PictFormatGreen | PictFormatGreenMask | 153 PictFormatBlue | PictFormatBlueMask; 154 XRenderDirectFormat directformat24 = { 155 .red = 16, 156 .redMask = 0xff, 157 .green = 8, 158 .greenMask = 0xff, 159 .blue = 0, 160 .blueMask = 0xff, 161 }; 162 XRenderDirectFormat directformat32 = { 163 .alpha = 24, 164 .alphaMask = 0xff, 165 .red = 16, 166 .redMask = 0xff, 167 .green = 8, 168 .greenMask = 0xff, 169 .blue = 0, 170 .blueMask = 0xff, 171 }; 172 XRenderPictFormat template = { 173 .type = PictTypeDirect, 174 .depth = depth, 175 }; 176 if (depth == 32) { 177 mask |= PictFormatAlpha | PictFormatAlphaMask; 178 template.direct = directformat32; 179 } else if (depth == 24) { 180 template.direct = directformat24; 181 } else { 182 fatal("unsupported depth"); 183 } 184 XRenderPictFormat *f = XRenderFindFormat(display, mask, &template, 0); 185 if (!f) { 186 return -1; 187 } 188 *return_pictformat = *f; 189 return 0; 190 }