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 for (int i = 0; i < countof(keymap); i++)
65 if (keymap[i].key == key)
69 Key_t x2key(KeySym sym)
71 for (int i = 0; i < countof(keymap); i++)
72 if (keymap[i].sym == sym)
79 return key - key_mouse0;
83 return btn + key_mouse0;
86 ptr_t x2ptr(XEvent _ev)
88 XKeyEvent ev = _ev.xkey;
89 return (ptr_t){ev.x, ev.y, ev.x_root, ev.y_root};
93 void sys_move(win_t *win, int x, int y, int w, int h)
95 printf("sys_move: %p - %d,%d %dx%d\n", win, x, y, w, h);
96 XMoveResizeWindow(win->sys->dpy, win->sys->win, x, y, w, h);
99 void sys_raise(win_t *win)
101 printf("sys_raise: %p\n", win);
102 XRaiseWindow(win->sys->dpy, win->sys->win);
105 void sys_watch(win_t *win, Key_t key, mod_t mod)
107 if (key_mouse0 <= key && key <= key_mouse7)
108 XGrabButton(win->sys->dpy, btn2x(key), mod2x(mod), win->sys->win, True,
109 mod.up ? ButtonReleaseMask : ButtonPressMask,
110 GrabModeAsync, GrabModeAsync, None, None);
112 XGrabKey(win->sys->dpy, XKeysymToKeycode(win->sys->dpy, key2x(key)),
113 mod2x(mod), win->sys->win, True, GrabModeAsync, GrabModeAsync);
116 win_t *win_new(Display *xdpy, Window xwin)
118 XWindowAttributes attr;
119 XGetWindowAttributes(xdpy, xwin, &attr);
120 win_t *win = new0(win_t);
124 win->h = attr.height;
125 win->sys = new0(win_sys_t);
126 win->sys->dpy = xdpy;
127 win->sys->win = xwin;
130 void win_free(win_t *win)
136 win_t *sys_init(void)
138 Display *xdpy = XOpenDisplay(NULL);
139 Window xwin = DefaultRootWindow(xdpy);
140 return win_new(xdpy, xwin);
143 void sys_run(win_t *root)
145 Display *dpy = root->sys->dpy;
149 XNextEvent(dpy, &ev);
150 printf("event: %d\n", ev.type);
151 if (ev.type == KeyPress && ev.xkey.subwindow) {
152 while (XCheckTypedEvent(dpy, KeyPress, &ev));
153 KeySym sym = XKeycodeToKeysym(dpy, ev.xkey.keycode, 0);
154 wm_handle_key(win_new(dpy, ev.xkey.subwindow),
155 x2key(sym), x2mod(ev.xkey.state), x2ptr(ev));
157 else if (ev.type == ButtonPress && ev.xbutton.subwindow) {
158 wm_handle_key(win_new(dpy, ev.xkey.subwindow),
159 x2btn(ev.xbutton.button), MOD(.up=0), x2ptr(ev));
160 XGrabPointer(dpy, ev.xkey.subwindow, True,
161 PointerMotionMask|ButtonReleaseMask, GrabModeAsync,
162 GrabModeAsync, None, None, CurrentTime);
164 else if(ev.type == ButtonRelease) {
165 XUngrabPointer(dpy, CurrentTime);
166 wm_handle_key(win_new(dpy, ev.xkey.subwindow),
167 x2btn(ev.xbutton.button), MOD(.up=1), x2ptr(ev));
169 else if(ev.type == MotionNotify) {
170 while (XCheckTypedEvent(dpy, MotionNotify, &ev));
171 wm_handle_ptr(win_new(dpy, ev.xkey.subwindow), x2ptr(ev));