From fbf50bbc03b154f82efc85756e735e1c66c67cfb Mon Sep 17 00:00:00 2001 From: Søren Sandmann Pedersen Date: Thu, 8 Dec 2011 22:57:21 -0500 Subject: More event handling --- main.c | 215 ++++++++++++++++++++++++++++++++++++++++++++------------------- window.c | 53 ++++++++++++---- window.h | 13 +++- 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 +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,9 +693,21 @@ 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) { @@ -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, -- cgit v1.2.3