summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSøren Sandmann Pedersen <ssp@l3000.localdomain>2011-12-08 02:44:48 -0500
committerSøren Sandmann Pedersen <ssp@l3000.localdomain>2011-12-08 02:44:48 -0500
commit388ca819efa64a12e28250b6fca3b83d2b30c9fa (patch)
tree0a1a76f348f8d287f95810159d24572e736b2c24
parent4ca2ad5eb73c1ca0c5641e11f78f54421b2fa537 (diff)
More event processing
-rw-r--r--main.c4
-rw-r--r--window.c227
-rw-r--r--window.h9
3 files changed, 166 insertions, 74 deletions
diff --git a/main.c b/main.c
index 7840510..43bfb89 100644
--- a/main.c
+++ b/main.c
@@ -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);
}
diff --git a/window.c b/window.c
index 73b9987..8717cbe 100644
--- a/window.c
+++ b/window.c
@@ -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);
}
}
diff --git a/window.h b/window.h
index fad1049..2a47fae 100644
--- a/window.h
+++ b/window.h
@@ -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);