WPrefs.app: zero X11 deps, zero #ifdef USE_X11_BACKEND
Complete architectural separation: all WPrefs.app panel code is now
backend-neutral. No X11 calls, no X11 types, no X11 includes, no
backend-specific #ifdef guards in shared sources.
New W_EventBackend vtable methods (implemented in X11, stubbed in WL):
- grab_keyboard / ungrab_keyboard / allow_events
- grab_pointer / ungrab_pointer / query_pointer
- get_window_geometry / move_window / translate_coordinates
- get_root_window / query_tree
- get_pointer_control / set_pointer_control
- modifier_from_key / get_modifier_keysyms
- keysym_to_string / keysym_to_keycode / keycode_to_keysym
- keysym_convert_case
- send_wm_command
- set_window_hints / set_window_property_string / set_window_property_data
- recolor_cursor
- set_error_handler / restore_error_handler
Panel changes:
- xmodifier.c: thin wrapper calling eventBackend->modifier_from_key()
- main.c: X11 locale init removed (belongs in backend screen_init)
- WPrefs.c: eventBackend->send_wm_command("Reconfigure")
- MouseSettings.c: vtable for pointer control + modifier keysyms
- KeyboardShortcuts.c: vtable for grab/keysym/modifier ops
- Menu.c: RImage crosshair icon, vtable keyboard grab
- editmenu.c: vtable for all window/pointer/property ops
Verified: nm audit shows zero X11 symbol refs in WPrefs .o files.
grep shows zero #ifdef USE_X11_BACKEND in WPrefs.app/.
This commit is contained in:
parent
b996a0e274
commit
8119bfe098
|
|
@ -471,6 +471,87 @@ typedef struct W_EventBackend {
|
|||
int (*fd)(void *ectx);
|
||||
void (*put_back)(void *ectx, WMEvent *ev);
|
||||
void (*post_dispatch)(void *ectx, WMEvent *ev, struct W_View *toplevel);
|
||||
|
||||
/* --- Keyboard grab for shortcut capture --- */
|
||||
/* Grab the keyboard so all key events come to `window`.
|
||||
* Returns True on success. */
|
||||
Bool (*grab_keyboard)(void *ectx, WNativeWindow window);
|
||||
void (*ungrab_keyboard)(void *ectx);
|
||||
/* Allow queued events to be replayed after a grab. */
|
||||
void (*allow_events)(void *ectx);
|
||||
|
||||
/* --- Pointer grab for window picking --- */
|
||||
/* Grab the pointer with the given cursor. Returns True on success. */
|
||||
Bool (*grab_pointer)(void *ectx, WNativeWindow window, WMNativePixmap cursor);
|
||||
void (*ungrab_pointer)(void *ectx);
|
||||
/* Query pointer position relative to `window`. Returns child window. */
|
||||
WNativeWindow (*query_pointer)(void *ectx, WNativeWindow window,
|
||||
int *root_x, int *root_y,
|
||||
int *win_x, int *win_y,
|
||||
unsigned int *mask);
|
||||
|
||||
/* --- Window geometry queries --- */
|
||||
Bool (*get_window_geometry)(void *ectx, WNativeWindow window,
|
||||
int *x, int *y,
|
||||
unsigned int *width, unsigned int *height);
|
||||
void (*move_window)(void *ectx, WNativeWindow window, int x, int y);
|
||||
WNativeWindow (*translate_coordinates)(void *ectx,
|
||||
WNativeWindow src, WNativeWindow dst,
|
||||
int src_x, int src_y,
|
||||
int *dst_x, int *dst_y);
|
||||
/* Get the root window (or equivalent top-level surface). */
|
||||
WNativeWindow (*get_root_window)(void *ectx);
|
||||
/* Get children of a window. Caller must free *children with wfree(). */
|
||||
Bool (*query_tree)(void *ectx, WNativeWindow window,
|
||||
WNativeWindow **children, unsigned int *nchildren);
|
||||
|
||||
/* --- Pointer control (acceleration) --- */
|
||||
void (*get_pointer_control)(void *ectx, int *accel_num, int *accel_denom, int *threshold);
|
||||
void (*set_pointer_control)(void *ectx, int accel_num, int accel_denom, int threshold);
|
||||
|
||||
/* --- Modifier mapping --- */
|
||||
/* Returns the modifier index (ShiftMapIndex..Mod5MapIndex) for a named
|
||||
* modifier ("SHIFT","CONTROL","ALT","META","SUPER","HYPER","MOD1".."MOD5").
|
||||
* Returns -1 if unknown. */
|
||||
int (*modifier_from_key)(void *ectx, const char *key_name);
|
||||
|
||||
/* --- Keysym helpers --- */
|
||||
const char *(*keysym_to_string)(void *ectx, WMNativeKeysym keysym);
|
||||
unsigned int (*keysym_to_keycode)(void *ectx, WMNativeKeysym keysym);
|
||||
WMNativeKeysym (*keycode_to_keysym)(void *ectx, unsigned int keycode, int index);
|
||||
void (*keysym_convert_case)(void *ectx, WMNativeKeysym sym,
|
||||
WMNativeKeysym *lower, WMNativeKeysym *upper);
|
||||
|
||||
/* Get keysyms assigned to each modifier index (0..7).
|
||||
* For each modifier index, returns up to max_per_mod keysyms in
|
||||
* keysyms_out[index * max_per_mod .. (index+1)*max_per_mod - 1].
|
||||
* Unused slots are set to 0 (NoSymbol).
|
||||
* Returns the actual max_keypermod from the server. */
|
||||
int (*get_modifier_keysyms)(void *ectx, WMNativeKeysym *keysyms_out,
|
||||
int max_per_mod);
|
||||
|
||||
/* --- WM notification --- */
|
||||
/* Send a command string to the running window manager. */
|
||||
void (*send_wm_command)(void *ectx, const char *command);
|
||||
|
||||
/* --- Window properties --- */
|
||||
void (*set_window_hints)(void *ectx, WNativeWindow window,
|
||||
int min_w, int min_h, int max_w, int max_h,
|
||||
int base_w, int base_h);
|
||||
void (*set_window_property_string)(void *ectx, WNativeWindow window,
|
||||
const char *atom_name, const char *value);
|
||||
void (*set_window_property_data)(void *ectx, WNativeWindow window,
|
||||
WMNativeAtom property, WMNativeAtom type,
|
||||
int format, const void *data, int nelements);
|
||||
|
||||
/* --- Cursor --- */
|
||||
void (*recolor_cursor)(void *ectx, WMNativePixmap cursor,
|
||||
unsigned short fr, unsigned short fg, unsigned short fb,
|
||||
unsigned short br, unsigned short bg, unsigned short bb);
|
||||
|
||||
/* --- Error handling --- */
|
||||
void (*set_error_handler)(void *ectx, void *handler);
|
||||
void (*restore_error_handler)(void *ectx);
|
||||
} W_EventBackend;
|
||||
|
||||
extern const W_EventBackend W_EventBackendX11 __attribute__((weak));
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@
|
|||
#include "WINGsP.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <strings.h>
|
||||
|
||||
/* ------------------------------------------------------------------ */
|
||||
|
||||
|
|
@ -186,6 +187,117 @@ wl_put_back(void *ectx, WMEvent *ev)
|
|||
ctx->head = prev;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------ */
|
||||
/* Stubs for new vtable methods (Wayland: not yet implemented) */
|
||||
/* ------------------------------------------------------------------ */
|
||||
|
||||
static Bool wl_grab_keyboard(void *ectx, WNativeWindow w)
|
||||
{ (void)ectx; (void)w; return False; }
|
||||
|
||||
static void wl_ungrab_keyboard(void *ectx) { (void)ectx; }
|
||||
static void wl_allow_events(void *ectx) { (void)ectx; }
|
||||
|
||||
static Bool wl_grab_pointer(void *ectx, WNativeWindow w, WMNativePixmap c)
|
||||
{ (void)ectx; (void)w; (void)c; return False; }
|
||||
|
||||
static void wl_ungrab_pointer(void *ectx) { (void)ectx; }
|
||||
|
||||
static WNativeWindow wl_query_pointer(void *ectx, WNativeWindow w,
|
||||
int *rx, int *ry, int *wx, int *wy, unsigned int *m)
|
||||
{ (void)ectx; (void)w;
|
||||
if (rx) *rx = 0; if (ry) *ry = 0;
|
||||
if (wx) *wx = 0; if (wy) *wy = 0; if (m) *m = 0;
|
||||
return 0; }
|
||||
|
||||
static Bool wl_get_window_geometry(void *ectx, WNativeWindow w,
|
||||
int *x, int *y, unsigned int *width, unsigned int *height)
|
||||
{ (void)ectx; (void)w;
|
||||
if (x) *x = 0; if (y) *y = 0;
|
||||
if (width) *width = 0; if (height) *height = 0;
|
||||
return False; }
|
||||
|
||||
static void wl_move_window(void *ectx, WNativeWindow w, int x, int y)
|
||||
{ (void)ectx; (void)w; (void)x; (void)y; }
|
||||
|
||||
static WNativeWindow wl_translate_coordinates(void *ectx,
|
||||
WNativeWindow src, WNativeWindow dst, int sx, int sy, int *dx, int *dy)
|
||||
{ (void)ectx; (void)src; (void)dst; (void)sx; (void)sy;
|
||||
if (dx) *dx = 0; if (dy) *dy = 0; return 0; }
|
||||
|
||||
static WNativeWindow wl_get_root_window(void *ectx)
|
||||
{ (void)ectx; return 0; }
|
||||
|
||||
static Bool wl_query_tree(void *ectx, WNativeWindow w,
|
||||
WNativeWindow **children, unsigned int *nc)
|
||||
{ (void)ectx; (void)w;
|
||||
if (children) *children = NULL; if (nc) *nc = 0; return False; }
|
||||
|
||||
static void wl_get_pointer_control(void *ectx, int *an, int *ad, int *t)
|
||||
{ (void)ectx; if (an) *an = 2; if (ad) *ad = 1; if (t) *t = 4; }
|
||||
|
||||
static void wl_set_pointer_control(void *ectx, int an, int ad, int t)
|
||||
{ (void)ectx; (void)an; (void)ad; (void)t; }
|
||||
|
||||
static int wl_modifier_from_key(void *ectx, const char *key)
|
||||
{
|
||||
(void)ectx;
|
||||
/* Sensible defaults matching common Wayland compositors */
|
||||
if (strcasecmp(key, "SHIFT") == 0) return 0;
|
||||
if (strcasecmp(key, "CONTROL") == 0) return 2;
|
||||
if (strcasecmp(key, "ALT") == 0) return 3;
|
||||
if (strcasecmp(key, "META") == 0) return 3;
|
||||
if (strcasecmp(key, "SUPER") == 0) return 6;
|
||||
if (strcasecmp(key, "HYPER") == 0) return 0;
|
||||
if (strcasecmp(key, "MOD1") == 0) return 3;
|
||||
if (strcasecmp(key, "MOD2") == 0) return 4;
|
||||
if (strcasecmp(key, "MOD3") == 0) return 5;
|
||||
if (strcasecmp(key, "MOD4") == 0) return 6;
|
||||
if (strcasecmp(key, "MOD5") == 0) return 7;
|
||||
return -1;
|
||||
}
|
||||
|
||||
static const char *wl_keysym_to_string(void *ectx, WMNativeKeysym ks)
|
||||
{ (void)ectx; (void)ks; return NULL; /* TODO: xkb_keysym_get_name */ }
|
||||
|
||||
static int wl_get_modifier_keysyms(void *ectx, WMNativeKeysym *out, int max_per_mod)
|
||||
{ (void)ectx; memset(out, 0, 8 * max_per_mod * sizeof(WMNativeKeysym)); return 0; }
|
||||
|
||||
static unsigned int wl_keysym_to_keycode(void *ectx, WMNativeKeysym ks)
|
||||
{ (void)ectx; (void)ks; return 0; }
|
||||
|
||||
static WMNativeKeysym wl_keycode_to_keysym(void *ectx, unsigned int kc, int idx)
|
||||
{ (void)ectx; (void)kc; (void)idx; return 0; }
|
||||
|
||||
static void wl_keysym_convert_case(void *ectx, WMNativeKeysym sym,
|
||||
WMNativeKeysym *lower, WMNativeKeysym *upper)
|
||||
{ (void)ectx; if (lower) *lower = sym; if (upper) *upper = sym; }
|
||||
|
||||
static void wl_send_wm_command(void *ectx, const char *cmd)
|
||||
{ (void)ectx; (void)cmd; /* TODO: signal wmaker via PID file */ }
|
||||
|
||||
static void wl_set_window_hints(void *ectx, WNativeWindow w,
|
||||
int minw, int minh, int maxw, int maxh, int bw, int bh)
|
||||
{ (void)ectx; (void)w; (void)minw; (void)minh; (void)maxw; (void)maxh; (void)bw; (void)bh; }
|
||||
|
||||
static void wl_set_window_property_string(void *ectx, WNativeWindow w,
|
||||
const char *atom, const char *val)
|
||||
{ (void)ectx; (void)w; (void)atom; (void)val; }
|
||||
|
||||
static void wl_set_window_property_data(void *ectx, WNativeWindow w,
|
||||
WMNativeAtom prop, WMNativeAtom type, int fmt, const void *data, int nel)
|
||||
{ (void)ectx; (void)w; (void)prop; (void)type; (void)fmt; (void)data; (void)nel; }
|
||||
|
||||
static void wl_recolor_cursor(void *ectx, WMNativePixmap c,
|
||||
unsigned short fr, unsigned short fg, unsigned short fb,
|
||||
unsigned short br, unsigned short bg, unsigned short bb)
|
||||
{ (void)ectx; (void)c; (void)fr; (void)fg; (void)fb; (void)br; (void)bg; (void)bb; }
|
||||
|
||||
static void wl_set_error_handler(void *ectx, void *h)
|
||||
{ (void)ectx; (void)h; }
|
||||
|
||||
static void wl_restore_error_handler(void *ectx)
|
||||
{ (void)ectx; }
|
||||
|
||||
const W_EventBackend W_EventBackendWL = {
|
||||
.screen_init = wl_screen_init,
|
||||
.screen_fini = wl_screen_fini,
|
||||
|
|
@ -197,6 +309,32 @@ const W_EventBackend W_EventBackendWL = {
|
|||
.fd = wl_fd,
|
||||
.put_back = wl_put_back,
|
||||
.post_dispatch = NULL,
|
||||
.grab_keyboard = wl_grab_keyboard,
|
||||
.ungrab_keyboard = wl_ungrab_keyboard,
|
||||
.allow_events = wl_allow_events,
|
||||
.grab_pointer = wl_grab_pointer,
|
||||
.ungrab_pointer = wl_ungrab_pointer,
|
||||
.query_pointer = wl_query_pointer,
|
||||
.get_window_geometry = wl_get_window_geometry,
|
||||
.move_window = wl_move_window,
|
||||
.translate_coordinates = wl_translate_coordinates,
|
||||
.get_root_window = wl_get_root_window,
|
||||
.query_tree = wl_query_tree,
|
||||
.get_pointer_control = wl_get_pointer_control,
|
||||
.set_pointer_control = wl_set_pointer_control,
|
||||
.modifier_from_key = wl_modifier_from_key,
|
||||
.keysym_to_string = wl_keysym_to_string,
|
||||
.keysym_to_keycode = wl_keysym_to_keycode,
|
||||
.keycode_to_keysym = wl_keycode_to_keysym,
|
||||
.keysym_convert_case = wl_keysym_convert_case,
|
||||
.get_modifier_keysyms = wl_get_modifier_keysyms,
|
||||
.send_wm_command = wl_send_wm_command,
|
||||
.set_window_hints = wl_set_window_hints,
|
||||
.set_window_property_string = wl_set_window_property_string,
|
||||
.set_window_property_data = wl_set_window_property_data,
|
||||
.recolor_cursor = wl_recolor_cursor,
|
||||
.set_error_handler = wl_set_error_handler,
|
||||
.restore_error_handler = wl_restore_error_handler,
|
||||
};
|
||||
|
||||
/* ------------------------------------------------------------------ */
|
||||
|
|
|
|||
|
|
@ -10,7 +10,10 @@
|
|||
#include "WINGs/WINGsX11.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <strings.h>
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/Xatom.h>
|
||||
#include <X11/Xutil.h>
|
||||
|
||||
/* ------------------------------------------------------------------ */
|
||||
/* XEvent → WMEvent translation (inline, X11 backend only) */
|
||||
|
|
@ -338,6 +341,405 @@ x11_post_dispatch(void *ectx, WMEvent *ev, W_View *toplevel)
|
|||
}
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------ */
|
||||
/* Keyboard/pointer grab */
|
||||
/* ------------------------------------------------------------------ */
|
||||
|
||||
static Bool
|
||||
x11_grab_keyboard(void *ectx, WNativeWindow window)
|
||||
{
|
||||
X11EventCtx *ctx = (X11EventCtx *)ectx;
|
||||
int r = XGrabKeyboard(ctx->dpy, (Window)window, True,
|
||||
GrabModeAsync, GrabModeAsync, CurrentTime);
|
||||
return (r == GrabSuccess) ? True : False;
|
||||
}
|
||||
|
||||
static void
|
||||
x11_ungrab_keyboard(void *ectx)
|
||||
{
|
||||
X11EventCtx *ctx = (X11EventCtx *)ectx;
|
||||
XUngrabKeyboard(ctx->dpy, CurrentTime);
|
||||
}
|
||||
|
||||
static void
|
||||
x11_allow_events(void *ectx)
|
||||
{
|
||||
X11EventCtx *ctx = (X11EventCtx *)ectx;
|
||||
XAllowEvents(ctx->dpy, AsyncKeyboard, CurrentTime);
|
||||
}
|
||||
|
||||
static Bool
|
||||
x11_grab_pointer(void *ectx, WNativeWindow window, WMNativePixmap cursor)
|
||||
{
|
||||
X11EventCtx *ctx = (X11EventCtx *)ectx;
|
||||
int r = XGrabPointer(ctx->dpy, (Window)window, True,
|
||||
ButtonPressMask | ButtonReleaseMask |
|
||||
ButtonMotionMask | PointerMotionMask,
|
||||
GrabModeAsync, GrabModeAsync,
|
||||
None, (Cursor)cursor, CurrentTime);
|
||||
return (r == GrabSuccess) ? True : False;
|
||||
}
|
||||
|
||||
static void
|
||||
x11_ungrab_pointer(void *ectx)
|
||||
{
|
||||
X11EventCtx *ctx = (X11EventCtx *)ectx;
|
||||
XUngrabPointer(ctx->dpy, CurrentTime);
|
||||
}
|
||||
|
||||
static WNativeWindow
|
||||
x11_query_pointer(void *ectx, WNativeWindow window,
|
||||
int *root_x, int *root_y,
|
||||
int *win_x, int *win_y, unsigned int *mask)
|
||||
{
|
||||
X11EventCtx *ctx = (X11EventCtx *)ectx;
|
||||
Window root_ret, child_ret;
|
||||
int rx, ry, wx, wy;
|
||||
unsigned int m;
|
||||
XQueryPointer(ctx->dpy, (Window)window, &root_ret, &child_ret,
|
||||
&rx, &ry, &wx, &wy, &m);
|
||||
if (root_x) *root_x = rx;
|
||||
if (root_y) *root_y = ry;
|
||||
if (win_x) *win_x = wx;
|
||||
if (win_y) *win_y = wy;
|
||||
if (mask) *mask = m;
|
||||
return (WNativeWindow)child_ret;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------ */
|
||||
/* Window geometry */
|
||||
/* ------------------------------------------------------------------ */
|
||||
|
||||
static Bool
|
||||
x11_get_window_geometry(void *ectx, WNativeWindow window,
|
||||
int *x, int *y, unsigned int *width, unsigned int *height)
|
||||
{
|
||||
X11EventCtx *ctx = (X11EventCtx *)ectx;
|
||||
Window root;
|
||||
int xr, yr;
|
||||
unsigned int w, h, bw, depth;
|
||||
Status s = XGetGeometry(ctx->dpy, (Window)window, &root,
|
||||
&xr, &yr, &w, &h, &bw, &depth);
|
||||
if (!s) return False;
|
||||
if (x) *x = xr;
|
||||
if (y) *y = yr;
|
||||
if (width) *width = w;
|
||||
if (height) *height = h;
|
||||
return True;
|
||||
}
|
||||
|
||||
static void
|
||||
x11_move_window(void *ectx, WNativeWindow window, int x, int y)
|
||||
{
|
||||
X11EventCtx *ctx = (X11EventCtx *)ectx;
|
||||
XMoveWindow(ctx->dpy, (Window)window, x, y);
|
||||
}
|
||||
|
||||
static WNativeWindow
|
||||
x11_translate_coordinates(void *ectx, WNativeWindow src, WNativeWindow dst,
|
||||
int src_x, int src_y, int *dst_x, int *dst_y)
|
||||
{
|
||||
X11EventCtx *ctx = (X11EventCtx *)ectx;
|
||||
Window child;
|
||||
int dx, dy;
|
||||
XTranslateCoordinates(ctx->dpy, (Window)src, (Window)dst,
|
||||
src_x, src_y, &dx, &dy, &child);
|
||||
if (dst_x) *dst_x = dx;
|
||||
if (dst_y) *dst_y = dy;
|
||||
return (WNativeWindow)child;
|
||||
}
|
||||
|
||||
static WNativeWindow
|
||||
x11_get_root_window(void *ectx)
|
||||
{
|
||||
X11EventCtx *ctx = (X11EventCtx *)ectx;
|
||||
return (WNativeWindow)DefaultRootWindow(ctx->dpy);
|
||||
}
|
||||
|
||||
static Bool
|
||||
x11_query_tree(void *ectx, WNativeWindow window,
|
||||
WNativeWindow **children, unsigned int *nchildren)
|
||||
{
|
||||
X11EventCtx *ctx = (X11EventCtx *)ectx;
|
||||
Window root, parent;
|
||||
Window *kids = NULL;
|
||||
unsigned int nkids = 0;
|
||||
if (!XQueryTree(ctx->dpy, (Window)window, &root, &parent, &kids, &nkids)) {
|
||||
if (children) *children = NULL;
|
||||
if (nchildren) *nchildren = 0;
|
||||
return False;
|
||||
}
|
||||
if (children) {
|
||||
if (nkids > 0) {
|
||||
*children = wmalloc(nkids * sizeof(WNativeWindow));
|
||||
for (unsigned int i = 0; i < nkids; i++)
|
||||
(*children)[i] = (WNativeWindow)kids[i];
|
||||
} else {
|
||||
*children = NULL;
|
||||
}
|
||||
}
|
||||
if (nchildren) *nchildren = nkids;
|
||||
if (kids) XFree(kids);
|
||||
return True;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------ */
|
||||
/* Pointer control */
|
||||
/* ------------------------------------------------------------------ */
|
||||
|
||||
static void
|
||||
x11_get_pointer_control(void *ectx, int *accel_num, int *accel_denom, int *threshold)
|
||||
{
|
||||
X11EventCtx *ctx = (X11EventCtx *)ectx;
|
||||
XGetPointerControl(ctx->dpy, accel_num, accel_denom, threshold);
|
||||
}
|
||||
|
||||
static void
|
||||
x11_set_pointer_control(void *ectx, int accel_num, int accel_denom, int threshold)
|
||||
{
|
||||
X11EventCtx *ctx = (X11EventCtx *)ectx;
|
||||
XChangePointerControl(ctx->dpy, True, True, accel_num, accel_denom, threshold);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------ */
|
||||
/* Modifier mapping */
|
||||
/* ------------------------------------------------------------------ */
|
||||
|
||||
#include <X11/keysym.h>
|
||||
#include <X11/XKBlib.h>
|
||||
|
||||
static int x11_MetaIndex, x11_HyperIndex, x11_SuperIndex, x11_AltIndex, x11_ModeIndex;
|
||||
static int x11_modmap_done;
|
||||
|
||||
static void
|
||||
x11_compute_modifier_mapping(Display *display)
|
||||
{
|
||||
int modifier_index, modifier_key, column, mkpm;
|
||||
int meta_bit = 0, hyper_bit = 0, super_bit = 0, alt_bit = 0, mode_bit = 0;
|
||||
XModifierKeymap *xmk = XGetModifierMapping(display);
|
||||
if (!xmk) return;
|
||||
|
||||
mkpm = xmk->max_keypermod;
|
||||
for (modifier_index = 0; modifier_index < 8; modifier_index++) {
|
||||
for (modifier_key = 0; modifier_key < mkpm; modifier_key++) {
|
||||
KeyCode code = xmk->modifiermap[modifier_index * mkpm + modifier_key];
|
||||
if (!code) continue;
|
||||
for (column = 0; column < 4; column += 2) {
|
||||
KeySym sym = XkbKeycodeToKeysym(display, code, 0, column);
|
||||
if (sym == NoSymbol) continue;
|
||||
switch (sym) {
|
||||
case XK_Meta_L: case XK_Meta_R: meta_bit = modifier_index; break;
|
||||
case XK_Super_L: case XK_Super_R: super_bit = modifier_index; break;
|
||||
case XK_Hyper_L: case XK_Hyper_R: hyper_bit = modifier_index; break;
|
||||
case XK_Alt_L: case XK_Alt_R: alt_bit = modifier_index; break;
|
||||
case XK_Mode_switch: mode_bit = modifier_index; break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
XFreeModifiermap(xmk);
|
||||
|
||||
if (!meta_bit && alt_bit) meta_bit = alt_bit, alt_bit = 0;
|
||||
if (mode_bit) {
|
||||
if (mode_bit == meta_bit) meta_bit = 0;
|
||||
else if (mode_bit == hyper_bit) hyper_bit = 0;
|
||||
else if (mode_bit == super_bit) super_bit = 0;
|
||||
else if (mode_bit == alt_bit) alt_bit = 0;
|
||||
}
|
||||
x11_MetaIndex = meta_bit;
|
||||
x11_HyperIndex = hyper_bit;
|
||||
x11_SuperIndex = super_bit;
|
||||
x11_AltIndex = alt_bit;
|
||||
x11_ModeIndex = mode_bit;
|
||||
x11_modmap_done = 1;
|
||||
}
|
||||
|
||||
static int
|
||||
x11_modifier_from_key(void *ectx, const char *key)
|
||||
{
|
||||
X11EventCtx *ctx = (X11EventCtx *)ectx;
|
||||
if (!x11_modmap_done)
|
||||
x11_compute_modifier_mapping(ctx->dpy);
|
||||
|
||||
if (strcasecmp(key, "SHIFT") == 0) return ShiftMapIndex;
|
||||
if (strcasecmp(key, "CONTROL") == 0) return ControlMapIndex;
|
||||
if (strcasecmp(key, "ALT") == 0) return x11_AltIndex;
|
||||
if (strcasecmp(key, "META") == 0) return x11_MetaIndex;
|
||||
if (strcasecmp(key, "SUPER") == 0) return x11_SuperIndex;
|
||||
if (strcasecmp(key, "HYPER") == 0) return x11_HyperIndex;
|
||||
if (strcasecmp(key, "MOD1") == 0) return Mod1MapIndex;
|
||||
if (strcasecmp(key, "MOD2") == 0) return Mod2MapIndex;
|
||||
if (strcasecmp(key, "MOD3") == 0) return Mod3MapIndex;
|
||||
if (strcasecmp(key, "MOD4") == 0) return Mod4MapIndex;
|
||||
if (strcasecmp(key, "MOD5") == 0) return Mod5MapIndex;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------ */
|
||||
/* Keysym helpers */
|
||||
/* ------------------------------------------------------------------ */
|
||||
|
||||
static int
|
||||
x11_get_modifier_keysyms(void *ectx, WMNativeKeysym *keysyms_out, int max_per_mod)
|
||||
{
|
||||
X11EventCtx *ctx = (X11EventCtx *)ectx;
|
||||
XModifierKeymap *xmk = XGetModifierMapping(ctx->dpy);
|
||||
if (!xmk) return 0;
|
||||
|
||||
int mkpm = xmk->max_keypermod;
|
||||
int out_per_mod = (mkpm < max_per_mod) ? mkpm : max_per_mod;
|
||||
|
||||
memset(keysyms_out, 0, 8 * max_per_mod * sizeof(WMNativeKeysym));
|
||||
|
||||
for (int j = 0; j < 8; j++) {
|
||||
int slot = 0;
|
||||
for (int i = 0; i < mkpm && slot < out_per_mod; i++) {
|
||||
KeyCode kc = xmk->modifiermap[j * mkpm + i];
|
||||
if (!kc) continue;
|
||||
KeySym ks = XkbKeycodeToKeysym(ctx->dpy, kc, 0, 0);
|
||||
if (ks == NoSymbol) {
|
||||
ks = XkbKeycodeToKeysym(ctx->dpy, kc, 0, 1);
|
||||
}
|
||||
if (ks != NoSymbol) {
|
||||
keysyms_out[j * max_per_mod + slot] = (WMNativeKeysym)ks;
|
||||
slot++;
|
||||
}
|
||||
}
|
||||
}
|
||||
XFreeModifiermap(xmk);
|
||||
return mkpm;
|
||||
}
|
||||
|
||||
static const char *
|
||||
x11_keysym_to_string(void *ectx, WMNativeKeysym keysym)
|
||||
{
|
||||
(void)ectx;
|
||||
return XKeysymToString((KeySym)keysym);
|
||||
}
|
||||
|
||||
static unsigned int
|
||||
x11_keysym_to_keycode(void *ectx, WMNativeKeysym keysym)
|
||||
{
|
||||
X11EventCtx *ctx = (X11EventCtx *)ectx;
|
||||
return (unsigned int)XKeysymToKeycode(ctx->dpy, (KeySym)keysym);
|
||||
}
|
||||
|
||||
static WMNativeKeysym
|
||||
x11_keycode_to_keysym(void *ectx, unsigned int keycode, int index)
|
||||
{
|
||||
X11EventCtx *ctx = (X11EventCtx *)ectx;
|
||||
return (WMNativeKeysym)XkbKeycodeToKeysym(ctx->dpy, (KeyCode)keycode, 0, index);
|
||||
}
|
||||
|
||||
static void
|
||||
x11_keysym_convert_case(void *ectx, WMNativeKeysym sym,
|
||||
WMNativeKeysym *lower, WMNativeKeysym *upper)
|
||||
{
|
||||
(void)ectx;
|
||||
KeySym lo, up;
|
||||
XConvertCase((KeySym)sym, &lo, &up);
|
||||
if (lower) *lower = (WMNativeKeysym)lo;
|
||||
if (upper) *upper = (WMNativeKeysym)up;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------ */
|
||||
/* WM notification */
|
||||
/* ------------------------------------------------------------------ */
|
||||
|
||||
static void
|
||||
x11_send_wm_command(void *ectx, const char *command)
|
||||
{
|
||||
X11EventCtx *ctx = (X11EventCtx *)ectx;
|
||||
XEvent ev;
|
||||
memset(&ev, 0, sizeof(ev));
|
||||
ev.xclient.type = ClientMessage;
|
||||
ev.xclient.message_type = XInternAtom(ctx->dpy, "_WINDOWMAKER_COMMAND", False);
|
||||
ev.xclient.window = DefaultRootWindow(ctx->dpy);
|
||||
ev.xclient.format = 8;
|
||||
strncpy(ev.xclient.data.b, command, sizeof(ev.xclient.data.b));
|
||||
XSendEvent(ctx->dpy, DefaultRootWindow(ctx->dpy), False,
|
||||
SubstructureRedirectMask, &ev);
|
||||
XFlush(ctx->dpy);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------ */
|
||||
/* Window properties */
|
||||
/* ------------------------------------------------------------------ */
|
||||
|
||||
static void
|
||||
x11_set_window_hints(void *ectx, WNativeWindow window,
|
||||
int min_w, int min_h, int max_w, int max_h,
|
||||
int base_w, int base_h)
|
||||
{
|
||||
X11EventCtx *ctx = (X11EventCtx *)ectx;
|
||||
XSizeHints *hints = XAllocSizeHints();
|
||||
if (!hints) return;
|
||||
hints->flags = PMinSize | PMaxSize | PBaseSize;
|
||||
hints->min_width = min_w; hints->min_height = min_h;
|
||||
hints->max_width = max_w; hints->max_height = max_h;
|
||||
hints->base_width = base_w; hints->base_height = base_h;
|
||||
XSetWMNormalHints(ctx->dpy, (Window)window, hints);
|
||||
XFree(hints);
|
||||
}
|
||||
|
||||
static void
|
||||
x11_set_window_property_string(void *ectx, WNativeWindow window,
|
||||
const char *atom_name, const char *value)
|
||||
{
|
||||
X11EventCtx *ctx = (X11EventCtx *)ectx;
|
||||
Atom atom = XInternAtom(ctx->dpy, atom_name, False);
|
||||
XChangeProperty(ctx->dpy, (Window)window, atom, XA_STRING, 8,
|
||||
PropModeReplace, (unsigned char *)value, strlen(value));
|
||||
}
|
||||
|
||||
static void
|
||||
x11_set_window_property_data(void *ectx, WNativeWindow window,
|
||||
WMNativeAtom property, WMNativeAtom type,
|
||||
int format, const void *data, int nelements)
|
||||
{
|
||||
X11EventCtx *ctx = (X11EventCtx *)ectx;
|
||||
XChangeProperty(ctx->dpy, (Window)window, (Atom)property, (Atom)type,
|
||||
format, PropModeReplace, (const unsigned char *)data, nelements);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------ */
|
||||
/* Cursor */
|
||||
/* ------------------------------------------------------------------ */
|
||||
|
||||
static void
|
||||
x11_recolor_cursor(void *ectx, WMNativePixmap cursor,
|
||||
unsigned short fr, unsigned short fg, unsigned short fb,
|
||||
unsigned short br, unsigned short bg, unsigned short bb)
|
||||
{
|
||||
X11EventCtx *ctx = (X11EventCtx *)ectx;
|
||||
XColor fg_c, bg_c;
|
||||
fg_c.red = fr; fg_c.green = fg; fg_c.blue = fb; fg_c.flags = DoRed|DoGreen|DoBlue;
|
||||
bg_c.red = br; bg_c.green = bg; bg_c.blue = bb; bg_c.flags = DoRed|DoGreen|DoBlue;
|
||||
XRecolorCursor(ctx->dpy, (Cursor)cursor, &fg_c, &bg_c);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------ */
|
||||
/* Error handling */
|
||||
/* ------------------------------------------------------------------ */
|
||||
|
||||
static int (*x11_saved_error_handler)(Display *, XErrorEvent *);
|
||||
|
||||
static void
|
||||
x11_set_error_handler(void *ectx, void *handler)
|
||||
{
|
||||
(void)ectx;
|
||||
x11_saved_error_handler = XSetErrorHandler((int (*)(Display *, XErrorEvent *))handler);
|
||||
}
|
||||
|
||||
static void
|
||||
x11_restore_error_handler(void *ectx)
|
||||
{
|
||||
(void)ectx;
|
||||
XSetErrorHandler(x11_saved_error_handler);
|
||||
x11_saved_error_handler = NULL;
|
||||
}
|
||||
|
||||
const W_EventBackend W_EventBackendX11 = {
|
||||
.screen_init = x11_screen_init,
|
||||
.screen_fini = x11_screen_fini,
|
||||
|
|
@ -349,4 +751,30 @@ const W_EventBackend W_EventBackendX11 = {
|
|||
.fd = x11_fd,
|
||||
.put_back = x11_put_back,
|
||||
.post_dispatch = x11_post_dispatch,
|
||||
.grab_keyboard = x11_grab_keyboard,
|
||||
.ungrab_keyboard = x11_ungrab_keyboard,
|
||||
.allow_events = x11_allow_events,
|
||||
.grab_pointer = x11_grab_pointer,
|
||||
.ungrab_pointer = x11_ungrab_pointer,
|
||||
.query_pointer = x11_query_pointer,
|
||||
.get_window_geometry = x11_get_window_geometry,
|
||||
.move_window = x11_move_window,
|
||||
.translate_coordinates = x11_translate_coordinates,
|
||||
.get_root_window = x11_get_root_window,
|
||||
.query_tree = x11_query_tree,
|
||||
.get_pointer_control = x11_get_pointer_control,
|
||||
.set_pointer_control = x11_set_pointer_control,
|
||||
.modifier_from_key = x11_modifier_from_key,
|
||||
.keysym_to_string = x11_keysym_to_string,
|
||||
.keysym_to_keycode = x11_keysym_to_keycode,
|
||||
.keycode_to_keysym = x11_keycode_to_keysym,
|
||||
.keysym_convert_case = x11_keysym_convert_case,
|
||||
.get_modifier_keysyms = x11_get_modifier_keysyms,
|
||||
.send_wm_command = x11_send_wm_command,
|
||||
.set_window_hints = x11_set_window_hints,
|
||||
.set_window_property_string = x11_set_window_property_string,
|
||||
.set_window_property_data = x11_set_window_property_data,
|
||||
.recolor_cursor = x11_recolor_cursor,
|
||||
.set_error_handler = x11_set_error_handler,
|
||||
.restore_error_handler = x11_restore_error_handler,
|
||||
};
|
||||
|
|
|
|||
|
|
@ -19,15 +19,11 @@
|
|||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
#include "config.h" /* for HAVE_XCONVERTCASE */
|
||||
#include "config.h"
|
||||
|
||||
#include "WPrefs.h"
|
||||
#include <WINGs/WINGsX11.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#include <X11/keysym.h>
|
||||
#include <X11/XKBlib.h>
|
||||
|
||||
typedef struct _Panel {
|
||||
WMBox *box;
|
||||
|
||||
|
|
@ -169,169 +165,66 @@ static struct keyOption {
|
|||
#endif /* XKB_MODELOCK */
|
||||
};
|
||||
|
||||
#ifndef HAVE_XCONVERTCASE
|
||||
/* from Xlib */
|
||||
|
||||
static void XConvertCase(register WMNativeKeysym sym, WMNativeKeysym * lower, WMNativeKeysym * upper)
|
||||
static int NumLockMask(WMScreen *scr)
|
||||
{
|
||||
*lower = sym;
|
||||
*upper = sym;
|
||||
switch (sym >> 8) {
|
||||
case 0: /* Latin 1 */
|
||||
if ((sym >= XK_A) && (sym <= XK_Z))
|
||||
*lower += (XK_a - XK_A);
|
||||
else if ((sym >= XK_a) && (sym <= XK_z))
|
||||
*upper -= (XK_a - XK_A);
|
||||
else if ((sym >= XK_Agrave) && (sym <= XK_Odiaeresis))
|
||||
*lower += (XK_agrave - XK_Agrave);
|
||||
else if ((sym >= XK_agrave) && (sym <= XK_odiaeresis))
|
||||
*upper -= (XK_agrave - XK_Agrave);
|
||||
else if ((sym >= XK_Ooblique) && (sym <= XK_Thorn))
|
||||
*lower += (XK_oslash - XK_Ooblique);
|
||||
else if ((sym >= XK_oslash) && (sym <= XK_thorn))
|
||||
*upper -= (XK_oslash - XK_Ooblique);
|
||||
break;
|
||||
case 1: /* Latin 2 */
|
||||
/* Assume the WMNativeKeysym is a legal value (ignore discontinuities) */
|
||||
if (sym == XK_Aogonek)
|
||||
*lower = XK_aogonek;
|
||||
else if (sym >= XK_Lstroke && sym <= XK_Sacute)
|
||||
*lower += (XK_lstroke - XK_Lstroke);
|
||||
else if (sym >= XK_Scaron && sym <= XK_Zacute)
|
||||
*lower += (XK_scaron - XK_Scaron);
|
||||
else if (sym >= XK_Zcaron && sym <= XK_Zabovedot)
|
||||
*lower += (XK_zcaron - XK_Zcaron);
|
||||
else if (sym == XK_aogonek)
|
||||
*upper = XK_Aogonek;
|
||||
else if (sym >= XK_lstroke && sym <= XK_sacute)
|
||||
*upper -= (XK_lstroke - XK_Lstroke);
|
||||
else if (sym >= XK_scaron && sym <= XK_zacute)
|
||||
*upper -= (XK_scaron - XK_Scaron);
|
||||
else if (sym >= XK_zcaron && sym <= XK_zabovedot)
|
||||
*upper -= (XK_zcaron - XK_Zcaron);
|
||||
else if (sym >= XK_Racute && sym <= XK_Tcedilla)
|
||||
*lower += (XK_racute - XK_Racute);
|
||||
else if (sym >= XK_racute && sym <= XK_tcedilla)
|
||||
*upper -= (XK_racute - XK_Racute);
|
||||
break;
|
||||
case 2: /* Latin 3 */
|
||||
/* Assume the WMNativeKeysym is a legal value (ignore discontinuities) */
|
||||
if (sym >= XK_Hstroke && sym <= XK_Hcircumflex)
|
||||
*lower += (XK_hstroke - XK_Hstroke);
|
||||
else if (sym >= XK_Gbreve && sym <= XK_Jcircumflex)
|
||||
*lower += (XK_gbreve - XK_Gbreve);
|
||||
else if (sym >= XK_hstroke && sym <= XK_hcircumflex)
|
||||
*upper -= (XK_hstroke - XK_Hstroke);
|
||||
else if (sym >= XK_gbreve && sym <= XK_jcircumflex)
|
||||
*upper -= (XK_gbreve - XK_Gbreve);
|
||||
else if (sym >= XK_Cabovedot && sym <= XK_Scircumflex)
|
||||
*lower += (XK_cabovedot - XK_Cabovedot);
|
||||
else if (sym >= XK_cabovedot && sym <= XK_scircumflex)
|
||||
*upper -= (XK_cabovedot - XK_Cabovedot);
|
||||
break;
|
||||
case 3: /* Latin 4 */
|
||||
/* Assume the WMNativeKeysym is a legal value (ignore discontinuities) */
|
||||
if (sym >= XK_Rcedilla && sym <= XK_Tslash)
|
||||
*lower += (XK_rcedilla - XK_Rcedilla);
|
||||
else if (sym >= XK_rcedilla && sym <= XK_tslash)
|
||||
*upper -= (XK_rcedilla - XK_Rcedilla);
|
||||
else if (sym == XK_ENG)
|
||||
*lower = XK_eng;
|
||||
else if (sym == XK_eng)
|
||||
*upper = XK_ENG;
|
||||
else if (sym >= XK_Amacron && sym <= XK_Umacron)
|
||||
*lower += (XK_amacron - XK_Amacron);
|
||||
else if (sym >= XK_amacron && sym <= XK_umacron)
|
||||
*upper -= (XK_amacron - XK_Amacron);
|
||||
break;
|
||||
case 6: /* Cyrillic */
|
||||
/* Assume the WMNativeKeysym is a legal value (ignore discontinuities) */
|
||||
if (sym >= XK_Serbian_DJE && sym <= XK_Serbian_DZE)
|
||||
*lower -= (XK_Serbian_DJE - XK_Serbian_dje);
|
||||
else if (sym >= XK_Serbian_dje && sym <= XK_Serbian_dze)
|
||||
*upper += (XK_Serbian_DJE - XK_Serbian_dje);
|
||||
else if (sym >= XK_Cyrillic_YU && sym <= XK_Cyrillic_HARDSIGN)
|
||||
*lower -= (XK_Cyrillic_YU - XK_Cyrillic_yu);
|
||||
else if (sym >= XK_Cyrillic_yu && sym <= XK_Cyrillic_hardsign)
|
||||
*upper += (XK_Cyrillic_YU - XK_Cyrillic_yu);
|
||||
break;
|
||||
case 7: /* Greek */
|
||||
/* Assume the WMNativeKeysym is a legal value (ignore discontinuities) */
|
||||
if (sym >= XK_Greek_ALPHAaccent && sym <= XK_Greek_OMEGAaccent)
|
||||
*lower += (XK_Greek_alphaaccent - XK_Greek_ALPHAaccent);
|
||||
else if (sym >= XK_Greek_alphaaccent && sym <= XK_Greek_omegaaccent &&
|
||||
sym != XK_Greek_iotaaccentdieresis && sym != XK_Greek_upsilonaccentdieresis)
|
||||
*upper -= (XK_Greek_alphaaccent - XK_Greek_ALPHAaccent);
|
||||
else if (sym >= XK_Greek_ALPHA && sym <= XK_Greek_OMEGA)
|
||||
*lower += (XK_Greek_alpha - XK_Greek_ALPHA);
|
||||
else if (sym >= XK_Greek_alpha && sym <= XK_Greek_omega && sym != XK_Greek_finalsmallsigma)
|
||||
*upper -= (XK_Greek_alpha - XK_Greek_ALPHA);
|
||||
break;
|
||||
case 0x14: /* Armenian */
|
||||
if (sym >= XK_Armenian_AYB && sym <= XK_Armenian_fe) {
|
||||
*lower = sym | 1;
|
||||
*upper = sym & ~1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
static int NumLockMask(Display *dpy)
|
||||
{
|
||||
int i, mask;
|
||||
XModifierKeymap *map;
|
||||
int i, j;
|
||||
static int mask_table[8] = {
|
||||
WM_MOD_SHIFT, WM_MOD_LOCK, WM_MOD_CONTROL, WM_MOD_MOD1,
|
||||
WM_MOD_MOD2, WM_MOD_MOD3, WM_MOD_MOD4, WM_MOD_MOD5
|
||||
};
|
||||
KeyCode numlock_keycode = XKeysymToKeycode(dpy, XK_Num_Lock);
|
||||
unsigned int numlock_keycode = scr->eventBackend->keysym_to_keycode(
|
||||
scr->eventBackendCtx, WMK_Num_Lock);
|
||||
|
||||
if (numlock_keycode == NoSymbol)
|
||||
if (numlock_keycode == 0)
|
||||
return 0;
|
||||
|
||||
map = XGetModifierMapping(dpy);
|
||||
if (!map)
|
||||
#define NL_MAX_PER_MOD 16
|
||||
WMNativeKeysym keysyms[8 * NL_MAX_PER_MOD];
|
||||
int mkpm = scr->eventBackend->get_modifier_keysyms(scr->eventBackendCtx,
|
||||
keysyms, NL_MAX_PER_MOD);
|
||||
if (mkpm == 0)
|
||||
return 0;
|
||||
|
||||
mask = 0;
|
||||
for (i = 0; i < 8 * map->max_keypermod; i++) {
|
||||
if (map->modifiermap[i] == numlock_keycode && mask == 0) {
|
||||
mask = mask_table[i/map->max_keypermod];
|
||||
break;
|
||||
for (j = 0; j < 8; j++) {
|
||||
for (i = 0; i < NL_MAX_PER_MOD; i++) {
|
||||
WMNativeKeysym ks = keysyms[j * NL_MAX_PER_MOD + i];
|
||||
if (ks == WMK_Num_Lock)
|
||||
return mask_table[j];
|
||||
}
|
||||
}
|
||||
|
||||
if (map)
|
||||
XFreeModifiermap(map);
|
||||
|
||||
return mask;
|
||||
#undef NL_MAX_PER_MOD
|
||||
return 0;
|
||||
}
|
||||
|
||||
char *capture_shortcut(WMScreen *scr, Bool *capturing, Bool convert_case)
|
||||
{
|
||||
Display *dpy = WMScreenDisplay(scr);
|
||||
WMEvent ev;
|
||||
WMNativeKeysym ksym, lksym, uksym;
|
||||
char buffer[64];
|
||||
char *key = NULL;
|
||||
const char *key = NULL;
|
||||
unsigned int numlock_mask;
|
||||
|
||||
while (*capturing) {
|
||||
XAllowEvents(dpy, AsyncKeyboard, WM_CURRENT_TIME);
|
||||
scr->eventBackend->allow_events(scr->eventBackendCtx);
|
||||
WMNextEvent(scr, &ev);
|
||||
if (ev.type == KeyPress && ev.u.key.keycode != 0) {
|
||||
numlock_mask = NumLockMask(dpy);
|
||||
if (ev.type == WME_KEY_PRESS && ev.u.key.keycode != 0) {
|
||||
numlock_mask = NumLockMask(scr);
|
||||
|
||||
/* conditional mask check to get numeric keypad keys */
|
||||
ksym = W_KeycodeToKeysym(dpy, ev.u.key.keycode, ev.u.key.state & numlock_mask?1:0);
|
||||
ksym = scr->eventBackend->keycode_to_keysym(
|
||||
scr->eventBackendCtx, ev.u.key.keycode,
|
||||
(ev.u.key.state & numlock_mask) ? 1 : 0);
|
||||
|
||||
if (!IsModifierKey(ksym)) {
|
||||
if (!WM_IsModifierKey(ksym)) {
|
||||
if (convert_case) {
|
||||
XConvertCase(ksym, &lksym, &uksym);
|
||||
key = XKeysymToString(uksym);
|
||||
scr->eventBackend->keysym_convert_case(
|
||||
scr->eventBackendCtx, ksym, &lksym, &uksym);
|
||||
key = scr->eventBackend->keysym_to_string(
|
||||
scr->eventBackendCtx, uksym);
|
||||
} else {
|
||||
key = XKeysymToString(ksym);
|
||||
key = scr->eventBackend->keysym_to_string(
|
||||
scr->eventBackendCtx, ksym);
|
||||
}
|
||||
|
||||
*capturing = 0;
|
||||
|
|
@ -406,7 +299,6 @@ static void captureClick(WMWidget * w, void *data)
|
|||
{
|
||||
_Panel *panel = (_Panel *) data;
|
||||
WMScreen *scr = WMWidgetScreen(panel->parent);
|
||||
Display *dpy = WMScreenDisplay(scr);
|
||||
char *shortcut;
|
||||
|
||||
if (!panel->capturing) {
|
||||
|
|
@ -414,7 +306,7 @@ static void captureClick(WMWidget * w, void *data)
|
|||
WMSetButtonText(w, _("Cancel"));
|
||||
WMSetLabelText(panel->instructionsL,
|
||||
_("Press the desired shortcut key(s) or click Cancel to stop capturing."));
|
||||
XGrabKeyboard(dpy, WMWidgetXID(panel->parent), True, WM_GRAB_MODE_ASYNC, WM_GRAB_MODE_ASYNC, WM_CURRENT_TIME);
|
||||
scr->eventBackend->grab_keyboard(scr->eventBackendCtx, WMWidgetXID(panel->parent));
|
||||
shortcut = capture_shortcut(scr, &panel->capturing, 1);
|
||||
if (shortcut) {
|
||||
int key_idx = -1;
|
||||
|
|
@ -448,7 +340,7 @@ static void captureClick(WMWidget * w, void *data)
|
|||
panel->capturing = 0;
|
||||
WMSetButtonText(w, _("Capture"));
|
||||
WMSetLabelText(panel->instructionsL, _("Click on Capture to interactively define the shortcut key."));
|
||||
XUngrabKeyboard(dpy, WM_CURRENT_TIME);
|
||||
scr->eventBackend->ungrab_keyboard(scr->eventBackendCtx);
|
||||
}
|
||||
|
||||
static void clearShortcut(WMWidget * w, void *data)
|
||||
|
|
@ -527,7 +419,6 @@ static void paintItem(WMList * lPtr, int index, WMDrawable d, char *text, int st
|
|||
int width, height, x, y;
|
||||
_Panel *panel = (_Panel *) WMGetHangedData(lPtr);
|
||||
WMScreen *scr = WMWidgetScreen(lPtr);
|
||||
Display *dpy = WMScreenDisplay(scr);
|
||||
WMColor *backColor = (state & WLDSSelected) ? panel->white : panel->gray;
|
||||
|
||||
width = rect->size.width;
|
||||
|
|
@ -535,7 +426,7 @@ static void paintItem(WMList * lPtr, int index, WMDrawable d, char *text, int st
|
|||
x = rect->pos.x;
|
||||
y = rect->pos.y;
|
||||
|
||||
XFillRectangle(dpy, d, WMColorGC(backColor), x, y, width, height);
|
||||
scr->renderBackend->fill_rect(scr->renderBackendCtx, d, backColor, x, y, width, height);
|
||||
|
||||
if (panel->shortcuts[index]) {
|
||||
WMPixmap *pix = WMGetSystemPixmap(scr, WSICheckMark);
|
||||
|
|
|
|||
|
|
@ -24,9 +24,6 @@
|
|||
#include <ctype.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <X11/keysym.h>
|
||||
#include <X11/cursorfont.h>
|
||||
|
||||
#include "editmenu.h"
|
||||
|
||||
typedef enum {
|
||||
|
|
@ -261,7 +258,7 @@ static void browseForFile(WMWidget * self, void *clientData)
|
|||
static void sgrabClicked(WMWidget * w, void *data)
|
||||
{
|
||||
_Panel *panel = (_Panel *) data;
|
||||
Display *dpy = WMScreenDisplay(WMWidgetScreen(panel->parent));
|
||||
WMScreen *scr = WMWidgetScreen(panel->parent);
|
||||
char *shortcut;
|
||||
|
||||
if (w == panel->sclearB) {
|
||||
|
|
@ -273,8 +270,8 @@ static void sgrabClicked(WMWidget * w, void *data)
|
|||
if (!panel->capturing) {
|
||||
panel->capturing = 1;
|
||||
WMSetButtonText(w, _("Cancel"));
|
||||
XGrabKeyboard(dpy, WMWidgetXID(panel->parent), True, WM_GRAB_MODE_ASYNC, WM_GRAB_MODE_ASYNC, WM_CURRENT_TIME);
|
||||
shortcut = capture_shortcut(WMWidgetScreen(panel->parent), &panel->capturing, 0);
|
||||
scr->eventBackend->grab_keyboard(scr->eventBackendCtx, WMWidgetXID(panel->parent));
|
||||
shortcut = capture_shortcut(scr, &panel->capturing, 0);
|
||||
if (shortcut) {
|
||||
WMSetTextFieldText(panel->shortT, shortcut);
|
||||
updateMenuItem(panel, panel->currentItem, panel->shortT);
|
||||
|
|
@ -283,7 +280,7 @@ static void sgrabClicked(WMWidget * w, void *data)
|
|||
}
|
||||
panel->capturing = 0;
|
||||
WMSetButtonText(w, _("Capture"));
|
||||
XUngrabKeyboard(dpy, WM_CURRENT_TIME);
|
||||
scr->eventBackend->ungrab_keyboard(scr->eventBackendCtx);
|
||||
}
|
||||
|
||||
static void changedItemPad(WMWidget * w, void *data)
|
||||
|
|
@ -367,33 +364,18 @@ static void createPanel(_Panel * p)
|
|||
panel->gray = gray;
|
||||
|
||||
{
|
||||
WMNativePixmap pix;
|
||||
Display *dpy = WMScreenDisplay(scr);
|
||||
GC gc;
|
||||
WMPixmap *pixm;
|
||||
RImage *img;
|
||||
RColor blk = {0, 0, 0, 255};
|
||||
|
||||
pixm = WMCreatePixmap(scr, 7, 7, WMScreenDepth(scr), True);
|
||||
/* Create a 7x7 crosshair marker icon */
|
||||
img = RCreateImage(7, 7, True);
|
||||
RClearImage(img, &(RColor){0, 0, 0, 0});
|
||||
RDrawLine(img, 0, 3, 6, 3, &blk);
|
||||
RDrawLine(img, 3, 0, 3, 6, &blk);
|
||||
|
||||
pix = WMGetPixmapXID(pixm);
|
||||
|
||||
XDrawLine(dpy, pix, WMColorGC(black), 0, 3, 6, 3);
|
||||
XDrawLine(dpy, pix, WMColorGC(black), 3, 0, 3, 6);
|
||||
/*
|
||||
XDrawLine(dpy, pix, WMColorGC(black), 1, 0, 3, 3);
|
||||
XDrawLine(dpy, pix, WMColorGC(black), 1, 6, 3, 3);
|
||||
XDrawLine(dpy, pix, WMColorGC(black), 0, 0, 0, 6);
|
||||
*/
|
||||
|
||||
pix = WMGetPixmapMaskXID(pixm);
|
||||
|
||||
gc = XCreateGC(dpy, pix, 0, NULL);
|
||||
|
||||
XSetForeground(dpy, gc, 0);
|
||||
XFillRectangle(dpy, pix, gc, 0, 0, 7, 7);
|
||||
|
||||
XSetForeground(dpy, gc, 1);
|
||||
XDrawLine(dpy, pix, gc, 0, 3, 6, 3);
|
||||
XDrawLine(dpy, pix, gc, 3, 0, 3, 6);
|
||||
pixm = WMCreatePixmapFromRImage(scr, img, 128);
|
||||
RReleaseImage(img);
|
||||
|
||||
panel->markerPix[ExternalInfo] = pixm;
|
||||
panel->markerPix[PipeInfo] = pixm;
|
||||
|
|
@ -401,8 +383,6 @@ static void createPanel(_Panel * p)
|
|||
panel->markerPix[DirectoryInfo] = pixm;
|
||||
panel->markerPix[WSMenuInfo] = pixm;
|
||||
panel->markerPix[WWindowListInfo] = pixm;
|
||||
|
||||
XFreeGC(dpy, gc);
|
||||
}
|
||||
|
||||
panel->box = WMCreateBox(panel->parent);
|
||||
|
|
|
|||
|
|
@ -22,9 +22,6 @@
|
|||
|
||||
#include "WPrefs.h"
|
||||
|
||||
#include <X11/Xutil.h>
|
||||
#include <X11/XKBlib.h>
|
||||
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
|
|
@ -121,7 +118,6 @@ typedef struct _Panel {
|
|||
|
||||
/* need access to the double click variables */
|
||||
#include <WINGs/WINGsP.h>
|
||||
#include <WINGs/WINGsX11.h>
|
||||
|
||||
static char *modifierNames[8];
|
||||
|
||||
|
|
@ -135,7 +131,7 @@ static void setMouseAccel(WMScreen * scr, float accel, int threshold)
|
|||
d = 10;
|
||||
n = accel * d;
|
||||
|
||||
XChangePointerControl(WMScreenDisplay(scr), True, True, n, d, threshold);
|
||||
scr->eventBackend->set_pointer_control(scr->eventBackendCtx, n, d, threshold);
|
||||
}
|
||||
|
||||
static void speedChange(WMWidget * w, void *data)
|
||||
|
|
@ -253,11 +249,11 @@ static int getWheelAction(const char *str)
|
|||
return -1;
|
||||
}
|
||||
|
||||
static void getMouseParameters(Display * dpy, float *accel, int *thre)
|
||||
static void getMouseParameters(WMScreen *scr, float *accel, int *thre)
|
||||
{
|
||||
int n, d;
|
||||
|
||||
XGetPointerControl(dpy, &n, &d, thre);
|
||||
scr->eventBackend->get_pointer_control(scr->eventBackendCtx, &n, &d, thre);
|
||||
|
||||
*accel = (float)n / (float)d;
|
||||
}
|
||||
|
|
@ -269,7 +265,7 @@ static void showData(_Panel * panel)
|
|||
int a = -1, b = -1;
|
||||
float accel;
|
||||
char buffer[32];
|
||||
Display *dpy = WMScreenDisplay(WMWidgetScreen(panel->parent));
|
||||
WMScreen *scr = WMWidgetScreen(panel->parent);
|
||||
|
||||
for (i = 0; i < wlengthof(button_list); i++) {
|
||||
int action;
|
||||
|
|
@ -291,8 +287,8 @@ static void showData(_Panel * panel)
|
|||
WMSetButtonSelected(panel->disaB, GetBoolForKey("DisableWSMouseActions"));
|
||||
toggle_disabling_of_mouse_actions(panel->disaB, panel);
|
||||
|
||||
/**/ getMouseParameters(dpy, &accel, &a);
|
||||
panel->maxThreshold = WidthOfScreen(DefaultScreenOfDisplay(dpy));
|
||||
/**/ getMouseParameters(scr, &accel, &a);
|
||||
panel->maxThreshold = WMScreenWidth(scr);
|
||||
if (a > panel->maxThreshold) {
|
||||
panel->maxThreshold = a;
|
||||
}
|
||||
|
|
@ -348,15 +344,17 @@ static void showData(_Panel * panel)
|
|||
|
||||
static void fillModifierPopUp(WMPopUpButton * pop)
|
||||
{
|
||||
XModifierKeymap *mapping;
|
||||
Display *dpy = WMScreenDisplay(WMWidgetScreen(pop));
|
||||
int i, j;
|
||||
WMScreen *scr = WMWidgetScreen(pop);
|
||||
int j, i, k;
|
||||
char *str;
|
||||
char buffer[64];
|
||||
#define MAX_KEYS_PER_MOD 8
|
||||
WMNativeKeysym keysyms[8 * MAX_KEYS_PER_MOD];
|
||||
int mkpm;
|
||||
|
||||
mapping = XGetModifierMapping(dpy);
|
||||
|
||||
if (!mapping || mapping->max_keypermod == 0) {
|
||||
mkpm = scr->eventBackend->get_modifier_keysyms(scr->eventBackendCtx,
|
||||
keysyms, MAX_KEYS_PER_MOD);
|
||||
if (mkpm == 0) {
|
||||
WMAddPopUpButtonItem(pop, "Mod1");
|
||||
WMAddPopUpButtonItem(pop, "Mod2");
|
||||
WMAddPopUpButtonItem(pop, "Mod3");
|
||||
|
|
@ -367,33 +365,18 @@ static void fillModifierPopUp(WMPopUpButton * pop)
|
|||
}
|
||||
|
||||
for (j = 0; j < 8; j++) {
|
||||
int idx;
|
||||
char *array[8];
|
||||
int a;
|
||||
WMNativeKeysym ksym;
|
||||
int k;
|
||||
char *ptr;
|
||||
char *tmp;
|
||||
int a = 0;
|
||||
char *ptr, *tmp;
|
||||
|
||||
a = 0;
|
||||
memset(array, 0, sizeof(char *) * 8);
|
||||
for (i = 0; i < mapping->max_keypermod; i++) {
|
||||
idx = i + j * mapping->max_keypermod;
|
||||
if (mapping->modifiermap[idx] != 0) {
|
||||
int l;
|
||||
for (l = 0; l < 4; l++) {
|
||||
ksym = W_KeycodeToKeysym(dpy, mapping->modifiermap[idx], l);
|
||||
if (ksym != NoSymbol)
|
||||
break;
|
||||
}
|
||||
if (ksym != NoSymbol)
|
||||
str = XKeysymToString(ksym);
|
||||
else
|
||||
str = NULL;
|
||||
if (str && !strstr(str, "_Lock") && !strstr(str, "Shift")
|
||||
&& !strstr(str, "Control")) {
|
||||
array[a++] = wstrdup(str);
|
||||
}
|
||||
memset(array, 0, sizeof(array));
|
||||
for (i = 0; i < MAX_KEYS_PER_MOD; i++) {
|
||||
WMNativeKeysym ksym = keysyms[j * MAX_KEYS_PER_MOD + i];
|
||||
if (ksym == 0) continue;
|
||||
str = (char *)scr->eventBackend->keysym_to_string(scr->eventBackendCtx, ksym);
|
||||
if (str && !strstr(str, "_Lock") && !strstr(str, "Shift")
|
||||
&& !strstr(str, "Control")) {
|
||||
array[a++] = wstrdup(str);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -402,17 +385,13 @@ static void fillModifierPopUp(WMPopUpButton * pop)
|
|||
continue;
|
||||
tmp = wstrdup(array[k]);
|
||||
ptr = strstr(tmp, "_L");
|
||||
if (ptr)
|
||||
*ptr = 0;
|
||||
if (ptr) *ptr = 0;
|
||||
ptr = strstr(tmp, "_R");
|
||||
if (ptr)
|
||||
*ptr = 0;
|
||||
if (ptr) *ptr = 0;
|
||||
sprintf(buffer, "%s (%s)", modifierNames[j], tmp);
|
||||
/*sprintf(buffer, "%s", tmp); */
|
||||
WMAddPopUpButtonItem(pop, buffer);
|
||||
for (i = k + 1; i < a; i++) {
|
||||
if (array[i] == NULL)
|
||||
continue;
|
||||
if (array[i] == NULL) continue;
|
||||
if (strstr(array[i], tmp)) {
|
||||
wfree(array[i]);
|
||||
array[i] = NULL;
|
||||
|
|
@ -427,9 +406,7 @@ static void fillModifierPopUp(WMPopUpButton * pop)
|
|||
wfree(array[a]);
|
||||
}
|
||||
}
|
||||
|
||||
if (mapping)
|
||||
XFreeModifiermap(mapping);
|
||||
#undef MAX_KEYS_PER_MOD
|
||||
}
|
||||
|
||||
static void createPanel(Panel * p)
|
||||
|
|
|
|||
|
|
@ -24,11 +24,6 @@
|
|||
#include "WPrefs.h"
|
||||
#include <assert.h>
|
||||
|
||||
#ifdef USE_X11_BACKEND
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/Xatom.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_STDNORETURN
|
||||
#include <stdnoreturn.h>
|
||||
#endif
|
||||
|
|
@ -132,39 +127,10 @@ static void save(WMWidget * w, void *data)
|
|||
|
||||
WMWritePropListToFile(WindowMakerDB, WindowMakerDBPath);
|
||||
|
||||
/* Tell the running wmaker to reconfigure. On X11 this sends a
|
||||
* _WINDOWMAKER_COMMAND ClientMessage; on Wayland we use the
|
||||
* WINGs screen flush (which triggers a wl_display_flush) and
|
||||
* rely on wmaker's file-watch or SIGUSR1 mechanism. */
|
||||
#ifdef USE_X11_BACKEND
|
||||
{
|
||||
Display *dpy = WMScreenDisplay(WMWidgetScreen(w));
|
||||
XEvent ev;
|
||||
memset(&ev, 0, sizeof(XEvent));
|
||||
ev.xclient.type = ClientMessage;
|
||||
ev.xclient.message_type = XInternAtom(dpy, "_WINDOWMAKER_COMMAND", False);
|
||||
ev.xclient.window = DefaultRootWindow(dpy);
|
||||
ev.xclient.format = 8;
|
||||
strncpy(ev.xclient.data.b, "Reconfigure", sizeof(ev.xclient.data.b));
|
||||
XSendEvent(dpy, DefaultRootWindow(dpy), False,
|
||||
SubstructureRedirectMask, &ev);
|
||||
XFlush(dpy);
|
||||
WMScreen *scr = WMWidgetScreen(w);
|
||||
scr->eventBackend->send_wm_command(scr->eventBackendCtx, "Reconfigure");
|
||||
}
|
||||
#else
|
||||
/* Wayland: signal wmaker to re-read config. */
|
||||
{
|
||||
/* Find wmaker's PID from the lock file and send SIGUSR1. */
|
||||
char pidfile[256];
|
||||
snprintf(pidfile, sizeof(pidfile), "/tmp/wmaker-%d.pid", getuid());
|
||||
FILE *f = fopen(pidfile, "r");
|
||||
if (f) {
|
||||
pid_t pid;
|
||||
if (fscanf(f, "%d", &pid) == 1 && pid > 0)
|
||||
kill(pid, SIGUSR1);
|
||||
fclose(f);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
static void undo(WMWidget * w, void *data)
|
||||
|
|
|
|||
|
|
@ -36,6 +36,19 @@
|
|||
/* Needed for HAVE_LIBINTL_H and EXTENDED_WINDOWSHORTCUT */
|
||||
#include "../src/wconfig.h"
|
||||
|
||||
/* Backend-neutral keysym constants (values match X11/xkbcommon) */
|
||||
#define WMK_Shift_L 0xffe1UL
|
||||
#define WMK_Hyper_R 0xffeeUL
|
||||
#define WMK_Mode_switch 0xff7eUL
|
||||
#define WMK_Num_Lock 0xff7fUL
|
||||
#define WMK_ISO_Lock 0xfe01UL
|
||||
#define WMK_ISO_Level5_Lock 0xfe13UL
|
||||
|
||||
#define WM_IsModifierKey(ks) \
|
||||
(((ks) >= WMK_Shift_L && (ks) <= WMK_Hyper_R) || \
|
||||
((ks) >= WMK_ISO_Lock && (ks) <= WMK_ISO_Level5_Lock) || \
|
||||
(ks) == WMK_Mode_switch || (ks) == WMK_Num_Lock)
|
||||
|
||||
/*
|
||||
* The macro 'wlengthof' should be used as much as possible, this macro
|
||||
* is reserved for the cases where wlengthof cannot be used because the
|
||||
|
|
|
|||
|
|
@ -192,7 +192,7 @@ static void paintEditMenuItem(WEditMenuItem * iPtr)
|
|||
color = scr->white;
|
||||
}
|
||||
|
||||
XClearWindow(scr->display, win);
|
||||
scr->renderBackend->fill_rect(scr->renderBackendCtx, win, scr->white, 0, 0, w, h);
|
||||
|
||||
W_DrawRelief(scr, win, 0, 0, w + 1, h, WRRaised);
|
||||
|
||||
|
|
@ -204,9 +204,9 @@ static void paintEditMenuItem(WEditMenuItem * iPtr)
|
|||
WMDrawPixmap(iPtr->pixmap, win, w - size.width - 5, (h - size.height) / 2);
|
||||
} else if (iPtr->submenu) {
|
||||
/* draw the cascade indicator */
|
||||
XDrawLine(scr->display, win, WMColorGC(scr->darkGray), w - 11, 6, w - 6, h / 2 - 1);
|
||||
XDrawLine(scr->display, win, WMColorGC(scr->white), w - 11, h - 8, w - 6, h / 2 - 1);
|
||||
XDrawLine(scr->display, win, WMColorGC(scr->black), w - 12, 6, w - 12, h - 8);
|
||||
scr->renderBackend->draw_line(scr->renderBackendCtx, win, scr->darkGray, w - 11, 6, w - 6, h / 2 - 1);
|
||||
scr->renderBackend->draw_line(scr->renderBackendCtx, win, scr->white, w - 11, h - 8, w - 6, h / 2 - 1);
|
||||
scr->renderBackend->draw_line(scr->renderBackendCtx, win, scr->black, w - 12, 6, w - 12, h - 8);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -325,8 +325,8 @@ static void writeGNUstepWMAttr(WMScreen * scr, WNativeWindow window, GNUstepWMAt
|
|||
data[6] = attr->miniaturize_mask;
|
||||
data[7] = attr->close_mask;
|
||||
data[8] = attr->extra_flags;
|
||||
XChangeProperty(scr->display, window, scr->attribsAtom, scr->attribsAtom,
|
||||
32, PropModeReplace, (unsigned char *)data, 9);
|
||||
scr->eventBackend->set_window_property_data(scr->eventBackendCtx, window,
|
||||
scr->attribsAtom, scr->attribsAtom, 32, (unsigned char *)data, 9);
|
||||
}
|
||||
|
||||
static void realizeObserver(void *self, WMNotification * not)
|
||||
|
|
@ -649,17 +649,12 @@ void WEditMenuUnhide(WEditMenu * mPtr)
|
|||
|
||||
void WEditMenuShowAt(WEditMenu * menu, int x, int y)
|
||||
{
|
||||
XSizeHints *hints;
|
||||
|
||||
hints = XAllocSizeHints();
|
||||
|
||||
hints->flags = USPosition;
|
||||
hints->x = x;
|
||||
hints->y = y;
|
||||
WMScreen *scr = W_VIEW_SCREEN(menu->view);
|
||||
|
||||
WMMoveWidget(menu, x, y);
|
||||
XSetWMNormalHints(W_VIEW_DISPLAY(menu->view), W_VIEW_DRAWABLE(menu->view), hints);
|
||||
XFree(hints);
|
||||
/* Set USPosition hint so the WM respects our placement */
|
||||
scr->eventBackend->set_window_hints(scr->eventBackendCtx,
|
||||
W_VIEW_DRAWABLE(menu->view), 0, 0, 0, 0, x, y);
|
||||
|
||||
WMMapWidget(menu);
|
||||
}
|
||||
|
|
@ -913,7 +908,7 @@ static void editItemLabel(WEditMenuItem * item)
|
|||
|
||||
/* -------------------------------------------------- */
|
||||
|
||||
static void slideWindow(Display * dpy, WNativeWindow win, int srcX, int srcY, int dstX, int dstY)
|
||||
static void slideWindow(WMScreen *scr, WNativeWindow win, int srcX, int srcY, int dstX, int dstY)
|
||||
{
|
||||
double x, y, dx, dy;
|
||||
int i;
|
||||
|
|
@ -928,8 +923,8 @@ static void slideWindow(Display * dpy, WNativeWindow win, int srcX, int srcY, in
|
|||
dy = (double)(dstY - srcY) / iterations;
|
||||
|
||||
for (i = 0; i <= iterations; i++) {
|
||||
XMoveWindow(dpy, win, x, y);
|
||||
XFlush(dpy);
|
||||
scr->eventBackend->move_window(scr->eventBackendCtx, win, x, y);
|
||||
scr->eventBackend->flush(scr->eventBackendCtx, False);
|
||||
|
||||
wusleep(800);
|
||||
|
||||
|
|
@ -938,27 +933,21 @@ static void slideWindow(Display * dpy, WNativeWindow win, int srcX, int srcY, in
|
|||
}
|
||||
}
|
||||
|
||||
static int errorHandler(Display * d, XErrorEvent * ev)
|
||||
static int errorHandler(void)
|
||||
{
|
||||
/* Parameter not used, but tell the compiler that it is ok */
|
||||
(void) d;
|
||||
(void) ev;
|
||||
|
||||
/* just ignore */
|
||||
return 0;
|
||||
}
|
||||
|
||||
static WEditMenu *findMenuInWindow(Display * dpy, WNativeWindow toplevel, int x, int y)
|
||||
static WEditMenu *findMenuInWindow(WMScreen *scr, WNativeWindow toplevel, int x, int y)
|
||||
{
|
||||
WNativeWindow foo, bar;
|
||||
WNativeWindow *children;
|
||||
unsigned nchildren;
|
||||
int i;
|
||||
WEditMenu *menu;
|
||||
WMView *view;
|
||||
int (*oldHandler) (Display *, XErrorEvent *);
|
||||
|
||||
view = W_GetViewForXWindow(dpy, toplevel);
|
||||
view = W_GetViewForXWindow(scr->display, toplevel);
|
||||
if (view && view->self && WMWidgetClass(view->self) == EditMenuClass) {
|
||||
menu = (WEditMenu *) view->self;
|
||||
if (menu->flags.acceptsDrop) {
|
||||
|
|
@ -966,34 +955,34 @@ static WEditMenu *findMenuInWindow(Display * dpy, WNativeWindow toplevel, int x,
|
|||
}
|
||||
}
|
||||
|
||||
if (!XQueryTree(dpy, toplevel, &foo, &bar, &children, &nchildren) || children == NULL) {
|
||||
scr->eventBackend->set_error_handler(scr->eventBackendCtx, NULL);
|
||||
|
||||
if (!scr->eventBackend->query_tree(scr->eventBackendCtx, toplevel, &children, &nchildren)
|
||||
|| children == NULL) {
|
||||
scr->eventBackend->restore_error_handler(scr->eventBackendCtx);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
oldHandler = XSetErrorHandler(errorHandler);
|
||||
|
||||
/* first window that contains the point is the one */
|
||||
for (i = nchildren - 1; i >= 0; i--) {
|
||||
XWindowAttributes attr;
|
||||
int cx, cy;
|
||||
unsigned int cw, ch;
|
||||
|
||||
if (XGetWindowAttributes(dpy, children[i], &attr)
|
||||
&& attr.map_state == IsViewable
|
||||
&& x >= attr.x && y >= attr.y && x < attr.x + attr.width && y < attr.y + attr.height) {
|
||||
WNativeWindow tmp;
|
||||
if (scr->eventBackend->get_window_geometry(scr->eventBackendCtx, children[i],
|
||||
&cx, &cy, &cw, &ch)
|
||||
&& x >= cx && y >= cy && x < cx + (int)cw && y < cy + (int)ch) {
|
||||
|
||||
tmp = children[i];
|
||||
|
||||
menu = findMenuInWindow(dpy, tmp, x - attr.x, y - attr.y);
|
||||
menu = findMenuInWindow(scr, children[i], x - cx, y - cy);
|
||||
if (menu) {
|
||||
XFree(children);
|
||||
wfree(children);
|
||||
scr->eventBackend->restore_error_handler(scr->eventBackendCtx);
|
||||
return menu;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
XSetErrorHandler(oldHandler);
|
||||
|
||||
XFree(children);
|
||||
scr->eventBackend->restore_error_handler(scr->eventBackendCtx);
|
||||
wfree(children);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
|
@ -1004,7 +993,7 @@ static void handleDragOver(WEditMenu *menu, WMView *view, WEditMenuItem *item, i
|
|||
int mx, my;
|
||||
int offs;
|
||||
|
||||
XTranslateCoordinates(scr->display, W_VIEW_DRAWABLE(menu->view), scr->rootWin, 0, 0, &mx, &my, &blaw);
|
||||
scr->eventBackend->translate_coordinates(scr->eventBackendCtx, W_VIEW_DRAWABLE(menu->view), scr->rootWin, 0, 0, &mx, &my);
|
||||
|
||||
offs = menu->flags.standalone ? 0 : 1;
|
||||
|
||||
|
|
@ -1022,7 +1011,7 @@ static void handleItemDrop(WEditMenu *menu, WEditMenuItem *item, int y)
|
|||
int mx, my;
|
||||
int index;
|
||||
|
||||
XTranslateCoordinates(scr->display, W_VIEW_DRAWABLE(menu->view), scr->rootWin, 0, 0, &mx, &my, &blaw);
|
||||
scr->eventBackend->translate_coordinates(scr->eventBackendCtx, W_VIEW_DRAWABLE(menu->view), scr->rootWin, 0, 0, &mx, &my);
|
||||
|
||||
index = y - my;
|
||||
if (menu->flags.isTitled) {
|
||||
|
|
@ -1061,16 +1050,15 @@ static void dragMenu(WEditMenu * menu)
|
|||
unsigned blau;
|
||||
WNativeWindow blaw;
|
||||
|
||||
XGetGeometry(scr->display, W_VIEW_DRAWABLE(menu->view), &blaw, &dx, &dy, &blau, &blau, &blau, &blau);
|
||||
scr->eventBackend->get_window_geometry(scr->eventBackendCtx,
|
||||
W_VIEW_DRAWABLE(menu->view), &dx, &dy, &blau, &blau);
|
||||
|
||||
XTranslateCoordinates(scr->display, W_VIEW_DRAWABLE(menu->view), scr->rootWin, dx, dy, &dx, &dy, &blaw);
|
||||
scr->eventBackend->translate_coordinates(scr->eventBackendCtx, W_VIEW_DRAWABLE(menu->view), scr->rootWin, dx, dy, &dx, &dy);
|
||||
|
||||
dx = menu->dragX - dx;
|
||||
dy = menu->dragY - dy;
|
||||
|
||||
XGrabPointer(scr->display, scr->rootWin, False,
|
||||
WM_EVMASK_BUTTON_RELEASE | WM_EVMASK_BUTTON_MOTION,
|
||||
WM_GRAB_MODE_ASYNC, WM_GRAB_MODE_ASYNC, WM_NATIVE_NONE, scr->defaultCursor, WM_CURRENT_TIME);
|
||||
scr->eventBackend->grab_pointer(scr->eventBackendCtx, scr->rootWin, scr->defaultCursor);
|
||||
|
||||
if (menu->parent)
|
||||
WTearOffEditMenu(menu->parent, menu);
|
||||
|
|
@ -1104,7 +1092,7 @@ static void dragMenu(WEditMenu * menu)
|
|||
}
|
||||
}
|
||||
|
||||
XUngrabPointer(scr->display, WM_CURRENT_TIME);
|
||||
scr->eventBackend->ungrab_pointer(scr->eventBackendCtx);
|
||||
}
|
||||
|
||||
static WEditMenuItem *duplicateItem(WEditMenuItem * item)
|
||||
|
|
@ -1154,10 +1142,10 @@ static WEditMenu *duplicateMenu(WEditMenu * menu)
|
|||
|
||||
static void dragItem(WEditMenu * menu, WEditMenuItem * item, Bool copy)
|
||||
{
|
||||
static XColor black = { 0, 0, 0, 0, DoRed | DoGreen | DoBlue, 0 };
|
||||
static XColor green = { 0x0045b045, 0x4500, 0xb000, 0x4500, DoRed | DoGreen | DoBlue, 0 };
|
||||
static XColor back = { 0, 0xffff, 0xffff, 0xffff, DoRed | DoGreen | DoBlue, 0 };
|
||||
Display *dpy = W_VIEW_DISPLAY(menu->view);
|
||||
static struct { unsigned short red, green, blue; } black = { 0, 0, 0 };
|
||||
static struct { unsigned short red, green, blue; } green = { 0x4500, 0xb000, 0x4500 };
|
||||
static struct { unsigned short red, green, blue; } back = { 0xffff, 0xffff, 0xffff };
|
||||
|
||||
WMScreen *scr = W_VIEW_SCREEN(menu->view);
|
||||
int x = 0, y = 0;
|
||||
int dx, dy;
|
||||
|
|
@ -1185,7 +1173,7 @@ static void dragItem(WEditMenu * menu, WEditMenuItem * item, Bool copy)
|
|||
|
||||
win = scr->rootWin;
|
||||
|
||||
XTranslateCoordinates(dpy, W_VIEW_DRAWABLE(item->view), win, 0, 0, &orix, &oriy, &blaw);
|
||||
scr->eventBackend->translate_coordinates(scr->eventBackendCtx, W_VIEW_DRAWABLE(item->view), win, 0, 0, &orix, &oriy);
|
||||
|
||||
dview = W_CreateUnmanagedTopView(scr);
|
||||
W_SetViewBackgroundColor(dview, scr->black);
|
||||
|
|
@ -1209,12 +1197,11 @@ static void dragItem(WEditMenu * menu, WEditMenuItem * item, Bool copy)
|
|||
dx = menu->dragX - orix;
|
||||
dy = menu->dragY - oriy;
|
||||
|
||||
XGrabPointer(dpy, scr->rootWin, False,
|
||||
WM_EVMASK_BUTTON_PRESS | WM_EVMASK_BUTTON_RELEASE | WM_EVMASK_BUTTON_MOTION,
|
||||
WM_GRAB_MODE_ASYNC, WM_GRAB_MODE_ASYNC, WM_NATIVE_NONE, scr->defaultCursor, WM_CURRENT_TIME);
|
||||
scr->eventBackend->grab_pointer(scr->eventBackendCtx, scr->rootWin, scr->defaultCursor);
|
||||
|
||||
if (menu->flags.acceptsDrop)
|
||||
XRecolorCursor(dpy, scr->defaultCursor, &green, &back);
|
||||
scr->eventBackend->recolor_cursor(scr->eventBackendCtx, scr->defaultCursor,
|
||||
green.red, green.green, green.blue, back.red, back.green, back.blue);
|
||||
|
||||
while (!done) {
|
||||
WMEvent ev;
|
||||
|
|
@ -1235,22 +1222,22 @@ static void dragItem(WEditMenu * menu, WEditMenuItem * item, Bool copy)
|
|||
}
|
||||
}
|
||||
|
||||
XQueryPointer(dpy, win, &blaw, &blaw, &blai, &blai, &x, &y, &blau);
|
||||
scr->eventBackend->query_pointer(scr->eventBackendCtx, win, NULL, NULL, &x, &y, NULL);
|
||||
|
||||
dmenu = findMenuInWindow(dpy, win, x, y);
|
||||
dmenu = findMenuInWindow(scr, win, x, y);
|
||||
|
||||
if (dmenu) {
|
||||
handleDragOver(dmenu, dview, dritem, y - dy);
|
||||
if (!enteredMenu) {
|
||||
enteredMenu = True;
|
||||
XRecolorCursor(dpy, scr->defaultCursor, &green, &back);
|
||||
scr->eventBackend->recolor_cursor(scr->eventBackendCtx, scr->defaultCursor, green.red, green.green, green.blue, back.red, back.green, back.blue);
|
||||
}
|
||||
} else {
|
||||
if (enteredMenu) {
|
||||
W_ResizeView(dview, oldSize.width, oldSize.height);
|
||||
W_ResizeView(dritem->view, oldSize.width, oldSize.height);
|
||||
enteredMenu = False;
|
||||
XRecolorCursor(dpy, scr->defaultCursor, &black, &back);
|
||||
scr->eventBackend->recolor_cursor(scr->eventBackendCtx, scr->defaultCursor, black.red, black.green, black.blue, back.red, back.green, back.blue);
|
||||
}
|
||||
W_MoveView(dview, x - dx, y - dy);
|
||||
}
|
||||
|
|
@ -1266,9 +1253,9 @@ static void dragItem(WEditMenu * menu, WEditMenuItem * item, Bool copy)
|
|||
break;
|
||||
}
|
||||
}
|
||||
XRecolorCursor(dpy, scr->defaultCursor, &black, &back);
|
||||
scr->eventBackend->recolor_cursor(scr->eventBackendCtx, scr->defaultCursor, black.red, black.green, black.blue, back.red, back.green, back.blue);
|
||||
|
||||
XUngrabPointer(dpy, WM_CURRENT_TIME);
|
||||
scr->eventBackend->ungrab_pointer(scr->eventBackendCtx);
|
||||
|
||||
if (!enteredMenu) {
|
||||
Bool rem = True;
|
||||
|
|
@ -1282,7 +1269,7 @@ static void dragItem(WEditMenu * menu, WEditMenuItem * item, Bool copy)
|
|||
}
|
||||
|
||||
if (!rem || menu->flags.isFactory || copy) {
|
||||
slideWindow(dpy, W_VIEW_DRAWABLE(dview), x - dx, y - dy, orix, oriy);
|
||||
slideWindow(scr, W_VIEW_DRAWABLE(dview), x - dx, y - dy, orix, oriy);
|
||||
|
||||
if (!menu->flags.isFactory && !copy) {
|
||||
WRemoveEditMenuItem(menu, dritem);
|
||||
|
|
|
|||
|
|
@ -26,10 +26,6 @@
|
|||
|
||||
#include <locale.h>
|
||||
|
||||
#ifdef USE_X11_BACKEND
|
||||
#include <X11/Xlocale.h>
|
||||
#endif
|
||||
|
||||
#include <sys/wait.h>
|
||||
#include <unistd.h>
|
||||
|
||||
|
|
@ -137,19 +133,6 @@ int main(int argc, char **argv)
|
|||
bindtextdomain("WPrefs", LOCALEDIR);
|
||||
bind_textdomain_codeset("WPrefs", "UTF-8");
|
||||
textdomain("WPrefs");
|
||||
|
||||
/* X11 locale checks only meaningful in X11 mode. In Wayland mode
|
||||
* locale handling is delegated to xkbcommon / glib. */
|
||||
#ifdef USE_X11_BACKEND
|
||||
if (!getenv("WAYLAND_DISPLAY") || getenv("DISPLAY")) {
|
||||
if (!XSupportsLocale()) {
|
||||
wwarning(_("X server does not support locale"));
|
||||
}
|
||||
if (XSetLocaleModifiers("") == NULL) {
|
||||
wwarning(_("cannot set locale modifiers"));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* WMOpenScreen autodetects Wayland-client mode (WAYLAND_DISPLAY set
|
||||
|
|
|
|||
|
|
@ -1,346 +1,18 @@
|
|||
/* Grok X modifier mappings for shortcuts.
|
||||
|
||||
Most of this code was taken from src/event-Xt.c in XEmacs 20.3-b17.
|
||||
The copyright(s) from the original XEmacs code are included below.
|
||||
|
||||
Perpetrator: Sudish Joseph <sj@eng.mindspring.net>, Sept. 1997. */
|
||||
|
||||
/*
|
||||
* More changes for WPrefs by Alfredo Kojima, Aug 1998
|
||||
/* Modifier mapping for WPrefs shortcut panels.
|
||||
*
|
||||
* Delegates to the event backend's modifier_from_key() vtable method,
|
||||
* which probes the actual modifier mapping on X11 (via XGetModifierMapping)
|
||||
* or returns sensible defaults on Wayland.
|
||||
*
|
||||
* Originally based on src/event-Xt.c in XEmacs 20.3-b17.
|
||||
* Perpetrator: Sudish Joseph <sj@eng.mindspring.net>, Sept. 1997.
|
||||
* More changes for WPrefs by Alfredo Kojima, Aug 1998.
|
||||
* Refactored to backend-neutral vtable dispatch, 2026.
|
||||
*/
|
||||
|
||||
/* The event_stream interface for X11 with Xt, and/or tty frames.
|
||||
Copyright (C) 1991, 1992, 1993, 1994, 1995 Free Software Foundation, Inc.
|
||||
Copyright (C) 1995 Sun Microsystems, Inc.
|
||||
Copyright (C) 1996 Ben Wing.
|
||||
|
||||
This file is part of XEmacs.
|
||||
|
||||
XEmacs is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by the
|
||||
Free Software Foundation; either version 2, or (at your option) any
|
||||
later version.
|
||||
|
||||
XEmacs is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along
|
||||
with XEmacs; see the file COPYING. if not, write to the
|
||||
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
Boston, MA 02110-1301 USA. */
|
||||
|
||||
#include <string.h>
|
||||
#include <strings.h>
|
||||
|
||||
#include "../src/wconfig.h"
|
||||
|
||||
#ifdef USE_X11_BACKEND
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/keysym.h>
|
||||
#include <X11/XKBlib.h>
|
||||
#include <WINGs/WINGsX11.h>
|
||||
#endif
|
||||
|
||||
#include <WINGs/WUtil.h>
|
||||
|
||||
#include "WPrefs.h"
|
||||
|
||||
/************************************************************************/
|
||||
/* keymap handling */
|
||||
/************************************************************************/
|
||||
|
||||
/* Modifier index results — populated by x_reset_modifier_mapping on X11,
|
||||
* or left at defaults (Mod1=Alt=Meta, Mod4=Super) on Wayland. */
|
||||
|
||||
/* X11 modifier map indices — values match <X11/X.h>. */
|
||||
#ifndef ShiftMapIndex
|
||||
#define ShiftMapIndex 0
|
||||
#define LockMapIndex 1
|
||||
#define ControlMapIndex 2
|
||||
#define Mod1MapIndex 3
|
||||
#define Mod2MapIndex 4
|
||||
#define Mod3MapIndex 5
|
||||
#define Mod4MapIndex 6
|
||||
#define Mod5MapIndex 7
|
||||
#endif
|
||||
|
||||
static int MetaIndex = Mod1MapIndex;
|
||||
static int HyperIndex = 0;
|
||||
static int SuperIndex = Mod4MapIndex;
|
||||
static int AltIndex = Mod1MapIndex;
|
||||
static int ModeIndex = 0;
|
||||
|
||||
#ifdef USE_X11_BACKEND
|
||||
|
||||
/* X bogusly doesn't define the interpretations of any bits besides
|
||||
ModControl, ModShift, and ModLock; so the Interclient Communication
|
||||
Conventions Manual says that we have to bend over backwards to figure
|
||||
out what the other modifier bits mean. According to ICCCM:
|
||||
|
||||
- Any keycode which is assigned ModControl is a "control" key.
|
||||
|
||||
- Any modifier bit which is assigned to a keycode which generates Meta_L
|
||||
or Meta_R is the modifier bit meaning "meta". Likewise for Super, Hyper,
|
||||
etc.
|
||||
|
||||
- Any keypress event which contains ModControl in its state should be
|
||||
interpreted as a "control" character.
|
||||
|
||||
- Any keypress event which contains a modifier bit in its state which is
|
||||
generated by a keycode whose corresponding keysym is Meta_L or Meta_R
|
||||
should be interpreted as a "meta" character. Likewise for Super, Hyper,
|
||||
etc.
|
||||
|
||||
- It is illegal for a keysym to be associated with more than one modifier
|
||||
bit.
|
||||
|
||||
This means that the only thing that emacs can reasonably interpret as a
|
||||
"meta" key is a key whose keysym is Meta_L or Meta_R, and which generates
|
||||
one of the modifier bits Mod1-Mod5.
|
||||
|
||||
Unfortunately, many keyboards don't have Meta keys in their default
|
||||
configuration. So, if there are no Meta keys, but there are "Alt" keys,
|
||||
emacs will interpret Alt as Meta. If there are both Meta and Alt keys,
|
||||
then the Meta keys mean "Meta", and the Alt keys mean "Alt" (it used to
|
||||
mean "Symbol," but that just confused the hell out of way too many people).
|
||||
|
||||
This works with the default configurations of the 19 keyboard-types I've
|
||||
checked.
|
||||
|
||||
Emacs detects keyboard configurations which violate the above rules, and
|
||||
prints an error message on the standard-error-output. (Perhaps it should
|
||||
use a pop-up-window instead.)
|
||||
*/
|
||||
|
||||
|
||||
static const char *index_to_name(int indice)
|
||||
{
|
||||
switch (indice) {
|
||||
case ShiftMapIndex:
|
||||
return "ModShift";
|
||||
case LockMapIndex:
|
||||
return "ModLock";
|
||||
case ControlMapIndex:
|
||||
return "ModControl";
|
||||
case Mod1MapIndex:
|
||||
return "Mod1";
|
||||
case Mod2MapIndex:
|
||||
return "Mod2";
|
||||
case Mod3MapIndex:
|
||||
return "Mod3";
|
||||
case Mod4MapIndex:
|
||||
return "Mod4";
|
||||
case Mod5MapIndex:
|
||||
return "Mod5";
|
||||
default:
|
||||
return "???";
|
||||
}
|
||||
}
|
||||
|
||||
static void x_reset_modifier_mapping(Display * display)
|
||||
{
|
||||
int modifier_index, modifier_key, column, mkpm;
|
||||
int meta_bit = 0;
|
||||
int hyper_bit = 0;
|
||||
int super_bit = 0;
|
||||
int alt_bit = 0;
|
||||
int mode_bit = 0;
|
||||
XModifierKeymap *x_modifier_keymap;
|
||||
|
||||
#define modwarn(name,old,other) \
|
||||
wwarning(_("%s (0x%x) generates %s which is generated by %s"), \
|
||||
name, code, index_to_name (old), other)
|
||||
|
||||
#define modbarf(name,other) \
|
||||
wwarning(_("%s (0x%x) generates %s which is nonsensical"), \
|
||||
name, code, other)
|
||||
|
||||
#define check_modifier(name,mask) \
|
||||
if ((1<<modifier_index) != mask) \
|
||||
wwarning(_("%s (0x%x) generates %s which is nonsensical"), \
|
||||
name, code, index_to_name (modifier_index))
|
||||
|
||||
#define store_modifier(name,old) \
|
||||
if (old && old != modifier_index) \
|
||||
wwarning(_("%s (0x%x) generates both %s and %s which is nonsensical"), \
|
||||
name, code, index_to_name (old), \
|
||||
index_to_name (modifier_index)); \
|
||||
if (modifier_index == ShiftMapIndex) modbarf (name,"ModShift"); \
|
||||
else if (modifier_index == LockMapIndex) modbarf (name,"ModLock"); \
|
||||
else if (modifier_index == ControlMapIndex) modbarf (name,"ModControl"); \
|
||||
else if (sym == XK_Mode_switch) \
|
||||
mode_bit = modifier_index; /* Mode_switch is special, see below... */ \
|
||||
else if (modifier_index == meta_bit && old != meta_bit) \
|
||||
modwarn (name, meta_bit, "Meta"); \
|
||||
else if (modifier_index == super_bit && old != super_bit) \
|
||||
modwarn (name, super_bit, "Super"); \
|
||||
else if (modifier_index == hyper_bit && old != hyper_bit) \
|
||||
modwarn (name, hyper_bit, "Hyper"); \
|
||||
else if (modifier_index == alt_bit && old != alt_bit) \
|
||||
modwarn (name, alt_bit, "Alt"); \
|
||||
else \
|
||||
old = modifier_index;
|
||||
|
||||
x_modifier_keymap = XGetModifierMapping(display);
|
||||
if (x_modifier_keymap == NULL) {
|
||||
wwarning(_("XGetModifierMapping returned NULL, there is no modifier or no memory"));
|
||||
return;
|
||||
}
|
||||
|
||||
mkpm = x_modifier_keymap->max_keypermod;
|
||||
for (modifier_index = 0; modifier_index < 8; modifier_index++)
|
||||
for (modifier_key = 0; modifier_key < mkpm; modifier_key++) {
|
||||
WMNativeKeysym last_sym = 0;
|
||||
for (column = 0; column < 4; column += 2) {
|
||||
KeyCode code = x_modifier_keymap->modifiermap[modifier_index * mkpm
|
||||
+ modifier_key];
|
||||
WMNativeKeysym sym;
|
||||
|
||||
if (code) {
|
||||
sym = W_KeycodeToKeysym(display, code, column);
|
||||
} else {
|
||||
sym = NoSymbol;
|
||||
}
|
||||
|
||||
if (sym == last_sym)
|
||||
continue;
|
||||
last_sym = sym;
|
||||
switch (sym) {
|
||||
case XK_Mode_switch:
|
||||
store_modifier("Mode_switch", mode_bit);
|
||||
break;
|
||||
case XK_Meta_L:
|
||||
store_modifier("Meta_L", meta_bit);
|
||||
break;
|
||||
case XK_Meta_R:
|
||||
store_modifier("Meta_R", meta_bit);
|
||||
break;
|
||||
case XK_Super_L:
|
||||
store_modifier("Super_L", super_bit);
|
||||
break;
|
||||
case XK_Super_R:
|
||||
store_modifier("Super_R", super_bit);
|
||||
break;
|
||||
case XK_Hyper_L:
|
||||
store_modifier("Hyper_L", hyper_bit);
|
||||
break;
|
||||
case XK_Hyper_R:
|
||||
store_modifier("Hyper_R", hyper_bit);
|
||||
break;
|
||||
case XK_Alt_L:
|
||||
store_modifier("Alt_L", alt_bit);
|
||||
break;
|
||||
case XK_Alt_R:
|
||||
store_modifier("Alt_R", alt_bit);
|
||||
break;
|
||||
case XK_Control_L:
|
||||
check_modifier("Control_L", WM_MOD_CONTROL);
|
||||
break;
|
||||
case XK_Control_R:
|
||||
check_modifier("Control_R", WM_MOD_CONTROL);
|
||||
break;
|
||||
case XK_Shift_L:
|
||||
check_modifier("Shift_L", WM_MOD_SHIFT);
|
||||
break;
|
||||
case XK_Shift_R:
|
||||
check_modifier("Shift_R", WM_MOD_SHIFT);
|
||||
break;
|
||||
case XK_Shift_Lock:
|
||||
check_modifier("Shift_Lock", WM_MOD_LOCK);
|
||||
break;
|
||||
case XK_Caps_Lock:
|
||||
check_modifier("Caps_Lock", WM_MOD_LOCK);
|
||||
break;
|
||||
|
||||
/* It probably doesn't make any sense for a modifier bit to be
|
||||
assigned to a key that is not one of the above, but OpenWindows
|
||||
assigns modifier bits to a couple of random function keys for
|
||||
no reason that I can discern, so printing a warning here would
|
||||
be annoying. */
|
||||
}
|
||||
}
|
||||
}
|
||||
#undef store_modifier
|
||||
#undef check_modifier
|
||||
#undef modwarn
|
||||
#undef modbarf
|
||||
|
||||
/* If there was no Meta key, then try using the Alt key instead.
|
||||
If there is both a Meta key and an Alt key, then the Alt key
|
||||
is not disturbed and remains an Alt key. */
|
||||
if (!meta_bit && alt_bit)
|
||||
meta_bit = alt_bit, alt_bit = 0;
|
||||
|
||||
/* mode_bit overrides everything, since it's processed down inside of
|
||||
XLookupString() instead of by us. If Meta and Mode_switch both
|
||||
generate the same modifier bit (which is an error), then we don't
|
||||
interpret that bit as Meta, because we can't make XLookupString()
|
||||
not interpret it as Mode_switch; and interpreting it as both would
|
||||
be totally wrong. */
|
||||
if (mode_bit) {
|
||||
const char *warn = 0;
|
||||
if (mode_bit == meta_bit)
|
||||
warn = "Meta", meta_bit = 0;
|
||||
else if (mode_bit == hyper_bit)
|
||||
warn = "Hyper", hyper_bit = 0;
|
||||
else if (mode_bit == super_bit)
|
||||
warn = "Super", super_bit = 0;
|
||||
else if (mode_bit == alt_bit)
|
||||
warn = "Alt", alt_bit = 0;
|
||||
if (warn) {
|
||||
wwarning(_("%s is being used for both %s and %s"),
|
||||
index_to_name(mode_bit), "Mode_switch", warn);
|
||||
}
|
||||
}
|
||||
|
||||
MetaIndex = meta_bit;
|
||||
HyperIndex = hyper_bit;
|
||||
SuperIndex = super_bit;
|
||||
AltIndex = alt_bit;
|
||||
ModeIndex = mode_bit;
|
||||
|
||||
XFreeModifiermap(x_modifier_keymap);
|
||||
}
|
||||
|
||||
#endif /* USE_X11_BACKEND */
|
||||
|
||||
int ModifierFromKey(WMScreen *scr, const char *key)
|
||||
{
|
||||
#ifdef USE_X11_BACKEND
|
||||
Display *dpy = WMScreenDisplay(scr);
|
||||
static int eqw = 0;
|
||||
|
||||
if (!eqw)
|
||||
x_reset_modifier_mapping(dpy);
|
||||
eqw = 1;
|
||||
#else
|
||||
(void)scr;
|
||||
#endif
|
||||
|
||||
if (strcasecmp(key, "SHIFT") == 0)
|
||||
return ShiftMapIndex;
|
||||
else if (strcasecmp(key, "CONTROL") == 0)
|
||||
return ControlMapIndex;
|
||||
else if (strcasecmp(key, "ALT") == 0)
|
||||
return AltIndex;
|
||||
else if (strcasecmp(key, "META") == 0)
|
||||
return MetaIndex;
|
||||
else if (strcasecmp(key, "SUPER") == 0)
|
||||
return SuperIndex;
|
||||
else if (strcasecmp(key, "HYPER") == 0)
|
||||
return HyperIndex;
|
||||
else if (strcasecmp(key, "MOD1") == 0)
|
||||
return Mod1MapIndex;
|
||||
else if (strcasecmp(key, "MOD2") == 0)
|
||||
return Mod2MapIndex;
|
||||
else if (strcasecmp(key, "MOD3") == 0)
|
||||
return Mod3MapIndex;
|
||||
else if (strcasecmp(key, "MOD4") == 0)
|
||||
return Mod4MapIndex;
|
||||
else if (strcasecmp(key, "MOD5") == 0)
|
||||
return Mod5MapIndex;
|
||||
else
|
||||
return -1;
|
||||
return scr->eventBackend->modifier_from_key(scr->eventBackendCtx, key);
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue