/[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

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

Parent Directory Parent Directory | Revision Log Revision Log


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

  ViewVC Help
Powered by ViewVC 1.1.26