blob: 5f1dff871eccae3b5a0d92bc77f0059c6209a454 [file] [log] [blame]
Felix Arends8002aa72002-04-27 17:10:15 +00001/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2002 by Felix Arends
11 *
12 * All files in this archive are subject to the GNU General Public License.
13 * See the file COPYING in the source tree root for full license agreement.
14 *
15 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
16 * KIND, either express or implied.
17 *
18 ****************************************************************************/
19
20#include <windows.h>
21#include <process.h>
22#include "uisw32.h"
23#include "resource.h"
Felix Arends664b2f72002-04-30 21:15:02 +000024#include "button.h"
Felix Arends0053ec02002-06-12 15:39:39 +000025#include "thread.h"
26#include "thread-win32.h"
Felix Arends07079462002-06-15 10:58:14 +000027#include "kernel.h"
Felix Arends8002aa72002-04-27 17:10:15 +000028
Daniel Stenberg714d6ff2002-08-02 12:17:54 +000029#ifndef LR_VGACOLOR /* Should be under MINGW32 builds? */
30#define LR_VGACOLOR LR_COLOR
31#endif
32
Felix Arends8002aa72002-04-27 17:10:15 +000033// extern functions
Felix Arends664b2f72002-04-30 21:15:02 +000034extern void app_main (void *); // mod entry point
35extern void new_key(int key);
Felix Arends8002aa72002-04-27 17:10:15 +000036
37// variables
38HWND hGUIWnd; // the GUI window handle
39unsigned int uThreadID; // id of mod thread
40PBYTE lpKeys;
Felix Arends647661c2002-06-01 20:56:38 +000041bool bActive; // window active?
Felix Arends0053ec02002-06-12 15:39:39 +000042HANDLE hGUIThread; // thread for GUI
Felix Arends8002aa72002-04-27 17:10:15 +000043
44// GUIWndProc
45// window proc for GUI simulator
46LRESULT GUIWndProc (
47 HWND hWnd,
48 UINT uMsg,
49 WPARAM wParam,
50 LPARAM lParam
51 )
52{
53 static HBITMAP hBkgnd;
Felix Arends8002aa72002-04-27 17:10:15 +000054 static HDC hMemDc;
55
56 switch (uMsg)
57 {
Felix Arends07079462002-06-15 10:58:14 +000058 case WM_TIMER:
59 current_tick++;
60 return TRUE;
Felix Arends647661c2002-06-01 20:56:38 +000061 case WM_ACTIVATE:
62 if (LOWORD(wParam) == WA_ACTIVE || LOWORD(wParam) == WA_CLICKACTIVE)
63 bActive = true;
64 else
65 bActive = false;
66 return TRUE;
Felix Arends8002aa72002-04-27 17:10:15 +000067 case WM_CREATE:
Felix Arends07079462002-06-15 10:58:14 +000068 SetTimer (hWnd, TIMER_EVENT, 50, NULL);
Felix Arends8002aa72002-04-27 17:10:15 +000069 // load background image
70 hBkgnd = (HBITMAP)LoadImage (GetModuleHandle (NULL), MAKEINTRESOURCE(IDB_UI),
Felix Arends175ac892002-05-29 16:34:40 +000071 IMAGE_BITMAP, 0, 0, LR_VGACOLOR);
Felix Arends8002aa72002-04-27 17:10:15 +000072 hMemDc = CreateCompatibleDC (GetDC (hWnd));
73 SelectObject (hMemDc, hBkgnd);
74 return TRUE;
75 case WM_SIZING:
76 {
77 LPRECT r = (LPRECT)lParam;
78 RECT r2;
79 char s[256];
80 int v;
81
82 switch (wParam)
83 {
84 case WMSZ_BOTTOM:
85 v = (r->bottom - r->top) / (UI_HEIGHT / 5);
86 r->bottom = r->top + v * UI_HEIGHT / 5;
87 r->right = r->left + v * UI_WIDTH / 5;
88 r->right += GetSystemMetrics (SM_CXSIZEFRAME) * 2;
89 r->bottom += GetSystemMetrics (SM_CYSIZEFRAME) * 2 + GetSystemMetrics (SM_CYSMCAPTION);
90 break;
91 case WMSZ_RIGHT:
92 v = (r->right - r->left) / (UI_WIDTH / 5);
93 r->bottom = r->top + v * UI_HEIGHT / 5;
94 r->right = r->left + v * UI_WIDTH / 5;
95 r->right += GetSystemMetrics (SM_CXSIZEFRAME) * 2;
96 r->bottom += GetSystemMetrics (SM_CYSIZEFRAME) * 2 + GetSystemMetrics (SM_CYSMCAPTION);
97 break;
98 case WMSZ_TOP:
99 v = (r->bottom - r->top) / (UI_HEIGHT / 5);
100 r->top = r->bottom - v * UI_HEIGHT / 5;
101 r->right = r->left + v * UI_WIDTH / 5;
102 r->right += GetSystemMetrics (SM_CXSIZEFRAME) * 2;
103 r->top -= GetSystemMetrics (SM_CYSIZEFRAME) * 2 + GetSystemMetrics (SM_CYSMCAPTION);
104 break;
105 case WMSZ_LEFT:
106 v = (r->right - r->left) / (UI_WIDTH / 5);
107 r->bottom = r->top + v * UI_HEIGHT / 5;
108 r->left = r->right - v * UI_WIDTH / 5;
109 r->left -= GetSystemMetrics (SM_CXSIZEFRAME) * 2;
110 r->bottom += GetSystemMetrics (SM_CYSIZEFRAME) * 2 + GetSystemMetrics (SM_CYSMCAPTION);
111 break;
112 case WMSZ_BOTTOMRIGHT:
113 GetWindowRect (hWnd, &r2);
114 if (abs(r2.right - r->right) > abs(r2.bottom - r->bottom))
115 v = (r->right - r->left) / (UI_WIDTH / 5);
116 else
117 v = (r->bottom - r->top) / (UI_HEIGHT / 5);
118 r->bottom = r->top + v * UI_HEIGHT / 5;
119 r->right = r->left + v * UI_WIDTH / 5;
120 r->right += GetSystemMetrics (SM_CXSIZEFRAME) * 2;
121 r->bottom += GetSystemMetrics (SM_CYSIZEFRAME) * 2 + GetSystemMetrics (SM_CYSMCAPTION);
122 break;
123 case WMSZ_BOTTOMLEFT:
124 GetWindowRect (hWnd, &r2);
125 if (abs(r2.left - r->left) > abs(r2.bottom - r->bottom))
126 v = (r->right - r->left) / (UI_WIDTH / 5);
127 else
128 v = (r->bottom - r->top) / (UI_HEIGHT / 5);
129 r->bottom = r->top + v * UI_HEIGHT / 5;
130 r->left = r->right - v * UI_WIDTH / 5;
131 r->left -= GetSystemMetrics (SM_CXSIZEFRAME) * 2;
132 r->bottom += GetSystemMetrics (SM_CYSIZEFRAME) * 2 + GetSystemMetrics (SM_CYSMCAPTION);
133 break;
134 case WMSZ_TOPRIGHT:
135 GetWindowRect (hWnd, &r2);
136 if (abs(r2.right - r->right) > abs(r2.top - r->top))
137 v = (r->right - r->left) / (UI_WIDTH / 5);
138 else
139 v = (r->bottom - r->top) / (UI_HEIGHT / 5);
140 r->top = r->bottom - v * UI_HEIGHT / 5;
141 r->right = r->left + v * UI_WIDTH / 5;
142 r->right += GetSystemMetrics (SM_CXSIZEFRAME) * 2;
143 r->top -= GetSystemMetrics (SM_CYSIZEFRAME) * 2 + GetSystemMetrics (SM_CYSMCAPTION);
144 break;
145 case WMSZ_TOPLEFT:
146 GetWindowRect (hWnd, &r2);
147 if (abs(r2.left - r->left) > abs(r2.top - r->top))
148 v = (r->right - r->left) / (UI_WIDTH / 5);
149 else
150 v = (r->bottom - r->top) / (UI_HEIGHT / 5);
151 r->top = r->bottom - v * UI_HEIGHT / 5;
152 r->left = r->right - v * UI_WIDTH / 5;
153 r->left -= GetSystemMetrics (SM_CXSIZEFRAME) * 2;
154 r->top -= GetSystemMetrics (SM_CYSIZEFRAME) * 2 + GetSystemMetrics (SM_CYSMCAPTION);
155 break;
156 }
157
158 wsprintf (s, "RockBox Simulator @%d%%",
159 (r->right - r->left - GetSystemMetrics (SM_CXSIZEFRAME) * 2)
160 * 100 / UI_WIDTH);
161 SetWindowText (hWnd, s);
162
163 return TRUE;
164 }
165 case WM_ERASEBKGND:
166 {
167 PAINTSTRUCT ps;
168 HDC hDc = BeginPaint (hWnd, &ps);
169 RECT r;
170
171 GetClientRect (hWnd, &r);
172 // blit to screen
173 StretchBlt (hDc, 0, 0, r.right, r.bottom,
174 hMemDc, 0, 0, UI_WIDTH, UI_HEIGHT, SRCCOPY);
175 EndPaint (hWnd, &ps);
176 return TRUE;
177 }
178 case WM_PAINT:
179 {
180 PAINTSTRUCT ps;
181 RECT r;
182 HDC hDc = BeginPaint (hWnd, &ps);
183
184 GetClientRect (hWnd, &r);
185 // draw lcd screen
186 StretchDIBits (hDc,
187 UI_LCD_POSX * r.right / UI_WIDTH, UI_LCD_POSY * r.bottom / UI_HEIGHT,
188 LCD_WIDTH * r.right / UI_WIDTH, LCD_HEIGHT * r.bottom / UI_HEIGHT,
189 0, 0, LCD_WIDTH, LCD_HEIGHT,
190 bitmap, (BITMAPINFO *) &bmi, DIB_RGB_COLORS, SRCCOPY);
191
192 EndPaint (hWnd, &ps);
193 return TRUE;
194 }
195 case WM_CLOSE:
196 // close simulator
Felix Arends07079462002-06-15 10:58:14 +0000197 KillTimer (hWnd, TIMER_EVENT);
Felix Arends8002aa72002-04-27 17:10:15 +0000198 hGUIWnd = NULL;
199 PostQuitMessage (0);
200 break;
Felix Arends0053ec02002-06-12 15:39:39 +0000201 case WM_DESTROY:
202 // close simulator
203 hGUIWnd = NULL;
204 PostQuitMessage (0);
205 break;
Felix Arends8002aa72002-04-27 17:10:15 +0000206 }
207
208 return DefWindowProc (hWnd, uMsg, wParam, lParam);
209}
210
211// GUIStartup
212// register window class, show window, init GUI
213BOOL GUIStartup ()
214{
215 WNDCLASS wc;
216
217 // create window class
218 ZeroMemory (&wc, sizeof(wc));
219 wc.hbrBackground = GetSysColorBrush (COLOR_WINDOW);
220 wc.hCursor = LoadCursor (NULL, IDC_ARROW);
221 wc.hInstance = GetModuleHandle (NULL);
222 wc.lpfnWndProc = (WNDPROC)GUIWndProc;
223 wc.lpszClassName = "RockBoxUISimulator";
224 wc.style = CS_HREDRAW | CS_VREDRAW;
225
226 if (RegisterClass (&wc) == 0)
227 return FALSE;
228
229 // create window
230 hGUIWnd = CreateWindowEx (
231 WS_EX_TOOLWINDOW | WS_EX_PALETTEWINDOW,
232 "RockBoxUISimulator", "ARCHOS JukeBox",
233 WS_VISIBLE | WS_SYSMENU | WS_OVERLAPPEDWINDOW,
234 CW_USEDEFAULT, CW_USEDEFAULT,
235 UI_WIDTH + GetSystemMetrics (SM_CXSIZEFRAME) * 2,
236 UI_HEIGHT + GetSystemMetrics (SM_CYSIZEFRAME) * 2 + GetSystemMetrics (SM_CYSMCAPTION),
237 NULL, NULL, GetModuleHandle (NULL), NULL);
238
239 if (hGUIWnd == NULL)
240 return FALSE;
241
242 return TRUE;
243}
244
245// GUIDown
246// destroy window, unregister window class
247int GUIDown ()
248{
Felix Arends0053ec02002-06-12 15:39:39 +0000249 int i;
250
Felix Arends8002aa72002-04-27 17:10:15 +0000251 DestroyWindow (hGUIWnd);
Felix Arends0053ec02002-06-12 15:39:39 +0000252 CloseHandle (hGUIThread);
253 for (i = 0; i < nThreads; i++)
254 {
255 ResumeThread (lpThreads[i]);
256 WaitForSingleObject (lpThreads[i], 1);
257 CloseHandle (lpThreads[i]);
258 }
Felix Arends8002aa72002-04-27 17:10:15 +0000259 return 0;
260}
261
262// GUIMessageLoop
263// standard message loop for GUI window
264void GUIMessageLoop ()
265{
266 MSG msg;
Felix Arends0053ec02002-06-12 15:39:39 +0000267 while (GetMessage (&msg, NULL, 0, 0))
Felix Arends8002aa72002-04-27 17:10:15 +0000268 {
269 TranslateMessage (&msg);
270 DispatchMessage (&msg);
Felix Arends0053ec02002-06-12 15:39:39 +0000271 if (msg.message == TM_YIELD)
272 {
273 SuspendThread (lpThreads[nPos]);
274 if (++nPos >= nThreads)
275 nPos = 0;
276 ResumeThread (lpThreads[nPos]);
277 }
Felix Arends8002aa72002-04-27 17:10:15 +0000278 }
279}
280
281
282// WinMain
283// program entry point
284int WINAPI WinMain (
285 HINSTANCE hInstance, // current instance
286 HINSTANCE hPrevInstance, // previous instance
287 LPSTR lpCmd, // command line
288 int nShowCmd // show command
289 )
290{
Felix Arends0053ec02002-06-12 15:39:39 +0000291 DWORD dwThreadID;
Daniel Stenberga32af772002-08-02 14:00:52 +0000292
293 (void)hInstance;
294 (void)hPrevInstance;
295 (void)lpCmd;
296 (void)nShowCmd;
297
Felix Arends8002aa72002-04-27 17:10:15 +0000298 if (!GUIStartup ())
299 return 0;
300
Felix Arends0053ec02002-06-12 15:39:39 +0000301 hGUIThread = CreateThread (NULL, 0, (LPTHREAD_START_ROUTINE)app_main,
302 NULL, 0, &dwThreadID);
303
304 if (hGUIThread == NULL)
305 return MessageBox (NULL, "Error creating gui thread!", "Error", MB_OK);
Felix Arends8002aa72002-04-27 17:10:15 +0000306
307 GUIMessageLoop ();
308
309 return GUIDown ();
Daniel Stenberg714d6ff2002-08-02 12:17:54 +0000310}