diff options
Diffstat (limited to 'window.c')
-rw-r--r-- | window.c | 92 |
1 files changed, 89 insertions, 3 deletions
@@ -1,6 +1,7 @@ #include <stdlib.h> #include <X11/Xlib.h> #include <X11/Xutil.h> +#include <assert.h> #include "window.h" struct ws_t @@ -10,6 +11,7 @@ struct ws_t pixman_format_code_t format; pixman_bool_t composited; pixman_bool_t has_alpha; + int byte_order; }; struct window_t @@ -42,6 +44,43 @@ popcount (uint32_t v) return n; } +/* A mask consisting of N bits set to 1. */ +#define MASK(N) ((1UL << (N))-1) + +static void +format_to_masks (pixman_format_code_t format, + uint32_t *alpha, + uint32_t *red, + uint32_t *green, + uint32_t *blue) +{ + int a, r, g, b; + + a = PIXMAN_FORMAT_A (format); + r = PIXMAN_FORMAT_R (format); + g = PIXMAN_FORMAT_G (format); + b = PIXMAN_FORMAT_B (format); + + if (PIXMAN_FORMAT_TYPE (format) == PIXMAN_TYPE_ARGB) + { + *alpha = MASK (a) << (r + g + b); + *red = MASK (r) << (g + b); + *green = MASK (g) << (g); + *blue = MASK (b); + } + else if (PIXMAN_FORMAT_TYPE (format) == PIXMAN_TYPE_ABGR) + { + *alpha = MASK (a) << (b + g + r); + *red = MASK (r) << (g + r); + *green = MASK (g) << (r); + *blue = MASK (b); + } + else + { + assert (0); + } +} + static pixman_bool_t visual_to_format (Visual *visual, int depth, pixman_format_code_t *format_o) { @@ -90,6 +129,7 @@ ws_open (void) ws_t *ws; Display *display; int depth; + int x; if (!(display = XOpenDisplay (NULL))) return NULL; @@ -135,6 +175,13 @@ ws_open (void) if (!visual_to_format (ws->visual, depth, &ws->format)) return NULL; + x = 1; + + if (*(char *)&x == 1) + ws->byte_order = LSBFirst; + else + ws->byte_order = MSBFirst; + return ws; } @@ -292,7 +339,7 @@ ws_window_copy_from_image (window_t *window, { /* copy from image to backing */ pixman_image_composite32 (PIXMAN_OP_SRC, - window->backing_store, NULL, image, + image, NULL, window->backing_store, win_x, win_y, 0, 0, image_x, image_y, width, height); } @@ -309,7 +356,7 @@ ws_window_copy_to_image (window_t *window, { /* copy from backing to image */ pixman_image_composite32 (PIXMAN_OP_SRC, - image, NULL, window->backing_store, + window->backing_store, NULL, image, image_x, image_y, 0, 0, win_x, win_y, width, height); } @@ -318,5 +365,44 @@ void ws_window_finish (window_t **windows, int n_windows) { - + int i; + + for (i = 0; i < n_windows; ++i) + { + window_t *window = windows[i]; + pixman_format_code_t format = window->ws->format; + Display *dpy = window->ws->display; + uint32_t a, r, g, b; + XImage image; + XGCValues values; + GC gc; + + format_to_masks (format, &a, &r, &g, &b); + + image.width = get_width (window); + image.height = get_height (window); + image.xoffset = 0; + image.format = ZPixmap; + image.data = (char *)pixman_image_get_data (window->backing_store); + image.byte_order = window->ws->byte_order; + image.bitmap_unit = 32; + image.bitmap_bit_order = window->ws->byte_order; + image.bitmap_pad = 32; + image.depth = PIXMAN_FORMAT_DEPTH (format); + image.bytes_per_line = pixman_image_get_stride (window->backing_store); + image.bits_per_pixel = PIXMAN_FORMAT_BPP (format); + image.red_mask = r; + image.green_mask = g; + image.blue_mask = b; + + XInitImage (&image); + + gc = XCreateGC (dpy, window->xid, 0, &values); + + XPutImage (dpy, window->xid, gc, &image, + 0, 0, 0, 0, image.width, image.height); + + XFreeGC (dpy, gc); + XFlush (dpy); + } } |