From d7d862c402564b4fe29f17e1a55cdbb2967aa6fd Mon Sep 17 00:00:00 2001 From: Andy Spencer Date: Wed, 18 May 2011 07:09:25 +0000 Subject: [PATCH] Initial code for win32 --- makefile | 11 ++- sys-win32.c | 235 ++++++++++++++++++++++++++++++++++++++++++++++++++++ sys-x11.c | 16 ++-- sys.h | 12 +-- util.h | 10 ++- wm-wmii.c | 36 +++++--- wm.h | 4 +- 7 files changed, 288 insertions(+), 36 deletions(-) diff --git a/makefile b/makefile index b1c9092..5cbe8fb 100644 --- a/makefile +++ b/makefile @@ -3,16 +3,21 @@ WM=wmii SYS=x11 CC=gcc PROG=awm -CFLAGS=-g -Wall +CFLAGS=-g -Wall -Os LIBS=-Wl,--as-needed -lX11 +TEST=DISPLAY=:2.0 #SYS=win32 #CC=i686-pc-mingw32-gcc -#CFLAGS=-g -Wall -mwindows +#CFLAGS=-g -Wall #PROG=awm.exe +#TEST=wine test: $(PROG) - DISPLAY=:2.0 ./$< + $(TEST) ./$< + +debug: $(PROG) + $(TEST) gdb ./$< $(PROG): main.o util.o sys-$(SYS).o wm-$(WM).o $(CC) $(CFLAGS) -o $@ $+ $(LIBS) diff --git a/sys-win32.c b/sys-win32.c index e69de29..8ec77ff 100644 --- a/sys-win32.c +++ b/sys-win32.c @@ -0,0 +1,235 @@ +#include +#include +#include + +#define WIN32_LEAN_AND_MEAN +#define _WIN32_WINNT 0x0500 +#include +#include +#include + +#include "util.h" +#include "sys.h" +#include "wm.h" + +int test; +int shellhookid; +mod_t mod_state; + +/* Internal structures */ +struct win_sys { + HWND hwnd; +}; + +typedef struct { + Key_t key; + int vk; +} keymap_t; + +win_t *win_new(HWND hwnd) +{ + RECT rect = {}; + GetWindowRect(hwnd, &rect); + win_t *win = new0(win_t); + win->x = rect.left; + win->y = rect.top; + win->w = rect.right - rect.left; + win->h = rect.bottom - rect.top; + win->sys = new0(win_sys_t); + win->sys->hwnd = hwnd; + return win; +} + +/* Conversion functions */ +keymap_t key2vk[] = { + {key_mouse1 , VK_LBUTTON }, + {key_mouse2 , VK_MBUTTON }, + {key_mouse3 , VK_RBUTTON }, + {key_left , VK_LEFT }, + {key_right , VK_RIGHT }, + {key_up , VK_UP }, + {key_down , VK_DOWN }, + {key_home , VK_HOME }, + {key_end , VK_END }, + {key_pageup , VK_PRIOR }, + {key_pagedown, VK_NEXT }, + {key_f1 , VK_F1 }, + {key_f2 , VK_F2 }, + {key_f3 , VK_F3 }, + {key_f4 , VK_F4 }, + {key_f5 , VK_F5 }, + {key_f6 , VK_F6 }, + {key_f7 , VK_F7 }, + {key_f8 , VK_F8 }, + {key_f9 , VK_F9 }, + {key_f10 , VK_F10 }, + {key_f11 , VK_F11 }, + {key_f12 , VK_F12 }, + {key_shift , VK_SHIFT }, + {key_shift , VK_LSHIFT }, + {key_shift , VK_RSHIFT }, + {key_ctrl , VK_CONTROL }, + {key_ctrl , VK_LCONTROL}, + {key_ctrl , VK_RCONTROL}, + {key_alt , VK_MENU }, + {key_alt , VK_LMENU }, + {key_alt , VK_RMENU }, + {key_win , VK_LWIN }, + {key_win , VK_RWIN }, +}; + +UINT key2w(Key_t key) +{ + keymap_t *km = map_get(key2vk,key); + return km ? km->vk : toupper(key); +} +Key_t w2key(UINT vk) +{ + keymap_t *km = map_getr(key2vk,vk); + return km ? km->key : vk; +} + +ptr_t getptr(void) +{ + POINT wptr; + GetCursorPos(&wptr); + return (ptr_t){-1, -1, wptr.x, wptr.y}; +} + +/* 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); + MoveWindow(win->sys->hwnd, x, y, w, h, TRUE); +} + +void sys_raise(win_t *win) +{ + printf("sys_raise: %p\n", win); +} + +void sys_watch(win_t *win, Key_t key, mod_t mod) +{ + printf("sys_watch: %p\n", win); +} + +LRESULT CALLBACK KbdProc(int msg, WPARAM wParam, LPARAM lParam) +{ + KBDLLHOOKSTRUCT *st = (KBDLLHOOKSTRUCT *)lParam; + Key_t key = w2key(st->vkCode); + mod_state.up = !!(st->flags & 0x80); + if (key == key_alt ) mod_state.alt = !mod_state.up; + if (key == key_ctrl ) mod_state.ctrl = !mod_state.up; + if (key == key_shift) mod_state.shift = !mod_state.up; + if (key == key_win ) mod_state.win = !mod_state.up; + printf("KbdProc: %d,%x,%lx - %lx,%lx,%lx - %x,%x\n", + msg, wParam, lParam, + st->vkCode, st->scanCode, st->flags, + key, mod2int(mod_state)); + HWND fghwnd = GetForegroundWindow(); + wm_handle_key(win_new(fghwnd), key, mod_state, getptr()); + return CallNextHookEx(0, msg, wParam, lParam); +} + +LRESULT CALLBACK MllProc(int msg, WPARAM wParam, LPARAM lParam) +{ + Key_t key = key_none; + HWND fghwnd = GetForegroundWindow(); + switch (wParam) { + case WM_LBUTTONDOWN: mod_state.up = 0; key = key_mouse1; break; + case WM_LBUTTONUP: mod_state.up = 1; key = key_mouse1; break; + case WM_RBUTTONDOWN: mod_state.up = 0; key = key_mouse3; break; + case WM_RBUTTONUP: mod_state.up = 1; key = key_mouse3; break; + } + if (wParam == WM_MOUSEMOVE) + return wm_handle_ptr(win_new(fghwnd), getptr()); + else if (key != key_none) + return wm_handle_key(win_new(fghwnd), key, mod_state, getptr()); + else + return CallNextHookEx(0, msg, wParam, lParam); +} + +LRESULT CALLBACK ShlWndProc(HWND hwnd, int msg, WPARAM wParam, LPARAM lParam) +{ + printf("ShlWndProc: %d, %x, %lx\n", msg, wParam, lParam); + switch (wParam) { + case HSHELL_WINDOWCREATED: + printf("ShlProc: window created\n"); + return 0; + case HSHELL_WINDOWDESTROYED: + printf("ShlProc: window destroyed\n"); + return 0; + case HSHELL_WINDOWACTIVATED: + printf("ShlProc: window activated\n"); + return 0; + } + return DefWindowProc(hwnd, msg, wParam, lParam); +} + +LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) +{ + printf("WndProc: %d, %x, %lx\n", msg, wParam, lParam); + switch (msg) { + case WM_CREATE: + case WM_CLOSE: + case WM_DESTROY: + return 0; + } + if (msg == shellhookid) { + printf("WndProc: shellhook\n"); + return ShlWndProc(hwnd, msg, wParam, lParam); + } + return DefWindowProc(hwnd, msg, wParam, lParam); +} + +win_t *sys_init(void) +{ + HINSTANCE hInst = GetModuleHandle(NULL); + test = 123; + + /* Class */ + WNDCLASSEX wc = {}; + wc.cbSize = sizeof(WNDCLASSEX); + wc.lpfnWndProc = WndProc; + wc.hInstance = hInst; + wc.lpszClassName = "awm_class"; + if (!RegisterClassEx(&wc)) + printf("sys_init: Error Registering Class - %lu\n", GetLastError()); + + /* Bargh!? */ + HWND hwnd = CreateWindowEx(0, "awm_class", "awm", 0, + 0, 0, 0, 0, HWND_MESSAGE, NULL, hInst, NULL); + if (!hwnd) + printf("sys_init: Error Creating Window - %lu\n", GetLastError()); + + /* Try Shell Hook Window */ + HINSTANCE hInstUser32 = GetModuleHandle("USER32.DLL"); + BOOL (*RegisterShellHookWindow)(HWND hwnd) = (void*)GetProcAddress(hInstUser32, "RegisterShellHookWindow"); + if (!RegisterShellHookWindow) + printf("sys_init: Error Finding RegisterShellHookWindow - %lu\n", GetLastError()); + if (!RegisterShellHookWindow(hwnd)) + printf("sys_init: Error Registering ShellHook Window - %lu\n", GetLastError()); + shellhookid = RegisterWindowMessage("SHELLHOOK"); + + /* Register other hooks for testing */ + SetWindowsHookEx(WH_MOUSE_LL, MllProc, hInst, 0); + SetWindowsHookEx(WH_KEYBOARD_LL, KbdProc, hInst, 0); + //SetWindowsHookEx(WH_SHELL, ShlProc, hInst, 0); + + //if (!RegisterHotKey(hwnd, 123, MOD_CONTROL, VK_LBUTTON)) + // printf("sys_init: Error Registering Hotkey - %lu\n", GetLastError()); + if (!RegisterHotKey(NULL, 123, MOD_CONTROL, VK_LBUTTON)) + printf("sys_init: Error Registering Hotkey - %lu\n", GetLastError()); + + return win_new(hwnd); + +} + +void sys_run(win_t *root) +{ + MSG msg; + while (GetMessage(&msg, NULL, 0, 0) > 0) { + TranslateMessage(&msg); + DispatchMessage(&msg); + } +} diff --git a/sys-x11.c b/sys-x11.c index 76195a9..16cbe63 100644 --- a/sys-x11.c +++ b/sys-x11.c @@ -19,7 +19,7 @@ struct win_sys { struct { Key_t key; int sym; -} keymap[] = { +} key2sym[] = { {key_left , XK_Left }, {key_right , XK_Right}, {key_up , XK_Up }, @@ -61,17 +61,11 @@ unsigned int mod2x(mod_t mod) KeySym key2x(Key_t key) { - for (int i = 0; i < countof(keymap); i++) - if (keymap[i].key == key) - return keymap[i].sym; - return key; + return map_get(key2sym,key)->sym ?: 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; + return map_getr(key2sym,sym)->key ?: sym; } int btn2x(Key_t key) @@ -115,6 +109,8 @@ void sys_watch(win_t *win, Key_t key, mod_t mod) win_t *win_new(Display *xdpy, Window xwin) { + if (!xdpy || !xwin) + return NULL; XWindowAttributes attr; XGetWindowAttributes(xdpy, xwin, &attr); win_t *win = new0(win_t); @@ -147,7 +143,7 @@ void sys_run(win_t *root) { XEvent ev; XNextEvent(dpy, &ev); - printf("event: %d\n", ev.type); + //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); diff --git a/sys.h b/sys.h index a302559..74938c7 100644 --- a/sys.h +++ b/sys.h @@ -28,16 +28,18 @@ typedef enum { 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_alt, key_ctrl, key_shift, key_win, } Key_t; typedef struct { - int up : 1; - int alt : 1; - int ctrl : 1; - int shift : 1; - int win : 1; + unsigned char up : 1; + unsigned char alt : 1; + unsigned char ctrl : 1; + unsigned char shift : 1; + unsigned char win : 1; } mod_t; #define MOD(...) ((mod_t){__VA_ARGS__}) +#define mod2int(mod) (*((unsigned*)&(mod))) typedef struct { int x, y; diff --git a/util.h b/util.h index a572a0a..965ca4e 100644 --- a/util.h +++ b/util.h @@ -5,9 +5,13 @@ #define countof(x) (sizeof(x)/sizeof((x)[0])) -#define map_get(map, key) ({ \ +#define map_getg(map, test) ({ \ int i; \ - for (i = 0; i < countof(map) && \ - *((typeof(key)*)&map[i]) != key; i++); \ + for (i = 0; i < countof(map) && !(test); i++); \ i < countof(map) ? &map[i] : NULL ; \ }) + +#define map_get(m,k) map_getg(m,k==*((typeof(k)*)&m[i])) +#define map_getr(m,k) map_getg(m,k==*(((typeof(k)*)&m[i+1])-1)) +#define map_getk(m,k,a) map_getg(m,k==m[i].a) + diff --git a/wm-wmii.c b/wm-wmii.c index 5faf9c9..444a596 100644 --- a/wm-wmii.c +++ b/wm-wmii.c @@ -5,36 +5,46 @@ typedef enum { none, move, resize -} mode_t; +} Mode_t; win_t *kwin; ptr_t kptr; -mode_t mode; +Mode_t mode; -void wm_handle_key(win_t *win, Key_t key, mod_t mod, ptr_t ptr) +int 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); + printf("wm_handle_key: %p - %x\n", win, key); kptr = ptr; kwin = win; - if (key == key_f1 && mod.ctrl) + + /* Raise */ + if ((key == key_f1 && mod.ctrl) || + (key_mouse0 <= key && key <= key_mouse7)) 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; + + /* Movement */ + if (key_mouse0 <= key && key <= key_mouse7 && + mod.up && mode != none) + return mode = none, 1; + else if (key == key_mouse1 && mod.ctrl) + return mode = move, 1; + else if (key == key_mouse3 && mod.ctrl) + return mode = resize, 1; + + return 0; } -void wm_handle_ptr(win_t *win, ptr_t ptr) +int wm_handle_ptr(win_t *win, ptr_t ptr) { - printf("wm_handle_ptr: %p - %d,%d (%d)\n", win, ptr.x, ptr.y, mode); + printf("wm_handle_ptr: %p - %d,%d %d,%d (%d) -- \n", + win, ptr.x, ptr.y, ptr.rx, ptr.ry, 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); + return 0; } void wm_init(win_t *root) diff --git a/wm.h b/wm.h index 4b1d834..e5e8d76 100644 --- a/wm.h +++ b/wm.h @@ -1,5 +1,5 @@ void wm_init(win_t *root); -void wm_handle_key(win_t *win, Key_t key, mod_t mod, ptr_t ptr); +int 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); +int wm_handle_ptr(win_t *win, ptr_t ptr); -- 2.43.2