summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSøren Sandmann Pedersen <ssp@redhat.com>2011-12-08 22:57:21 -0500
committerSøren Sandmann Pedersen <ssp@redhat.com>2011-12-08 22:57:21 -0500
commitfbf50bbc03b154f82efc85756e735e1c66c67cfb (patch)
tree17903300b4e21d84dd3fcd101b3c81b85d59d64f
parent58b172153a94061d1f6b5c781980d6347e7a9359 (diff)
More event handling
-rw-r--r--main.c215
-rw-r--r--window.c53
-rw-r--r--window.h13
3 files changed, 203 insertions, 78 deletions
diff --git a/main.c b/main.c
index a87c2ee..9a50e0e 100644
--- a/main.c
+++ b/main.c
@@ -4,6 +4,132 @@
/* According to POSIX.1-2001 */
#include <sys/select.h>
+static void
+repaint (window_t *window)
+{
+ pixman_color_t color = { 0xffff, 0xabcd, 0x7777, 0xaaaa };
+ pixman_color_t bg = { 0x0, 0x0, 0x0, 0xffff };
+ pixman_point_fixed_t p1 = { 0, 0 };
+ pixman_point_fixed_t p2 = { 0, 0 };
+ pixman_gradient_stop_t stops[3] =
+ {
+ { pixman_int_to_fixed (0), { 0x2222, 0x2222, 0xeeee, 0xeeee } },
+ { pixman_double_to_fixed (0.5), { 0xdddd, 0xdddd, 0x0000, 0xdddd } },
+ { pixman_int_to_fixed (1), { 0xffff, 0x1111, 0x1111, 0xdddd } }
+ };
+ pixman_image_t *image;
+ int w, h;
+
+#if 0
+ color.red = rand();
+ color.blue = rand();
+#endif
+
+ w = ws_window_get_width (window);
+ h = ws_window_get_height (window);
+
+ image = pixman_image_create_solid_fill (&bg);
+ ws_window_copy_from_image (window, image, 0, 0, 0, 0, w, h);
+ pixman_image_unref (image);
+
+#if 0
+ p2.x = w << 16;
+ p2.y = h << 16;
+ image = pixman_image_create_linear_gradient (&p1, &p2, stops, 3);
+ ws_window_copy_from_image (window, image, 0, 0, 0, 0, w, h);
+ pixman_image_unref (image);
+#endif
+
+ image = pixman_image_create_solid_fill (&color);
+ ws_window_copy_from_image (window, image, 0, 0, 0, 0, 20, h);
+ ws_window_copy_from_image (window, image, 0, 0, w - 20, 0, 20, h);
+ ws_window_copy_from_image (window, image, 0, 0, 0, 0, w, 20);
+ ws_window_copy_from_image (window, image, 0, 0, 0, h - 20, w, 20);
+ pixman_image_unref (image);
+
+ image = pixman_image_create_solid_fill (&bg);
+ ws_window_copy_from_image (window, image, 0, 0, 0, 0, 1, h);
+ ws_window_copy_from_image (window, image, 0, 0, w - 1, 0, 1, h);
+ ws_window_copy_from_image (window, image, 0, 0, 0, 0, w, 1);
+ ws_window_copy_from_image (window, image, 0, 0, 0, h - 1, w, 1);
+ pixman_image_unref (image);
+
+ ws_window_finish (&window, 1);
+}
+
+int need_repaint = 0;
+int dragging = 0;
+int drag_x = -1;
+int drag_y = -1;
+int drag_w = -1;
+int drag_h = -1;
+int drag_pos_x = -1;
+int drag_pos_y = -1;
+
+static void
+on_event (window_t *window, ws_event_t *event, void *data)
+{
+ int w = ws_window_get_width (window);
+ int h = ws_window_get_height (window);
+ int x = ws_window_get_x (window);
+ int y = ws_window_get_y (window);
+
+ switch (event->common.type)
+ {
+ case WS_CONFIGURE:
+ printf ("configure %d %d %d %d\n", x, y, w, h);
+ need_repaint = 1;
+ break;
+
+ case WS_BUTTON_DOWN:
+ if (!dragging)
+ {
+ if (event->button.x > w - 20 &&
+ event->button.y > h - 20)
+ {
+ dragging = 1;
+ }
+ else if (event->button.y < 20)
+ {
+ dragging = 2;
+ }
+
+ if (dragging)
+ {
+ drag_x = event->button.root_x;
+ drag_y = event->button.root_y;
+ drag_w = w;
+ drag_h = h;
+ drag_pos_x = x;
+ drag_pos_y = y;
+ }
+ }
+ break;
+
+ case WS_BUTTON_UP:
+ if (dragging)
+ dragging = 0;
+ break;
+
+ case WS_MOTION:
+ if (dragging == 1)
+ {
+ int dx = event->motion.root_x - drag_x;
+ int dy = event->motion.root_y - drag_y;
+
+ ws_window_resize (window, drag_w + dx, drag_h + dy);
+ need_repaint = 1;
+ }
+ else if (dragging == 2)
+ {
+ int dx = event->motion.root_x - drag_x;
+ int dy = event->motion.root_y - drag_y;
+
+ ws_window_move (window, drag_pos_x + dx, drag_pos_y + dy);
+ }
+ }
+}
+
int
main ()
{
@@ -12,90 +138,49 @@ main ()
pixman_image_t *image;
pixman_color_t color = { 0xffff, 0xabcd, 0x7777, 0x7777 };
fd_set set;
-
+ int fd;
+
if (!ws)
{
printf ("could not open display\n");
return 0;
}
-
+
+ fd = ws_get_fd (ws);
+
window = ws_create_window (ws, 300, 200, 200, 200);
-
+
+ ws_window_set_callback (window, on_event, ws);
+
ws_window_show (window);
-
+
image = pixman_image_create_solid_fill (&color);
ws_window_copy_from_image (window, image, 0, 0, 0, 0, 200, 200);
ws_window_finish (&window, 1);
ws_process (ws);
-
+
while (1)
{
- pixman_color_t color = { 0xffff, 0xabcd, 0x7777, 0xaaaa };
- pixman_color_t bg = { 0x0, 0x0, 0x0, 0xffff };
- pixman_point_fixed_t p1 = { 0, 0 };
- pixman_point_fixed_t p2 = { 0, 0 };
- pixman_gradient_stop_t stops[3] =
- {
- { pixman_int_to_fixed (0), { 0x2222, 0x2222, 0xeeee, 0xeeee } },
- { pixman_double_to_fixed (0.5), { 0xdddd, 0xdddd, 0x0000, 0xdddd } },
- { pixman_int_to_fixed (1), { 0xffff, 0x1111, 0x1111, 0xdddd } }
- };
- int fd = ws_get_fd (ws);
- struct timeval tv;
- pixman_image_t *image;
- int w, h;
-
- FD_ZERO (&set);
- FD_SET (fd, &set);
-
- tv.tv_usec = 0;
- tv.tv_sec = 5;
-
if (!ws_pending (ws))
{
- printf ("select\n");
+ struct timeval tv;
+
+ FD_ZERO (&set);
+ FD_SET (fd, &set);
+
+ tv.tv_usec = 0;
+ tv.tv_sec = 5;
+
select (fd + 1, &set, NULL, NULL, NULL);
}
ws_process (ws);
-
-#if 0
- color.red = rand();
- color.blue = rand();
-#endif
-
- w = ws_window_get_width (window);
- h = ws_window_get_height (window);
-
- image = pixman_image_create_solid_fill (&bg);
- ws_window_copy_from_image (window, image, 0, 0, 0, 0, w, h);
- pixman_image_unref (image);
-
- p2.x = w << 16;
- p2.y = h << 16;
- image = pixman_image_create_linear_gradient (&p1, &p2, stops, 3);
- ws_window_copy_from_image (window, image, 0, 0, 0, 0, w, h);
- pixman_image_unref (image);
-
- image = pixman_image_create_solid_fill (&color);
- ws_window_copy_from_image (window, image, 0, 0, 0, 0, 20, h);
- ws_window_copy_from_image (window, image, 0, 0, w - 20, 0, 20, h);
- ws_window_copy_from_image (window, image, 0, 0, 0, 0, w, 20);
- ws_window_copy_from_image (window, image, 0, 0, 0, h - 20, w, 20);
- pixman_image_unref (image);
-
- image = pixman_image_create_solid_fill (&bg);
- ws_window_copy_from_image (window, image, 0, 0, 0, 0, 1, h);
- ws_window_copy_from_image (window, image, 0, 0, w - 1, 0, 1, h);
- ws_window_copy_from_image (window, image, 0, 0, 0, 0, w, 1);
- ws_window_copy_from_image (window, image, 0, 0, 0, h - 1, w, 1);
- pixman_image_unref (image);
-
- ws_window_resize (window, 700, 700);
- ws_window_move (window, 600, 200);
-
- ws_window_finish (&window, 1);
+ if (need_repaint)
+ {
+ repaint (window);
+ need_repaint = 0;
+ }
}
-
+
while (1)
;
return 0;
diff --git a/window.c b/window.c
index 2757858..b176780 100644
--- a/window.c
+++ b/window.c
@@ -32,6 +32,9 @@ struct window_t
pixman_region32_t repaint;
list_t event_queue;
uint32_t motion_notify_time;
+
+ ws_event_func_t event_func;
+ void * event_data;
};
static pixman_bool_t
@@ -246,6 +249,18 @@ ws_window_get_height (window_t *window)
return get_height (window);
}
+int
+ws_window_get_x (window_t *window)
+{
+ return window->x;
+}
+
+int
+ws_window_get_y (window_t *window)
+{
+ return window->y;
+}
+
static void
copy_backing_store_to_window (window_t *window, int x, int y, int width, int height)
{
@@ -342,8 +357,6 @@ process_configure_notify (ws_t *ws, XEvent *event)
Window child_window;
Display *dpy = window->ws->display;
- printf ("new untranslated: %d %d\n",
- event->xconfigure.x, event->xconfigure.y);
XTranslateCoordinates (
dpy, window->xid, RootWindow (dpy, 0), 0, 0, &new_x, &new_y,
&child_window);
@@ -357,8 +370,6 @@ process_configure_notify (ws_t *ws, XEvent *event)
new_width = event->xconfigure.width;
new_height = event->xconfigure.height;
- printf ("new: %d %d %d %d\n", new_x, new_y, new_width, new_height);
-
/* If we are configure to a new size, then notify the user */
config_type = 0;
@@ -412,7 +423,8 @@ emit_events (window_t *window)
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);
+ if (window->event_func)
+ window->event_func (window, event, window->event_data);
list_unlink (link);
free (event);
@@ -471,7 +483,6 @@ use_this_motion_notify (Display *dpy, window_t *window,
else
{
/* More motion events are already queued up */
- printf ("skipping event\n");
return FALSE;
}
}
@@ -488,7 +499,6 @@ use_this_motion_notify (Display *dpy, window_t *window,
}
else
{
- printf ("skipping event initially\n");
window->motion_notify_time = data.last_motion_time;
return FALSE;
}
@@ -496,7 +506,8 @@ use_this_motion_notify (Display *dpy, window_t *window,
}
static void
-process_motion (ws_t *ws, Window xwindow, uint32_t time, int x, int y)
+process_motion (ws_t *ws, Window xwindow, uint32_t time,
+ int x, int y, int root_x, int root_y)
{
window_t *window;
@@ -511,6 +522,8 @@ process_motion (ws_t *ws, Window xwindow, uint32_t time, int x, int y)
wsevent.motion.window = window;
wsevent.motion.x = x;
wsevent.motion.y = y;
+ wsevent.motion.root_x = root_x;
+ wsevent.motion.root_y = root_y;
window_queue_event (window, &wsevent);
}
@@ -529,7 +542,9 @@ process_button_event (ws_t *ws, ws_event_type_t type, const XEvent *event)
wsevent.button.window = window;
wsevent.button.x = event->xbutton.x;
wsevent.button.y = event->xbutton.y;
-
+ wsevent.button.root_x = event->xbutton.x_root;
+ wsevent.button.root_y = event->xbutton.y_root;
+
window_queue_event (window, &wsevent);
}
@@ -558,13 +573,15 @@ ws_process (ws_t *ws)
case MotionNotify:
process_motion (ws,
event.xmotion.window, event.xmotion.time,
- event.xmotion.x, event.xmotion.y);
+ event.xmotion.x, event.xmotion.y,
+ event.xmotion.x_root, event.xmotion.y_root);
break;
case EnterNotify:
case LeaveNotify:
process_motion (ws,
event.xcrossing.window, event.xcrossing.time,
- event.xcrossing.x, event.xcrossing.y);
+ event.xcrossing.x, event.xcrossing.y,
+ event.xcrossing.x_root, event.xcrossing.y_root);
break;
case ButtonPress:
process_button_event (ws, WS_BUTTON_DOWN, &event);
@@ -676,10 +693,22 @@ ws_create_window (ws_t *ws,
disable_decorations (window);
+ window->event_func = NULL;
+ window->event_data = NULL;
+
return window;
}
void
+ws_window_set_callback (window_t *window,
+ ws_event_func_t func,
+ void * data)
+{
+ window->event_func = func;
+ window->event_data = data;
+}
+
+void
ws_window_ref (window_t *window)
{
window->ref_count++;
@@ -721,7 +750,7 @@ ws_window_move_resize (window_t *window,
need |= 1;
if (width != get_width (window) || height != get_height (window))
need |= 2;
-
+
update_local_geometry (window, x, y, width, height);
switch (need)
diff --git a/window.h b/window.h
index 1d86164..6d374fb 100644
--- a/window.h
+++ b/window.h
@@ -24,7 +24,7 @@ typedef union ws_event_t ws_event_t;
typedef enum
{
- WS_CONFIGURE,
+ WS_CONFIGURE, // FIXME: rename to USER_POSITION?
WS_MOTION,
WS_BUTTON_DOWN,
WS_BUTTON_UP
@@ -53,6 +53,8 @@ union ws_event_t
window_t * window;
int x;
int y;
+ int root_x;
+ int root_y;
} motion;
struct
@@ -62,9 +64,13 @@ union ws_event_t
int button;
int x;
int y;
+ int root_x;
+ int root_y;
} button, button_up, button_down;
};
+typedef void (* ws_event_func_t) (window_t *window, ws_event_t *event, void *data);
+
/* Window system */
ws_t * ws_open (void);
int ws_get_width (ws_t *ws);
@@ -79,6 +85,9 @@ window_t *ws_create_window (ws_t *ws,
int y,
int width,
int height);
+void ws_window_set_callback (window_t *window,
+ ws_event_func_t func,
+ void * data);
void ws_window_ref (window_t *window);
void ws_window_unref (window_t *window);
void ws_window_show (window_t *window);
@@ -88,6 +97,8 @@ void ws_window_move (window_t *window,
int y);
int ws_window_get_width (window_t *window);
int ws_window_get_height (window_t *window);
+int ws_window_get_x (window_t *window);
+int ws_window_get_y (window_t *window);
void ws_window_resize (window_t *window,
int w,