]> Pileus Git - wmpus/blob - sys-win32.c
Initial code for win32
[wmpus] / sys-win32.c
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <ctype.h>
4
5 #define WIN32_LEAN_AND_MEAN
6 #define _WIN32_WINNT 0x0500
7 #include <windows.h>
8 #include <winbase.h>
9 #include <winuser.h>
10
11 #include "util.h"
12 #include "sys.h"
13 #include "wm.h"
14
15 int   test;
16 int   shellhookid;
17 mod_t mod_state;
18
19 /* Internal structures */
20 struct win_sys {
21         HWND hwnd;
22 };
23
24 typedef struct {
25         Key_t key;
26         int   vk;
27 } keymap_t;
28
29 win_t *win_new(HWND hwnd)
30 {
31         RECT rect = {};
32         GetWindowRect(hwnd, &rect);
33         win_t *win = new0(win_t);
34         win->x         = rect.left;
35         win->y         = rect.top;
36         win->w         = rect.right  - rect.left;
37         win->h         = rect.bottom - rect.top;
38         win->sys       = new0(win_sys_t);
39         win->sys->hwnd = hwnd;
40         return win;
41 }
42
43 /* Conversion functions */
44 keymap_t key2vk[] = {
45         {key_mouse1  , VK_LBUTTON },
46         {key_mouse2  , VK_MBUTTON },
47         {key_mouse3  , VK_RBUTTON },
48         {key_left    , VK_LEFT    },
49         {key_right   , VK_RIGHT   },
50         {key_up      , VK_UP      },
51         {key_down    , VK_DOWN    },
52         {key_home    , VK_HOME    },
53         {key_end     , VK_END     },
54         {key_pageup  , VK_PRIOR   },
55         {key_pagedown, VK_NEXT    },
56         {key_f1      , VK_F1      },
57         {key_f2      , VK_F2      },
58         {key_f3      , VK_F3      },
59         {key_f4      , VK_F4      },
60         {key_f5      , VK_F5      },
61         {key_f6      , VK_F6      },
62         {key_f7      , VK_F7      },
63         {key_f8      , VK_F8      },
64         {key_f9      , VK_F9      },
65         {key_f10     , VK_F10     },
66         {key_f11     , VK_F11     },
67         {key_f12     , VK_F12     },
68         {key_shift   , VK_SHIFT   },
69         {key_shift   , VK_LSHIFT  },
70         {key_shift   , VK_RSHIFT  },
71         {key_ctrl    , VK_CONTROL },
72         {key_ctrl    , VK_LCONTROL},
73         {key_ctrl    , VK_RCONTROL},
74         {key_alt     , VK_MENU    },
75         {key_alt     , VK_LMENU   },
76         {key_alt     , VK_RMENU   },
77         {key_win     , VK_LWIN    },
78         {key_win     , VK_RWIN    },
79 };
80
81 UINT key2w(Key_t key)
82 {
83         keymap_t *km = map_get(key2vk,key);
84         return km ? km->vk : toupper(key);
85 }
86 Key_t w2key(UINT vk)
87 {
88         keymap_t *km = map_getr(key2vk,vk);
89         return km ? km->key : vk;
90 }
91
92 ptr_t getptr(void)
93 {
94         POINT wptr;
95         GetCursorPos(&wptr);
96         return (ptr_t){-1, -1, wptr.x, wptr.y};
97 }
98
99 /* Functions */
100 void sys_move(win_t *win, int x, int y, int w, int h)
101 {
102         printf("sys_move: %p - %d,%d  %dx%d\n", win, x, y, w, h);
103         MoveWindow(win->sys->hwnd, x, y, w, h, TRUE);
104 }
105
106 void sys_raise(win_t *win)
107 {
108         printf("sys_raise: %p\n", win);
109 }
110
111 void sys_watch(win_t *win, Key_t key, mod_t mod)
112 {
113         printf("sys_watch: %p\n", win);
114 }
115
116 LRESULT CALLBACK KbdProc(int msg, WPARAM wParam, LPARAM lParam)
117 {
118         KBDLLHOOKSTRUCT *st = (KBDLLHOOKSTRUCT *)lParam;
119         Key_t key = w2key(st->vkCode);
120         mod_state.up = !!(st->flags & 0x80);
121         if (key == key_alt  ) mod_state.alt   = !mod_state.up;
122         if (key == key_ctrl ) mod_state.ctrl  = !mod_state.up;
123         if (key == key_shift) mod_state.shift = !mod_state.up;
124         if (key == key_win  ) mod_state.win   = !mod_state.up;
125         printf("KbdProc: %d,%x,%lx - %lx,%lx,%lx - %x,%x\n",
126                         msg, wParam, lParam,
127                         st->vkCode, st->scanCode, st->flags,
128                         key, mod2int(mod_state));
129         HWND fghwnd = GetForegroundWindow();
130         wm_handle_key(win_new(fghwnd), key, mod_state, getptr());
131         return CallNextHookEx(0, msg, wParam, lParam);
132 }
133
134 LRESULT CALLBACK MllProc(int msg, WPARAM wParam, LPARAM lParam)
135 {
136         Key_t key   = key_none;
137         HWND fghwnd = GetForegroundWindow();
138         switch (wParam) {
139         case WM_LBUTTONDOWN: mod_state.up = 0; key = key_mouse1; break;
140         case WM_LBUTTONUP:   mod_state.up = 1; key = key_mouse1; break;
141         case WM_RBUTTONDOWN: mod_state.up = 0; key = key_mouse3; break;
142         case WM_RBUTTONUP:   mod_state.up = 1; key = key_mouse3; break;
143         }
144         if (wParam == WM_MOUSEMOVE)
145                 return wm_handle_ptr(win_new(fghwnd), getptr());
146         else if (key != key_none)
147                 return wm_handle_key(win_new(fghwnd), key, mod_state, getptr());
148         else
149                 return CallNextHookEx(0, msg, wParam, lParam);
150 }
151
152 LRESULT CALLBACK ShlWndProc(HWND hwnd, int msg, WPARAM wParam, LPARAM lParam)
153 {
154         printf("ShlWndProc: %d, %x, %lx\n", msg, wParam, lParam);
155         switch (wParam) {
156         case HSHELL_WINDOWCREATED:
157                 printf("ShlProc: window created\n");
158                 return 0;
159         case HSHELL_WINDOWDESTROYED:
160                 printf("ShlProc: window destroyed\n");
161                 return 0;
162         case HSHELL_WINDOWACTIVATED:
163                 printf("ShlProc: window activated\n");
164                 return 0;
165         }
166         return DefWindowProc(hwnd, msg, wParam, lParam);
167 }
168
169 LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
170 {
171         printf("WndProc: %d, %x, %lx\n", msg, wParam, lParam);
172         switch (msg) {
173         case WM_CREATE:
174         case WM_CLOSE:
175         case WM_DESTROY:
176                 return 0;
177         }
178         if (msg == shellhookid) {
179                 printf("WndProc: shellhook\n");
180                 return ShlWndProc(hwnd, msg, wParam, lParam);
181         }
182         return DefWindowProc(hwnd, msg, wParam, lParam);
183 }
184
185 win_t *sys_init(void)
186 {
187         HINSTANCE hInst = GetModuleHandle(NULL);
188         test = 123;
189
190         /* Class */
191         WNDCLASSEX wc    = {};
192         wc.cbSize        = sizeof(WNDCLASSEX);
193         wc.lpfnWndProc   = WndProc;
194         wc.hInstance     = hInst;
195         wc.lpszClassName = "awm_class";
196         if (!RegisterClassEx(&wc))
197                 printf("sys_init: Error Registering Class - %lu\n", GetLastError());
198
199         /* Bargh!? */
200         HWND hwnd = CreateWindowEx(0, "awm_class", "awm", 0,
201                         0, 0, 0, 0, HWND_MESSAGE, NULL, hInst, NULL);
202         if (!hwnd)
203                 printf("sys_init: Error Creating Window - %lu\n", GetLastError());
204
205         /* Try Shell Hook Window */
206         HINSTANCE hInstUser32 = GetModuleHandle("USER32.DLL");
207         BOOL (*RegisterShellHookWindow)(HWND hwnd) = (void*)GetProcAddress(hInstUser32, "RegisterShellHookWindow");
208         if (!RegisterShellHookWindow)
209                 printf("sys_init: Error Finding RegisterShellHookWindow - %lu\n", GetLastError());
210         if (!RegisterShellHookWindow(hwnd))
211                 printf("sys_init: Error Registering ShellHook Window - %lu\n", GetLastError());
212         shellhookid = RegisterWindowMessage("SHELLHOOK");
213
214         /* Register other hooks for testing */
215         SetWindowsHookEx(WH_MOUSE_LL,    MllProc, hInst, 0);
216         SetWindowsHookEx(WH_KEYBOARD_LL, KbdProc, hInst, 0);
217         //SetWindowsHookEx(WH_SHELL,       ShlProc, hInst, 0);
218
219         //if (!RegisterHotKey(hwnd, 123, MOD_CONTROL, VK_LBUTTON))
220         //      printf("sys_init: Error Registering Hotkey - %lu\n", GetLastError());
221         if (!RegisterHotKey(NULL, 123, MOD_CONTROL, VK_LBUTTON))
222                 printf("sys_init: Error Registering Hotkey - %lu\n", GetLastError());
223
224         return win_new(hwnd);
225
226 }
227
228 void sys_run(win_t *root)
229 {
230         MSG msg;
231         while (GetMessage(&msg, NULL, 0, 0) > 0) {
232                 TranslateMessage(&msg);
233                 DispatchMessage(&msg);
234         }
235 }