From b5eca40b64ae2dda71d78ed74f222f24e96a8471 Mon Sep 17 00:00:00 2001 From: Dylan Araps Date: Tue, 21 Jul 2020 09:18:05 +0300 Subject: [PATCH] rewrite --- event.h | 23 ----- sowm.c | 229 +++++++-------------------------------------- sowm2.c | 285 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ types.h | 10 -- 4 files changed, 318 insertions(+), 229 deletions(-) delete mode 100644 event.h create mode 100644 sowm2.c delete mode 100644 types.h diff --git a/event.h b/event.h deleted file mode 100644 index 83e36c1..0000000 --- a/event.h +++ /dev/null @@ -1,23 +0,0 @@ -#include - -#define EVENT_MASK(e) (((e) & ~0x80)) - -void event_button_press(xcb_generic_event_t *ev); -void event_button_release(xcb_generic_event_t *ev); -void event_configure_request(xcb_generic_event_t *ev); -void event_key_press(xcb_generic_event_t *ev); -void event_notify_create(xcb_generic_event_t *ev); -void event_notify_destroy(xcb_generic_event_t *ev); -void event_notify_enter(xcb_generic_event_t *ev); -void event_notify_motion(xcb_generic_event_t *ev); - -void (*events[XCB_NO_OPERATION])(xcb_generic_event_t *) = { - [XCB_BUTTON_PRESS] = event_button_press, - [XCB_BUTTON_RELEASE] = event_button_release, - [XCB_CONFIGURE_REQUEST] = event_configure_request, - [XCB_KEY_PRESS] = event_key_press, - [XCB_CREATE_NOTIFY] = event_notify_create, - [XCB_DESTROY_NOTIFY] = event_notify_destroy, - [XCB_ENTER_NOTIFY] = event_notify_enter, - [XCB_MOTION_NOTIFY] = event_notify_motion -}; diff --git a/sowm.c b/sowm.c index c85ef03..18ecbac 100644 --- a/sowm.c +++ b/sowm.c @@ -5,189 +5,26 @@ #include -#include "event.h" -#include "types.h" - static xcb_connection_t *dpy; static xcb_screen_t *scr; -static xcb_drawable_t root; - -/* required for button press, motion and release */ -static uint32_t motion_vals[3]; -static xcb_window_t motion_win; -static xcb_get_geometry_reply_t *motion_geom; -static int is_motion = 0; static void init_wm(void); static void init_input(void); -static void run_loop(void); -static void win_add(xcb_window_t win); -void event_button_press(xcb_generic_event_t *ev) { - xcb_button_press_event_t *e = (xcb_button_press_event_t *)ev; +void (*events[XCB_NO_OPERATION])(xcb_generic_event_t *) = { + /* [XCB_BUTTON_PRESS] = event_button_press, */ + /* [XCB_BUTTON_RELEASE] = event_button_release, */ + /* [XCB_CONFIGURE_REQUEST] = event_configure_request, */ + /* [XCB_KEY_PRESS] = event_key_press, */ + /* [XCB_CREATE_NOTIFY] = event_notify_create, */ + /* [XCB_DESTROY_NOTIFY] = event_notify_destroy, */ + /* [XCB_ENTER_NOTIFY] = event_notify_enter, */ + /* [XCB_MOTION_NOTIFY] = event_notify_motion */ +}; - if (e->child == root) { - return; - } - - motion_vals[0] = XCB_STACK_MODE_ABOVE; - motion_win = e->child; - is_motion = 1; - - xcb_configure_window(dpy, motion_win, XCB_CONFIG_WINDOW_STACK_MODE, - motion_vals); - - motion_geom = xcb_get_geometry_reply(dpy, - xcb_get_geometry(dpy, motion_win), NULL); - - /* resize */ - if (e->detail == 1) { - xcb_warp_pointer(dpy, XCB_NONE, motion_win, 0, 0, 0, 0, 1, 1); - motion_vals[2] = 1; - - /* move */ - } else { - xcb_warp_pointer(dpy, XCB_NONE, motion_win, 0, 0, 0, 0, 1, 1); - motion_vals[2] = 3; - } - - xcb_grab_pointer(dpy, 0, root, XCB_EVENT_MASK_BUTTON_RELEASE | - XCB_EVENT_MASK_BUTTON_MOTION | XCB_EVENT_MASK_POINTER_MOTION_HINT, - XCB_GRAB_MODE_ASYNC, XCB_GRAB_MODE_ASYNC, root, XCB_NONE, - XCB_CURRENT_TIME); - - xcb_flush(dpy); -} - -void event_button_release(xcb_generic_event_t *ev) { - xcb_ungrab_pointer(dpy, XCB_CURRENT_TIME); - xcb_flush(dpy); - is_motion = 0; -} - -void event_configure_request(xcb_generic_event_t *ev) { - xcb_configure_request_event_t *e = (xcb_configure_request_event_t *)ev; - uint32_t values[7]; - int8_t i = -1; - - if (e->value_mask & XCB_CONFIG_WINDOW_X) { - e->value_mask |= XCB_CONFIG_WINDOW_X; - i++; - values[i] = e->x; - } - - if (e->value_mask & XCB_CONFIG_WINDOW_Y) { - e->value_mask |= XCB_CONFIG_WINDOW_Y; - i++; - values[i] = e->y; - } - - if (e->value_mask & XCB_CONFIG_WINDOW_WIDTH) { - e->value_mask |= XCB_CONFIG_WINDOW_WIDTH; - i++; - values[i] = e->width; - } - - if (e->value_mask & XCB_CONFIG_WINDOW_HEIGHT) { - e->value_mask |= XCB_CONFIG_WINDOW_HEIGHT; - i++; - values[i] = e->height; - } - - if (e->value_mask & XCB_CONFIG_WINDOW_SIBLING) { - e->value_mask |= XCB_CONFIG_WINDOW_SIBLING; - i++; - values[i] = e->sibling; - } - - if (e->value_mask & XCB_CONFIG_WINDOW_STACK_MODE) { - e->value_mask |= XCB_CONFIG_WINDOW_STACK_MODE; - i++; - values[i] = e->stack_mode; - } - - if (i != -1) { - xcb_configure_window(dpy, e->window, e->value_mask, values); - xcb_flush(dpy); - } -} - -void event_key_press(xcb_generic_event_t *ev) { - xcb_key_press_event_t *e = (xcb_key_press_event_t *)ev; -} - -void event_notify_create(xcb_generic_event_t *ev) { - xcb_create_notify_event_t *e = (xcb_create_notify_event_t *)ev; +static void init_wm(void) { uint32_t values[2]; - values[0] = XCB_EVENT_MASK_ENTER_WINDOW | XCB_EVENT_MASK_FOCUS_CHANGE; - values[1] = XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY; - - xcb_change_window_attributes(dpy, e->window, XCB_CW_EVENT_MASK, values); - xcb_map_window(dpy, e->window); -} - -void event_notify_destroy(xcb_generic_event_t *ev) { - xcb_destroy_notify_event_t *e = (xcb_destroy_notify_event_t *)ev; -} - -void event_notify_enter(xcb_generic_event_t *ev) { - xcb_enter_notify_event_t *e = (xcb_enter_notify_event_t *)ev; - - if (e->event == root || is_motion) { - return; - } - - xcb_set_input_focus(dpy, XCB_INPUT_FOCUS_POINTER_ROOT, - e->event, XCB_CURRENT_TIME); - - xcb_flush(dpy); -} - -void event_notify_motion(xcb_generic_event_t *ev) { - xcb_query_pointer_reply_t *ptr; - - ptr = xcb_query_pointer_reply(dpy, xcb_query_pointer(dpy, root), 0); - - /* move */ - if (motion_vals[2] == 1) { - motion_geom = xcb_get_geometry_reply(dpy, - xcb_get_geometry(dpy, motion_win), NULL); - - motion_vals[0] = - (ptr->root_x + motion_geom->width > scr->width_in_pixels)? - (scr->width_in_pixels - motion_geom->width):ptr->root_x; - - motion_vals[1] = - (ptr->root_y + motion_geom->height > scr->height_in_pixels)? - (scr->height_in_pixels - motion_geom->height):ptr->root_y; - - xcb_configure_window(dpy, motion_win, XCB_CONFIG_WINDOW_X | - XCB_CONFIG_WINDOW_Y, motion_vals); - - xcb_flush(dpy); - - /* resize */ - } else if (motion_vals[2] == 3) { - motion_geom = xcb_get_geometry_reply(dpy, - xcb_get_geometry(dpy, motion_win), NULL); - - motion_vals[0] = ptr->root_x - motion_geom->x; - motion_vals[1] = ptr->root_y - motion_geom->y; - - xcb_configure_window(dpy, motion_win, XCB_CONFIG_WINDOW_WIDTH | - XCB_CONFIG_WINDOW_HEIGHT, motion_vals); - - xcb_flush(dpy); - } -} - -void win_add(xcb_window_t win) { - -} - -void init_wm(void) { - uint32_t values[2]; dpy = xcb_connect(NULL, NULL); if (xcb_connection_has_error(dpy)) { @@ -203,42 +40,33 @@ void init_wm(void) { exit(1); } - root = scr->root; - values[0] = XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY; - xcb_change_window_attributes_checked(dpy, root, XCB_CW_EVENT_MASK, values); + + xcb_change_window_attributes_checked(dpy, scr->root, + XCB_CW_EVENT_MASK, values); + xcb_flush(dpy); } -void init_input(void) { - xcb_grab_key(dpy, 1, root, XCB_MOD_MASK_4, XCB_NO_SYMBOL, +static void init_input(void) { + xcb_grab_key(dpy, 1, scr->root, XCB_MOD_MASK_4, XCB_NO_SYMBOL, XCB_GRAB_MODE_ASYNC, XCB_GRAB_MODE_ASYNC); - xcb_grab_button(dpy, 0, root, XCB_EVENT_MASK_BUTTON_PRESS | + xcb_grab_button(dpy, 0, scr->root, XCB_EVENT_MASK_BUTTON_PRESS | XCB_EVENT_MASK_BUTTON_RELEASE, XCB_GRAB_MODE_ASYNC, - XCB_GRAB_MODE_ASYNC, root, XCB_NONE, 1, XCB_MOD_MASK_4); + XCB_GRAB_MODE_ASYNC, scr->root, XCB_NONE, 1, XCB_MOD_MASK_4); - xcb_grab_button(dpy, 0, root, XCB_EVENT_MASK_BUTTON_PRESS | + xcb_grab_button(dpy, 0, scr->root, XCB_EVENT_MASK_BUTTON_PRESS | XCB_EVENT_MASK_BUTTON_RELEASE, XCB_GRAB_MODE_ASYNC, - XCB_GRAB_MODE_ASYNC, root, XCB_NONE, 3, XCB_MOD_MASK_4); + XCB_GRAB_MODE_ASYNC, scr->root, XCB_NONE, 3, XCB_MOD_MASK_4); xcb_flush(dpy); } -void run_loop(void) { +int main(int argc, char **argv) { xcb_generic_event_t *ev; + unsigned int ev_type; - for (;;) { - ev = xcb_wait_for_event(dpy); - - if (events[EVENT_MASK(ev->response_type)]) { - events[EVENT_MASK(ev->response_type)](ev); - } - free(ev); - } -} - -int main(int argc, char *argv[]) { /* unused */ (void) argc; (void) argv; @@ -248,7 +76,16 @@ int main(int argc, char *argv[]) { init_wm(); init_input(); - run_loop(); + + while ((ev = xcb_wait_for_event(dpy))) { + ev_type = ev->response_type & ~0x80; + + if (events[ev_type]) { + events[ev_type](ev); + } + + free(ev); + } return 0; } diff --git a/sowm2.c b/sowm2.c new file mode 100644 index 0000000..21953b6 --- /dev/null +++ b/sowm2.c @@ -0,0 +1,285 @@ +#define _POSIX_C_SOURCE 200809L +#include +#include +#include + +#include + +#include "event.h" +#include "types.h" + +static xcb_connection_t *dpy; +static xcb_screen_t *scr; +static xcb_drawable_t root; + +/* required for button press, motion and release */ +static uint32_t motion_vals[3]; +static xcb_window_t motion_win; +static xcb_get_geometry_reply_t *motion_geom; +static int is_motion = 0; + +static void init_wm(void); +static void init_input(void); +static void run_loop(void); +static void win_add(xcb_window_t win); + +void event_button_press(xcb_generic_event_t *ev) { + xcb_button_press_event_t *e = (xcb_button_press_event_t *)ev; + + if (e->child == root) { + return; + } + + motion_vals[0] = XCB_STACK_MODE_ABOVE; + motion_win = e->child; + is_motion = 1; + + xcb_configure_window(dpy, motion_win, XCB_CONFIG_WINDOW_STACK_MODE, + motion_vals); + + motion_geom = xcb_get_geometry_reply(dpy, + xcb_get_geometry(dpy, motion_win), NULL); + + /* resize */ + if (e->detail == 1) { + xcb_warp_pointer(dpy, XCB_NONE, motion_win, 0, 0, 0, 0, 1, 1); + motion_vals[2] = 1; + + /* move */ + } else { + xcb_warp_pointer(dpy, XCB_NONE, motion_win, 0, 0, 0, 0, 1, 1); + motion_vals[2] = 3; + } + + xcb_grab_pointer(dpy, 0, root, XCB_EVENT_MASK_BUTTON_RELEASE | + XCB_EVENT_MASK_BUTTON_MOTION | XCB_EVENT_MASK_POINTER_MOTION_HINT, + XCB_GRAB_MODE_ASYNC, XCB_GRAB_MODE_ASYNC, root, XCB_NONE, + XCB_CURRENT_TIME); + + xcb_flush(dpy); +} + +void event_button_release(xcb_generic_event_t *ev) { + xcb_ungrab_pointer(dpy, XCB_CURRENT_TIME); + xcb_flush(dpy); + is_motion = 0; +} + +void event_configure_request(xcb_generic_event_t *ev) { + xcb_configure_request_event_t *e = (xcb_configure_request_event_t *)ev; + uint32_t values[7]; + int8_t i = -1; + + if (e->value_mask & XCB_CONFIG_WINDOW_X) { + e->value_mask |= XCB_CONFIG_WINDOW_X; + i++; + values[i] = e->x; + } + + if (e->value_mask & XCB_CONFIG_WINDOW_Y) { + e->value_mask |= XCB_CONFIG_WINDOW_Y; + i++; + values[i] = e->y; + } + + if (e->value_mask & XCB_CONFIG_WINDOW_WIDTH) { + e->value_mask |= XCB_CONFIG_WINDOW_WIDTH; + i++; + values[i] = e->width; + } + + if (e->value_mask & XCB_CONFIG_WINDOW_HEIGHT) { + e->value_mask |= XCB_CONFIG_WINDOW_HEIGHT; + i++; + values[i] = e->height; + } + + if (e->value_mask & XCB_CONFIG_WINDOW_SIBLING) { + e->value_mask |= XCB_CONFIG_WINDOW_SIBLING; + i++; + values[i] = e->sibling; + } + + if (e->value_mask & XCB_CONFIG_WINDOW_STACK_MODE) { + e->value_mask |= XCB_CONFIG_WINDOW_STACK_MODE; + i++; + values[i] = e->stack_mode; + } + + if (i != -1) { + xcb_configure_window(dpy, e->window, e->value_mask, values); + xcb_flush(dpy); + } +} + +void event_key_press(xcb_generic_event_t *ev) { + xcb_key_press_event_t *e = (xcb_key_press_event_t *)ev; +} + +void event_notify_create(xcb_generic_event_t *ev) { + xcb_create_notify_event_t *e = (xcb_create_notify_event_t *)ev; + uint32_t values[2]; + + values[0] = XCB_EVENT_MASK_ENTER_WINDOW | XCB_EVENT_MASK_FOCUS_CHANGE; + values[1] = XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY; + + xcb_change_window_attributes(dpy, e->window, XCB_CW_EVENT_MASK, values); + xcb_map_window(dpy, e->window); +} + +void event_notify_destroy(xcb_generic_event_t *ev) { + xcb_destroy_notify_event_t *e = (xcb_destroy_notify_event_t *)ev; +} + +void event_notify_enter(xcb_generic_event_t *ev) { + xcb_enter_notify_event_t *e = (xcb_enter_notify_event_t *)ev; + + if (e->event == root || is_motion) { + return; + } + + xcb_set_input_focus(dpy, XCB_INPUT_FOCUS_POINTER_ROOT, + e->event, XCB_CURRENT_TIME); + + xcb_flush(dpy); +} + +void event_notify_motion(xcb_generic_event_t *ev) { + xcb_query_pointer_reply_t *ptr; + + ptr = xcb_query_pointer_reply(dpy, xcb_query_pointer(dpy, root), 0); + + /* move */ + if (motion_vals[2] == 1) { + motion_geom = xcb_get_geometry_reply(dpy, + xcb_get_geometry(dpy, motion_win), NULL); + + motion_vals[0] = + (ptr->root_x + motion_geom->width > scr->width_in_pixels)? + (scr->width_in_pixels - motion_geom->width):ptr->root_x; + + motion_vals[1] = + (ptr->root_y + motion_geom->height > scr->height_in_pixels)? + (scr->height_in_pixels - motion_geom->height):ptr->root_y; + + xcb_configure_window(dpy, motion_win, XCB_CONFIG_WINDOW_X | + XCB_CONFIG_WINDOW_Y, motion_vals); + + xcb_flush(dpy); + + /* resize */ + } else if (motion_vals[2] == 3) { + motion_geom = xcb_get_geometry_reply(dpy, + xcb_get_geometry(dpy, motion_win), NULL); + + motion_vals[0] = ptr->root_x - motion_geom->x; + motion_vals[1] = ptr->root_y - motion_geom->y; + + xcb_configure_window(dpy, motion_win, XCB_CONFIG_WINDOW_WIDTH | + XCB_CONFIG_WINDOW_HEIGHT, motion_vals); + + xcb_flush(dpy); + } +} + +void win_add(xcb_window_t win) { + +} + +void init_wm(void) { + uint32_t values[2]; + dpy = xcb_connect(NULL, NULL); + + if (xcb_connection_has_error(dpy)) { + printf("error: Failed to start sowm\n"); + exit(1); + } + + scr = xcb_setup_roots_iterator(xcb_get_setup(dpy)).data; + + if (!scr) { + printf("error: Failed to assign screen number\n"); + xcb_disconnect(dpy); + exit(1); + } + + root = scr->root; + + values[0] = XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY; + xcb_change_window_attributes_checked(dpy, root, XCB_CW_EVENT_MASK, values); + xcb_flush(dpy); +} + +void init_input(void) { + xcb_grab_key(dpy, 1, root, XCB_MOD_MASK_4, XCB_NO_SYMBOL, + XCB_GRAB_MODE_ASYNC, XCB_GRAB_MODE_ASYNC); + + xcb_grab_button(dpy, 0, root, XCB_EVENT_MASK_BUTTON_PRESS | + XCB_EVENT_MASK_BUTTON_RELEASE, XCB_GRAB_MODE_ASYNC, + XCB_GRAB_MODE_ASYNC, root, XCB_NONE, 1, XCB_MOD_MASK_4); + + xcb_grab_button(dpy, 0, root, XCB_EVENT_MASK_BUTTON_PRESS | + XCB_EVENT_MASK_BUTTON_RELEASE, XCB_GRAB_MODE_ASYNC, + XCB_GRAB_MODE_ASYNC, root, XCB_NONE, 3, XCB_MOD_MASK_4); + + xcb_flush(dpy); +} + +void run_loop(void) { + xcb_generic_event_t *ev; + + for (;;) { + ev = xcb_wait_for_event(dpy); + + switch (EVENT_MASK(ev->response_type)) { + case XCB_BUTTON_PRESS: { + break; + } + + case XCB_BUTTON_RELEASE: { + break; + } + + case XCB_CONFIGURE_REQUEST: { + break; + } + + case XCB_KEY_PRESS: { + break; + } + + case XCB_CREATE_NOTIFY: { + break; + } + + case XCB_DESTROY_NOTIFY: { + break; + } + + case XCB_ENTER_NOTIFY: { + break; + } + + case XCB_MOTION_NOTIFY: { + break; + } + } + + free(ev); + } +} + +int main(int argc, char *argv[]) { + /* unused */ + (void) argc; + (void) argv; + + /* we don't want sigchld */ + signal(SIGCHLD, SIG_IGN); + + init_wm(); + init_input(); + run_loop(); + + return 0; +} diff --git a/types.h b/types.h deleted file mode 100644 index 38a9d4e..0000000 --- a/types.h +++ /dev/null @@ -1,10 +0,0 @@ -#include - -struct wconf { - int16_t x; - int16_t y; - uint16_t width; - uint16_t height; - xcb_window_t sibling; - uint8_t stack_mode; -};