diff --git a/src/backend/backend.h b/src/backend/backend.h index 3bf3234..6cb5b7e 100644 --- a/src/backend/backend.h +++ b/src/backend/backend.h @@ -1709,6 +1709,16 @@ typedef struct WMBackend { WNativeWindow (*prop_get_client_leader)(WNativeWindow window); int (*prop_get_window_state)(WNativeWindow window); + void (*setup_modifier_lock_masks)(void); + void (*key_grab_hacked)(WNativeWindow window, int keycode, unsigned int modifiers); + void (*button_grab_hacked)(unsigned int button, unsigned int modifiers, + WNativeWindow window, int owner_events, + unsigned int event_mask); + void (*context_init)(void); + void (*query_tree)(WNativeWindow root, WNativeWindow **children_out, + unsigned int *nchildren_out); + WScreen *(*screen_for_window)(WNativeWindow window); + } WMBackend; /* diff --git a/src/backend/wayland/wl_backend.c b/src/backend/wayland/wl_backend.c index a588bda..f184235 100644 --- a/src/backend/wayland/wl_backend.c +++ b/src/backend/wayland/wl_backend.c @@ -6214,6 +6214,26 @@ static void wl_noop_frame_paint_titlebar(WFrameWindow *fwin, int state) { (void) static WNativeWindow wl_noop_prop_get_client_leader(WNativeWindow window) { (void)window; return WNATIVE_NONE; } static int wl_noop_prop_get_window_state(WNativeWindow window) { (void)window; return -1; } +static void wl_noop_setup_modifier_lock_masks(void) { } +static void wl_noop_key_grab_hacked(WNativeWindow window, int keycode, unsigned int modifiers) +{ (void)window; (void)keycode; (void)modifiers; } +static void wl_noop_button_grab_hacked(unsigned int button, unsigned int modifiers, + WNativeWindow window, int owner_events, unsigned int event_mask) +{ (void)button; (void)modifiers; (void)window; (void)owner_events; (void)event_mask; } +static void wl_context_init(void) +{ + /* Wayland uses a hash table instead of X11 contexts */ + w_global.context.client_win = 1; + w_global.context.app_win = 2; + w_global.context.stack = 3; +} +static void wl_noop_query_tree(WNativeWindow root, WNativeWindow **children_out, + unsigned int *nchildren_out) +{ (void)root; *children_out = NULL; *nchildren_out = 0; } + +static WScreen *wl_noop_screen_for_window(WNativeWindow window) +{ (void)window; return wScreenWithNumber(0); } + /* ------------------------------------------------------------------ */ /* vtable */ /* ------------------------------------------------------------------ */ @@ -6435,4 +6455,10 @@ const WMBackend wl_backend = { .frame_paint_titlebar = wl_noop_frame_paint_titlebar, .prop_get_client_leader = wl_noop_prop_get_client_leader, .prop_get_window_state = wl_noop_prop_get_window_state, + .setup_modifier_lock_masks = wl_noop_setup_modifier_lock_masks, + .key_grab_hacked = wl_noop_key_grab_hacked, + .button_grab_hacked = wl_noop_button_grab_hacked, + .context_init = wl_context_init, + .query_tree = wl_noop_query_tree, + .screen_for_window = wl_noop_screen_for_window, }; diff --git a/src/backend/x11/x11_backend.c b/src/backend/x11/x11_backend.c index 403de59..ae09c5f 100644 --- a/src/backend/x11/x11_backend.c +++ b/src/backend/x11/x11_backend.c @@ -17,6 +17,8 @@ #include #include #include +#include +#include #include #include #include @@ -2921,6 +2923,123 @@ static int x11_prop_get_window_state(WNativeWindow window) return state; } +static void x11_setup_modifier_lock_masks(void) +{ + int i; + XModifierKeymap *modmap; + KeyCode nlock, slock; + static int mask_table[8] = { + ShiftMask, LockMask, ControlMask, Mod1Mask, + Mod2Mask, Mod3Mask, Mod4Mask, Mod5Mask + }; + + nlock = XKeysymToKeycode(dpy, XK_Num_Lock); + slock = XKeysymToKeycode(dpy, XK_Scroll_Lock); + modmap = XGetModifierMapping(dpy); + + if (modmap != NULL && modmap->max_keypermod > 0) { + for (i = 0; i < 8 * modmap->max_keypermod; i++) { + if (modmap->modifiermap[i] == nlock && nlock != 0) + _NumLockMask = mask_table[i / modmap->max_keypermod]; + else if (modmap->modifiermap[i] == slock && slock != 0) + _ScrollLockMask = mask_table[i / modmap->max_keypermod]; + } + } + if (modmap) + XFreeModifiermap(modmap); +} + +static void x11_key_grab_hacked(WNativeWindow window, int keycode, unsigned int modifiers) +{ + if (modifiers == AnyModifier) + return; + if (_NumLockMask) + XGrabKey(dpy, keycode, modifiers | _NumLockMask, + (Window)window, True, GrabModeAsync, GrabModeAsync); + if (_ScrollLockMask) + XGrabKey(dpy, keycode, modifiers | _ScrollLockMask, + (Window)window, True, GrabModeAsync, GrabModeAsync); + if (_NumLockMask && _ScrollLockMask) + XGrabKey(dpy, keycode, modifiers | _NumLockMask | _ScrollLockMask, + (Window)window, True, GrabModeAsync, GrabModeAsync); + if (_NumLockMask) + XGrabKey(dpy, keycode, modifiers | _NumLockMask | LockMask, + (Window)window, True, GrabModeAsync, GrabModeAsync); + if (_ScrollLockMask) + XGrabKey(dpy, keycode, modifiers | _ScrollLockMask | LockMask, + (Window)window, True, GrabModeAsync, GrabModeAsync); + if (_NumLockMask && _ScrollLockMask) + XGrabKey(dpy, keycode, modifiers | _NumLockMask | _ScrollLockMask | LockMask, + (Window)window, True, GrabModeAsync, GrabModeAsync); +} + +static void x11_button_grab_hacked(unsigned int button, unsigned int modifiers, + WNativeWindow window, int owner_events, + unsigned int event_mask) +{ + XGrabButton(dpy, button, modifiers, (Window)window, owner_events, + event_mask, GrabModeAsync, GrabModeAsync, None, None); + if (modifiers == AnyModifier) + return; + XGrabButton(dpy, button, modifiers | LockMask, (Window)window, owner_events, + event_mask, GrabModeAsync, GrabModeAsync, None, None); + if (_NumLockMask) + XGrabButton(dpy, button, modifiers | _NumLockMask, (Window)window, + owner_events, event_mask, GrabModeAsync, GrabModeAsync, None, None); + if (_ScrollLockMask) + XGrabButton(dpy, button, modifiers | _ScrollLockMask, (Window)window, + owner_events, event_mask, GrabModeAsync, GrabModeAsync, None, None); + if (_NumLockMask && _ScrollLockMask) + XGrabButton(dpy, button, modifiers | _NumLockMask | _ScrollLockMask, (Window)window, + owner_events, event_mask, GrabModeAsync, GrabModeAsync, None, None); + if (_NumLockMask) + XGrabButton(dpy, button, modifiers | _NumLockMask | LockMask, (Window)window, + owner_events, event_mask, GrabModeAsync, GrabModeAsync, None, None); + if (_ScrollLockMask) + XGrabButton(dpy, button, modifiers | _ScrollLockMask | LockMask, (Window)window, + owner_events, event_mask, GrabModeAsync, GrabModeAsync, None, None); + if (_NumLockMask && _ScrollLockMask) + XGrabButton(dpy, button, modifiers | _NumLockMask | _ScrollLockMask | LockMask, (Window)window, + owner_events, event_mask, GrabModeAsync, GrabModeAsync, None, None); +} + +static void x11_context_init(void) +{ + w_global.context.client_win = XUniqueContext(); + w_global.context.app_win = XUniqueContext(); + w_global.context.stack = XUniqueContext(); +} + +static void x11_query_tree(WNativeWindow root, WNativeWindow **children_out, + unsigned int *nchildren_out) +{ + Window xroot, parent; + Window *children = NULL; + unsigned int n = 0; + XQueryTree(dpy, (Window)root, &xroot, &parent, &children, &n); + /* Copy to wfree-able memory */ + if (children && n > 0) { + WNativeWindow *out = wmalloc(n * sizeof(WNativeWindow)); + unsigned int i; + for (i = 0; i < n; i++) + out[i] = (WNativeWindow)children[i]; + XFree(children); + *children_out = out; + } else { + if (children) XFree(children); + *children_out = NULL; + } + *nchildren_out = n; +} + +static WScreen *x11_screen_for_window(WNativeWindow window) +{ + XWindowAttributes attr; + if (XGetWindowAttributes(dpy, (Window)window, &attr)) + return wScreenForRootWindow(attr.root); + return NULL; +} + /* -------------------------------------------------------------------- */ /* Client operations (Phase 80) */ /* -------------------------------------------------------------------- */ @@ -3625,6 +3744,12 @@ const WMBackend x11_backend = { .frame_paint_titlebar = x11_frame_paint_titlebar, .prop_get_client_leader = x11_prop_get_client_leader, .prop_get_window_state = x11_prop_get_window_state, + .setup_modifier_lock_masks = x11_setup_modifier_lock_masks, + .key_grab_hacked = x11_key_grab_hacked, + .button_grab_hacked = x11_button_grab_hacked, + .context_init = x11_context_init, + .query_tree = x11_query_tree, + .screen_for_window = x11_screen_for_window, }; /* diff --git a/src/startup.c b/src/startup.c index ce60d2c..e91ce00 100644 --- a/src/startup.c +++ b/src/startup.c @@ -33,7 +33,6 @@ #endif -#include /* XrmUniqueQuark — needed by XUniqueContext() */ #include "WindowMaker.h" #include "GNUstep.h" #include "texture.h" @@ -73,8 +72,8 @@ /***** Local *****/ static WScreen **wScreen = NULL; -static unsigned int _NumLockMask = 0; -static unsigned int _ScrollLockMask = 0; +unsigned int _NumLockMask = 0; +unsigned int _ScrollLockMask = 0; /* catchXError and handleXIO moved to x11_backend.c (Phase 25) */ @@ -169,37 +168,7 @@ static RETSIGTYPE buryChild(int foo) static void getOffendingModifiers(void) { - int i; - XModifierKeymap *modmap; - KeyCode nlock, slock; - static int mask_table[8] = { - ShiftMask, LockMask, ControlMask, Mod1Mask, - Mod2Mask, Mod3Mask, Mod4Mask, Mod5Mask - }; - - if (!dpy || wm_backend->is_wayland) - return; /* Wayland: modifier mapping handled by wlroots/XKB */ - - nlock = wm_backend->keysym_to_keycode(WM_KEY_NUM_LOCK); - slock = wm_backend->keysym_to_keycode(WM_KEY_SCROLL_LOCK); - - /* - * Find out the masks for the NumLock and ScrollLock modifiers, - * so that we can bind the grabs for when they are enabled too. - */ - modmap = XGetModifierMapping(dpy); - - if (modmap != NULL && modmap->max_keypermod > 0) { - for (i = 0; i < 8 * modmap->max_keypermod; i++) { - if (modmap->modifiermap[i] == nlock && nlock != 0) - _NumLockMask = mask_table[i / modmap->max_keypermod]; - else if (modmap->modifiermap[i] == slock && slock != 0) - _ScrollLockMask = mask_table[i / modmap->max_keypermod]; - } - } - - if (modmap) - XFreeModifiermap(modmap); + wm_backend->setup_modifier_lock_masks(); } #ifdef NUMLOCK_HACK @@ -207,32 +176,8 @@ void wHackedGrabKey(int keycode, unsigned int modifiers, Window grab_window, Bool owner_events, int pointer_mode, int keyboard_mode) { - if (modifiers == AnyModifier) - return; - - /* grab all combinations of the modifier with CapsLock, NumLock and - * ScrollLock. How much memory/CPU does such a monstrosity consume - * in the server? - */ - if (_NumLockMask) - XGrabKey(dpy, keycode, modifiers | _NumLockMask, - grab_window, owner_events, pointer_mode, keyboard_mode); - if (_ScrollLockMask) - XGrabKey(dpy, keycode, modifiers | _ScrollLockMask, - grab_window, owner_events, pointer_mode, keyboard_mode); - if (_NumLockMask && _ScrollLockMask) - XGrabKey(dpy, keycode, modifiers | _NumLockMask | _ScrollLockMask, - grab_window, owner_events, pointer_mode, keyboard_mode); - if (_NumLockMask) - XGrabKey(dpy, keycode, modifiers | _NumLockMask | LockMask, - grab_window, owner_events, pointer_mode, keyboard_mode); - if (_ScrollLockMask) - XGrabKey(dpy, keycode, modifiers | _ScrollLockMask | LockMask, - grab_window, owner_events, pointer_mode, keyboard_mode); - if (_NumLockMask && _ScrollLockMask) - XGrabKey(dpy, keycode, modifiers | _NumLockMask | _ScrollLockMask | LockMask, - grab_window, owner_events, pointer_mode, keyboard_mode); - /* phew, I guess that's all, right? */ + (void)owner_events; (void)pointer_mode; (void)keyboard_mode; + wm_backend->key_grab_hacked((WNativeWindow)grab_window, keycode, modifiers); } #endif @@ -241,42 +186,9 @@ wHackedGrabButton(unsigned int button, unsigned int modifiers, Window grab_window, Bool owner_events, unsigned int event_mask, int pointer_mode, int keyboard_mode, Window confine_to, Cursor cursor) { - XGrabButton(dpy, button, modifiers, grab_window, owner_events, - event_mask, pointer_mode, keyboard_mode, confine_to, cursor); - - if (modifiers == AnyModifier) - return; - - XGrabButton(dpy, button, modifiers | LockMask, grab_window, owner_events, - event_mask, pointer_mode, keyboard_mode, confine_to, cursor); - -#ifdef NUMLOCK_HACK - /* same as above, but for mouse buttons */ - if (_NumLockMask) - XGrabButton(dpy, button, modifiers | _NumLockMask, - grab_window, owner_events, event_mask, pointer_mode, - keyboard_mode, confine_to, cursor); - if (_ScrollLockMask) - XGrabButton(dpy, button, modifiers | _ScrollLockMask, - grab_window, owner_events, event_mask, pointer_mode, - keyboard_mode, confine_to, cursor); - if (_NumLockMask && _ScrollLockMask) - XGrabButton(dpy, button, modifiers | _ScrollLockMask | _NumLockMask, - grab_window, owner_events, event_mask, pointer_mode, - keyboard_mode, confine_to, cursor); - if (_NumLockMask) - XGrabButton(dpy, button, modifiers | _NumLockMask | LockMask, - grab_window, owner_events, event_mask, pointer_mode, - keyboard_mode, confine_to, cursor); - if (_ScrollLockMask) - XGrabButton(dpy, button, modifiers | _ScrollLockMask | LockMask, - grab_window, owner_events, event_mask, pointer_mode, - keyboard_mode, confine_to, cursor); - if (_NumLockMask && _ScrollLockMask) - XGrabButton(dpy, button, modifiers | _ScrollLockMask | _NumLockMask | LockMask, - grab_window, owner_events, event_mask, pointer_mode, - keyboard_mode, confine_to, cursor); -#endif /* NUMLOCK_HACK */ + (void)pointer_mode; (void)keyboard_mode; (void)confine_to; (void)cursor; + wm_backend->button_grab_hacked(button, modifiers, (WNativeWindow)grab_window, + owner_events, event_mask); } WScreen *wScreenWithNumber(int i) @@ -305,15 +217,10 @@ WScreen *wScreenForRootWindow(WNativeWindow window) WScreen *wScreenForWindow(WNativeWindow window) { - XWindowAttributes attr; - if (w_global.screen_count == 1) return wScreen[0]; - if (XGetWindowAttributes(dpy, window, &attr)) - return wScreenForRootWindow(attr.root); - - return NULL; + return wm_backend->screen_for_window(window); } static char *atomNames[] = { @@ -375,9 +282,7 @@ void StartUp(Bool defaultScreenOnly) memset(&wKeyBindings, 0, sizeof(wKeyBindings)); - w_global.context.client_win = XUniqueContext(); - w_global.context.app_win = XUniqueContext(); - w_global.context.stack = XUniqueContext(); + wm_backend->context_init(); { int ai; @@ -647,14 +552,14 @@ static Bool windowInList(Window window, Window * list, int count) */ void wManageAllWindows(WScreen * scr, int crashRecovery) { - Window root, parent; - Window *children; + + WNativeWindow *children; unsigned int nchildren; unsigned int i, j; WWindow *wwin; wm_backend->server_grab(); - XQueryTree(dpy, scr->root_win, &root, &parent, &children, &nchildren); + wm_backend->query_tree((WNativeWindow)scr->root_win, &children, &nchildren); scr->flags.startup = 1; @@ -733,7 +638,7 @@ void wManageAllWindows(WScreen * scr, int crashRecovery) wwin = wwin->prev; } - XFree(children); + wfree(children); scr->flags.startup = 0; scr->flags.startup2 = 1; diff --git a/src/startup.h b/src/startup.h index d905db3..a5fc6db 100644 --- a/src/startup.h +++ b/src/startup.h @@ -37,3 +37,5 @@ void wHackedGrabKey(int keycode, unsigned int modifiers, #endif #endif /* WMSTARTUP_H */ +extern unsigned int _NumLockMask; +extern unsigned int _ScrollLockMask;