/[pearpc]/src/system/ui/win32/syswin.cc
This is repository of my old source code which isn't updated any more. Go to git.rot13.org for current projects!
ViewVC logotype

Contents of /src/system/ui/win32/syswin.cc

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1 - (show annotations)
Wed Sep 5 17:11:21 2007 UTC (16 years, 6 months ago) by dpavlin
File size: 12862 byte(s)
import upstream CVS
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 }

  ViewVC Help
Powered by ViewVC 1.1.26