1 |
dpavlin |
1 |
/* |
2 |
|
|
* PearPC |
3 |
|
|
* syswin.cc |
4 |
|
|
* |
5 |
|
|
* Copyright (C) 1999-2002 Stefan Weyergraf |
6 |
|
|
* Copyright (C) 1999-2004 Sebastian Biallas (sb@biallas.net) |
7 |
|
|
* |
8 |
|
|
* This program is free software; you can redistribute it and/or modify |
9 |
|
|
* it under the terms of the GNU General Public License version 2 as |
10 |
|
|
* published by the Free Software Foundation. |
11 |
|
|
* |
12 |
|
|
* This program is distributed in the hope that it will be useful, |
13 |
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
14 |
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
15 |
|
|
* GNU General Public License for more details. |
16 |
|
|
* |
17 |
|
|
* You should have received a copy of the GNU General Public License |
18 |
|
|
* along with this program; if not, write to the Free Software |
19 |
|
|
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. |
20 |
|
|
*/ |
21 |
|
|
|
22 |
|
|
#include <csignal> |
23 |
|
|
#include <cstdlib> |
24 |
|
|
#include <cstdio> |
25 |
|
|
#include <unistd.h> |
26 |
|
|
#include <cstring> |
27 |
|
|
|
28 |
|
|
// for stopping the CPU |
29 |
|
|
#include "cpu/cpu.h" |
30 |
|
|
|
31 |
|
|
#undef FASTCALL |
32 |
|
|
|
33 |
|
|
#define WIN32_LEAN_AND_MEAN |
34 |
|
|
#include <windows.h> |
35 |
|
|
#include <windowsx.h> |
36 |
|
|
#include <commctrl.h> |
37 |
|
|
#include <process.h> |
38 |
|
|
|
39 |
|
|
#undef FASTCALL |
40 |
|
|
|
41 |
|
|
#include "system/display.h" |
42 |
|
|
#include "system/keyboard.h" |
43 |
|
|
#include "system/mouse.h" |
44 |
|
|
|
45 |
|
|
#include "tools/snprintf.h" |
46 |
|
|
|
47 |
|
|
#include "syswin.h" |
48 |
|
|
#include "resources.h" |
49 |
|
|
|
50 |
|
|
HWND gHWNDMain = NULL; |
51 |
|
|
CRITICAL_SECTION gDrawCS; |
52 |
|
|
int gMenuHeight; |
53 |
|
|
BITMAPINFO gMenuBitmapInfo; |
54 |
|
|
byte *menuData; |
55 |
|
|
|
56 |
|
|
static HANDLE eventThread = INVALID_HANDLE_VALUE; |
57 |
|
|
static HINSTANCE gHInst; |
58 |
|
|
|
59 |
|
|
static byte scancode_to_ascii[] = { |
60 |
|
|
//00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f |
61 |
|
|
0x00,'\e', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '-', '=',0x08,'\t', |
62 |
|
|
'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p', '[', ']','\n',0x00, 'a', 's', |
63 |
|
|
'd', 'f', 'g', 'h', 'j', 'k', 'l', ';',0x00,0x00,0x00,'\\', 'z', 'x', 'c', 'v', |
64 |
|
|
'b', 'n', 'm', ',', '.', '/',0x00,0x00,0x00, ' ',0x00,0x00,0x00,0x00,0x00,0x00, |
65 |
|
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, |
66 |
|
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, |
67 |
|
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, |
68 |
|
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, |
69 |
|
|
|
70 |
|
|
//00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f |
71 |
|
|
0x00,'\e', '1', '2', '3', '4', '5', '6', '7', '*', '(', ')', '_', '+',0x08,'\t', |
72 |
|
|
'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', 'O', 'P', '[', ']','\n',0x00, 'A', 'S', |
73 |
|
|
'D', 'F', 'G', 'H', 'J', 'K', 'L', ':',0x00,0x00,0x00,'\\', 'Z', 'X', 'C', 'V', |
74 |
|
|
'B', 'N', 'M', '<', '>', '?',0x00,0x00,0x00, ' ',0x00,0x00,0x00,0x00,0x00,0x00, |
75 |
|
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, |
76 |
|
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, |
77 |
|
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, |
78 |
|
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, |
79 |
|
|
}; |
80 |
|
|
|
81 |
|
|
byte scancode_to_mackey[] = { |
82 |
|
|
//00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f |
83 |
|
|
0xff,0x35,0x12,0x13,0x14,0x15,0x17,0x16,0x1a,0x1c,0x19,0x1d,0x1b,0x18,0x33,0x30, |
84 |
|
|
0x0c,0x0d,0x0e,0x0f,0x11,0x10,0x20,0x22,0x1f,0x23,0x21,0x1e,0x24,0x36,0x00,0x01, |
85 |
|
|
0x02,0x03,0x05,0x04,0x26,0x28,0x25,0x29,0x27,0x32,0x38,0x2a,0x06,0x07,0x08,0x09, |
86 |
|
|
0x0b,0x2d,0x2e,0x2b,0x2f,0x2c,0x38,0x43,0x37,0x31,0x39,0x7a,0x78,0x63,0x76,0x60, |
87 |
|
|
0x61,0x62,0x64,0x65,0x6d,0xff,0xff,0x59,0x5b,0x5c,0x4e,0x56,0x57,0x58,0x45,0x53, |
88 |
|
|
0x54,0x55,0x52,0x41,0xff,0xff,0x0a,0x67,0x6f,0xff,0xff,0xff,0xff,0xff,0xff,0xff, |
89 |
|
|
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, |
90 |
|
|
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, |
91 |
|
|
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, |
92 |
|
|
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, |
93 |
|
|
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, |
94 |
|
|
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, |
95 |
|
|
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, |
96 |
|
|
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, |
97 |
|
|
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, |
98 |
|
|
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, |
99 |
|
|
|
100 |
|
|
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, |
101 |
|
|
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x4c,0x36,0xff,0xff, |
102 |
|
|
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, |
103 |
|
|
0xff,0xff,0xff,0xff,0xff,0x4b,0xff,0xff,0x3a,0xff,0xff,0xff,0xff,0xff,0xff,0xff, |
104 |
|
|
0xff,0xff,0xff,0xff,0xff,0x47,0xff,0x73,0x3e,0x74,0xff,0x3b,0xff,0x3c,0xff,0x77, |
105 |
|
|
0x3d,0x79,0x72,0x75,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, |
106 |
|
|
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, |
107 |
|
|
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, |
108 |
|
|
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, |
109 |
|
|
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, |
110 |
|
|
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, |
111 |
|
|
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, |
112 |
|
|
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, |
113 |
|
|
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, |
114 |
|
|
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, |
115 |
|
|
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, |
116 |
|
|
}; |
117 |
|
|
|
118 |
|
|
static bool needUpdateDisplay() |
119 |
|
|
{ |
120 |
|
|
if (gDisplay->isExposed()) { |
121 |
|
|
RECT rect; |
122 |
|
|
HDC hdc = GetDC(gHWNDMain); |
123 |
|
|
int gcb = GetClipBox(hdc, &rect); |
124 |
|
|
ReleaseDC(gHWNDMain, hdc); |
125 |
|
|
if (gcb != NULLREGION) { |
126 |
|
|
return true; |
127 |
|
|
} |
128 |
|
|
} |
129 |
|
|
return false; |
130 |
|
|
} |
131 |
|
|
|
132 |
|
|
static VOID CALLBACK TimerProc(HWND hwnd, UINT uMsg, UINT idEvent, DWORD dwTime) |
133 |
|
|
{ |
134 |
|
|
if (needUpdateDisplay()) gDisplay->displayShow(); |
135 |
|
|
} |
136 |
|
|
|
137 |
|
|
static LRESULT CALLBACK MainWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam); |
138 |
|
|
|
139 |
|
|
/* |
140 |
|
|
* This is the thread doing the display |
141 |
|
|
* and event handling stuff |
142 |
|
|
*/ |
143 |
|
|
static void eventLoop(void *pvoid) |
144 |
|
|
{ |
145 |
|
|
DuplicateHandle(GetCurrentProcess(), GetCurrentThread(), |
146 |
|
|
GetCurrentProcess(), &eventThread, 0, FALSE, |
147 |
|
|
DUPLICATE_SAME_ACCESS); |
148 |
|
|
|
149 |
|
|
Win32Display *display = (Win32Display *)pvoid; |
150 |
|
|
|
151 |
|
|
gMenuHeight = display->mMenuHeight; |
152 |
|
|
WNDCLASS wc; |
153 |
|
|
|
154 |
|
|
memset(&wc,0,sizeof wc); |
155 |
|
|
wc.style = CS_HREDRAW | CS_VREDRAW; |
156 |
|
|
wc.lpfnWndProc = (WNDPROC)MainWndProc; |
157 |
|
|
wc.hInstance = gHInst; |
158 |
|
|
wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1); |
159 |
|
|
wc.lpszClassName = "ClassClass"; |
160 |
|
|
wc.lpszMenuName = 0; |
161 |
|
|
wc.hCursor = LoadCursor(NULL, IDC_ARROW); |
162 |
|
|
wc.hIcon = LoadIcon(gHInst, MAKEINTRESOURCE(IDI_PEAR_PC)); |
163 |
|
|
RegisterClass(&wc); |
164 |
|
|
|
165 |
|
|
RECT rect; |
166 |
|
|
rect.top = 0; rect.left = 0; |
167 |
|
|
rect.bottom = display->mWinChar.height + gMenuHeight; |
168 |
|
|
rect.right = display->mWinChar.width; |
169 |
|
|
AdjustWindowRect(&rect, WS_VISIBLE | WS_CLIPSIBLINGS | WS_CLIPCHILDREN |
170 |
|
|
| WS_CAPTION | WS_BORDER | WS_SYSMENU | WS_MINIMIZEBOX, FALSE); |
171 |
|
|
|
172 |
|
|
gHWNDMain = CreateWindow("ClassClass", "PearPC", |
173 |
|
|
WS_VISIBLE | WS_CLIPSIBLINGS | WS_CLIPCHILDREN |
174 |
|
|
| WS_CAPTION | WS_BORDER | WS_SYSMENU | WS_MINIMIZEBOX, |
175 |
|
|
CW_USEDEFAULT, CW_USEDEFAULT, |
176 |
|
|
rect.right-rect.left, rect.bottom-rect.top, |
177 |
|
|
NULL, NULL, gHInst, NULL); |
178 |
|
|
|
179 |
|
|
display->initCursor(); |
180 |
|
|
|
181 |
|
|
display->updateTitle(); |
182 |
|
|
|
183 |
|
|
display->createBitmap(); |
184 |
|
|
|
185 |
|
|
display->setExposed(true); |
186 |
|
|
display->displayShow(); |
187 |
|
|
ShowWindow(gHWNDMain, SW_SHOW); |
188 |
|
|
|
189 |
|
|
SetTimer(gHWNDMain, 0, gDisplay->mRedraw_ms, TimerProc); |
190 |
|
|
display->setFullscreenMode(gDisplay->mFullscreen); |
191 |
|
|
|
192 |
|
|
MSG msg; |
193 |
|
|
while (GetMessage(&msg, NULL, 0, 0)) { |
194 |
|
|
TranslateMessage(&msg); |
195 |
|
|
DispatchMessage(&msg); |
196 |
|
|
} |
197 |
|
|
|
198 |
|
|
KillTimer(gHWNDMain, 0); |
199 |
|
|
|
200 |
|
|
ppc_cpu_stop(); |
201 |
|
|
|
202 |
|
|
gHWNDMain = NULL; |
203 |
|
|
|
204 |
|
|
_endthread(); |
205 |
|
|
} |
206 |
|
|
|
207 |
|
|
|
208 |
|
|
void MainWndProc_OnCommand(HWND hwnd, int id, HWND hwndCtl, UINT codeNotify) |
209 |
|
|
{ |
210 |
|
|
switch(id) { |
211 |
|
|
/* case IDM_EXIT: |
212 |
|
|
PostMessage(hwnd, WM_CLOSE, 0, 0); |
213 |
|
|
break;*/ |
214 |
|
|
} |
215 |
|
|
} |
216 |
|
|
|
217 |
|
|
static LRESULT CALLBACK MainWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) |
218 |
|
|
{ |
219 |
|
|
static int shiftDown = false; |
220 |
|
|
switch (msg) { |
221 |
|
|
case WM_PAINT: |
222 |
|
|
{ |
223 |
|
|
EnterCriticalSection(&gDrawCS); |
224 |
|
|
PAINTSTRUCT ps; |
225 |
|
|
|
226 |
|
|
HDC hdc = BeginPaint(hwnd, &ps); |
227 |
|
|
|
228 |
|
|
SetDIBitsToDevice(hdc, 0, 0, gDisplay->mClientChar.width, gMenuHeight, 0, 0, |
229 |
|
|
0, gMenuHeight, menuData, &gMenuBitmapInfo, DIB_RGB_COLORS); |
230 |
|
|
EndPaint(hwnd, &ps); |
231 |
|
|
LeaveCriticalSection(&gDrawCS); |
232 |
|
|
damageFrameBufferAll(); |
233 |
|
|
gDisplay->displayShow(); |
234 |
|
|
break; |
235 |
|
|
} |
236 |
|
|
case WM_KEYDOWN: |
237 |
|
|
case WM_SYSKEYDOWN: |
238 |
|
|
// This tests if the key is really pressed |
239 |
|
|
// or if it is only a repeated event |
240 |
|
|
if (!(lParam & (1<<30))) { |
241 |
|
|
SystemEvent ev; |
242 |
|
|
int scancode = HIWORD(lParam) & 0x01FF; |
243 |
|
|
ev.type = sysevKey; |
244 |
|
|
ev.key.pressed = true; |
245 |
|
|
|
246 |
|
|
int chr = 0; |
247 |
|
|
if (scancode < 128) { |
248 |
|
|
chr = scancode_to_ascii[scancode + shiftDown*128]; |
249 |
|
|
} |
250 |
|
|
if (scancode == 42 || scancode == 54) shiftDown = 1; |
251 |
|
|
if (scancode == 0x138) { |
252 |
|
|
// altgr == ctrl+alt --> release ctrl, press alt |
253 |
|
|
ev.key.chr = 0; |
254 |
|
|
ev.key.keycode = scancode_to_mackey[0x1d]; |
255 |
|
|
ev.key.pressed = false; |
256 |
|
|
gKeyboard->handleEvent(ev); |
257 |
|
|
ev.type = sysevKey; |
258 |
|
|
ev.key.pressed = true; |
259 |
|
|
ev.key.chr = 0; |
260 |
|
|
ev.key.keycode = scancode_to_mackey[0x138]; |
261 |
|
|
gKeyboard->handleEvent(ev); |
262 |
|
|
} else { |
263 |
|
|
ev.key.keycode = scancode_to_mackey[scancode]; |
264 |
|
|
if ((ev.key.keycode & 0xff) != 0xff) { |
265 |
|
|
ev.key.chr = chr; |
266 |
|
|
gKeyboard->handleEvent(ev); |
267 |
|
|
} |
268 |
|
|
} |
269 |
|
|
} |
270 |
|
|
break; |
271 |
|
|
case WM_KEYUP: |
272 |
|
|
case WM_SYSKEYUP: { |
273 |
|
|
SystemEvent ev; |
274 |
|
|
int scancode = HIWORD(lParam) & 0x01FF; |
275 |
|
|
ev.type = sysevKey; |
276 |
|
|
ev.key.pressed = false; |
277 |
|
|
|
278 |
|
|
if (scancode == 42 || scancode == 54) shiftDown = 0; |
279 |
|
|
|
280 |
|
|
ev.key.keycode = scancode_to_mackey[scancode]; |
281 |
|
|
|
282 |
|
|
if ((ev.key.keycode & 0xff) != 0xff) { |
283 |
|
|
gKeyboard->handleEvent(ev); |
284 |
|
|
} |
285 |
|
|
break; |
286 |
|
|
} |
287 |
|
|
case WM_CHAR: |
288 |
|
|
case WM_DEADCHAR: |
289 |
|
|
case WM_SYSCHAR: |
290 |
|
|
case WM_SYSDEADCHAR: |
291 |
|
|
break; |
292 |
|
|
case WM_ACTIVATE: |
293 |
|
|
if (wParam == WA_INACTIVE) { |
294 |
|
|
if (gDisplay->isMouseGrabbed()) gDisplay->setMouseGrab(false); |
295 |
|
|
} |
296 |
|
|
break; |
297 |
|
|
case WM_LBUTTONUP: |
298 |
|
|
if (!gDisplay->isMouseGrabbed()) { |
299 |
|
|
/* if (HIWORD(lParam) < gMenuHeight) { |
300 |
|
|
gDisplay->clickMenu(LOWORD(lParam), HIWORD(lParam)); |
301 |
|
|
} else {*/ |
302 |
|
|
gDisplay->setMouseGrab(true); |
303 |
|
|
break; |
304 |
|
|
// } |
305 |
|
|
} |
306 |
|
|
// fall throu |
307 |
|
|
case WM_RBUTTONDOWN: |
308 |
|
|
case WM_RBUTTONDBLCLK: |
309 |
|
|
case WM_RBUTTONUP: |
310 |
|
|
case WM_LBUTTONDOWN: |
311 |
|
|
case WM_LBUTTONDBLCLK: |
312 |
|
|
case WM_MOUSEMOVE: { |
313 |
|
|
SystemEvent ev; |
314 |
|
|
gDisplay->mCurMouseX = LOWORD(lParam); |
315 |
|
|
gDisplay->mCurMouseY = HIWORD(lParam); |
316 |
|
|
if (!gDisplay->isMouseGrabbed()) break; |
317 |
|
|
if (msg == WM_MOUSEMOVE) { |
318 |
|
|
if (gDisplay->mCurMouseX == gDisplay->mHomeMouseX |
319 |
|
|
&& gDisplay->mCurMouseY == gDisplay->mHomeMouseY) break; |
320 |
|
|
} |
321 |
|
|
ev.type = sysevMouse; |
322 |
|
|
ev.mouse.button1 = wParam & MK_LBUTTON; |
323 |
|
|
ev.mouse.button2 = wParam & MK_RBUTTON; |
324 |
|
|
ev.mouse.button3 = wParam & MK_MBUTTON; |
325 |
|
|
ev.mouse.relx = gDisplay->mCurMouseX - gDisplay->mHomeMouseX; |
326 |
|
|
ev.mouse.rely = gDisplay->mCurMouseY - gDisplay->mHomeMouseY; |
327 |
|
|
|
328 |
|
|
gMouse->handleEvent(ev); |
329 |
|
|
|
330 |
|
|
if (gDisplay->mFullscreen) { |
331 |
|
|
SetCursorPos(gDisplay->mHomeMouseX, gDisplay->mHomeMouseY); |
332 |
|
|
} else { |
333 |
|
|
RECT wndRect; |
334 |
|
|
GetWindowRect(hwnd, &wndRect); |
335 |
|
|
SetCursorPos(wndRect.left + gDisplay->mHomeMouseX + GetSystemMetrics(SM_CXFIXEDFRAME), |
336 |
|
|
wndRect.top + gDisplay->mHomeMouseY + GetSystemMetrics(SM_CYFIXEDFRAME) |
337 |
|
|
+ GetSystemMetrics(SM_CYCAPTION)); |
338 |
|
|
} |
339 |
|
|
break; |
340 |
|
|
} |
341 |
|
|
case WM_SIZE: |
342 |
|
|
gDisplay->setExposed(wParam != SIZE_MINIMIZED); |
343 |
|
|
break; |
344 |
|
|
case WM_COMMAND: |
345 |
|
|
MainWndProc_OnCommand(hwnd, (int)(LOWORD(wParam)), (HWND)lParam, (UINT)HIWORD(wParam)); |
346 |
|
|
break; |
347 |
|
|
case WM_DESTROY: |
348 |
|
|
gDisplay->setFullscreenMode(false); |
349 |
|
|
PostQuitMessage(0); |
350 |
|
|
break; |
351 |
|
|
default: |
352 |
|
|
return DefWindowProc(hwnd,msg,wParam,lParam); |
353 |
|
|
} |
354 |
|
|
return 0; |
355 |
|
|
} |
356 |
|
|
|
357 |
|
|
static VOID CALLBACK TimerProc(HWND hwnd, UINT uMsg, UINT idEvent, DWORD dwTime); |
358 |
|
|
|
359 |
|
|
extern SystemDisplay *allocSystemDisplay(const char *title, const DisplayCharacteristics &chr, int redraw_ms); |
360 |
|
|
extern SystemMouse *allocSystemMouse(); |
361 |
|
|
extern SystemKeyboard *allocSystemKeyboard(); |
362 |
|
|
|
363 |
|
|
void initUI(const char *title, const DisplayCharacteristics &chr, int redraw_ms, const KeyboardCharacteristics &keyConfig, bool fullscreen) |
364 |
|
|
{ |
365 |
|
|
gHInst = GetModuleHandle(NULL); |
366 |
|
|
|
367 |
|
|
gDisplay = allocSystemDisplay(title, chr, redraw_ms); |
368 |
|
|
gMouse = allocSystemMouse(); |
369 |
|
|
gKeyboard = allocSystemKeyboard(); |
370 |
|
|
if (!gKeyboard->setKeyConfig(keyConfig)) { |
371 |
|
|
ht_printf("no keyConfig, or is empty"); |
372 |
|
|
exit(1); |
373 |
|
|
} |
374 |
|
|
|
375 |
|
|
gDisplay->mFullscreen = fullscreen; |
376 |
|
|
|
377 |
|
|
_beginthread(eventLoop, 0, gDisplay); |
378 |
|
|
|
379 |
|
|
SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_BELOW_NORMAL); |
380 |
|
|
} |
381 |
|
|
|
382 |
|
|
void doneUI() |
383 |
|
|
{ |
384 |
|
|
if (eventThread != INVALID_HANDLE_VALUE) { |
385 |
|
|
if (gHWNDMain != NULL) { |
386 |
|
|
if (PostMessage(gHWNDMain, WM_DESTROY, 0, 0)) { |
387 |
|
|
WaitForSingleObject(eventThread, INFINITE); |
388 |
|
|
} |
389 |
|
|
} |
390 |
|
|
CloseHandle(eventThread); |
391 |
|
|
} |
392 |
|
|
delete gDisplay; |
393 |
|
|
delete gMouse; |
394 |
|
|
delete gKeyboard; |
395 |
|
|
} |