summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSøren Sandmann Pedersen <ssp@redhat.com>2011-12-08 19:11:35 -0500
committerSøren Sandmann Pedersen <ssp@redhat.com>2011-12-08 19:11:35 -0500
commit445e7f394d709d25ed05d1f2b159acabd189728a (patch)
treef24b65b4e2dc3357a552c8f2e641872e1650c253
parent81653f78a1568ba497fe19c4bcfbe1430445ef86 (diff)
Events
-rw-r--r--list.h15
-rw-r--r--window.c81
-rw-r--r--window.h26
3 files changed, 111 insertions, 11 deletions
diff --git a/list.h b/list.h
index c78e1c3..aae194c 100644
--- a/list.h
+++ b/list.h
@@ -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)
{
diff --git a/window.c b/window.c
index eef465f..ed4b850 100644
--- a/window.c
+++ b/window.c
@@ -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, &copy->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;
}
diff --git a/window.h b/window.h
index a6f4eb9..4f569d7 100644
--- a/window.h
+++ b/window.h
@@ -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);