diff options
author | Søren Sandmann Pedersen <ssp@redhat.com> | 2011-12-08 19:11:35 -0500 |
---|---|---|
committer | Søren Sandmann Pedersen <ssp@redhat.com> | 2011-12-08 19:11:35 -0500 |
commit | 445e7f394d709d25ed05d1f2b159acabd189728a (patch) | |
tree | f24b65b4e2dc3357a552c8f2e641872e1650c253 | |
parent | 81653f78a1568ba497fe19c4bcfbe1430445ef86 (diff) |
Events
-rw-r--r-- | list.h | 15 | ||||
-rw-r--r-- | window.c | 81 | ||||
-rw-r--r-- | window.h | 26 |
3 files changed, 111 insertions, 11 deletions
@@ -33,12 +33,27 @@ list_prepend (list_t *list, link_t *link) } static inline void +list_append (list_t *list, link_t *link) +{ + link->prev = list->tail; + link->next = (link_t *)list; + list->tail->next = link; + list->tail = link; +} + +static inline void list_unlink (link_t *link) { link->prev->next = link->next; link->next->prev = link->prev; } +static inline int +list_is_empty (list_t *list) +{ + return list->head == (link_t *)list; +} + static inline void list_move_to_front (list_t *list, link_t *link) { @@ -28,6 +28,8 @@ struct window_t int ref_count; pixman_image_t * backing_store; int x, y; + pixman_region32_t repaint; + list_t event_queue; }; static pixman_bool_t @@ -310,6 +312,16 @@ update_local_geometry (window_t *window, int x, int y, int width, int height) } static void +window_queue_event (window_t *window, const ws_event_t *event) +{ + ws_event_t *copy = malloc (sizeof *copy); + + *copy = *event; + + list_append (&window->event_queue, ©->common.link); +} + +static void process_configure_notify (ws_t *ws, XEvent *event) { window_t *window; @@ -355,9 +367,13 @@ process_configure_notify (ws_t *ws, XEvent *event) if (config_type) { - /* FIXME: emit an event indicating that the window\ - * manager changed the size behind our back - */ + ws_event_t wsevent; + + wsevent.configure.common.type = WS_CONFIGURE; + wsevent.configure.configure_type = config_type; + wsevent.configure.window = window; + + window_queue_event (window, &wsevent); } update_local_geometry (window, new_x, new_y, new_width, new_height); @@ -367,12 +383,13 @@ static void process_expose (ws_t *ws, const XEvent *event) { 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); + pixman_region32_union_rect (&window->repaint, &window->repaint, + event->xexpose.x, event->xexpose.y, + event->xexpose.width, event->xexpose.height); } pixman_bool_t @@ -381,11 +398,28 @@ ws_pending (ws_t *ws) return XPending (ws->display); } +static void +emit_events (window_t *window) +{ + while (!list_is_empty (&window->event_queue)) + { + link_t *link = window->event_queue.head; + ws_event_t *event = CONTAINER_OF (ws_event_t, common.link, link); + + printf ("emit %d\n", event->common.type); + + list_unlink (link); + free (event); + } +} + void ws_process (ws_t *ws) { - int n_expose = 0; - int n_configure = 0; + pixman_region32_t expose; + link_t *link; + + pixman_region32_init (&expose); while (ws_pending (ws)) { @@ -396,11 +430,9 @@ ws_process (ws_t *ws) switch (event.type) { case ConfigureNotify: - n_configure++; process_configure_notify (ws, &event); break; case Expose: - n_expose++; process_expose (ws, &event); break; case MotionNotify: @@ -410,7 +442,31 @@ ws_process (ws_t *ws) } } - printf ("expose: %d, configure: %d\n", n_expose, n_configure); + LIST_FOREACH (&ws->windows, link) + { + window_t *window = CONTAINER_OF (window_t, link, link); + pixman_box32_t *boxes; + int n_boxes; + + /* FIXME: when resizing windows, the associated exposes end up + * causing undefined data to be copied to the window. Something + * should perhaps be done about that. For example by keeping + * track of windows bits that haven't been painted, and never + * painting those. + */ + boxes = pixman_region32_rectangles (&window->repaint, &n_boxes); + while (n_boxes--) + { + copy_backing_store_to_window (window, + boxes->x1, boxes->y1, + boxes->x2 - boxes->x1, + boxes->y2 - boxes->y1); + + boxes++; + } + + emit_events (window); + } } /* Window */ @@ -450,6 +506,9 @@ ws_create_window (ws_t *ws, XSelectInput (ws->display, window->xid, ExposureMask | StructureNotifyMask); + pixman_region32_init (&window->repaint); + list_init (&window->event_queue); + return window; } @@ -1,5 +1,6 @@ #include <stdio.h> #include <pixman.h> +#include "list.h" #ifndef FALSE #define FALSE 0 @@ -19,6 +20,31 @@ typedef struct ws_t ws_t; typedef struct drawable_t drawable_t; typedef struct window_t window_t; typedef struct surfade_t surface_t; +typedef union ws_event_t ws_event_t; + +typedef enum +{ + WS_CONFIGURE, +} ws_event_type_t; + +typedef struct +{ + link_t link; + ws_event_type_t type; +} ws_event_common_t; + +union ws_event_t +{ + ws_event_common_t common; + + struct + { + ws_event_common_t common; + ws_window_configure_type_t configure_type; + window_t * window; + } configure; + +}; /* Window system */ ws_t * ws_open (void); |