5 #include <X11/Xproto.h>
6 #include <X11/keysym.h>
12 /* Internal structures */
18 /* Conversion functions */
23 {key_left , XK_Left },
24 {key_right , XK_Right},
26 {key_down , XK_Down },
27 {key_home , XK_Home },
29 {key_pageup , XK_Prior},
30 {key_pagedown, XK_Next },
45 mod_t x2mod(unsigned int state)
48 .alt = !!(state & Mod1Mask ),
49 .ctrl = !!(state & ControlMask),
50 .shift = !!(state & ShiftMask ),
51 .win = !!(state & Mod4Mask ),
54 unsigned int mod2x(mod_t mod)
56 return mod.alt ? Mod1Mask : 0
57 | mod.ctrl ? ControlMask : 0
58 | mod.shift ? ShiftMask : 0
59 | mod.win ? Mod4Mask : 0;
62 KeySym key2x(Key_t key)
64 return map_get(key2sym,key)->sym ?: key;
66 Key_t x2key(KeySym sym)
68 return map_getr(key2sym,sym)->key ?: sym;
73 return key - key_mouse0;
77 return btn + key_mouse0;
80 ptr_t x2ptr(XEvent _ev)
82 XKeyEvent ev = _ev.xkey;
83 return (ptr_t){ev.x, ev.y, ev.x_root, ev.y_root};
87 void sys_move(win_t *win, int x, int y, int w, int h)
89 printf("sys_move: %p - %d,%d %dx%d\n", win, x, y, w, h);
90 XMoveResizeWindow(win->sys->dpy, win->sys->win, x, y, w, h);
93 void sys_raise(win_t *win)
95 printf("sys_raise: %p\n", win);
96 XRaiseWindow(win->sys->dpy, win->sys->win);
99 void sys_watch(win_t *win, Key_t key, mod_t mod)
101 if (key_mouse0 <= key && key <= key_mouse7)
102 XGrabButton(win->sys->dpy, btn2x(key), mod2x(mod), win->sys->win, True,
103 mod.up ? ButtonReleaseMask : ButtonPressMask,
104 GrabModeAsync, GrabModeAsync, None, None);
106 XGrabKey(win->sys->dpy, XKeysymToKeycode(win->sys->dpy, key2x(key)),
107 mod2x(mod), win->sys->win, True, GrabModeAsync, GrabModeAsync);
110 win_t *win_new(Display *xdpy, Window xwin)
114 XWindowAttributes attr;
115 XGetWindowAttributes(xdpy, xwin, &attr);
116 win_t *win = new0(win_t);
120 win->h = attr.height;
121 win->sys = new0(win_sys_t);
122 win->sys->dpy = xdpy;
123 win->sys->win = xwin;
126 void win_free(win_t *win)
132 win_t *sys_init(void)
134 Display *xdpy = XOpenDisplay(NULL);
135 Window xwin = DefaultRootWindow(xdpy);
136 return win_new(xdpy, xwin);
139 void sys_run(win_t *root)
141 Display *dpy = root->sys->dpy;
145 XNextEvent(dpy, &ev);
146 //printf("event: %d\n", ev.type);
147 if (ev.type == KeyPress && ev.xkey.subwindow) {
148 while (XCheckTypedEvent(dpy, KeyPress, &ev));
149 KeySym sym = XKeycodeToKeysym(dpy, ev.xkey.keycode, 0);
150 wm_handle_key(win_new(dpy, ev.xkey.subwindow),
151 x2key(sym), x2mod(ev.xkey.state), x2ptr(ev));
153 else if (ev.type == ButtonPress && ev.xbutton.subwindow) {
154 wm_handle_key(win_new(dpy, ev.xkey.subwindow),
155 x2btn(ev.xbutton.button), MOD(.up=0), x2ptr(ev));
156 XGrabPointer(dpy, ev.xkey.subwindow, True,
157 PointerMotionMask|ButtonReleaseMask, GrabModeAsync,
158 GrabModeAsync, None, None, CurrentTime);
160 else if(ev.type == ButtonRelease) {
161 XUngrabPointer(dpy, CurrentTime);
162 wm_handle_key(win_new(dpy, ev.xkey.subwindow),
163 x2btn(ev.xbutton.button), MOD(.up=1), x2ptr(ev));
165 else if(ev.type == MotionNotify) {
166 while (XCheckTypedEvent(dpy, MotionNotify, &ev));
167 wm_handle_ptr(win_new(dpy, ev.xkey.subwindow), x2ptr(ev));