summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSøren Sandmann Pedersen <ssp@redhat.com>2011-12-08 19:40:54 -0500
committerSøren Sandmann Pedersen <ssp@redhat.com>2011-12-08 19:40:54 -0500
commit4bdb829f0a41f82320f8fd84b681e6050a0e92c8 (patch)
treeda5b3bde50f8fbe945d3680271bad82392173e3e
parent445e7f394d709d25ed05d1f2b159acabd189728a (diff)
Motion events
-rw-r--r--main.c3
-rw-r--r--window.c112
-rw-r--r--window.h8
3 files changed, 122 insertions, 1 deletions
diff --git a/main.c b/main.c
index c328052..973499f 100644
--- a/main.c
+++ b/main.c
@@ -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
diff --git a/window.c b/window.c
index ed4b850..cf65e6c 100644
--- a/window.c
+++ b/window.c
@@ -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;
}
diff --git a/window.h b/window.h
index 4f569d7..f2ae17c 100644
--- a/window.h
+++ b/window.h
@@ -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 */