From: Andy Spencer Date: Sat, 14 May 2011 22:13:38 +0000 (+0000) Subject: Initial code for x11/wmii X-Git-Url: http://pileus.org/git/?p=wmpus;a=commitdiff_plain;h=c00388973ecb2af94cc7b74ef762f0b8d10741e6 Initial code for x11/wmii --- diff --git a/main.c b/main.c index f93793e..a30fd1c 100644 --- a/main.c +++ b/main.c @@ -1,7 +1,14 @@ +#include #include +#include "util.h" +#include "sys.h" +#include "wm.h" + int main(int argc, char **argv) { - printf("hello, world\n"); + win_t *root = sys_init(); + wm_init(root); + sys_run(root); return 0; } diff --git a/sys-x11.c b/sys-x11.c index e69de29..76195a9 100644 --- a/sys-x11.c +++ b/sys-x11.c @@ -0,0 +1,174 @@ +#include +#include + +#include +#include +#include + +#include "util.h" +#include "sys.h" +#include "wm.h" + +/* Internal structures */ +struct win_sys { + Window win; + Display *dpy; +}; + +/* Conversion functions */ +struct { + Key_t key; + int sym; +} keymap[] = { + {key_left , XK_Left }, + {key_right , XK_Right}, + {key_up , XK_Up }, + {key_down , XK_Down }, + {key_home , XK_Home }, + {key_end , XK_End }, + {key_pageup , XK_Prior}, + {key_pagedown, XK_Next }, + {key_f1 , XK_F1 }, + {key_f2 , XK_F2 }, + {key_f3 , XK_F3 }, + {key_f4 , XK_F4 }, + {key_f5 , XK_F5 }, + {key_f6 , XK_F6 }, + {key_f7 , XK_F7 }, + {key_f8 , XK_F8 }, + {key_f9 , XK_F9 }, + {key_f10 , XK_F10 }, + {key_f11 , XK_F11 }, + {key_f12 , XK_F12 }, +}; + +mod_t x2mod(unsigned int state) +{ + return (mod_t){ + .alt = !!(state & Mod1Mask ), + .ctrl = !!(state & ControlMask), + .shift = !!(state & ShiftMask ), + .win = !!(state & Mod4Mask ), + }; +} +unsigned int mod2x(mod_t mod) +{ + return mod.alt ? Mod1Mask : 0 + | mod.ctrl ? ControlMask : 0 + | mod.shift ? ShiftMask : 0 + | mod.win ? Mod4Mask : 0; +} + +KeySym key2x(Key_t key) +{ + for (int i = 0; i < countof(keymap); i++) + if (keymap[i].key == key) + return keymap[i].sym; + return key; +} +Key_t x2key(KeySym sym) +{ + for (int i = 0; i < countof(keymap); i++) + if (keymap[i].sym == sym) + return keymap[i].key; + return sym; +} + +int btn2x(Key_t key) +{ + return key - key_mouse0; +} +Key_t x2btn(int btn) +{ + return btn + key_mouse0; +} + +ptr_t x2ptr(XEvent _ev) +{ + XKeyEvent ev = _ev.xkey; + return (ptr_t){ev.x, ev.y, ev.x_root, ev.y_root}; +} + +/* Functions */ +void sys_move(win_t *win, int x, int y, int w, int h) +{ + printf("sys_move: %p - %d,%d %dx%d\n", win, x, y, w, h); + XMoveResizeWindow(win->sys->dpy, win->sys->win, x, y, w, h); +} + +void sys_raise(win_t *win) +{ + printf("sys_raise: %p\n", win); + XRaiseWindow(win->sys->dpy, win->sys->win); +} + +void sys_watch(win_t *win, Key_t key, mod_t mod) +{ + if (key_mouse0 <= key && key <= key_mouse7) + XGrabButton(win->sys->dpy, btn2x(key), mod2x(mod), win->sys->win, True, + mod.up ? ButtonReleaseMask : ButtonPressMask, + GrabModeAsync, GrabModeAsync, None, None); + else + XGrabKey(win->sys->dpy, XKeysymToKeycode(win->sys->dpy, key2x(key)), + mod2x(mod), win->sys->win, True, GrabModeAsync, GrabModeAsync); +} + +win_t *win_new(Display *xdpy, Window xwin) +{ + XWindowAttributes attr; + XGetWindowAttributes(xdpy, xwin, &attr); + win_t *win = new0(win_t); + win->x = attr.x; + win->y = attr.y; + win->w = attr.width; + win->h = attr.height; + win->sys = new0(win_sys_t); + win->sys->dpy = xdpy; + win->sys->win = xwin; + return win; +} +void win_free(win_t *win) +{ + free(win->sys); + free(win); +} + +win_t *sys_init(void) +{ + Display *xdpy = XOpenDisplay(NULL); + Window xwin = DefaultRootWindow(xdpy); + return win_new(xdpy, xwin); +} + +void sys_run(win_t *root) +{ + Display *dpy = root->sys->dpy; + for(;;) + { + XEvent ev; + XNextEvent(dpy, &ev); + printf("event: %d\n", ev.type); + if (ev.type == KeyPress && ev.xkey.subwindow) { + while (XCheckTypedEvent(dpy, KeyPress, &ev)); + KeySym sym = XKeycodeToKeysym(dpy, ev.xkey.keycode, 0); + wm_handle_key(win_new(dpy, ev.xkey.subwindow), + x2key(sym), x2mod(ev.xkey.state), x2ptr(ev)); + } + else if (ev.type == ButtonPress && ev.xbutton.subwindow) { + wm_handle_key(win_new(dpy, ev.xkey.subwindow), + x2btn(ev.xbutton.button), MOD(.up=0), x2ptr(ev)); + XGrabPointer(dpy, ev.xkey.subwindow, True, + PointerMotionMask|ButtonReleaseMask, GrabModeAsync, + GrabModeAsync, None, None, CurrentTime); + } + else if(ev.type == ButtonRelease) { + XUngrabPointer(dpy, CurrentTime); + wm_handle_key(win_new(dpy, ev.xkey.subwindow), + x2btn(ev.xbutton.button), MOD(.up=1), x2ptr(ev)); + } + else if(ev.type == MotionNotify) { + while (XCheckTypedEvent(dpy, MotionNotify, &ev)); + wm_handle_ptr(win_new(dpy, ev.xkey.subwindow), x2ptr(ev)); + } + } +} diff --git a/sys.h b/sys.h index e69de29..a302559 100644 --- a/sys.h +++ b/sys.h @@ -0,0 +1,55 @@ +typedef struct win_sys win_sys_t; +typedef struct win_wm win_wm_t; +typedef struct { + int x, y, z; + int w, h; + win_sys_t *sys; + win_wm_t *wm; +} win_t; + +typedef enum { + // 'char' = unicode, + key_alert = '\a', // Bell (alert) + key_backspace = '\b', // Backspace + key_formfeed = '\f', // Formfeed + key_newline = '\n', // New line + key_return = '\r', // Carriage return + key_tab = '\t', // Horizontal tab + key_vtab = '\v', // Vertical tab + key_singlequote = '\'', // Single quotation mark + key_doublequote = '\"', // Double quotation mark + key_backslash = '\\', // Backslash + key_question = '\?', // Literal question mark + key_none = 0xF0000, // unused unicode space + key_mouse0, key_mouse1, key_mouse2, key_mouse3, + key_mouse4, key_mouse5, key_mouse6, key_mouse7, + key_left, key_right, key_up, key_down, + key_home, key_end, key_pageup, key_pagedown, + key_f1, key_f2, key_f3, key_f4, + key_f5, key_f6, key_f7, key_f8, + key_f9, key_f10, key_f11, key_f12, +} Key_t; + +typedef struct { + int up : 1; + int alt : 1; + int ctrl : 1; + int shift : 1; + int win : 1; +} mod_t; +#define MOD(...) ((mod_t){__VA_ARGS__}) + +typedef struct { + int x, y; + int rx, ry; +} ptr_t; + +void sys_watch(win_t *win, Key_t key, mod_t mod); + +void sys_move(win_t *win, int x, int y, int w, int h); + +void sys_raise(win_t *win); + +win_t *sys_init(void); + +void sys_run(win_t *root); diff --git a/util.h b/util.h index e69de29..a572a0a 100644 --- a/util.h +++ b/util.h @@ -0,0 +1,13 @@ +#define MAX(a,b) ((a) > (b) ? (a) : (b)) +#define MIN(a,b) ((a) < (b) ? (a) : (b)) + +#define new0(type) (calloc(1, sizeof(type))) + +#define countof(x) (sizeof(x)/sizeof((x)[0])) + +#define map_get(map, key) ({ \ + int i; \ + for (i = 0; i < countof(map) && \ + *((typeof(key)*)&map[i]) != key; i++); \ + i < countof(map) ? &map[i] : NULL ; \ +}) diff --git a/wm-wmii.c b/wm-wmii.c index e69de29..5faf9c9 100644 --- a/wm-wmii.c +++ b/wm-wmii.c @@ -0,0 +1,45 @@ +#include + +#include "sys.h" +#include "wm.h" + +typedef enum { + none, move, resize +} mode_t; + +win_t *kwin; +ptr_t kptr; +mode_t mode; + +void wm_handle_key(win_t *win, Key_t key, mod_t mod, ptr_t ptr) +{ + printf("wm_handle_key: %p - %x %x\n", win, key, *(int*)&mod); + kptr = ptr; + kwin = win; + if (key == key_f1 && mod.ctrl) + sys_raise(win); + else if (key_mouse0 <= key && key <= key_mouse7 && mod.up) + mode = none; + else if (key == key_mouse1) + mode = move; + else if (key == key_mouse3) + mode = resize; +} + +void wm_handle_ptr(win_t *win, ptr_t ptr) +{ + printf("wm_handle_ptr: %p - %d,%d (%d)\n", win, ptr.x, ptr.y, mode); + int dx = ptr.rx - kptr.rx; + int dy = ptr.ry - kptr.ry; + if (mode == move) + sys_move(kwin, kwin->x+dx, kwin->y+dy, kwin->w, kwin->h); + else if (mode == resize) + sys_move(kwin, kwin->x, kwin->y, kwin->w+dx, kwin->h+dy); +} + +void wm_init(win_t *root) +{ + sys_watch(root, key_f1, MOD(.ctrl=1)); + sys_watch(root, key_mouse1, MOD(.ctrl=1)); + sys_watch(root, key_mouse3, MOD(.ctrl=1)); +} diff --git a/wm.h b/wm.h index e69de29..4b1d834 100644 --- a/wm.h +++ b/wm.h @@ -0,0 +1,5 @@ +void wm_init(win_t *root); + +void wm_handle_key(win_t *win, Key_t key, mod_t mod, ptr_t ptr); + +void wm_handle_ptr(win_t *win, ptr_t ptr);