diff options
author | Søren Sandmann Pedersen <ssp@redhat.com> | 2011-12-08 19:40:54 -0500 |
---|---|---|
committer | Søren Sandmann Pedersen <ssp@redhat.com> | 2011-12-08 19:40:54 -0500 |
commit | 4bdb829f0a41f82320f8fd84b681e6050a0e92c8 (patch) | |
tree | da5b3bde50f8fbe945d3680271bad82392173e3e | |
parent | 445e7f394d709d25ed05d1f2b159acabd189728a (diff) |
Motion events
-rw-r--r-- | main.c | 3 | ||||
-rw-r--r-- | window.c | 112 | ||||
-rw-r--r-- | window.h | 8 |
3 files changed, 122 insertions, 1 deletions
@@ -52,7 +52,10 @@ main () tv.tv_sec = 5; if (!ws_pending (ws)) + { + printf ("select\n"); select (fd + 1, &set, NULL, NULL, NULL); + } ws_process (ws); #if 0 @@ -30,6 +30,7 @@ struct window_t int x, y; pixman_region32_t repaint; list_t event_queue; + uint32_t motion_notify_time; }; static pixman_bool_t @@ -413,6 +414,102 @@ emit_events (window_t *window) } } +typedef struct +{ + Window window; + uint32_t last_motion_time; + pixman_bool_t stop_compressing; +} event_scanner_data_t; + +static pixman_bool_t +get_motion_time (Display *dpy, XEvent *event, XPointer arg) +{ + event_scanner_data_t *data = (event_scanner_data_t *)arg; + + if (data->stop_compressing) + return FALSE; + + if (data->window != event->xany.window) + { + data->stop_compressing = TRUE; + return FALSE; + } + + if (event->type == MotionNotify) + { + data->last_motion_time = event->xmotion.time; + return FALSE; + } + + if (event->type == EnterNotify || + event->type == LeaveNotify) + { + data->last_motion_time = event->xcrossing.time; + return FALSE; + } + + return FALSE; +} + +static int +use_this_motion_notify (Display *dpy, window_t *window, + uint32_t event_time) +{ + if (window->motion_notify_time) + { + if (event_time >= window->motion_notify_time) + { + window->motion_notify_time = 0; + + return TRUE; + } + else + { + /* More motion events are already queued up */ + printf ("skipping event\n"); + return FALSE; + } + } + else + { + event_scanner_data_t data = { window->xid, 0, FALSE }; + XEvent dummy; + + XCheckIfEvent (dpy, &dummy, get_motion_time, (XPointer)&data); + + if (data.last_motion_time == 0) + { + return TRUE; + } + else + { + window->motion_notify_time = data.last_motion_time; + return FALSE; + } + } +} + +static void +process_motion (ws_t *ws, Window xwindow, uint32_t time, int x, int y) +{ + window_t *window; + + if (!(window = find_window (ws, xwindow))) + return; + + if (use_this_motion_notify (ws->display, window, time)) + { + ws_event_t wsevent; + + wsevent.motion.common.type = WS_MOTION; + wsevent.motion.window = window; + wsevent.motion.x = x; + wsevent.motion.y = y; + + window_queue_event (window, &wsevent); + } +} + void ws_process (ws_t *ws) { @@ -436,6 +533,16 @@ ws_process (ws_t *ws) process_expose (ws, &event); break; case MotionNotify: + process_motion (ws, + event.xmotion.window, event.xmotion.time, + event.xmotion.x, event.xmotion.y); + break; + case EnterNotify: + case LeaveNotify: + process_motion (ws, + event.xcrossing.window, event.xcrossing.time, + event.xcrossing.x, event.xcrossing.y); + break; case ButtonPress: case ButtonRelease: ; @@ -504,10 +611,13 @@ ws_create_window (ws_t *ws, list_prepend (&ws->windows, &window->link); - XSelectInput (ws->display, window->xid, ExposureMask | StructureNotifyMask); + XSelectInput (ws->display, window->xid, ExposureMask | StructureNotifyMask | + PointerMotionMask | EnterWindowMask | LeaveWindowMask ); pixman_region32_init (&window->repaint); list_init (&window->event_queue); + + window->motion_notify_time = 0; return window; } @@ -25,6 +25,7 @@ typedef union ws_event_t ws_event_t; typedef enum { WS_CONFIGURE, + WS_MOTION } ws_event_type_t; typedef struct @@ -44,6 +45,13 @@ union ws_event_t window_t * window; } configure; + struct + { + ws_event_common_t common; + window_t * window; + int x; + int y; + } motion; }; /* Window system */ |