5 #include <X11/Xproto.h>
6 #include <X11/keysym.h>
12 /* Internal structures */
23 /* Conversion functions */
24 keymap_t key2sym[] = {
25 {key_left , XK_Left },
26 {key_right , XK_Right},
28 {key_down , XK_Down },
29 {key_home , XK_Home },
31 {key_pageup , XK_Prior},
32 {key_pagedown, XK_Next },
48 mod_t x2mod(unsigned int state, int up)
51 .alt = !!(state & Mod1Mask ),
52 .ctrl = !!(state & ControlMask),
53 .shift = !!(state & ShiftMask ),
54 .win = !!(state & Mod4Mask ),
59 unsigned int mod2x(mod_t mod)
61 return mod.alt ? Mod1Mask : 0
62 | mod.ctrl ? ControlMask : 0
63 | mod.shift ? ShiftMask : 0
64 | mod.win ? Mod4Mask : 0;
68 Key_t x2key(KeySym sym)
70 keymap_t *km = map_getr(key2sym,sym);
71 return km ? km->key : sym;
74 KeySym key2x(Key_t key)
76 keymap_t *km = map_get(key2sym,key);
77 return km ? km->sym : key;
82 return btn + key_mouse0;
87 return key - key_mouse0;
91 ptr_t x2ptr(XEvent _ev)
93 XKeyEvent ev = _ev.xkey;
94 return (ptr_t){ev.x, ev.y, ev.x_root, ev.y_root};
97 /* Helper functions */
98 win_t *win_new(Display *xdpy, Window xwin)
102 XWindowAttributes attr;
103 XGetWindowAttributes(xdpy, xwin, &attr);
104 win_t *win = new0(win_t);
108 win->h = attr.height;
109 win->sys = new0(win_sys_t);
110 win->sys->dpy = xdpy;
111 win->sys->win = xwin;
115 void win_free(win_t *win)
124 void sys_move(win_t *win, int x, int y, int w, int h)
126 printf("sys_move: %p - %d,%d %dx%d\n", win, x, y, w, h);
127 XMoveResizeWindow(win->sys->dpy, win->sys->win, x, y, w, h);
130 void sys_raise(win_t *win)
132 printf("sys_raise: %p\n", win);
133 XRaiseWindow(win->sys->dpy, win->sys->win);
136 void sys_watch(win_t *win, Key_t key, mod_t mod)
138 if (key_mouse0 <= key && key <= key_mouse7)
139 XGrabButton(win->sys->dpy, btn2x(key), mod2x(mod), win->sys->win, True,
140 mod.up ? ButtonReleaseMask : ButtonPressMask,
141 GrabModeAsync, GrabModeAsync, None, None);
143 XGrabKey(win->sys->dpy, XKeysymToKeycode(win->sys->dpy, key2x(key)),
144 mod2x(mod), win->sys->win, True, GrabModeAsync, GrabModeAsync);
147 win_t *sys_init(void)
149 Display *xdpy = XOpenDisplay(NULL);
150 Window xwin = DefaultRootWindow(xdpy);
151 return win_new(xdpy, xwin);
154 void sys_run(win_t *root)
156 Display *dpy = root->sys->dpy;
160 XNextEvent(dpy, &ev);
161 //printf("event: %d\n", ev.type);
162 if (ev.type == KeyPress) {
163 while (XCheckTypedEvent(dpy, KeyPress, &ev));
164 KeySym sym = XKeycodeToKeysym(dpy, ev.xkey.keycode, 0);
165 wm_handle_key(win_new(dpy, ev.xkey.subwindow),
166 x2key(sym), x2mod(ev.xkey.state,0), x2ptr(ev));
168 else if (ev.type == ButtonPress) {
169 wm_handle_key(win_new(dpy, ev.xkey.subwindow),
170 x2btn(ev.xbutton.button),
171 x2mod(ev.xbutton.state,0), x2ptr(ev));
172 XGrabPointer(dpy, ev.xkey.subwindow, True,
173 PointerMotionMask|ButtonReleaseMask, GrabModeAsync,
174 GrabModeAsync, None, None, CurrentTime);
176 else if(ev.type == ButtonRelease) {
177 XUngrabPointer(dpy, CurrentTime);
178 wm_handle_key(win_new(dpy, ev.xkey.subwindow),
179 x2btn(ev.xbutton.button),
180 x2mod(ev.xbutton.state,1), x2ptr(ev));
182 else if(ev.type == MotionNotify) {
183 while (XCheckTypedEvent(dpy, MotionNotify, &ev));
184 wm_handle_ptr(win_new(dpy, ev.xkey.subwindow), x2ptr(ev));