diff options
author | Søren Sandmann Pedersen <ssp@l3000.localdomain> | 2011-12-08 02:44:48 -0500 |
---|---|---|
committer | Søren Sandmann Pedersen <ssp@l3000.localdomain> | 2011-12-08 02:44:48 -0500 |
commit | 388ca819efa64a12e28250b6fca3b83d2b30c9fa (patch) | |
tree | 0a1a76f348f8d287f95810159d24572e736b2c24 | |
parent | 4ca2ad5eb73c1ca0c5641e11f78f54421b2fa537 (diff) |
More event processing
-rw-r--r-- | main.c | 4 | ||||
-rw-r--r-- | window.c | 227 | ||||
-rw-r--r-- | window.h | 9 |
3 files changed, 166 insertions, 74 deletions
@@ -43,7 +43,9 @@ main () color.blue = rand(); image = pixman_image_create_solid_fill (&color); - ws_window_copy_from_image (window, image, 0, 0, 0, 0, 200, 200); + ws_window_copy_from_image (window, image, 0, 0, 0, 0, + ws_window_get_width (window), + ws_window_get_height (window)); pixman_image_unref (image); ws_window_finish (&window, 1); } @@ -218,16 +218,161 @@ find_window (ws_t *ws, XID xid) return NULL; } +static int +get_width (window_t *window) +{ + return pixman_image_get_width (window->backing_store); +} + +static int +get_height (window_t *window) +{ + return pixman_image_get_height (window->backing_store); +} + +int +ws_window_get_width (window_t *window) +{ + return get_width (window); +} + +int +ws_window_get_height (window_t *window) +{ + return get_height (window); +} + +static void +copy_backing_store_to_window (window_t *window, int x, int y, int width, int height) +{ + 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, + x, y, x, y, width, height); + + XFreeGC (dpy, gc); +} + +#define MIN(a,b) (((a) < (b))? (a) : (b)) + +static void +update_local_geometry (window_t *window, int x, int y, int width, int height) +{ + int old_width = get_width (window); + int old_height = get_height (window); + + if (width != old_width || height != old_height) + { + pixman_image_t *new_backing = + pixman_image_create_bits ( + window->ws->format, width, height, NULL, -1); + + pixman_image_composite32 ( + PIXMAN_OP_SRC, + window->backing_store, NULL, new_backing, + 0, 0, 0, 0, 0, 0, + MIN (width, old_width), + MIN (height, old_height)); + + pixman_image_unref (window->backing_store); + window->backing_store = new_backing; + } + + window->x = x; + window->y = y; +} + static void process_configure_notify (ws_t *ws, XEvent *event) { + window_t *window; + int new_x, new_y; + int new_width, new_height; + ws_window_configure_type_t config_type; + + if (!(window = find_window (ws, event->xexpose.window))) + return; + + new_x = window->x; + new_y = window->y; + + if (!event->xconfigure.send_event && !event->xconfigure.override_redirect) + { + Window child_window; + Display *dpy = window->ws->display; + + XTranslateCoordinates ( + dpy, window->xid, RootWindow (dpy, 0), 0, 0, &new_x, &new_y, + &child_window); + } + else + { + new_x = event->xconfigure.x; + new_y = event->xconfigure.y; + } + + new_width = event->xconfigure.width; + new_height = event->xconfigure.height; + + /* If we are configure to a new size, then notify the user */ + config_type = 0; + + if (new_width != get_width (window) || + new_height != get_height (window)) + { + config_type |= WS_WINDOW_SIZE_CHANGED; + } + + if (new_x != window->x || new_y != window->y) + config_type |= WS_WINDOW_POSITION_CHANGED; + + if (config_type) + { + /* FIXME: emit an event indicating that the window\ + * manager changed the size behind our back + */ + } + + update_local_geometry (window, new_x, new_y, new_width, new_height); } static void process_expose (ws_t *ws, const XEvent *event) { - window_t *window = find_window (ws, event->xexpose.window); - printf ("expose %x\n", window->xid); + window_t *window; + + if (!(window = find_window (ws, event->xexpose.window))) + return; + + copy_backing_store_to_window ( + window, event->xexpose.x, event->xexpose.y, event->xexpose.width, event->xexpose.height); } void @@ -289,7 +434,7 @@ ws_create_window (ws_t *ws, list_prepend (&ws->windows, &window->link); - XSelectInput (ws->display, window->xid, ExposureMask); + XSelectInput (ws->display, window->xid, ExposureMask | StructureNotifyMask); return window; } @@ -323,20 +468,6 @@ ws_window_hide (window_t *window) XUnmapWindow (window->ws->display, window->xid); } -static int -get_width (window_t *window) -{ - return pixman_image_get_width (window->backing_store); -} - -static int -get_height (window_t *window) -{ - return pixman_image_get_height (window->backing_store); -} - -#define MIN(a,b) (((a) < (b))? (a) : (b)) - static void ws_window_move_resize (window_t *window, int x, @@ -344,28 +475,7 @@ ws_window_move_resize (window_t *window, int width, int height) { - int old_width = get_width (window); - int old_height = get_height (window); - - if (width != old_width || height != old_height) - { - pixman_image_t *new_backing = - pixman_image_create_bits ( - window->ws->format, width, height, NULL, -1); - - pixman_image_composite32 ( - PIXMAN_OP_SRC, - window->backing_store, NULL, new_backing, - 0, 0, 0, 0, 0, 0, - MIN (width, old_width), - MIN (height, old_height)); - - pixman_image_unref (window->backing_store); - window->backing_store = new_backing; - } - - window->x = x; - window->y = y; + update_local_geometry (window, x, y, width, height); XMoveResizeWindow ( window->ws->display, window->xid, x, y, width, height); @@ -453,39 +563,10 @@ ws_window_finish (window_t **windows, 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); + + copy_backing_store_to_window ( + window, 0, 0, get_width (window), get_height (window)); + + XFlush (window->ws->display); } } @@ -9,6 +9,12 @@ #define TRUE 1 #endif +typedef enum +{ + WS_WINDOW_SIZE_CHANGED = (1 << 0), + WS_WINDOW_POSITION_CHANGED = (1 << 1) +} ws_window_configure_type_t; + typedef struct ws_t ws_t; typedef struct drawable_t drawable_t; typedef struct window_t window_t; @@ -34,6 +40,9 @@ void ws_window_hide (window_t *window); void ws_window_move (window_t *window, int x, int y); +int ws_window_get_width (window_t *window); +int ws_window_get_height (window_t *window); + void ws_window_resize (window_t *window, int w, int h); |