]> Pileus Git - wmpus/blob - sys-win32.c
Playing with focus
[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 keymap_t key2vk[] = {
30         {key_mouse1  , VK_LBUTTON },
31         {key_mouse2  , VK_MBUTTON },
32         {key_mouse3  , VK_RBUTTON },
33         {key_left    , VK_LEFT    },
34         {key_right   , VK_RIGHT   },
35         {key_up      , VK_UP      },
36         {key_down    , VK_DOWN    },
37         {key_home    , VK_HOME    },
38         {key_end     , VK_END     },
39         {key_pageup  , VK_PRIOR   },
40         {key_pagedown, VK_NEXT    },
41         {key_f1      , VK_F1      },
42         {key_f2      , VK_F2      },
43         {key_f3      , VK_F3      },
44         {key_f4      , VK_F4      },
45         {key_f5      , VK_F5      },
46         {key_f6      , VK_F6      },
47         {key_f7      , VK_F7      },
48         {key_f8      , VK_F8      },
49         {key_f9      , VK_F9      },
50         {key_f10     , VK_F10     },
51         {key_f11     , VK_F11     },
52         {key_f12     , VK_F12     },
53         {key_shift   , VK_SHIFT   },
54         {key_shift   , VK_LSHIFT  },
55         {key_shift   , VK_RSHIFT  },
56         {key_ctrl    , VK_CONTROL },
57         {key_ctrl    , VK_LCONTROL},
58         {key_ctrl    , VK_RCONTROL},
59         {key_alt     , VK_MENU    },
60         {key_alt     , VK_LMENU   },
61         {key_alt     , VK_RMENU   },
62         {key_win     , VK_LWIN    },
63         {key_win     , VK_RWIN    },
64 };
65
66 /* Helper functions */
67 win_t *win_new(HWND hwnd)
68 {
69         RECT rect = {};
70         GetWindowRect(hwnd, &rect);
71         win_t *win = new0(win_t);
72         win->x         = rect.left;
73         win->y         = rect.top;
74         win->w         = rect.right  - rect.left;
75         win->h         = rect.bottom - rect.top;
76         win->sys       = new0(win_sys_t);
77         win->sys->hwnd = hwnd;
78         return win;
79 }
80
81 /* Conversion functions */
82 /* - Keycodes */
83 Key_t w2key(UINT vk)
84 {
85         keymap_t *km = map_getr(key2vk,vk);
86         return km ? km->key : vk;
87 }
88
89 UINT key2w(Key_t key)
90 {
91         keymap_t *km = map_get(key2vk,key);
92         return km ? km->vk : toupper(key);
93 }
94
95 /* - Pointers */
96 ptr_t getptr(void)
97 {
98         POINT wptr;
99         GetCursorPos(&wptr);
100         return (ptr_t){-1, -1, wptr.x, wptr.y};
101 }
102
103 win_t *getwin(void)
104 {
105         POINT wptr;
106         GetCursorPos(&wptr);
107         return win_new(GetAncestor(WindowFromPoint(wptr),GA_ROOT));
108 }
109
110 /* Callbacks */
111 LRESULT CALLBACK KbdProc(int msg, WPARAM wParam, LPARAM lParam)
112 {
113         KBDLLHOOKSTRUCT *st = (KBDLLHOOKSTRUCT *)lParam;
114         Key_t key = w2key(st->vkCode);
115         mod_state.up = !!(st->flags & 0x80);
116         if (key == key_alt  ) mod_state.alt   = !mod_state.up;
117         if (key == key_ctrl ) mod_state.ctrl  = !mod_state.up;
118         if (key == key_shift) mod_state.shift = !mod_state.up;
119         if (key == key_win  ) mod_state.win   = !mod_state.up;
120         printf("KbdProc: %d,%x,%lx - %lx,%lx,%lx - %x,%x\n",
121                         msg, wParam, lParam,
122                         st->vkCode, st->scanCode, st->flags,
123                         key, mod2int(mod_state));
124         wm_handle_key(getwin(), key, mod_state, getptr());
125         return CallNextHookEx(0, msg, wParam, lParam);
126 }
127
128 LRESULT CALLBACK MllProc(int msg, WPARAM wParam, LPARAM lParam)
129 {
130         Key_t key   = key_none;
131         switch (wParam) {
132         case WM_LBUTTONDOWN: mod_state.up = 0; key = key_mouse1; break;
133         case WM_LBUTTONUP:   mod_state.up = 1; key = key_mouse1; break;
134         case WM_RBUTTONDOWN: mod_state.up = 0; key = key_mouse3; break;
135         case WM_RBUTTONUP:   mod_state.up = 1; key = key_mouse3; break;
136         }
137         if (wParam == WM_MOUSEMOVE)
138                 return wm_handle_ptr(getwin(), getptr());
139         else if (key != key_none)
140                 return wm_handle_key(getwin(), key, mod_state, getptr());
141         else
142                 return CallNextHookEx(0, msg, wParam, lParam);
143 }
144
145 LRESULT CALLBACK ShlWndProc(HWND hwnd, int msg, WPARAM wParam, LPARAM lParam)
146 {
147         printf("ShlWndProc: %d, %x, %lx\n", msg, wParam, lParam);
148         switch (wParam) {
149         case HSHELL_WINDOWCREATED:
150                 printf("ShlProc: window created\n");
151                 return 0;
152         case HSHELL_WINDOWDESTROYED:
153                 printf("ShlProc: window destroyed\n");
154                 return 0;
155         case HSHELL_WINDOWACTIVATED:
156                 printf("ShlProc: window activated\n");
157                 return 0;
158         }
159         return DefWindowProc(hwnd, msg, wParam, lParam);
160 }
161
162 LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
163 {
164         printf("WndProc: %d, %x, %lx\n", msg, wParam, lParam);
165         switch (msg) {
166         case WM_CREATE:
167         case WM_CLOSE:
168         case WM_DESTROY:
169                 return 0;
170         }
171         if (msg == shellhookid) {
172                 printf("WndProc: shellhook\n");
173                 return ShlWndProc(hwnd, msg, wParam, lParam);
174         }
175         return DefWindowProc(hwnd, msg, wParam, lParam);
176 }
177
178 /*****************
179  * Sys functions *
180  *****************/
181 void sys_move(win_t *win, int x, int y, int w, int h)
182 {
183         printf("sys_move: %p - %d,%d  %dx%d\n", win, x, y, w, h);
184         MoveWindow(win->sys->hwnd, x, y, w, h, TRUE);
185 }
186
187 void sys_raise(win_t *win)
188 {
189         printf("sys_raise: %p\n", win);
190         SetForegroundWindow(win->sys->hwnd);
191         //HWND hwnd = win->sys->hwnd;
192         //HWND top  = GetAncestor(hwnd,GA_ROOT);
193         //SetWindowPos(top, HWND_TOPMOST, 0, 0, 0, 0,
194         //              SWP_NOMOVE|SWP_NOSIZE|SWP_NOACTIVATE);
195 }
196
197 void sys_focus(win_t *win)
198 {
199         printf("sys_focus: %p\n", win);
200         //POINT wptr;
201         //GetCursorPos(&wptr);
202         //HWND old  = GetForegroundWindow();
203         //HWND newc = WindowFromPoint(wptr);
204         //HWND new  = GetAncestor(newc,GA_ROOT);
205         //SetWindowPos(new, HWND_NOTOPMOST, 0, 0, 0, 0,
206         //              SWP_NOMOVE|SWP_NOSIZE);
207         //SetWindowPos(old, HWND_NOTOPMOST, 0, 0, 0, 0,
208         //              SWP_NOMOVE|SWP_NOSIZE|SWP_NOACTIVATE);
209         //SetFocus(hwnd);
210         //SetActiveWindow(hwnd);
211
212         // Go to: HKEY_CURRENT_USER\Control Panel\Mouse
213         // Modify/Create DWORD Value of Data type REG_DWORD Named [ActiveWindowTracking] Setting for Value Data: [0 = ActiveWindowTracking Disabled / 1 = ActiveWindowTracking Enabled]
214
215         //LockSetForegroundWindow(LSFW_LOCK);
216         //SetForegroundWindow(win->sys->hwnd);
217         //LockSetForegroundWindow(LSFW_UNLOCK);
218         //SetFocus(win->sys->hwnd);
219         //SetActiveWindow(win->sys->hwnd);
220         //EnableWindow(win->sys->hwnd, TRUE);
221 }
222
223 void sys_watch(win_t *win, Key_t key, mod_t mod)
224 {
225         printf("sys_watch: %p\n", win);
226 }
227
228 win_t *sys_init(void)
229 {
230         HINSTANCE hInst = GetModuleHandle(NULL);
231         test = 123;
232
233         /* Class */
234         WNDCLASSEX wc    = {};
235         wc.cbSize        = sizeof(WNDCLASSEX);
236         wc.lpfnWndProc   = WndProc;
237         wc.hInstance     = hInst;
238         wc.lpszClassName = "awm_class";
239         if (!RegisterClassEx(&wc))
240                 printf("sys_init: Error Registering Class - %lu\n", GetLastError());
241
242         /* Bargh!? */
243         HWND hwnd = CreateWindowEx(0, "awm_class", "awm", 0,
244                         0, 0, 0, 0, HWND_MESSAGE, NULL, hInst, NULL);
245         if (!hwnd)
246                 printf("sys_init: Error Creating Window - %lu\n", GetLastError());
247
248         /* Try Shell Hook Window */
249         HINSTANCE hInstUser32 = GetModuleHandle("USER32.DLL");
250         BOOL (*RegisterShellHookWindow)(HWND hwnd) = (void*)GetProcAddress(hInstUser32, "RegisterShellHookWindow");
251         if (!RegisterShellHookWindow)
252                 printf("sys_init: Error Finding RegisterShellHookWindow - %lu\n", GetLastError());
253         if (!RegisterShellHookWindow(hwnd))
254                 printf("sys_init: Error Registering ShellHook Window - %lu\n", GetLastError());
255         shellhookid = RegisterWindowMessage("SHELLHOOK");
256
257         /* Register other hooks for testing */
258         SetWindowsHookEx(WH_MOUSE_LL,    MllProc, hInst, 0);
259         SetWindowsHookEx(WH_KEYBOARD_LL, KbdProc, hInst, 0);
260         //SetWindowsHookEx(WH_SHELL,       ShlProc, hInst, 0);
261
262         //if (!RegisterHotKey(hwnd, 123, MOD_CONTROL, VK_LBUTTON))
263         //      printf("sys_init: Error Registering Hotkey - %lu\n", GetLastError());
264         if (!RegisterHotKey(NULL, 123, MOD_CONTROL, VK_LBUTTON))
265                 printf("sys_init: Error Registering Hotkey - %lu\n", GetLastError());
266
267         return win_new(hwnd);
268
269 }
270
271 void sys_run(win_t *root)
272 {
273         MSG msg;
274         while (GetMessage(&msg, NULL, 0, 0) > 0) {
275                 TranslateMessage(&msg);
276                 DispatchMessage(&msg);
277         }
278 }