comparison src/video/os2fslib/SDL_os2fslib.c @ 1895:c121d94672cb

SDL 1.2 is moving to a branch, and SDL 1.3 is becoming the head.
author Sam Lantinga <slouken@libsdl.org>
date Mon, 10 Jul 2006 21:04:37 +0000
parents 066236f0cbf0
children e1da92da346c 204be4fc2726
comparison
equal deleted inserted replaced
1894:c69cee13dd76 1895:c121d94672cb
21 */ 21 */
22 #include "SDL_config.h" 22 #include "SDL_config.h"
23 23
24 #define _ULS_CALLCONV_ 24 #define _ULS_CALLCONV_
25 #define CALLCONV _System 25 #define CALLCONV _System
26 #include <unidef.h> // Unicode API 26 #include <unidef.h> // Unicode API
27 #include <uconv.h> // Unicode API (codepage conversion) 27 #include <uconv.h> // Unicode API (codepage conversion)
28 28
29 #include <process.h> 29 #include <process.h>
30 #include <time.h> 30 #include <time.h>
31 31
32 #include "SDL_video.h" 32 #include "SDL_video.h"
36 #include "../../events/SDL_events_c.h" 36 #include "../../events/SDL_events_c.h"
37 37
38 #include "SDL_os2fslib.h" 38 #include "SDL_os2fslib.h"
39 39
40 static ULONG ulFCFToUse = 40 static ULONG ulFCFToUse =
41 FCF_TITLEBAR | 41 FCF_TITLEBAR |
42 FCF_SYSMENU | 42 FCF_SYSMENU |
43 FCF_MINBUTTON | 43 FCF_MINBUTTON |
44 FCF_MAXBUTTON | 44 FCF_MAXBUTTON | FCF_NOBYTEALIGN | FCF_SIZEBORDER | FCF_TASKLIST;
45 FCF_NOBYTEALIGN | 45
46 FCF_SIZEBORDER | 46 static int bMouseCaptured = 0;
47 FCF_TASKLIST;
48
49 static int bMouseCaptured = 0;
50 static int bMouseCapturable = 0; 47 static int bMouseCapturable = 0;
51 static HPOINTER hptrGlobalPointer = NULL; 48 static HPOINTER hptrGlobalPointer = NULL;
52 static HPOINTER hptrCurrentIcon = NULL; 49 static HPOINTER hptrCurrentIcon = NULL;
53 static int iWindowSizeX = 320; 50 static int iWindowSizeX = 320;
54 static int iWindowSizeY = 200; 51 static int iWindowSizeY = 200;
55 static int bWindowResized = 0; 52 static int bWindowResized = 0;
56 53
57 #pragma pack(1) 54 #pragma pack(1)
58 typedef struct BMPINFO 55 typedef struct BMPINFO
59 { 56 {
60 BITMAPINFO; 57 BITMAPINFO;
61 RGB clr; 58 RGB clr;
62 } BMPINFO, *PBMPINFO; 59 } BMPINFO, *PBMPINFO;
63 #pragma pack() 60 #pragma pack()
64 61
65 62
66 // Backdoors: 63 // Backdoors:
67 DECLSPEC void SDLCALL SDL_OS2FSLIB_SetFCFToUse(ULONG ulFCF) 64 DECLSPEC void SDLCALL
68 { 65 SDL_OS2FSLIB_SetFCFToUse(ULONG ulFCF)
69 ulFCFToUse = ulFCF; 66 {
67 ulFCFToUse = ulFCF;
70 } 68 }
71 69
72 // Configuration defines: 70 // Configuration defines:
73 71
74 // We have to report empty alpha mask, otherwise SDL will select 72 // We have to report empty alpha mask, otherwise SDL will select
90 // even if the surface is resizable. 88 // even if the surface is resizable.
91 //#define RESIZE_EVEN_IF_RESIZABLE 89 //#define RESIZE_EVEN_IF_RESIZABLE
92 90
93 /* The translation table from a VK keysym to a SDL keysym */ 91 /* The translation table from a VK keysym to a SDL keysym */
94 static SDLKey HWScanKeyMap[256]; 92 static SDLKey HWScanKeyMap[256];
95 static SDL_keysym *TranslateKey(int vkey, int chcode, int scancode, SDL_keysym *keysym, int iPressed); 93 static SDL_keysym *TranslateKey(int vkey, int chcode, int scancode,
96 static int iShiftIsPressed; 94 SDL_keysym * keysym, int iPressed);
95 static int iShiftIsPressed;
97 96
98 #ifdef BITBLT_IN_WINMESSAGEPROC 97 #ifdef BITBLT_IN_WINMESSAGEPROC
99 #define WM_UPDATERECTSREQUEST WM_USER+50 98 #define WM_UPDATERECTSREQUEST WM_USER+50
100 #endif 99 #endif
101 100
117 // 116 //
118 // Same as WinSetWindowPos(), but takes care for the window to be 117 // Same as WinSetWindowPos(), but takes care for the window to be
119 // always on the screen, the titlebar will be accessable everytime. 118 // always on the screen, the titlebar will be accessable everytime.
120 // 119 //
121 ///////////////////////////////////////////////////////////////////// 120 /////////////////////////////////////////////////////////////////////
122 static BOOL SetAccessableWindowPos(HWND hwnd, HWND hwndInsertBehind, 121 static BOOL
123 LONG x, LONG y, 122 SetAccessableWindowPos(HWND hwnd, HWND hwndInsertBehind,
124 LONG cx, LONG cy, 123 LONG x, LONG y, LONG cx, LONG cy, ULONG fl)
125 ULONG fl) 124 {
126 { 125 SWP swpDesktop, swp;
127 SWP swpDesktop, swp; 126 // Get desktop area
128 // Get desktop area 127 WinQueryWindowPos(HWND_DESKTOP, &swpDesktop);
129 WinQueryWindowPos(HWND_DESKTOP, &swpDesktop); 128
130 129 if ((fl & SWP_MOVE) && (fl & SWP_SIZE)) {
131 if ((fl & SWP_MOVE) && (fl & SWP_SIZE)) 130 // If both moving and sizing, then change size and pos now!!
132 { 131 if (x + cx > swpDesktop.cx)
133 // If both moving and sizing, then change size and pos now!! 132 x = swpDesktop.cx - cx;
134 if (x+cx>swpDesktop.cx) 133 if (x < 0)
135 x = swpDesktop.cx - cx; 134 x = 0;
136 if (x<0) 135 if (y < 0)
137 x = 0; 136 y = 0;
138 if (y<0) 137 if (y + cy > swpDesktop.cy)
139 y = 0; 138 y = swpDesktop.cy - cy;
140 if (y+cy>swpDesktop.cy) 139 return WinSetWindowPos(hwnd, hwndInsertBehind, x, y, cx, cy, fl);
141 y = swpDesktop.cy - cy; 140 } else if (fl & SWP_MOVE) {
142 return WinSetWindowPos(hwnd, hwndInsertBehind, x, y, cx, cy, fl); 141 // Just moving
143 } else 142 WinQueryWindowPos(hwnd, &swp);
144 if (fl & SWP_MOVE) 143 if (x + swp.cx > swpDesktop.cx)
145 { 144 x = swpDesktop.cx - swp.cx;
146 // Just moving 145 if (x < 0)
147 WinQueryWindowPos(hwnd, &swp); 146 x = 0;
148 if (x+swp.cx>swpDesktop.cx) 147 if (y < 0)
149 x = swpDesktop.cx - swp.cx; 148 y = 0;
150 if (x<0) 149 if (y + swp.cy > swpDesktop.cy)
151 x = 0; 150 y = swpDesktop.cy - swp.cy;
152 if (y<0) 151 return WinSetWindowPos(hwnd, hwndInsertBehind, x, y, cx, cy, fl);
153 y = 0; 152 } else if (fl & SWP_SIZE) {
154 if (y+swp.cy>swpDesktop.cy) 153 // Just sizing
155 y = swpDesktop.cy - swp.cy; 154 WinQueryWindowPos(hwnd, &swp);
156 return WinSetWindowPos(hwnd, hwndInsertBehind, x, y, cx, cy, fl); 155 x = swp.x;
157 } else 156 y = swp.y;
158 if (fl & SWP_SIZE) 157 if (x + cx > swpDesktop.cx)
159 { 158 x = swpDesktop.cx - cx;
160 // Just sizing 159 if (x < 0)
161 WinQueryWindowPos(hwnd, &swp); 160 x = 0;
162 x = swp.x; 161 if (y < 0)
163 y = swp.y; 162 y = 0;
164 if (x+cx>swpDesktop.cx) 163 if (y + cy > swpDesktop.cy)
165 x = swpDesktop.cx - cx; 164 y = swpDesktop.cy - cy;
166 if (x<0) 165 return WinSetWindowPos(hwnd, hwndInsertBehind, x, y, cx, cy,
167 x = 0; 166 fl | SWP_MOVE);
168 if (y<0) 167 } else
169 y = 0; 168 return WinSetWindowPos(hwnd, hwndInsertBehind, x, y, cx, cy, fl);
170 if (y+cy>swpDesktop.cy) 169 }
171 y = swpDesktop.cy - cy; 170
172 return WinSetWindowPos(hwnd, hwndInsertBehind, x, y, cx, cy, fl | SWP_MOVE); 171 static UniChar
173 } else 172 NativeCharToUniChar(int chcode)
174 return WinSetWindowPos(hwnd, hwndInsertBehind, x, y, cx, cy, fl); 173 {
175 } 174 UniChar ucResult = (UniChar) chcode;
176 175 int rc;
177 static UniChar NativeCharToUniChar(int chcode) 176 UconvObject ucoTemp;
178 { 177 char achFrom[2];
179 UniChar ucResult = (UniChar) chcode; 178 char *pchFrom;
180 int rc; 179 size_t iFromCount;
181 UconvObject ucoTemp; 180 UniChar aucTo[10];
182 char achFrom[2]; 181 UniChar *pucTo;
183 char *pchFrom; 182 size_t iToCount;
184 size_t iFromCount; 183 size_t iNonIdentical;
185 UniChar aucTo[10]; 184
186 UniChar *pucTo; 185 // Create unicode convert object
187 size_t iToCount; 186 rc = UniCreateUconvObject(L"", &ucoTemp);
188 size_t iNonIdentical; 187 if (rc != ULS_SUCCESS) {
189 188 // Could not create convert object!
190 // Create unicode convert object 189 return ucResult;
191 rc = UniCreateUconvObject(L"", &ucoTemp); 190 }
192 if (rc!=ULS_SUCCESS) 191 // Convert language code string to unicode string
193 { 192 achFrom[0] = (char) chcode;
194 // Could not create convert object! 193 achFrom[1] = 0;
195 return ucResult; 194 iFromCount = sizeof(char) * 2;
196 } 195 iToCount = sizeof(UniChar) * 2;
197 196 pucTo = &(aucTo[0]);
198 // Convert language code string to unicode string 197 pchFrom = &(achFrom[0]);
199 achFrom[0] = (char) chcode; 198
200 achFrom[1] = 0; 199 rc = UniUconvToUcs(ucoTemp,
201 iFromCount = sizeof(char) * 2; 200 &pchFrom,
202 iToCount = sizeof(UniChar) * 2; 201 &iFromCount, &pucTo, &iToCount, &iNonIdentical);
203 pucTo = &(aucTo[0]); 202
204 pchFrom = &(achFrom[0]); 203 if (rc != ULS_SUCCESS) {
205 204 // Could not convert language code to UCS string!
206 rc = UniUconvToUcs(ucoTemp, 205 UniFreeUconvObject(ucoTemp);
207 &pchFrom, 206 return ucResult;
208 &iFromCount, 207 }
209 &pucTo, 208
210 &iToCount,
211 &iNonIdentical);
212
213 if (rc!=ULS_SUCCESS)
214 {
215 // Could not convert language code to UCS string!
216 UniFreeUconvObject(ucoTemp); 209 UniFreeUconvObject(ucoTemp);
217 return ucResult; 210
218 } 211 #ifdef DEBUG_BUILD
219 212 printf("%02x converted to %02x\n", (int) chcode, (int) (aucTo[0]));
220 UniFreeUconvObject(ucoTemp); 213 #endif
221 214
222 #ifdef DEBUG_BUILD 215 return aucTo[0];
223 printf("%02x converted to %02x\n", (int) chcode, (int) (aucTo[0]));
224 #endif
225
226 return aucTo[0];
227 } 216 }
228 217
229 ///////////////////////////////////////////////////////////////////// 218 /////////////////////////////////////////////////////////////////////
230 // 219 //
231 // TranslateKey 220 // TranslateKey
232 // 221 //
233 // This creates SDL Keycodes from VK_ and hardware scan codes 222 // This creates SDL Keycodes from VK_ and hardware scan codes
234 // 223 //
235 ///////////////////////////////////////////////////////////////////// 224 /////////////////////////////////////////////////////////////////////
236 static SDL_keysym *TranslateKey(int vkey, int chcode, int scancode, SDL_keysym *keysym, int iPressed) 225 static SDL_keysym *
237 { 226 TranslateKey(int vkey, int chcode, int scancode, SDL_keysym * keysym,
238 keysym->scancode = (unsigned char) scancode; 227 int iPressed)
239 keysym->mod = KMOD_NONE; 228 {
240 keysym->unicode = 0; 229 keysym->scancode = (unsigned char) scancode;
241 230 keysym->mod = KMOD_NONE;
242 if (iPressed && SDL_TranslateUNICODE) 231 keysym->unicode = 0;
243 { 232
244 if (chcode) 233 if (iPressed && SDL_TranslateUNICODE) {
245 keysym->unicode = NativeCharToUniChar(chcode); 234 if (chcode)
246 else 235 keysym->unicode = NativeCharToUniChar(chcode);
247 keysym->unicode = vkey; 236 else
248 } 237 keysym->unicode = vkey;
249 238 }
250 keysym->sym = HWScanKeyMap[scancode]; 239
251 240 keysym->sym = HWScanKeyMap[scancode];
252 // Now stuffs based on state of shift key(s)! 241
253 if (vkey == VK_SHIFT) 242 // Now stuffs based on state of shift key(s)!
254 { 243 if (vkey == VK_SHIFT) {
255 iShiftIsPressed = iPressed; 244 iShiftIsPressed = iPressed;
256 } 245 }
257 246
258 if ((iShiftIsPressed) && (SDL_TranslateUNICODE)) 247 if ((iShiftIsPressed) && (SDL_TranslateUNICODE)) {
259 { 248 // Change syms, if Unicode stuff is required
260 // Change syms, if Unicode stuff is required 249 // I think it's silly, but it's SDL...
261 // I think it's silly, but it's SDL... 250 switch (keysym->sym) {
262 switch (keysym->sym) 251 case SDLK_BACKQUOTE:
263 { 252 keysym->sym = '~';
264 case SDLK_BACKQUOTE: 253 break;
265 keysym->sym = '~'; 254 case SDLK_1:
266 break; 255 keysym->sym = SDLK_EXCLAIM;
267 case SDLK_1: 256 break;
268 keysym->sym = SDLK_EXCLAIM; 257 case SDLK_2:
269 break; 258 keysym->sym = SDLK_AT;
270 case SDLK_2: 259 break;
271 keysym->sym = SDLK_AT; 260 case SDLK_3:
272 break; 261 keysym->sym = SDLK_HASH;
273 case SDLK_3: 262 break;
274 keysym->sym = SDLK_HASH; 263 case SDLK_4:
275 break; 264 keysym->sym = SDLK_DOLLAR;
276 case SDLK_4: 265 break;
277 keysym->sym = SDLK_DOLLAR; 266 case SDLK_5:
278 break; 267 keysym->sym = '%';
279 case SDLK_5: 268 break;
280 keysym->sym = '%'; 269 case SDLK_6:
281 break; 270 keysym->sym = SDLK_CARET;
282 case SDLK_6: 271 break;
283 keysym->sym = SDLK_CARET; 272 case SDLK_7:
284 break; 273 keysym->sym = SDLK_AMPERSAND;
285 case SDLK_7: 274 break;
286 keysym->sym = SDLK_AMPERSAND; 275 case SDLK_8:
287 break; 276 keysym->sym = SDLK_ASTERISK;
288 case SDLK_8: 277 break;
289 keysym->sym = SDLK_ASTERISK; 278 case SDLK_9:
290 break; 279 keysym->sym = SDLK_LEFTPAREN;
291 case SDLK_9: 280 break;
292 keysym->sym = SDLK_LEFTPAREN; 281 case SDLK_0:
293 break; 282 keysym->sym = SDLK_RIGHTPAREN;
294 case SDLK_0: 283 break;
295 keysym->sym = SDLK_RIGHTPAREN; 284 case SDLK_MINUS:
296 break; 285 keysym->sym = SDLK_UNDERSCORE;
297 case SDLK_MINUS: 286 break;
298 keysym->sym = SDLK_UNDERSCORE; 287 case SDLK_PLUS:
299 break; 288 keysym->sym = SDLK_EQUALS;
300 case SDLK_PLUS: 289 break;
301 keysym->sym = SDLK_EQUALS; 290
302 break; 291 case SDLK_LEFTBRACKET:
303 292 keysym->sym = '{';
304 case SDLK_LEFTBRACKET: 293 break;
305 keysym->sym = '{'; 294 case SDLK_RIGHTBRACKET:
306 break; 295 keysym->sym = '}';
307 case SDLK_RIGHTBRACKET: 296 break;
308 keysym->sym = '}'; 297
309 break; 298 case SDLK_SEMICOLON:
310 299 keysym->sym = SDLK_COLON;
311 case SDLK_SEMICOLON: 300 break;
312 keysym->sym = SDLK_COLON; 301 case SDLK_QUOTE:
313 break; 302 keysym->sym = SDLK_QUOTEDBL;
314 case SDLK_QUOTE: 303 break;
315 keysym->sym = SDLK_QUOTEDBL; 304 case SDLK_BACKSLASH:
316 break; 305 keysym->sym = '|';
317 case SDLK_BACKSLASH: 306 break;
318 keysym->sym = '|'; 307
319 break; 308 case SDLK_COMMA:
320 309 keysym->sym = SDLK_LESS;
321 case SDLK_COMMA: 310 break;
322 keysym->sym = SDLK_LESS; 311 case SDLK_PERIOD:
323 break; 312 keysym->sym = SDLK_GREATER;
324 case SDLK_PERIOD: 313 break;
325 keysym->sym = SDLK_GREATER; 314 case SDLK_SLASH:
326 break; 315 keysym->sym = SDLK_QUESTION;
327 case SDLK_SLASH: 316 break;
328 keysym->sym = SDLK_QUESTION; 317
329 break; 318 default:
330 319 break;
331 default: 320 }
332 break; 321 }
333 } 322 return keysym;
334 }
335 return keysym;
336 } 323 }
337 324
338 #define CONVERTMOUSEPOSITION() \ 325 #define CONVERTMOUSEPOSITION() \
339 /* We have to inverse the mouse position, because every non-os/2 system */ \ 326 /* We have to inverse the mouse position, because every non-os/2 system */ \
340 /* has a coordinate system where the (0;0) is the top-left corner, */ \ 327 /* has a coordinate system where the (0;0) is the top-left corner, */ \
377 // It handles switching back and away from the app (taking care of 364 // It handles switching back and away from the app (taking care of
378 // going out and back to and from fullscreen mode), sending keystrokes 365 // going out and back to and from fullscreen mode), sending keystrokes
379 // and mouse events to where it has to be sent, etc... 366 // and mouse events to where it has to be sent, etc...
380 // 367 //
381 ///////////////////////////////////////////////////////////////////// 368 /////////////////////////////////////////////////////////////////////
382 static MRESULT EXPENTRY WndProc( HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2) 369 static MRESULT EXPENTRY
383 { 370 WndProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
384 HPS ps; 371 {
385 RECTL rcl; 372 HPS ps;
386 SDL_VideoDevice *pVideo = NULL; 373 RECTL rcl;
387 374 SDL_VideoDevice *pVideo = NULL;
388 switch (msg) 375
389 { 376 switch (msg) {
390 case WM_CHAR: // Keypress notification 377 case WM_CHAR: // Keypress notification
391 #ifdef DEBUG_BUILD 378 #ifdef DEBUG_BUILD
392 // printf("WM_CHAR\n"); fflush(stdout); 379 // printf("WM_CHAR\n"); fflush(stdout);
393 #endif 380 #endif
394 pVideo = WinQueryWindowPtr(hwnd, 0); 381 pVideo = WinQueryWindowPtr(hwnd, 0);
395 if (pVideo) 382 if (pVideo) {
396 { 383 /*
397 /* 384 // We skip repeated keys:
398 // We skip repeated keys: 385 if (CHARMSG(&msg)->cRepeat>1)
399 if (CHARMSG(&msg)->cRepeat>1) 386 {
387 #ifdef DEBUG_BUILD
388 // printf("Repeated key (%d), skipping...\n", CHARMSG(&msg)->cRepeat); fflush(stdout);
389 #endif
390 return (MRESULT) TRUE;
391 }
392 */
393
394 // If it's not repeated, then let's see if its pressed or released!
395 if (SHORT1FROMMP(mp1) & KC_KEYUP) {
396 // A key has been released
397 SDL_keysym keysym;
398
399 #ifdef DEBUG_BUILD
400 // printf("WM_CHAR, keyup, code is [0x%0x]\n", CHAR4FROMMP(mp1)); // HW scan code
401 #endif
402
403 // One problem is with F1, which gets only the keyup message because
404 // it is a system key.
405 // So, when we get keyup message, we simulate keydown too!
406 // UPDATE:
407 // This problem should be solved now, that the accelerator keys are
408 // disabled for this window!
409 /*
410 if (SHORT2FROMMP(mp2)==VK_F1)
411 {
412 SDL_PrivateKeyboard(SDL_PRESSED, TranslateKey(SHORT2FROMMP(mp2), // VK_ code
413 SHORT1FROMMP(mp2), // Character code
414 CHAR4FROMMP(mp1), // HW Scan code
415 &keysym,0));
416 } */
417
418 SDL_PrivateKeyboard(SDL_RELEASED, TranslateKey(SHORT2FROMMP(mp2), // VK_ code
419 SHORT1FROMMP(mp2), // Character code
420 CHAR4FROMMP(mp1), // HW Scan code
421 &keysym, 0));
422
423 } else {
424 // A key has been pressed
425 SDL_keysym keysym;
426
427 #ifdef DEBUG_BUILD
428 // printf("WM_CHAR, keydown, code is [0x%0x]\n", CHAR4FROMMP(mp1)); // HW scan code
429 #endif
430 // Check for fastkeys: ALT+HOME to toggle FS mode
431 // ALT+END to close app
432 if ((SHORT1FROMMP(mp1) & KC_ALT) &&
433 (SHORT2FROMMP(mp2) == VK_HOME)) {
434 #ifdef DEBUG_BUILD
435 printf(" Pressed ALT+HOME!\n");
436 fflush(stdout);
437 #endif
438 // Only switch between fullscreen and back if it's not
439 // a resizable mode!
440 if ((!pVideo->hidden->pSDLSurface) ||
441 ((pVideo->hidden->pSDLSurface)
442 &&
443 ((pVideo->hidden->pSDLSurface->
444 flags & SDL_RESIZABLE) == 0)))
445 FSLib_ToggleFSMode(hwnd, !FSLib_QueryFSMode(hwnd));
446 #ifdef DEBUG_BUILD
447 else
448 printf(" Resizable mode, so discarding ALT+HOME!\n");
449 fflush(stdout);
450 #endif
451 } else if ((SHORT1FROMMP(mp1) & KC_ALT) &&
452 (SHORT2FROMMP(mp2) == VK_END)) {
453 #ifdef DEBUG_BUILD
454 printf(" Pressed ALT+END!\n");
455 fflush(stdout);
456 #endif
457 // Close window, and get out of loop!
458 // Also send event to SDL application, but we won't
459 // wait for it to be processed!
460 SDL_PrivateQuit();
461 WinPostMsg(hwnd, WM_QUIT, 0, 0);
462 } else {
463
464 SDL_PrivateKeyboard(SDL_PRESSED, TranslateKey(SHORT2FROMMP(mp2), // VK_ code
465 SHORT1FROMMP(mp2), // Character code
466 CHAR4FROMMP(mp1), // HW Scan code
467 &keysym,
468 1));
469
470 }
471 }
472 }
473 return (MRESULT) TRUE;
474
475 case WM_TRANSLATEACCEL:
400 { 476 {
401 #ifdef DEBUG_BUILD 477 PQMSG pqmsg;
402 // printf("Repeated key (%d), skipping...\n", CHARMSG(&msg)->cRepeat); fflush(stdout); 478 pqmsg = (PQMSG) mp1;
403 #endif 479 if (mp1) {
404 return (MRESULT) TRUE; 480 if (pqmsg->msg == WM_CHAR) {
405 } 481 // WM_CHAR message!
406 */ 482 // Let's filter the ALT keypress and all other acceleration keys!
407 483 return (MRESULT) FALSE;
408 // If it's not repeated, then let's see if its pressed or released! 484 }
409 if (SHORT1FROMMP(mp1) & KC_KEYUP) 485 }
486 break; // Default processing (pass to parent until frame control)
487 }
488
489 case WM_PAINT: // Window redraw!
490 #ifdef DEBUG_BUILD
491 printf("WM_PAINT (0x%x)\n", hwnd);
492 fflush(stdout);
493 #endif
494 ps = WinBeginPaint(hwnd, 0, &rcl);
495 pVideo = FSLib_GetUserParm(hwnd);
496 if (pVideo) {
497 if (!pVideo->hidden->pSDLSurface) {
498 RECTL rclRect;
499 // So, don't blit now!
500 #ifdef DEBUG_BUILD
501 printf("WM_PAINT : Skipping blit while resizing (Pre!)!\n");
502 fflush(stdout);
503 #endif
504 WinQueryWindowRect(hwnd, &rclRect);
505 // Fill with black
506 WinFillRect(ps, &rclRect, CLR_BLACK);
507 } else {
508 if (DosRequestMutexSem
509 (pVideo->hidden->hmtxUseSrcBuffer, 1000) == NO_ERROR) {
510 int iTop, iLeft, iWidth, iHeight;
511 int iXScaleError, iYScaleError;
512 int iXScaleError2, iYScaleError2;
513 SWP swp;
514
515 // Re-blit the modified area!
516 // For this, we have to calculate the points, scaled!
517 WinQueryWindowPos(hwnd, &swp);
518 #ifdef DEBUG_BUILD
519 printf
520 ("WM_PAINT : WinSize: %d %d, BufSize: %d %d\n",
521 swp.cx, swp.cy,
522 pVideo->hidden->SrcBufferDesc.uiXResolution,
523 pVideo->hidden->SrcBufferDesc.uiYResolution);
524 fflush(stdout);
525 #endif
526
527 #ifndef RESIZE_EVEN_IF_RESIZABLE
528 // But only blit if the window is not resizable, or if
529 // the window is resizable and the source buffer size is the
530 // same as the destination buffer size!
531 if ((!pVideo->hidden->pSDLSurface) ||
532 ((pVideo->hidden->pSDLSurface) &&
533 (pVideo->hidden->pSDLSurface->flags & SDL_RESIZABLE)
534 &&
535 ((swp.cx !=
536 pVideo->hidden->SrcBufferDesc.uiXResolution)
537 || (swp.cy !=
538 pVideo->hidden->SrcBufferDesc.uiYResolution))
539 && (!FSLib_QueryFSMode(hwnd)))) {
540 RECTL rclRect;
541 // Resizable surface and in resizing!
542 // So, don't blit now!
543 #ifdef DEBUG_BUILD
544 printf("WM_PAINT : Skipping blit while resizing!\n");
545 fflush(stdout);
546 #endif
547 WinQueryWindowRect(hwnd, &rclRect);
548 // Fill with black
549 WinFillRect(ps, &rclRect, CLR_BLACK);
550 } else
551 #endif
552 {
553
554 iXScaleError =
555 (pVideo->hidden->SrcBufferDesc.
556 uiXResolution - 1) / swp.cx;
557 iYScaleError =
558 (pVideo->hidden->SrcBufferDesc.
559 uiYResolution - 1) / swp.cy;
560 if (iXScaleError < 0)
561 iXScaleError = 0;
562 if (iYScaleError < 0)
563 iYScaleError = 0;
564 iXScaleError2 =
565 (swp.cx -
566 1) /
567 (pVideo->hidden->SrcBufferDesc.uiXResolution);
568 iYScaleError2 =
569 (swp.cy -
570 1) /
571 (pVideo->hidden->SrcBufferDesc.uiYResolution);
572 if (iXScaleError2 < 0)
573 iXScaleError2 = 0;
574 if (iYScaleError2 < 0)
575 iYScaleError2 = 0;
576
577 iTop =
578 (swp.cy -
579 rcl.yTop) *
580 pVideo->hidden->SrcBufferDesc.
581 uiYResolution / swp.cy - iYScaleError;
582 iLeft =
583 rcl.xLeft *
584 pVideo->hidden->SrcBufferDesc.
585 uiXResolution / swp.cx - iXScaleError;
586 iWidth =
587 ((rcl.xRight -
588 rcl.xLeft) *
589 pVideo->hidden->SrcBufferDesc.
590 uiXResolution + swp.cx - 1) / swp.cx +
591 2 * iXScaleError;
592 iHeight =
593 ((rcl.yTop -
594 rcl.yBottom) *
595 pVideo->hidden->SrcBufferDesc.
596 uiYResolution + swp.cy - 1) / swp.cy +
597 2 * iYScaleError;
598
599 iWidth += iXScaleError2;
600 iHeight += iYScaleError2;
601
602 if (iTop < 0)
603 iTop = 0;
604 if (iLeft < 0)
605 iLeft = 0;
606 if (iTop + iHeight >
607 pVideo->hidden->SrcBufferDesc.uiYResolution)
608 iHeight =
609 pVideo->hidden->SrcBufferDesc.
610 uiYResolution - iTop;
611 if (iLeft + iWidth >
612 pVideo->hidden->SrcBufferDesc.uiXResolution)
613 iWidth =
614 pVideo->hidden->SrcBufferDesc.
615 uiXResolution - iLeft;
616
617 #ifdef DEBUG_BUILD
618 printf
619 ("WM_PAINT : BitBlt: %d %d -> %d %d (Buf %d x %d)\n",
620 iTop, iLeft, iWidth, iHeight,
621 pVideo->hidden->SrcBufferDesc.
622 uiXResolution,
623 pVideo->hidden->SrcBufferDesc.uiYResolution);
624 fflush(stdout);
625 #endif
626
627 FSLIB_BITBLT(hwnd,
628 pVideo->hidden->pchSrcBuffer,
629 iTop, iLeft, iWidth, iHeight);
630 }
631
632 DosReleaseMutexSem(pVideo->hidden->hmtxUseSrcBuffer);
633 }
634 }
635 }
636 #ifdef DEBUG_BUILD
637 else {
638 printf("WM_PAINT : No pVideo!\n");
639 fflush(stdout);
640 }
641 #endif
642 WinEndPaint(ps);
643 #ifdef DEBUG_BUILD
644 printf("WM_PAINT : Done.\n");
645 fflush(stdout);
646 #endif
647 return 0;
648
649 case WM_SIZE:
410 { 650 {
411 // A key has been released 651 #ifdef DEBUG_BUILD
412 SDL_keysym keysym; 652 printf("WM_SIZE : (%d %d)\n",
413 653 SHORT1FROMMP(mp2), SHORT2FROMMP(mp2));
414 #ifdef DEBUG_BUILD 654 fflush(stdout);
415 // printf("WM_CHAR, keyup, code is [0x%0x]\n", CHAR4FROMMP(mp1)); // HW scan code 655 #endif
416 #endif 656 iWindowSizeX = SHORT1FROMMP(mp2);
417 657 iWindowSizeY = SHORT2FROMMP(mp2);
418 // One problem is with F1, which gets only the keyup message because 658 bWindowResized = 1;
419 // it is a system key. 659
420 // So, when we get keyup message, we simulate keydown too! 660 // Make sure the window will be redrawn
421 // UPDATE: 661 WinInvalidateRegion(hwnd, NULL, TRUE);
422 // This problem should be solved now, that the accelerator keys are 662 }
423 // disabled for this window! 663 break;
424 /* 664
425 if (SHORT2FROMMP(mp2)==VK_F1) 665 case WM_FSLIBNOTIFICATION:
426 { 666 #ifdef DEBUG_BUILD
427 SDL_PrivateKeyboard(SDL_PRESSED, TranslateKey(SHORT2FROMMP(mp2), // VK_ code 667 printf("WM_FSLIBNOTIFICATION\n");
428 SHORT1FROMMP(mp2), // Character code 668 fflush(stdout);
429 CHAR4FROMMP(mp1), // HW Scan code 669 #endif
430 &keysym,0)); 670 if ((int) mp1 == FSLN_TOGGLEFSMODE) {
431 }*/ 671 // FS mode changed, reblit image!
432 672 pVideo = FSLib_GetUserParm(hwnd);
433 SDL_PrivateKeyboard(SDL_RELEASED, TranslateKey(SHORT2FROMMP(mp2), // VK_ code 673 if (pVideo) {
434 SHORT1FROMMP(mp2), // Character code 674 if (!pVideo->hidden->pSDLSurface) {
435 CHAR4FROMMP(mp1), // HW Scan code 675 // Resizable surface and in resizing!
436 &keysym,0)); 676 // So, don't blit now!
437 677 #ifdef DEBUG_BUILD
438 } else 678 printf
439 { 679 ("WM_FSLIBNOTIFICATION : Can not blit if there is no surface, doing nothing.\n");
440 // A key has been pressed 680 fflush(stdout);
441 SDL_keysym keysym; 681 #endif
442 682 } else {
443 #ifdef DEBUG_BUILD 683 if (DosRequestMutexSem
444 // printf("WM_CHAR, keydown, code is [0x%0x]\n", CHAR4FROMMP(mp1)); // HW scan code 684 (pVideo->hidden->hmtxUseSrcBuffer,
445 #endif 685 1000) == NO_ERROR) {
446 // Check for fastkeys: ALT+HOME to toggle FS mode 686 if (pVideo->hidden->pSDLSurface) {
447 // ALT+END to close app 687 #ifndef RESIZE_EVEN_IF_RESIZABLE
448 if ((SHORT1FROMMP(mp1) & KC_ALT) && 688 SWP swp;
449 (SHORT2FROMMP(mp2) == VK_HOME)) 689
450 { 690 // But only blit if the window is not resizable, or if
451 #ifdef DEBUG_BUILD 691 // the window is resizable and the source buffer size is the
452 printf(" Pressed ALT+HOME!\n"); fflush(stdout); 692 // same as the destination buffer size!
453 #endif 693 WinQueryWindowPos(hwnd, &swp);
454 // Only switch between fullscreen and back if it's not 694 if ((!pVideo->hidden->pSDLSurface) ||
455 // a resizable mode! 695 ((pVideo->hidden->pSDLSurface) &&
456 if ( 696 (pVideo->hidden->pSDLSurface->
457 (!pVideo->hidden->pSDLSurface) || 697 flags & SDL_RESIZABLE)
458 ((pVideo->hidden->pSDLSurface) 698 &&
459 && ((pVideo->hidden->pSDLSurface->flags & SDL_RESIZABLE)==0) 699 ((swp.cx !=
460 ) 700 pVideo->hidden->SrcBufferDesc.
461 ) 701 uiXResolution)
462 FSLib_ToggleFSMode(hwnd, !FSLib_QueryFSMode(hwnd)); 702 || (swp.cy !=
463 #ifdef DEBUG_BUILD 703 pVideo->hidden->
464 else 704 SrcBufferDesc.uiYResolution))
465 printf(" Resizable mode, so discarding ALT+HOME!\n"); fflush(stdout); 705 && (!FSLib_QueryFSMode(hwnd)))) {
466 #endif 706 // Resizable surface and in resizing!
467 } else 707 // So, don't blit now!
468 if ((SHORT1FROMMP(mp1) & KC_ALT) && 708 #ifdef DEBUG_BUILD
469 (SHORT2FROMMP(mp2) == VK_END)) 709 printf
470 { 710 ("WM_FSLIBNOTIFICATION : Cannot blit while resizing, doing nothing.\n");
471 #ifdef DEBUG_BUILD 711 fflush(stdout);
472 printf(" Pressed ALT+END!\n"); fflush(stdout); 712 #endif
473 #endif 713 } else
474 // Close window, and get out of loop! 714 #endif
475 // Also send event to SDL application, but we won't 715 {
476 // wait for it to be processed! 716 #ifdef DEBUG_BUILD
717 printf("WM_FSLIBNOTIFICATION : Blitting!\n");
718 fflush(stdout);
719 #endif
720 FSLIB_BITBLT(hwnd,
721 pVideo->hidden->
722 pchSrcBuffer, 0,
723 0,
724 pVideo->hidden->
725 SrcBufferDesc.
726 uiXResolution,
727 pVideo->hidden->
728 SrcBufferDesc.uiYResolution);
729 }
730 }
731 #ifdef DEBUG_BUILD
732 else
733 printf
734 ("WM_FSLIBNOTIFICATION : No public surface!\n");
735 fflush(stdout);
736 #endif
737
738 DosReleaseMutexSem(pVideo->hidden->hmtxUseSrcBuffer);
739 }
740 }
741 }
742 }
743 return (MPARAM) 1;
744
745 case WM_ACTIVATE:
746 #ifdef DEBUG_BUILD
747 printf("WM_ACTIVATE\n");
748 fflush(stdout);
749 #endif
750
751 pVideo = FSLib_GetUserParm(hwnd);
752 if (pVideo) {
753 pVideo->hidden->fInFocus = (int) mp1;
754 if (pVideo->hidden->fInFocus) {
755 // Went into focus
756 if ((pVideo->hidden->iMouseVisible)
757 && (!bMouseCaptured))
758 WinSetPointer(HWND_DESKTOP,
759 WinQuerySysPointer(HWND_DESKTOP,
760 SPTR_ARROW, FALSE));
761 else
762 WinSetPointer(HWND_DESKTOP, NULL);
763
764 if (bMouseCapturable) {
765 // Re-capture the mouse, if we captured it before!
766 WinSetCapture(HWND_DESKTOP, hwnd);
767 bMouseCaptured = 1;
768 {
769 SWP swpClient;
770 POINTL ptl;
771 // Center the mouse to the middle of the window!
772 WinQueryWindowPos(pVideo->hidden->hwndClient,
773 &swpClient);
774 ptl.x = 0;
775 ptl.y = 0;
776 WinMapWindowPoints(pVideo->hidden->
777 hwndClient, HWND_DESKTOP, &ptl, 1);
778 pVideo->hidden->iSkipWMMOUSEMOVE++; /* Don't take next WM_MOUSEMOVE into account! */
779 WinSetPointerPos(HWND_DESKTOP,
780 ptl.x + swpClient.cx / 2,
781 ptl.y + swpClient.cy / 2);
782 }
783 }
784 } else {
785 // Went out of focus
786 WinSetPointer(HWND_DESKTOP,
787 WinQuerySysPointer(HWND_DESKTOP,
788 SPTR_ARROW, FALSE));
789
790 if (bMouseCaptured) {
791 // Release the mouse
792 WinSetCapture(HWND_DESKTOP, hwnd);
793 bMouseCaptured = 0;
794 }
795 }
796 }
797 #ifdef DEBUG_BUILD
798 printf("WM_ACTIVATE done\n");
799 fflush(stdout);
800 #endif
801
802 break;
803
804 case WM_BUTTON1DOWN:
805 #ifdef DEBUG_BUILD
806 printf("WM_BUTTON1DOWN\n");
807 fflush(stdout);
808 #endif
809
810 pVideo = FSLib_GetUserParm(hwnd);
811 if (pVideo) {
812 SDL_PrivateMouseButton(SDL_PRESSED, SDL_BUTTON_LEFT, 0, 0); // Don't report mouse movement!
813
814 if (bMouseCapturable) {
815 // We should capture the mouse!
816 if (!bMouseCaptured) {
817 WinSetCapture(HWND_DESKTOP, hwnd);
818 WinSetPointer(HWND_DESKTOP, NULL);
819 bMouseCaptured = 1;
820 {
821 SWP swpClient;
822 POINTL ptl;
823 // Center the mouse to the middle of the window!
824 WinQueryWindowPos(pVideo->hidden->hwndClient,
825 &swpClient);
826 ptl.x = 0;
827 ptl.y = 0;
828 WinMapWindowPoints(pVideo->hidden->
829 hwndClient, HWND_DESKTOP, &ptl, 1);
830 pVideo->hidden->iSkipWMMOUSEMOVE++; /* Don't take next WM_MOUSEMOVE into account! */
831 WinSetPointerPos(HWND_DESKTOP,
832 ptl.x + swpClient.cx / 2,
833 ptl.y + swpClient.cy / 2);
834 }
835 }
836 }
837 }
838 break;
839 case WM_BUTTON1UP:
840 #ifdef DEBUG_BUILD
841 printf("WM_BUTTON1UP\n");
842 fflush(stdout);
843 #endif
844 SDL_PrivateMouseButton(SDL_RELEASED, SDL_BUTTON_LEFT, 0, 0); // Don't report mouse movement!
845 break;
846 case WM_BUTTON2DOWN:
847 #ifdef DEBUG_BUILD
848 printf("WM_BUTTON2DOWN\n");
849 fflush(stdout);
850 #endif
851
852 pVideo = FSLib_GetUserParm(hwnd);
853 if (pVideo) {
854 SDL_PrivateMouseButton(SDL_PRESSED, SDL_BUTTON_RIGHT, 0, 0); // Don't report mouse movement!
855
856 if (bMouseCapturable) {
857 // We should capture the mouse!
858 if (!bMouseCaptured) {
859 WinSetCapture(HWND_DESKTOP, hwnd);
860 WinSetPointer(HWND_DESKTOP, NULL);
861 bMouseCaptured = 1;
862 {
863 SWP swpClient;
864 POINTL ptl;
865 // Center the mouse to the middle of the window!
866 WinQueryWindowPos(pVideo->hidden->hwndClient,
867 &swpClient);
868 ptl.x = 0;
869 ptl.y = 0;
870 WinMapWindowPoints(pVideo->hidden->
871 hwndClient, HWND_DESKTOP, &ptl, 1);
872 pVideo->hidden->iSkipWMMOUSEMOVE++; /* Don't take next WM_MOUSEMOVE into account! */
873 WinSetPointerPos(HWND_DESKTOP,
874 ptl.x + swpClient.cx / 2,
875 ptl.y + swpClient.cy / 2);
876 }
877 }
878 }
879
880 }
881 break;
882 case WM_BUTTON2UP:
883 #ifdef DEBUG_BUILD
884 printf("WM_BUTTON2UP\n");
885 fflush(stdout);
886 #endif
887 SDL_PrivateMouseButton(SDL_RELEASED, SDL_BUTTON_RIGHT, 0, 0); // Don't report mouse movement!
888 break;
889 case WM_BUTTON3DOWN:
890 #ifdef DEBUG_BUILD
891 printf("WM_BUTTON3DOWN\n");
892 fflush(stdout);
893 #endif
894
895 pVideo = FSLib_GetUserParm(hwnd);
896 if (pVideo) {
897 SDL_PrivateMouseButton(SDL_PRESSED, SDL_BUTTON_MIDDLE, 0, 0); // Don't report mouse movement!
898
899 if (bMouseCapturable) {
900 // We should capture the mouse!
901 if (!bMouseCaptured) {
902 WinSetCapture(HWND_DESKTOP, hwnd);
903 WinSetPointer(HWND_DESKTOP, NULL);
904 bMouseCaptured = 1;
905 {
906 SWP swpClient;
907 POINTL ptl;
908 // Center the mouse to the middle of the window!
909 WinQueryWindowPos(pVideo->hidden->hwndClient,
910 &swpClient);
911 ptl.x = 0;
912 ptl.y = 0;
913 WinMapWindowPoints(pVideo->hidden->
914 hwndClient, HWND_DESKTOP, &ptl, 1);
915 pVideo->hidden->iSkipWMMOUSEMOVE++; /* Don't take next WM_MOUSEMOVE into account! */
916 WinSetPointerPos(HWND_DESKTOP,
917 ptl.x + swpClient.cx / 2,
918 ptl.y + swpClient.cy / 2);
919 }
920 }
921 }
922 }
923 break;
924 case WM_BUTTON3UP:
925 #ifdef DEBUG_BUILD
926 printf("WM_BUTTON3UP\n");
927 fflush(stdout);
928 #endif
929 SDL_PrivateMouseButton(SDL_RELEASED, SDL_BUTTON_MIDDLE, 0, 0); // Don't report mouse movement!
930 break;
931 case WM_MOUSEMOVE:
932 #ifdef DEBUG_BUILD
933 // printf("WM_MOUSEMOVE\n"); fflush(stdout);
934 #endif
935
936 pVideo = FSLib_GetUserParm(hwnd);
937 if (pVideo) {
938 if (pVideo->hidden->iSkipWMMOUSEMOVE) {
939 pVideo->hidden->iSkipWMMOUSEMOVE--;
940 } else {
941 POINTS *ppts = (POINTS *) (&mp1);
942 POINTL ptl;
943
944 if (bMouseCaptured) {
945 SWP swpClient;
946
947 WinQueryWindowPos(pVideo->hidden->hwndClient, &swpClient);
948
949 // Send relative mouse position, and re-center the mouse
950 // Reposition the mouse to the center of the screen/window
951 SDL_PrivateMouseMotion(0, // Buttons not changed
952 1, // Relative position
953 ppts->x -
954 (swpClient.cx / 2),
955 (swpClient.cy / 2) - ppts->y);
956
957 ptl.x = 0;
958 ptl.y = 0;
959 WinMapWindowPoints(pVideo->hidden->hwndClient,
960 HWND_DESKTOP, &ptl, 1);
961 pVideo->hidden->iSkipWMMOUSEMOVE++; /* Don't take next WM_MOUSEMOVE into account! */
962 // Center the mouse to the middle of the window!
963 WinSetPointerPos(HWND_DESKTOP,
964 ptl.x + swpClient.cx / 2,
965 ptl.y + swpClient.cy / 2);
966 } else {
967 CONVERTMOUSEPOSITION();
968
969 // Send absolute mouse position
970 SDL_PrivateMouseMotion(0, // Buttons not changed
971 0, // Absolute position
972 ppts->x, ppts->y);
973 }
974 }
975 if ((pVideo->hidden->iMouseVisible) && (!bMouseCaptured)) {
976 #ifdef DEBUG_BUILD
977 // printf("WM_MOUSEMOVE : ptr = %p\n", hptrGlobalPointer); fflush(stdout);
978 #endif
979
980 if (hptrGlobalPointer)
981 WinSetPointer(HWND_DESKTOP, hptrGlobalPointer);
982 else
983 WinSetPointer(HWND_DESKTOP,
984 WinQuerySysPointer(HWND_DESKTOP,
985 SPTR_ARROW, FALSE));
986 } else {
987 WinSetPointer(HWND_DESKTOP, NULL);
988 }
989 }
990 #ifdef DEBUG_BUILD
991 // printf("WM_MOUSEMOVE done\n"); fflush(stdout);
992 #endif
993
994 return (MRESULT) FALSE;
995 case WM_CLOSE: // Window close
996 #ifdef DEBUG_BUILD
997 printf("WM_CLOSE\n");
998 fflush(stdout);
999 #endif
1000
1001 pVideo = FSLib_GetUserParm(hwnd);
1002 if (pVideo) {
1003 // Send Quit message to the SDL application!
477 SDL_PrivateQuit(); 1004 SDL_PrivateQuit();
478 WinPostMsg(hwnd, WM_QUIT, 0, 0); 1005 return 0;
479 } else 1006 }
480 { 1007 break;
481
482 SDL_PrivateKeyboard(SDL_PRESSED, TranslateKey(SHORT2FROMMP(mp2), // VK_ code
483 SHORT1FROMMP(mp2), // Character code
484 CHAR4FROMMP(mp1), // HW Scan code
485 &keysym,1));
486
487 }
488 }
489 }
490 return (MRESULT) TRUE;
491
492 case WM_TRANSLATEACCEL:
493 {
494 PQMSG pqmsg;
495 pqmsg = (PQMSG) mp1;
496 if (mp1)
497 {
498 if (pqmsg->msg == WM_CHAR)
499 {
500 // WM_CHAR message!
501 // Let's filter the ALT keypress and all other acceleration keys!
502 return (MRESULT) FALSE;
503 }
504 }
505 break; // Default processing (pass to parent until frame control)
506 }
507
508 case WM_PAINT: // Window redraw!
509 #ifdef DEBUG_BUILD
510 printf("WM_PAINT (0x%x)\n", hwnd); fflush(stdout);
511 #endif
512 ps = WinBeginPaint(hwnd,0,&rcl);
513 pVideo = FSLib_GetUserParm(hwnd);
514 if (pVideo)
515 {
516 if (!pVideo->hidden->pSDLSurface)
517 {
518 RECTL rclRect;
519 // So, don't blit now!
520 #ifdef DEBUG_BUILD
521 printf("WM_PAINT : Skipping blit while resizing (Pre!)!\n"); fflush(stdout);
522 #endif
523 WinQueryWindowRect(hwnd, &rclRect);
524 // Fill with black
525 WinFillRect(ps, &rclRect, CLR_BLACK);
526 } else
527 {
528 if (DosRequestMutexSem(pVideo->hidden->hmtxUseSrcBuffer, 1000)==NO_ERROR)
529 {
530 int iTop, iLeft, iWidth, iHeight;
531 int iXScaleError, iYScaleError;
532 int iXScaleError2, iYScaleError2;
533 SWP swp;
534
535 // Re-blit the modified area!
536 // For this, we have to calculate the points, scaled!
537 WinQueryWindowPos(hwnd, &swp);
538 #ifdef DEBUG_BUILD
539 printf("WM_PAINT : WinSize: %d %d, BufSize: %d %d\n",
540 swp.cx,
541 swp.cy,
542 pVideo->hidden->SrcBufferDesc.uiXResolution,
543 pVideo->hidden->SrcBufferDesc.uiYResolution
544 );
545 fflush(stdout);
546 #endif
547
548 #ifndef RESIZE_EVEN_IF_RESIZABLE
549 // But only blit if the window is not resizable, or if
550 // the window is resizable and the source buffer size is the
551 // same as the destination buffer size!
552 if ((!pVideo->hidden->pSDLSurface) ||
553 ((pVideo->hidden->pSDLSurface) &&
554 (pVideo->hidden->pSDLSurface->flags & SDL_RESIZABLE) &&
555 ((swp.cx != pVideo->hidden->SrcBufferDesc.uiXResolution) ||
556 (swp.cy != pVideo->hidden->SrcBufferDesc.uiYResolution)
557 ) &&
558 (!FSLib_QueryFSMode(hwnd))
559 )
560 )
561 {
562 RECTL rclRect;
563 // Resizable surface and in resizing!
564 // So, don't blit now!
565 #ifdef DEBUG_BUILD
566 printf("WM_PAINT : Skipping blit while resizing!\n"); fflush(stdout);
567 #endif
568 WinQueryWindowRect(hwnd, &rclRect);
569 // Fill with black
570 WinFillRect(ps, &rclRect, CLR_BLACK);
571 } else
572 #endif
573 {
574
575 iXScaleError = (pVideo->hidden->SrcBufferDesc.uiXResolution-1) / swp.cx;
576 iYScaleError = (pVideo->hidden->SrcBufferDesc.uiYResolution-1) / swp.cy;
577 if (iXScaleError<0) iXScaleError = 0;
578 if (iYScaleError<0) iYScaleError = 0;
579 iXScaleError2 = (swp.cx-1)/(pVideo->hidden->SrcBufferDesc.uiXResolution);
580 iYScaleError2 = (swp.cy-1)/(pVideo->hidden->SrcBufferDesc.uiYResolution);
581 if (iXScaleError2<0) iXScaleError2 = 0;
582 if (iYScaleError2<0) iYScaleError2 = 0;
583
584 iTop = (swp.cy - rcl.yTop) * pVideo->hidden->SrcBufferDesc.uiYResolution / swp.cy - iYScaleError;
585 iLeft = rcl.xLeft * pVideo->hidden->SrcBufferDesc.uiXResolution / swp.cx - iXScaleError;
586 iWidth = ((rcl.xRight-rcl.xLeft) * pVideo->hidden->SrcBufferDesc.uiXResolution + swp.cx-1)
587 / swp.cx + 2*iXScaleError;
588 iHeight = ((rcl.yTop-rcl.yBottom) * pVideo->hidden->SrcBufferDesc.uiYResolution + swp.cy-1)
589 / swp.cy + 2*iYScaleError;
590
591 iWidth+=iXScaleError2;
592 iHeight+=iYScaleError2;
593
594 if (iTop<0) iTop = 0;
595 if (iLeft<0) iLeft = 0;
596 if (iTop+iHeight>pVideo->hidden->SrcBufferDesc.uiYResolution) iHeight = pVideo->hidden->SrcBufferDesc.uiYResolution-iTop;
597 if (iLeft+iWidth>pVideo->hidden->SrcBufferDesc.uiXResolution) iWidth = pVideo->hidden->SrcBufferDesc.uiXResolution-iLeft;
598
599 #ifdef DEBUG_BUILD
600 printf("WM_PAINT : BitBlt: %d %d -> %d %d (Buf %d x %d)\n",
601 iTop, iLeft, iWidth, iHeight,
602 pVideo->hidden->SrcBufferDesc.uiXResolution,
603 pVideo->hidden->SrcBufferDesc.uiYResolution
604 );
605 fflush(stdout);
606 #endif
607
608 FSLIB_BITBLT(hwnd, pVideo->hidden->pchSrcBuffer, iTop, iLeft, iWidth, iHeight);
609 }
610
611 DosReleaseMutexSem(pVideo->hidden->hmtxUseSrcBuffer);
612 }
613 }
614 }
615 #ifdef DEBUG_BUILD
616 else
617 {
618 printf("WM_PAINT : No pVideo!\n"); fflush(stdout);
619 }
620 #endif
621 WinEndPaint(ps);
622 #ifdef DEBUG_BUILD
623 printf("WM_PAINT : Done.\n");
624 fflush(stdout);
625 #endif
626 return 0;
627
628 case WM_SIZE:
629 {
630 #ifdef DEBUG_BUILD
631 printf("WM_SIZE : (%d %d)\n",
632 SHORT1FROMMP(mp2), SHORT2FROMMP(mp2)); fflush(stdout);
633 #endif
634 iWindowSizeX = SHORT1FROMMP(mp2);
635 iWindowSizeY = SHORT2FROMMP(mp2);
636 bWindowResized = 1;
637
638 // Make sure the window will be redrawn
639 WinInvalidateRegion(hwnd, NULL, TRUE);
640 }
641 break;
642
643 case WM_FSLIBNOTIFICATION:
644 #ifdef DEBUG_BUILD
645 printf("WM_FSLIBNOTIFICATION\n"); fflush(stdout);
646 #endif
647 if ((int)mp1 == FSLN_TOGGLEFSMODE)
648 {
649 // FS mode changed, reblit image!
650 pVideo = FSLib_GetUserParm(hwnd);
651 if (pVideo)
652 {
653 if (!pVideo->hidden->pSDLSurface)
654 {
655 // Resizable surface and in resizing!
656 // So, don't blit now!
657 #ifdef DEBUG_BUILD
658 printf("WM_FSLIBNOTIFICATION : Can not blit if there is no surface, doing nothing.\n"); fflush(stdout);
659 #endif
660 } else
661 {
662 if (DosRequestMutexSem(pVideo->hidden->hmtxUseSrcBuffer, 1000)==NO_ERROR)
663 {
664 if (pVideo->hidden->pSDLSurface)
665 {
666 #ifndef RESIZE_EVEN_IF_RESIZABLE
667 SWP swp;
668
669 // But only blit if the window is not resizable, or if
670 // the window is resizable and the source buffer size is the
671 // same as the destination buffer size!
672 WinQueryWindowPos(hwnd, &swp);
673 if ((!pVideo->hidden->pSDLSurface) ||
674 (
675 (pVideo->hidden->pSDLSurface) &&
676 (pVideo->hidden->pSDLSurface->flags & SDL_RESIZABLE) &&
677 ((swp.cx != pVideo->hidden->SrcBufferDesc.uiXResolution) ||
678 (swp.cy != pVideo->hidden->SrcBufferDesc.uiYResolution)
679 ) &&
680 (!FSLib_QueryFSMode(hwnd))
681 )
682 )
683 {
684 // Resizable surface and in resizing!
685 // So, don't blit now!
686 #ifdef DEBUG_BUILD
687 printf("WM_FSLIBNOTIFICATION : Cannot blit while resizing, doing nothing.\n"); fflush(stdout);
688 #endif
689 } else
690 #endif
691 {
692 #ifdef DEBUG_BUILD
693 printf("WM_FSLIBNOTIFICATION : Blitting!\n"); fflush(stdout);
694 #endif
695 FSLIB_BITBLT(hwnd, pVideo->hidden->pchSrcBuffer,
696 0, 0,
697 pVideo->hidden->SrcBufferDesc.uiXResolution,
698 pVideo->hidden->SrcBufferDesc.uiYResolution);
699 }
700 }
701 #ifdef DEBUG_BUILD
702 else
703 printf("WM_FSLIBNOTIFICATION : No public surface!\n"); fflush(stdout);
704 #endif
705
706 DosReleaseMutexSem(pVideo->hidden->hmtxUseSrcBuffer);
707 }
708 }
709 }
710 }
711 return (MPARAM) 1;
712
713 case WM_ACTIVATE:
714 #ifdef DEBUG_BUILD
715 printf("WM_ACTIVATE\n"); fflush(stdout);
716 #endif
717
718 pVideo = FSLib_GetUserParm(hwnd);
719 if (pVideo)
720 {
721 pVideo->hidden->fInFocus = (int) mp1;
722 if (pVideo->hidden->fInFocus)
723 {
724 // Went into focus
725 if ((pVideo->hidden->iMouseVisible) && (!bMouseCaptured))
726 WinSetPointer(HWND_DESKTOP, WinQuerySysPointer(HWND_DESKTOP, SPTR_ARROW, FALSE));
727 else
728 WinSetPointer(HWND_DESKTOP, NULL);
729
730 if (bMouseCapturable)
731 {
732 // Re-capture the mouse, if we captured it before!
733 WinSetCapture(HWND_DESKTOP, hwnd);
734 bMouseCaptured = 1;
735 {
736 SWP swpClient;
737 POINTL ptl;
738 // Center the mouse to the middle of the window!
739 WinQueryWindowPos(pVideo->hidden->hwndClient, &swpClient);
740 ptl.x = 0; ptl.y = 0;
741 WinMapWindowPoints(pVideo->hidden->hwndClient, HWND_DESKTOP, &ptl, 1);
742 pVideo->hidden->iSkipWMMOUSEMOVE++; /* Don't take next WM_MOUSEMOVE into account! */
743 WinSetPointerPos(HWND_DESKTOP,
744 ptl.x + swpClient.cx/2,
745 ptl.y + swpClient.cy/2);
746 }
747 }
748 } else
749 {
750 // Went out of focus
751 WinSetPointer(HWND_DESKTOP, WinQuerySysPointer(HWND_DESKTOP, SPTR_ARROW, FALSE));
752
753 if (bMouseCaptured)
754 {
755 // Release the mouse
756 WinSetCapture(HWND_DESKTOP, hwnd);
757 bMouseCaptured = 0;
758 }
759 }
760 }
761 #ifdef DEBUG_BUILD
762 printf("WM_ACTIVATE done\n"); fflush(stdout);
763 #endif
764
765 break;
766
767 case WM_BUTTON1DOWN:
768 #ifdef DEBUG_BUILD
769 printf("WM_BUTTON1DOWN\n"); fflush(stdout);
770 #endif
771
772 pVideo = FSLib_GetUserParm(hwnd);
773 if (pVideo)
774 {
775 SDL_PrivateMouseButton(SDL_PRESSED,
776 SDL_BUTTON_LEFT,
777 0, 0); // Don't report mouse movement!
778
779 if (bMouseCapturable)
780 {
781 // We should capture the mouse!
782 if (!bMouseCaptured)
783 {
784 WinSetCapture(HWND_DESKTOP, hwnd);
785 WinSetPointer(HWND_DESKTOP, NULL);
786 bMouseCaptured = 1;
787 {
788 SWP swpClient;
789 POINTL ptl;
790 // Center the mouse to the middle of the window!
791 WinQueryWindowPos(pVideo->hidden->hwndClient, &swpClient);
792 ptl.x = 0; ptl.y = 0;
793 WinMapWindowPoints(pVideo->hidden->hwndClient, HWND_DESKTOP, &ptl, 1);
794 pVideo->hidden->iSkipWMMOUSEMOVE++; /* Don't take next WM_MOUSEMOVE into account! */
795 WinSetPointerPos(HWND_DESKTOP,
796 ptl.x + swpClient.cx/2,
797 ptl.y + swpClient.cy/2);
798 }
799 }
800 }
801 }
802 break;
803 case WM_BUTTON1UP:
804 #ifdef DEBUG_BUILD
805 printf("WM_BUTTON1UP\n"); fflush(stdout);
806 #endif
807 SDL_PrivateMouseButton(SDL_RELEASED,
808 SDL_BUTTON_LEFT,
809 0, 0); // Don't report mouse movement!
810 break;
811 case WM_BUTTON2DOWN:
812 #ifdef DEBUG_BUILD
813 printf("WM_BUTTON2DOWN\n"); fflush(stdout);
814 #endif
815
816 pVideo = FSLib_GetUserParm(hwnd);
817 if (pVideo)
818 {
819 SDL_PrivateMouseButton(SDL_PRESSED,
820 SDL_BUTTON_RIGHT,
821 0, 0); // Don't report mouse movement!
822
823 if (bMouseCapturable)
824 {
825 // We should capture the mouse!
826 if (!bMouseCaptured)
827 {
828 WinSetCapture(HWND_DESKTOP, hwnd);
829 WinSetPointer(HWND_DESKTOP, NULL);
830 bMouseCaptured = 1;
831 {
832 SWP swpClient;
833 POINTL ptl;
834 // Center the mouse to the middle of the window!
835 WinQueryWindowPos(pVideo->hidden->hwndClient, &swpClient);
836 ptl.x = 0; ptl.y = 0;
837 WinMapWindowPoints(pVideo->hidden->hwndClient, HWND_DESKTOP, &ptl, 1);
838 pVideo->hidden->iSkipWMMOUSEMOVE++; /* Don't take next WM_MOUSEMOVE into account! */
839 WinSetPointerPos(HWND_DESKTOP,
840 ptl.x + swpClient.cx/2,
841 ptl.y + swpClient.cy/2);
842 }
843 }
844 }
845
846 }
847 break;
848 case WM_BUTTON2UP:
849 #ifdef DEBUG_BUILD
850 printf("WM_BUTTON2UP\n"); fflush(stdout);
851 #endif
852 SDL_PrivateMouseButton(SDL_RELEASED,
853 SDL_BUTTON_RIGHT,
854 0, 0); // Don't report mouse movement!
855 break;
856 case WM_BUTTON3DOWN:
857 #ifdef DEBUG_BUILD
858 printf("WM_BUTTON3DOWN\n"); fflush(stdout);
859 #endif
860
861 pVideo = FSLib_GetUserParm(hwnd);
862 if (pVideo)
863 {
864 SDL_PrivateMouseButton(SDL_PRESSED,
865 SDL_BUTTON_MIDDLE,
866 0, 0); // Don't report mouse movement!
867
868 if (bMouseCapturable)
869 {
870 // We should capture the mouse!
871 if (!bMouseCaptured)
872 {
873 WinSetCapture(HWND_DESKTOP, hwnd);
874 WinSetPointer(HWND_DESKTOP, NULL);
875 bMouseCaptured = 1;
876 {
877 SWP swpClient;
878 POINTL ptl;
879 // Center the mouse to the middle of the window!
880 WinQueryWindowPos(pVideo->hidden->hwndClient, &swpClient);
881 ptl.x = 0; ptl.y = 0;
882 WinMapWindowPoints(pVideo->hidden->hwndClient, HWND_DESKTOP, &ptl, 1);
883 pVideo->hidden->iSkipWMMOUSEMOVE++; /* Don't take next WM_MOUSEMOVE into account! */
884 WinSetPointerPos(HWND_DESKTOP,
885 ptl.x + swpClient.cx/2,
886 ptl.y + swpClient.cy/2);
887 }
888 }
889 }
890 }
891 break;
892 case WM_BUTTON3UP:
893 #ifdef DEBUG_BUILD
894 printf("WM_BUTTON3UP\n"); fflush(stdout);
895 #endif
896 SDL_PrivateMouseButton(SDL_RELEASED,
897 SDL_BUTTON_MIDDLE,
898 0, 0); // Don't report mouse movement!
899 break;
900 case WM_MOUSEMOVE:
901 #ifdef DEBUG_BUILD
902 // printf("WM_MOUSEMOVE\n"); fflush(stdout);
903 #endif
904
905 pVideo = FSLib_GetUserParm(hwnd);
906 if (pVideo)
907 {
908 if (pVideo->hidden->iSkipWMMOUSEMOVE)
909 {
910 pVideo->hidden->iSkipWMMOUSEMOVE--;
911 } else
912 {
913 POINTS *ppts = (POINTS *) (&mp1);
914 POINTL ptl;
915
916 if (bMouseCaptured)
917 {
918 SWP swpClient;
919
920 WinQueryWindowPos(pVideo->hidden->hwndClient, &swpClient);
921
922 // Send relative mouse position, and re-center the mouse
923 // Reposition the mouse to the center of the screen/window
924 SDL_PrivateMouseMotion(0, // Buttons not changed
925 1, // Relative position
926 ppts->x - (swpClient.cx/2),
927 (swpClient.cy/2) - ppts->y);
928
929 ptl.x = 0; ptl.y = 0;
930 WinMapWindowPoints(pVideo->hidden->hwndClient, HWND_DESKTOP, &ptl, 1);
931 pVideo->hidden->iSkipWMMOUSEMOVE++; /* Don't take next WM_MOUSEMOVE into account! */
932 // Center the mouse to the middle of the window!
933 WinSetPointerPos(HWND_DESKTOP,
934 ptl.x + swpClient.cx/2,
935 ptl.y + swpClient.cy/2);
936 } else
937 {
938 CONVERTMOUSEPOSITION();
939
940 // Send absolute mouse position
941 SDL_PrivateMouseMotion(0, // Buttons not changed
942 0, // Absolute position
943 ppts->x,
944 ppts->y);
945 }
946 }
947 if ((pVideo->hidden->iMouseVisible) && (!bMouseCaptured))
948 {
949 #ifdef DEBUG_BUILD
950 // printf("WM_MOUSEMOVE : ptr = %p\n", hptrGlobalPointer); fflush(stdout);
951 #endif
952
953 if (hptrGlobalPointer)
954 WinSetPointer(HWND_DESKTOP, hptrGlobalPointer);
955 else
956 WinSetPointer(HWND_DESKTOP, WinQuerySysPointer(HWND_DESKTOP, SPTR_ARROW, FALSE));
957 }
958 else
959 {
960 WinSetPointer(HWND_DESKTOP, NULL);
961 }
962 }
963 #ifdef DEBUG_BUILD
964 // printf("WM_MOUSEMOVE done\n"); fflush(stdout);
965 #endif
966
967 return (MRESULT) FALSE;
968 case WM_CLOSE: // Window close
969 #ifdef DEBUG_BUILD
970 printf("WM_CLOSE\n"); fflush(stdout);
971 #endif
972
973 pVideo = FSLib_GetUserParm(hwnd);
974 if (pVideo)
975 {
976 // Send Quit message to the SDL application!
977 SDL_PrivateQuit();
978 return 0;
979 }
980 break;
981 1008
982 #ifdef BITBLT_IN_WINMESSAGEPROC 1009 #ifdef BITBLT_IN_WINMESSAGEPROC
983 case WM_UPDATERECTSREQUEST: 1010 case WM_UPDATERECTSREQUEST:
984 pVideo = FSLib_GetUserParm(hwnd); 1011 pVideo = FSLib_GetUserParm(hwnd);
985 if ((pVideo) && (pVideo->hidden->pSDLSurface)) 1012 if ((pVideo) && (pVideo->hidden->pSDLSurface)) {
986 { 1013 if (DosRequestMutexSem
987 if (DosRequestMutexSem(pVideo->hidden->hmtxUseSrcBuffer, SEM_INDEFINITE_WAIT)==NO_ERROR) 1014 (pVideo->hidden->hmtxUseSrcBuffer,
988 { 1015 SEM_INDEFINITE_WAIT) == NO_ERROR) {
989 int numrects; 1016 int numrects;
990 SDL_Rect *rects; 1017 SDL_Rect *rects;
991 int i; 1018 int i;
992 SWP swp; 1019 SWP swp;
993 1020
994 numrects = (int) mp1; 1021 numrects = (int) mp1;
995 rects = (SDL_Rect *) mp2; 1022 rects = (SDL_Rect *) mp2;
996 1023
997 WinQueryWindowPos(hwnd, &swp); 1024 WinQueryWindowPos(hwnd, &swp);
998 #ifndef RESIZE_EVEN_IF_RESIZABLE 1025 #ifndef RESIZE_EVEN_IF_RESIZABLE
999 if ((!pVideo->hidden->pSDLSurface) || 1026 if ((!pVideo->hidden->pSDLSurface) ||
1000 ( 1027 ((pVideo->hidden->pSDLSurface) &&
1001 (pVideo->hidden->pSDLSurface) && 1028 (pVideo->hidden->pSDLSurface->flags & SDL_RESIZABLE)
1002 (pVideo->hidden->pSDLSurface->flags & SDL_RESIZABLE) && 1029 &&
1003 ((swp.cx != pVideo->hidden->SrcBufferDesc.uiXResolution) || 1030 ((swp.cx != pVideo->hidden->SrcBufferDesc.uiXResolution)
1004 (swp.cy != pVideo->hidden->SrcBufferDesc.uiYResolution) 1031 || (swp.cy !=
1005 ) && 1032 pVideo->hidden->SrcBufferDesc.uiYResolution))
1006 (!FSLib_QueryFSMode(hwnd)) 1033 && (!FSLib_QueryFSMode(hwnd)))) {
1007 ) 1034 // Resizable surface and in resizing!
1008 ) 1035 // So, don't blit now!
1009 { 1036 #ifdef DEBUG_BUILD
1010 // Resizable surface and in resizing! 1037 printf
1011 // So, don't blit now! 1038 ("[WM_UPDATERECTSREQUEST] : Skipping blit while resizing!\n");
1012 #ifdef DEBUG_BUILD 1039 fflush(stdout);
1013 printf("[WM_UPDATERECTSREQUEST] : Skipping blit while resizing!\n"); fflush(stdout); 1040 #endif
1014 #endif 1041 } else
1015 } else 1042 #endif
1016 #endif 1043 {
1017 { 1044 #ifdef DEBUG_BUILD
1018 #ifdef DEBUG_BUILD 1045 printf("[WM_UPDATERECTSREQUEST] : Blitting!\n");
1019 printf("[WM_UPDATERECTSREQUEST] : Blitting!\n"); fflush(stdout); 1046 fflush(stdout);
1020 #endif 1047 #endif
1021 1048
1022 // Blit the changed areas 1049 // Blit the changed areas
1023 for (i=0; i<numrects; i++) 1050 for (i = 0; i < numrects; i++)
1024 FSLIB_BITBLT(hwnd, pVideo->hidden->pchSrcBuffer, 1051 FSLIB_BITBLT(hwnd,
1025 rects[i].y, rects[i].x, rects[i].w, rects[i].h); 1052 pVideo->hidden->pchSrcBuffer,
1026 } 1053 rects[i].y, rects[i].x,
1027 DosReleaseMutexSem(pVideo->hidden->hmtxUseSrcBuffer); 1054 rects[i].w, rects[i].h);
1028 } 1055 }
1029 } 1056 DosReleaseMutexSem(pVideo->hidden->hmtxUseSrcBuffer);
1030 return 0; 1057 }
1058 }
1059 return 0;
1031 #endif 1060 #endif
1032 1061
1033 default: 1062 default:
1034 #ifdef DEBUG_BUILD 1063 #ifdef DEBUG_BUILD
1035 printf("Unhandled: %x\n", msg); fflush(stdout); 1064 printf("Unhandled: %x\n", msg);
1036 #endif 1065 fflush(stdout);
1037 1066 #endif
1038 break; 1067
1039 } 1068 break;
1040 // Run the default window procedure for unhandled stuffs 1069 }
1041 return WinDefWindowProc(hwnd, msg, mp1, mp2); 1070 // Run the default window procedure for unhandled stuffs
1071 return WinDefWindowProc(hwnd, msg, mp1, mp2);
1042 } 1072 }
1043 1073
1044 ///////////////////////////////////////////////////////////////////// 1074 /////////////////////////////////////////////////////////////////////
1045 // 1075 //
1046 // FrameWndProc 1076 // FrameWndProc
1047 // 1077 //
1048 // This is the message processing window procedure for the 1078 // This is the message processing window procedure for the
1049 // frame window of SDLWindowClass. 1079 // frame window of SDLWindowClass.
1050 // 1080 //
1051 ///////////////////////////////////////////////////////////////////// 1081 /////////////////////////////////////////////////////////////////////
1052 static MRESULT EXPENTRY FrameWndProc( HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2) 1082 static MRESULT EXPENTRY
1053 { 1083 FrameWndProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
1054 PFNWP pOldFrameProc; 1084 {
1055 MRESULT result; 1085 PFNWP pOldFrameProc;
1056 PTRACKINFO ti; 1086 MRESULT result;
1057 int cx, cy, ncx, ncy; 1087 PTRACKINFO ti;
1058 RECTL rclTemp; 1088 int cx, cy, ncx, ncy;
1059 PSWP pswpTemp; 1089 RECTL rclTemp;
1060 1090 PSWP pswpTemp;
1061 SDL_VideoDevice *pVideo = NULL; 1091
1062 1092 SDL_VideoDevice *pVideo = NULL;
1063 pVideo = (SDL_VideoDevice *) WinQueryWindowULong(hwnd, QWL_USER); 1093
1064 1094 pVideo = (SDL_VideoDevice *) WinQueryWindowULong(hwnd, QWL_USER);
1065 pOldFrameProc = pVideo->hidden->pfnOldFrameProc; 1095
1066 1096 pOldFrameProc = pVideo->hidden->pfnOldFrameProc;
1067 if ((pVideo->hidden->bProportionalResize) && 1097
1068 (msg==WM_ADJUSTWINDOWPOS) && 1098 if ((pVideo->hidden->bProportionalResize) &&
1069 (!FSLib_QueryFSMode(pVideo->hidden->hwndClient)) 1099 (msg == WM_ADJUSTWINDOWPOS) &&
1070 ) 1100 (!FSLib_QueryFSMode(pVideo->hidden->hwndClient))) {
1071 { 1101 pswpTemp = (PSWP) mp1;
1072 pswpTemp = (PSWP) mp1; 1102
1073 1103 /* Resizing? */
1074 /* Resizing? */ 1104 if (pswpTemp->fl & SWP_SIZE) {
1075 if (pswpTemp->fl & SWP_SIZE) 1105 /* Calculate client size */
1076 { 1106 rclTemp.xLeft = pswpTemp->x;
1077 /* Calculate client size */ 1107 rclTemp.xRight = pswpTemp->x + pswpTemp->cx;
1078 rclTemp.xLeft = pswpTemp->x; 1108 rclTemp.yBottom = pswpTemp->y;
1079 rclTemp.xRight = pswpTemp->x + pswpTemp->cx; 1109 rclTemp.yTop = pswpTemp->y + pswpTemp->cy;
1080 rclTemp.yBottom = pswpTemp->y; 1110 WinCalcFrameRect(hwnd, &rclTemp, TRUE);
1081 rclTemp.yTop = pswpTemp->y + pswpTemp->cy; 1111
1082 WinCalcFrameRect(hwnd, &rclTemp, TRUE); 1112 ncx = cx = rclTemp.xRight - rclTemp.xLeft;
1083 1113 ncy = cy = rclTemp.yTop - rclTemp.yBottom;
1084 ncx = cx = rclTemp.xRight - rclTemp.xLeft; 1114
1085 ncy = cy = rclTemp.yTop - rclTemp.yBottom; 1115 /* Calculate new size to keep it proportional */
1086 1116
1087 /* Calculate new size to keep it proportional */ 1117 if ((pVideo->hidden->ulResizingFlag & TF_LEFT)
1088 1118 || (pVideo->hidden->ulResizingFlag & TF_RIGHT)) {
1089 if ((pVideo->hidden->ulResizingFlag & TF_LEFT) || (pVideo->hidden->ulResizingFlag & TF_RIGHT)) 1119 /* The window is resized horizontally */
1090 { 1120 ncy =
1091 /* The window is resized horizontally */ 1121 pVideo->hidden->SrcBufferDesc.uiYResolution * cx /
1092 ncy = pVideo->hidden->SrcBufferDesc.uiYResolution * cx / pVideo->hidden->SrcBufferDesc.uiXResolution; 1122 pVideo->hidden->SrcBufferDesc.uiXResolution;
1093 } else 1123 } else if ((pVideo->hidden->ulResizingFlag & TF_TOP)
1094 if ((pVideo->hidden->ulResizingFlag & TF_TOP) || (pVideo->hidden->ulResizingFlag & TF_BOTTOM)) 1124 || (pVideo->hidden->ulResizingFlag & TF_BOTTOM)) {
1095 { 1125 /* The window is resized vertically */
1096 /* The window is resized vertically */ 1126 ncx =
1097 ncx = pVideo->hidden->SrcBufferDesc.uiXResolution * cy / pVideo->hidden->SrcBufferDesc.uiYResolution; 1127 pVideo->hidden->SrcBufferDesc.uiXResolution * cy /
1098 } 1128 pVideo->hidden->SrcBufferDesc.uiYResolution;
1099 1129 }
1100 /* Calculate back frame coordinates */ 1130
1101 rclTemp.xLeft = pswpTemp->x; 1131 /* Calculate back frame coordinates */
1102 rclTemp.xRight = pswpTemp->x + ncx; 1132 rclTemp.xLeft = pswpTemp->x;
1103 rclTemp.yBottom = pswpTemp->y; 1133 rclTemp.xRight = pswpTemp->x + ncx;
1104 rclTemp.yTop = pswpTemp->y + ncy; 1134 rclTemp.yBottom = pswpTemp->y;
1105 WinCalcFrameRect(hwnd, &rclTemp, FALSE); 1135 rclTemp.yTop = pswpTemp->y + ncy;
1106 1136 WinCalcFrameRect(hwnd, &rclTemp, FALSE);
1107 /* Store new size/position info */ 1137
1108 pswpTemp->cx = rclTemp.xRight - rclTemp.xLeft; 1138 /* Store new size/position info */
1109 1139 pswpTemp->cx = rclTemp.xRight - rclTemp.xLeft;
1110 if (!(pVideo->hidden->ulResizingFlag & TF_TOP)) 1140
1111 { 1141 if (!(pVideo->hidden->ulResizingFlag & TF_TOP)) {
1112 pswpTemp->y = pswpTemp->y + pswpTemp->cy - (rclTemp.yTop - rclTemp.yBottom); 1142 pswpTemp->y =
1113 pswpTemp->cy = rclTemp.yTop - rclTemp.yBottom; 1143 pswpTemp->y + pswpTemp->cy - (rclTemp.yTop -
1114 } else 1144 rclTemp.yBottom);
1115 { 1145 pswpTemp->cy = rclTemp.yTop - rclTemp.yBottom;
1116 pswpTemp->cy = rclTemp.yTop - rclTemp.yBottom; 1146 } else {
1117 } 1147 pswpTemp->cy = rclTemp.yTop - rclTemp.yBottom;
1118 } 1148 }
1119 } 1149 }
1120 1150 }
1121 result = (*pOldFrameProc)(hwnd, msg, mp1, mp2); 1151
1122 1152 result = (*pOldFrameProc) (hwnd, msg, mp1, mp2);
1123 if ((pVideo->hidden->bProportionalResize) && (msg==WM_QUERYTRACKINFO)) 1153
1124 { 1154 if ((pVideo->hidden->bProportionalResize) && (msg == WM_QUERYTRACKINFO)) {
1125 ti = (PTRACKINFO) mp2; 1155 ti = (PTRACKINFO) mp2;
1126 1156
1127 /* Store the direction of resizing */ 1157 /* Store the direction of resizing */
1128 if ((ti->fs & TF_LEFT) || (ti->fs & TF_RIGHT) || 1158 if ((ti->fs & TF_LEFT) || (ti->fs & TF_RIGHT) ||
1129 (ti->fs & TF_TOP) || (ti->fs & TF_BOTTOM)) 1159 (ti->fs & TF_TOP) || (ti->fs & TF_BOTTOM))
1130 pVideo->hidden->ulResizingFlag = ti->fs; 1160 pVideo->hidden->ulResizingFlag = ti->fs;
1131 } 1161 }
1132 1162
1133 return result; 1163 return result;
1134 } 1164 }
1135 1165
1136 ///////////////////////////////////////////////////////////////////// 1166 /////////////////////////////////////////////////////////////////////
1137 // 1167 //
1138 // PMThreadFunc 1168 // PMThreadFunc
1139 // 1169 //
1140 // This function implements the PM-Thread, which initializes the 1170 // This function implements the PM-Thread, which initializes the
1141 // application window itself, the DIVE, and start message processing. 1171 // application window itself, the DIVE, and start message processing.
1142 // 1172 //
1143 ///////////////////////////////////////////////////////////////////// 1173 /////////////////////////////////////////////////////////////////////
1144 int iNumOfPMThreadInstances = 0; // Global! 1174 int iNumOfPMThreadInstances = 0; // Global!
1145 static void PMThreadFunc(void *pParm) 1175 static void
1146 { 1176 PMThreadFunc(void *pParm)
1147 SDL_VideoDevice *pVideo = pParm; 1177 {
1148 HAB hab; 1178 SDL_VideoDevice *pVideo = pParm;
1149 HMQ hmq; 1179 HAB hab;
1150 QMSG msg; 1180 HMQ hmq;
1151 ULONG fcf; 1181 QMSG msg;
1152 1182 ULONG fcf;
1153 #ifdef DEBUG_BUILD 1183
1154 printf("[PMThreadFunc] : Starting\n"); fflush(stdout); 1184 #ifdef DEBUG_BUILD
1155 #endif 1185 printf("[PMThreadFunc] : Starting\n");
1156
1157 iNumOfPMThreadInstances++;
1158
1159 // Initialize PM, create a message queue.
1160
1161 hab=WinInitialize(0);
1162 hmq=WinCreateMsgQueue(hab,0);
1163 if (hmq==0)
1164 {
1165 #ifdef DEBUG_BUILD
1166 printf("[PMThreadFunc] : Could not create message queue!\n");
1167 printf(" It might be that the application using SDL is not a PM app!\n");
1168 fflush(stdout); 1186 fflush(stdout);
1169 #endif 1187 #endif
1170 pVideo->hidden->iPMThreadStatus = 2; 1188
1171 } else 1189 iNumOfPMThreadInstances++;
1172 { 1190
1173 int rc; 1191 // Initialize PM, create a message queue.
1174 RECTL rectl; 1192
1175 1193 hab = WinInitialize(0);
1176 fcf = ulFCFToUse; // Get from global setting 1194 hmq = WinCreateMsgQueue(hab, 0);
1177 1195 if (hmq == 0) {
1178 #ifdef DEBUG_BUILD 1196 #ifdef DEBUG_BUILD
1179 printf("[PMThreadFunc] : FSLib_CreateWindow()!\n"); 1197 printf("[PMThreadFunc] : Could not create message queue!\n");
1198 printf
1199 (" It might be that the application using SDL is not a PM app!\n");
1200 fflush(stdout);
1201 #endif
1202 pVideo->hidden->iPMThreadStatus = 2;
1203 } else {
1204 int rc;
1205 RECTL rectl;
1206
1207 fcf = ulFCFToUse; // Get from global setting
1208
1209 #ifdef DEBUG_BUILD
1210 printf("[PMThreadFunc] : FSLib_CreateWindow()!\n");
1211 fflush(stdout);
1212 #endif
1213
1214 rc = FSLib_CreateWindow(HWND_DESKTOP, 0, &fcf,
1215 "SDL Application",
1216 NULLHANDLE, 0,
1217 &(pVideo->hidden->SrcBufferDesc),
1218 WndProc,
1219 &(pVideo->hidden->hwndClient),
1220 &(pVideo->hidden->hwndFrame));
1221
1222 #ifdef DEBUG_BUILD
1223 printf("[PMThreadFunc] : FSLib_CreateWindow() rc = %d\n", rc);
1224 fflush(stdout);
1225 #endif
1226
1227 if (!rc) {
1228 #ifdef DEBUG_BUILD
1229 printf("[PMThreadFunc] : Could not create FSLib window!\n");
1230 fflush(stdout);
1231 #endif
1232 pVideo->hidden->iPMThreadStatus = 3;
1233 } else {
1234 #ifdef DEBUG_BUILD
1235 printf("[PMThreadFunc] : FSLib_AddUserParm()!\n");
1236 fflush(stdout);
1237 #endif
1238
1239 // Store pVideo pointer in window data for client window, so
1240 // it will know the instance to which it belongs to.
1241 FSLib_AddUserParm(pVideo->hidden->hwndClient, pVideo);
1242
1243 // Now set default image width height and fourcc!
1244 #ifdef DEBUG_BUILD
1245 printf("[PMThreadFunc] : SetWindowPos()!\n");
1246 fflush(stdout);
1247 #endif
1248
1249 // Set the position and size of the main window,
1250 // and make it visible!
1251 // Calculate frame window size from client window size
1252 rectl.xLeft = 0;
1253 rectl.yBottom = 0;
1254 rectl.xRight = pVideo->hidden->SrcBufferDesc.uiXResolution; // Noninclusive
1255 rectl.yTop = pVideo->hidden->SrcBufferDesc.uiYResolution; // Noninclusive
1256 WinCalcFrameRect(pVideo->hidden->hwndFrame, &rectl, FALSE);
1257
1258 SetAccessableWindowPos(pVideo->hidden->hwndFrame,
1259 HWND_TOP,
1260 (WinQuerySysValue
1261 (HWND_DESKTOP,
1262 SV_CXSCREEN) - (rectl.xRight -
1263 rectl.xLeft)) / 2,
1264 (WinQuerySysValue
1265 (HWND_DESKTOP,
1266 SV_CYSCREEN) - (rectl.yTop -
1267 rectl.yBottom)) / 2,
1268 (rectl.xRight - rectl.xLeft),
1269 (rectl.yTop - rectl.yBottom),
1270 SWP_SIZE | SWP_ACTIVATE | SWP_SHOW |
1271 SWP_MOVE);
1272
1273 // Subclass frame procedure and store old window proc address
1274 pVideo->hidden->pfnOldFrameProc =
1275 WinSubclassWindow(pVideo->hidden->hwndFrame, FrameWndProc);
1276 WinSetWindowULong(pVideo->hidden->hwndFrame, QWL_USER,
1277 (ULONG) pVideo);
1278
1279 #ifdef DEBUG_BUILD
1280 printf("[PMThreadFunc] : Entering message loop\n");
1281 fflush(stdout);
1282 #endif
1283 pVideo->hidden->iPMThreadStatus = 1;
1284
1285 while (WinGetMsg(hab, (PQMSG) & msg, 0, 0, 0))
1286 WinDispatchMsg(hab, (PQMSG) & msg);
1287
1288 #ifdef DEBUG_BUILD
1289 printf("[PMThreadFunc] : Leaving message loop\n");
1290 fflush(stdout);
1291 #endif
1292 // We should release the captured the mouse!
1293 if (bMouseCaptured) {
1294 WinSetCapture(HWND_DESKTOP, NULLHANDLE);
1295 bMouseCaptured = 0;
1296 }
1297 // Destroy our window
1298 WinDestroyWindow(pVideo->hidden->hwndFrame);
1299 pVideo->hidden->hwndFrame = NULL;
1300 // Show pointer to make sure it will not be left hidden.
1301 WinSetPointer(HWND_DESKTOP,
1302 WinQuerySysPointer(HWND_DESKTOP, SPTR_ARROW,
1303 FALSE));
1304 WinShowPointer(HWND_DESKTOP, TRUE);
1305 }
1306 // Uninitialize PM
1307 WinDestroyMsgQueue(hmq);
1308 // All done!
1309 pVideo->hidden->iPMThreadStatus = 0;
1310 }
1311 WinTerminate(hab);
1312 /* Commented out, should not be needed anymore, because we send it
1313 from WM_CLOSE.
1314 // Notify SDL that it should really die now...
1315 SDL_PrivateQuit(); SDL_PrivateQuit(); SDL_PrivateQuit(); //... :))
1316 */
1317 #ifdef DEBUG_BUILD
1318 printf("[PMThreadFunc] : End, status is %d!\n",
1319 pVideo->hidden->iPMThreadStatus);
1180 fflush(stdout); 1320 fflush(stdout);
1181 #endif 1321 #endif
1182 1322
1183 rc = FSLib_CreateWindow(HWND_DESKTOP, 0, &fcf, 1323 iNumOfPMThreadInstances--;
1184 "SDL Application", 1324
1185 NULLHANDLE, 0, 1325 // HACK to prevent zombie and hanging SDL applications, which does not take
1186 &(pVideo->hidden->SrcBufferDesc), 1326 // care of closing the window for some reason:
1187 WndProc, 1327 // There are some apps which do not process messages, so do a lot of things
1188 &(pVideo->hidden->hwndClient), 1328 // without noticing that the application should close. To close these,
1189 &(pVideo->hidden->hwndFrame)); 1329 // I've thought about the following:
1190 1330 // If the window is closed (the execution came here), I wait a bit to
1191 #ifdef DEBUG_BUILD 1331 // give time to the app to finish its execution. If it does not, I kill it
1192 printf("[PMThreadFunc] : FSLib_CreateWindow() rc = %d\n", rc); 1332 // using DosExit(). Brute force, but should work.
1333 if (pVideo->hidden->iPMThreadStatus == 0) {
1334 DosSleep(5000); // Wait 5 secs
1335 // If a new PM thread has been spawned (reinitializing video mode), then all right.
1336 // Otherwise, we have a problem, the app doesn't want to stop. Kill!
1337 if (iNumOfPMThreadInstances == 0) {
1338 #ifdef DEBUG_BUILD
1339 printf
1340 ("[PMThreadFunc] : It seems that the application haven't terminated itself\n");
1341 fflush(stdout);
1342 printf
1343 ("[PMThreadFunc] : in the last 5 seconds, so we go berserk.\n");
1344 fflush(stdout);
1345 printf
1346 ("[PMThreadFunc] : Brute force mode. :) Killing process! Dieeeee...\n");
1347 fflush(stdout);
1348 #endif
1349 DosExit(EXIT_PROCESS, -1);
1350 }
1351 }
1352 _endthread();
1353 }
1354
1355 struct WMcursor
1356 {
1357 HBITMAP hbm;
1358 HPOINTER hptr;
1359 char *pchData;
1360 };
1361
1362 /* Free a window manager cursor */
1363 void
1364 os2fslib_FreeWMCursor(_THIS, WMcursor * cursor)
1365 {
1366 if (cursor) {
1367 GpiDeleteBitmap(cursor->hbm);
1368 WinDestroyPointer(cursor->hptr);
1369 SDL_free(cursor->pchData);
1370 SDL_free(cursor);
1371 }
1372 }
1373
1374 /* Local functions to convert the SDL cursor mask into OS/2 format */
1375 static void
1376 memnot(Uint8 * dst, Uint8 * src, int len)
1377 {
1378 while (len-- > 0)
1379 *dst++ = ~*src++;
1380 }
1381 static void
1382 memxor(Uint8 * dst, Uint8 * src1, Uint8 * src2, int len)
1383 {
1384 while (len-- > 0)
1385 *dst++ = (*src1++) ^ (*src2++);
1386 }
1387
1388 /* Create a black/white window manager cursor */
1389 WMcursor *
1390 os2fslib_CreateWMCursor_Win(_THIS, Uint8 * data, Uint8 * mask,
1391 int w, int h, int hot_x, int hot_y)
1392 {
1393 HPOINTER hptr;
1394 HBITMAP hbm;
1395 BITMAPINFOHEADER bmih;
1396 BMPINFO bmi;
1397 HPS hps;
1398 char *pchTemp;
1399 char *xptr, *aptr;
1400 int maxx, maxy;
1401 int i, run, pad;
1402 WMcursor *pResult;
1403
1404 maxx = WinQuerySysValue(HWND_DESKTOP, SV_CXPOINTER);
1405 maxy = WinQuerySysValue(HWND_DESKTOP, SV_CYPOINTER);
1406
1407 // Check for max size!
1408 if ((w > maxx) || (h > maxy))
1409 return (WMcursor *) NULL;
1410
1411 pResult = (WMcursor *) SDL_malloc(sizeof(WMcursor));
1412 if (!pResult)
1413 return (WMcursor *) NULL;
1414
1415 pchTemp = (char *) SDL_malloc((maxx + 7) / 8 * maxy * 2);
1416 if (!pchTemp) {
1417 SDL_free(pResult);
1418 return (WMcursor *) NULL;
1419 }
1420
1421 SDL_memset(pchTemp, 0, (maxx + 7) / 8 * maxy * 2);
1422
1423 hps = WinGetPS(_this->hidden->hwndClient);
1424
1425 bmi.cbFix = sizeof(BITMAPINFOHEADER);
1426 bmi.cx = maxx;
1427 bmi.cy = 2 * maxy;
1428 bmi.cPlanes = 1;
1429 bmi.cBitCount = 1;
1430 bmi.argbColor[0].bBlue = 0x00;
1431 bmi.argbColor[0].bGreen = 0x00;
1432 bmi.argbColor[0].bRed = 0x00;
1433 bmi.argbColor[1].bBlue = 0x00;
1434 bmi.argbColor[1].bGreen = 0x00;
1435 bmi.argbColor[1].bRed = 0xff;
1436
1437 SDL_memset(&bmih, 0, sizeof(BITMAPINFOHEADER));
1438 bmih.cbFix = sizeof(BITMAPINFOHEADER);
1439 bmih.cx = maxx;
1440 bmih.cy = 2 * maxy;
1441 bmih.cPlanes = 1;
1442 bmih.cBitCount = 1;
1443
1444 run = (w + 7) / 8;
1445 pad = (maxx + 7) / 8 - run;
1446
1447 for (i = 0; i < h; i++) {
1448 xptr = pchTemp + (maxx + 7) / 8 * (maxy - 1 - i);
1449 aptr = pchTemp + (maxx + 7) / 8 * (maxy + maxy - 1 - i);
1450 memxor(xptr, data, mask, run);
1451 xptr += run;
1452 data += run;
1453 memnot(aptr, mask, run);
1454 mask += run;
1455 aptr += run;
1456 SDL_memset(xptr, 0, pad);
1457 xptr += pad;
1458 SDL_memset(aptr, ~0, pad);
1459 aptr += pad;
1460 }
1461 pad += run;
1462 for (i = h; i < maxy; i++) {
1463 xptr = pchTemp + (maxx + 7) / 8 * (maxy - 1 - i);
1464 aptr = pchTemp + (maxx + 7) / 8 * (maxy + maxy - 1 - i);
1465
1466 SDL_memset(xptr, 0, (maxx + 7) / 8);
1467 xptr += (maxx + 7) / 8;
1468 SDL_memset(aptr, ~0, (maxx + 7) / 8);
1469 aptr += (maxx + 7) / 8;
1470 }
1471
1472 hbm =
1473 GpiCreateBitmap(hps, (PBITMAPINFOHEADER2) & bmih, CBM_INIT,
1474 (PBYTE) pchTemp, (PBITMAPINFO2) & bmi);
1475 hptr = WinCreatePointer(HWND_DESKTOP, hbm, TRUE, hot_x, maxy - hot_y - 1);
1476
1477 #ifdef DEBUG_BUILD
1478 printf("HotSpot : %d ; %d\n", hot_x, hot_y);
1479 printf("HPS returned : %x\n", (ULONG) hps);
1480 printf("HBITMAP returned : %x\n", (ULONG) hbm);
1481 printf("HPOINTER returned: %x\n", (ULONG) hptr);
1482 #endif
1483
1484 WinReleasePS(hps);
1485
1486 #ifdef DEBUG_BUILD
1487 printf("[CreateWMCursor] : ptr = %p\n", hptr);
1193 fflush(stdout); 1488 fflush(stdout);
1194 #endif 1489 #endif
1195 1490
1196 if (!rc) 1491 pResult->hptr = hptr;
1197 { 1492 pResult->hbm = hbm;
1198 #ifdef DEBUG_BUILD 1493 pResult->pchData = pchTemp;
1199 printf("[PMThreadFunc] : Could not create FSLib window!\n"); 1494
1200 fflush(stdout); 1495 #ifdef DEBUG_BUILD
1201 #endif 1496 printf("[CreateWMCursor] : ptr = %p return.\n", hptr);
1202 pVideo->hidden->iPMThreadStatus = 3; 1497 fflush(stdout);
1203 } else 1498 #endif
1204 { 1499
1205 #ifdef DEBUG_BUILD 1500 return (WMcursor *) pResult;
1206 printf("[PMThreadFunc] : FSLib_AddUserParm()!\n"); 1501 }
1207 fflush(stdout); 1502
1208 #endif 1503 WMcursor *
1209 1504 os2fslib_CreateWMCursor_FS(_THIS, Uint8 * data, Uint8 * mask,
1210 // Store pVideo pointer in window data for client window, so 1505 int w, int h, int hot_x, int hot_y)
1211 // it will know the instance to which it belongs to. 1506 {
1212 FSLib_AddUserParm(pVideo->hidden->hwndClient, pVideo); 1507 #ifdef DEBUG_BUILD
1213 1508 printf("[CreateWMCursor_FS] : returning pointer NULL\n");
1214 // Now set default image width height and fourcc! 1509 fflush(stdout);
1215 #ifdef DEBUG_BUILD 1510 #endif
1216 printf("[PMThreadFunc] : SetWindowPos()!\n"); 1511
1217 fflush(stdout); 1512 // In FS mode we'll use software cursor
1218 #endif
1219
1220 // Set the position and size of the main window,
1221 // and make it visible!
1222 // Calculate frame window size from client window size
1223 rectl.xLeft = 0;
1224 rectl.yBottom = 0;
1225 rectl.xRight = pVideo->hidden->SrcBufferDesc.uiXResolution; // Noninclusive
1226 rectl.yTop = pVideo->hidden->SrcBufferDesc.uiYResolution; // Noninclusive
1227 WinCalcFrameRect(pVideo->hidden->hwndFrame, &rectl, FALSE);
1228
1229 SetAccessableWindowPos(pVideo->hidden->hwndFrame,
1230 HWND_TOP,
1231 (WinQuerySysValue (HWND_DESKTOP, SV_CXSCREEN) - (rectl.xRight-rectl.xLeft)) / 2,
1232 (WinQuerySysValue (HWND_DESKTOP, SV_CYSCREEN) - (rectl.yTop-rectl.yBottom)) / 2,
1233 (rectl.xRight-rectl.xLeft),
1234 (rectl.yTop-rectl.yBottom),
1235 SWP_SIZE | SWP_ACTIVATE | SWP_SHOW | SWP_MOVE);
1236
1237 // Subclass frame procedure and store old window proc address
1238 pVideo->hidden->pfnOldFrameProc =
1239 WinSubclassWindow(pVideo->hidden->hwndFrame, FrameWndProc);
1240 WinSetWindowULong(pVideo->hidden->hwndFrame, QWL_USER, (ULONG) pVideo);
1241
1242 #ifdef DEBUG_BUILD
1243 printf("[PMThreadFunc] : Entering message loop\n"); fflush(stdout);
1244 #endif
1245 pVideo->hidden->iPMThreadStatus = 1;
1246
1247 while (WinGetMsg(hab, (PQMSG)&msg, 0, 0, 0))
1248 WinDispatchMsg(hab, (PQMSG) &msg);
1249
1250 #ifdef DEBUG_BUILD
1251 printf("[PMThreadFunc] : Leaving message loop\n"); fflush(stdout);
1252 #endif
1253 // We should release the captured the mouse!
1254 if (bMouseCaptured)
1255 {
1256 WinSetCapture(HWND_DESKTOP, NULLHANDLE);
1257 bMouseCaptured = 0;
1258 }
1259 // Destroy our window
1260 WinDestroyWindow(pVideo->hidden->hwndFrame); pVideo->hidden->hwndFrame=NULL;
1261 // Show pointer to make sure it will not be left hidden.
1262 WinSetPointer(HWND_DESKTOP, WinQuerySysPointer(HWND_DESKTOP, SPTR_ARROW, FALSE));
1263 WinShowPointer(HWND_DESKTOP, TRUE);
1264 }
1265 // Uninitialize PM
1266 WinDestroyMsgQueue(hmq);
1267 // All done!
1268 pVideo->hidden->iPMThreadStatus = 0;
1269 }
1270 WinTerminate(hab);
1271 /* Commented out, should not be needed anymore, because we send it
1272 from WM_CLOSE.
1273 // Notify SDL that it should really die now...
1274 SDL_PrivateQuit(); SDL_PrivateQuit(); SDL_PrivateQuit(); //... :))
1275 */
1276 #ifdef DEBUG_BUILD
1277 printf("[PMThreadFunc] : End, status is %d!\n", pVideo->hidden->iPMThreadStatus); fflush(stdout);
1278 #endif
1279
1280 iNumOfPMThreadInstances--;
1281
1282 // HACK to prevent zombie and hanging SDL applications, which does not take
1283 // care of closing the window for some reason:
1284 // There are some apps which do not process messages, so do a lot of things
1285 // without noticing that the application should close. To close these,
1286 // I've thought about the following:
1287 // If the window is closed (the execution came here), I wait a bit to
1288 // give time to the app to finish its execution. If it does not, I kill it
1289 // using DosExit(). Brute force, but should work.
1290 if (pVideo->hidden->iPMThreadStatus==0)
1291 {
1292 DosSleep(5000); // Wait 5 secs
1293 // If a new PM thread has been spawned (reinitializing video mode), then all right.
1294 // Otherwise, we have a problem, the app doesn't want to stop. Kill!
1295 if (iNumOfPMThreadInstances==0)
1296 {
1297 #ifdef DEBUG_BUILD
1298 printf("[PMThreadFunc] : It seems that the application haven't terminated itself\n"); fflush(stdout);
1299 printf("[PMThreadFunc] : in the last 5 seconds, so we go berserk.\n"); fflush(stdout);
1300 printf("[PMThreadFunc] : Brute force mode. :) Killing process! Dieeeee...\n"); fflush(stdout);
1301 #endif
1302 DosExit(EXIT_PROCESS, -1);
1303 }
1304 }
1305 _endthread();
1306 }
1307
1308 struct WMcursor
1309 {
1310 HBITMAP hbm;
1311 HPOINTER hptr;
1312 char *pchData;
1313 };
1314
1315 /* Free a window manager cursor */
1316 void os2fslib_FreeWMCursor(_THIS, WMcursor *cursor)
1317 {
1318 if (cursor)
1319 {
1320 GpiDeleteBitmap(cursor->hbm);
1321 WinDestroyPointer(cursor->hptr);
1322 SDL_free(cursor->pchData);
1323 SDL_free(cursor);
1324 }
1325 }
1326
1327 /* Local functions to convert the SDL cursor mask into OS/2 format */
1328 static void memnot(Uint8 *dst, Uint8 *src, int len)
1329 {
1330 while ( len-- > 0 )
1331 *dst++ = ~*src++;
1332 }
1333 static void memxor(Uint8 *dst, Uint8 *src1, Uint8 *src2, int len)
1334 {
1335 while ( len-- > 0 )
1336 *dst++ = (*src1++)^(*src2++);
1337 }
1338
1339 /* Create a black/white window manager cursor */
1340 WMcursor *os2fslib_CreateWMCursor_Win(_THIS, Uint8 *data, Uint8 *mask,
1341 int w, int h, int hot_x, int hot_y)
1342 {
1343 HPOINTER hptr;
1344 HBITMAP hbm;
1345 BITMAPINFOHEADER bmih;
1346 BMPINFO bmi;
1347 HPS hps;
1348 char *pchTemp;
1349 char *xptr, *aptr;
1350 int maxx, maxy;
1351 int i, run, pad;
1352 WMcursor *pResult;
1353
1354 maxx = WinQuerySysValue(HWND_DESKTOP, SV_CXPOINTER);
1355 maxy = WinQuerySysValue(HWND_DESKTOP, SV_CYPOINTER);
1356
1357 // Check for max size!
1358 if ((w>maxx) || (h>maxy))
1359 return (WMcursor *) NULL; 1513 return (WMcursor *) NULL;
1360
1361 pResult = (WMcursor *) SDL_malloc(sizeof(WMcursor));
1362 if (!pResult) return (WMcursor *) NULL;
1363
1364 pchTemp = (char *) SDL_malloc((maxx + 7)/8 * maxy*2);
1365 if (!pchTemp)
1366 {
1367 SDL_free(pResult);
1368 return (WMcursor *) NULL;
1369 }
1370
1371 SDL_memset(pchTemp, 0, (maxx + 7)/8 * maxy*2);
1372
1373 hps = WinGetPS(_this->hidden->hwndClient);
1374
1375 bmi.cbFix = sizeof(BITMAPINFOHEADER);
1376 bmi.cx = maxx;
1377 bmi.cy = 2*maxy;
1378 bmi.cPlanes = 1;
1379 bmi.cBitCount = 1;
1380 bmi.argbColor[0].bBlue = 0x00;
1381 bmi.argbColor[0].bGreen = 0x00;
1382 bmi.argbColor[0].bRed = 0x00;
1383 bmi.argbColor[1].bBlue = 0x00;
1384 bmi.argbColor[1].bGreen = 0x00;
1385 bmi.argbColor[1].bRed = 0xff;
1386
1387 SDL_memset(&bmih, 0, sizeof(BITMAPINFOHEADER));
1388 bmih.cbFix = sizeof(BITMAPINFOHEADER);
1389 bmih.cx = maxx;
1390 bmih.cy = 2*maxy;
1391 bmih.cPlanes = 1;
1392 bmih.cBitCount = 1;
1393
1394 run = (w+7)/8;
1395 pad = (maxx+7)/8 - run;
1396
1397 for (i=0; i<h; i++)
1398 {
1399 xptr = pchTemp + (maxx+7)/8 * (maxy-1-i);
1400 aptr = pchTemp + (maxx+7)/8 * (maxy+maxy-1-i);
1401 memxor(xptr, data, mask, run);
1402 xptr += run;
1403 data += run;
1404 memnot(aptr, mask, run);
1405 mask += run;
1406 aptr += run;
1407 SDL_memset(xptr, 0, pad);
1408 xptr += pad;
1409 SDL_memset(aptr, ~0, pad);
1410 aptr += pad;
1411 }
1412 pad += run;
1413 for (i=h ; i<maxy; i++ )
1414 {
1415 xptr = pchTemp + (maxx+7)/8 * (maxy-1-i);
1416 aptr = pchTemp + (maxx+7)/8 * (maxy+maxy-1-i);
1417
1418 SDL_memset(xptr, 0, (maxx+7)/8);
1419 xptr += (maxx+7)/8;
1420 SDL_memset(aptr, ~0, (maxx+7)/8);
1421 aptr += (maxx+7)/8;
1422 }
1423
1424 hbm = GpiCreateBitmap(hps, (PBITMAPINFOHEADER2)&bmih, CBM_INIT, (PBYTE) pchTemp, (PBITMAPINFO2)&bmi);
1425 hptr = WinCreatePointer(HWND_DESKTOP, hbm, TRUE, hot_x, maxy - hot_y - 1);
1426
1427 #ifdef DEBUG_BUILD
1428 printf("HotSpot : %d ; %d\n", hot_x, hot_y);
1429 printf("HPS returned : %x\n", (ULONG)hps);
1430 printf("HBITMAP returned : %x\n", (ULONG)hbm);
1431 printf("HPOINTER returned: %x\n", (ULONG)hptr);
1432 #endif
1433
1434 WinReleasePS(hps);
1435
1436 #ifdef DEBUG_BUILD
1437 printf("[CreateWMCursor] : ptr = %p\n", hptr); fflush(stdout);
1438 #endif
1439
1440 pResult->hptr = hptr;
1441 pResult->hbm = hbm;
1442 pResult->pchData = pchTemp;
1443
1444 #ifdef DEBUG_BUILD
1445 printf("[CreateWMCursor] : ptr = %p return.\n", hptr); fflush(stdout);
1446 #endif
1447
1448 return (WMcursor *) pResult;
1449 }
1450
1451 WMcursor *os2fslib_CreateWMCursor_FS(_THIS, Uint8 *data, Uint8 *mask,
1452 int w, int h, int hot_x, int hot_y)
1453 {
1454 #ifdef DEBUG_BUILD
1455 printf("[CreateWMCursor_FS] : returning pointer NULL\n"); fflush(stdout);
1456 #endif
1457
1458 // In FS mode we'll use software cursor
1459 return (WMcursor *) NULL;
1460 } 1514 }
1461 1515
1462 /* Show the specified cursor, or hide if cursor is NULL */ 1516 /* Show the specified cursor, or hide if cursor is NULL */
1463 int os2fslib_ShowWMCursor(_THIS, WMcursor *cursor) 1517 int
1464 { 1518 os2fslib_ShowWMCursor(_THIS, WMcursor * cursor)
1465 #ifdef DEBUG_BUILD 1519 {
1466 printf("[ShowWMCursor] : ptr = %p\n", cursor); fflush(stdout); 1520 #ifdef DEBUG_BUILD
1467 #endif 1521 printf("[ShowWMCursor] : ptr = %p\n", cursor);
1468 1522 fflush(stdout);
1469 if (cursor) 1523 #endif
1470 { 1524
1471 WinSetPointer(HWND_DESKTOP, cursor->hptr); 1525 if (cursor) {
1472 hptrGlobalPointer = cursor->hptr; 1526 WinSetPointer(HWND_DESKTOP, cursor->hptr);
1473 _this->hidden->iMouseVisible = 1; 1527 hptrGlobalPointer = cursor->hptr;
1474 } 1528 _this->hidden->iMouseVisible = 1;
1475 else 1529 } else {
1476 { 1530 WinSetPointer(HWND_DESKTOP, FALSE);
1477 WinSetPointer(HWND_DESKTOP, FALSE); 1531 hptrGlobalPointer = NULL;
1478 hptrGlobalPointer = NULL; 1532 _this->hidden->iMouseVisible = 0;
1479 _this->hidden->iMouseVisible = 0; 1533 }
1480 } 1534
1481 1535 #ifdef DEBUG_BUILD
1482 #ifdef DEBUG_BUILD 1536 printf("[ShowWMCursor] : ptr = %p, DONE\n", cursor);
1483 printf("[ShowWMCursor] : ptr = %p, DONE\n", cursor); fflush(stdout); 1537 fflush(stdout);
1484 #endif 1538 #endif
1485 1539
1486 return 1; 1540 return 1;
1487 } 1541 }
1488 1542
1489 /* Warp the window manager cursor to (x,y) 1543 /* Warp the window manager cursor to (x,y)
1490 If NULL, a mouse motion event is posted internally. 1544 If NULL, a mouse motion event is posted internally.
1491 */ 1545 */
1492 void os2fslib_WarpWMCursor(_THIS, Uint16 x, Uint16 y) 1546 void
1493 { 1547 os2fslib_WarpWMCursor(_THIS, Uint16 x, Uint16 y)
1494 LONG lx, ly; 1548 {
1495 SWP swpClient; 1549 LONG lx, ly;
1496 POINTL ptlPoints; 1550 SWP swpClient;
1497 WinQueryWindowPos(_this->hidden->hwndClient, &swpClient); 1551 POINTL ptlPoints;
1498 ptlPoints.x = swpClient.x; 1552 WinQueryWindowPos(_this->hidden->hwndClient, &swpClient);
1499 ptlPoints.y = swpClient.y; 1553 ptlPoints.x = swpClient.x;
1500 WinMapWindowPoints(_this->hidden->hwndFrame, HWND_DESKTOP, &ptlPoints, 1); 1554 ptlPoints.y = swpClient.y;
1501 lx = ptlPoints.x + (x*swpClient.cx) / _this->hidden->SrcBufferDesc.uiXResolution; 1555 WinMapWindowPoints(_this->hidden->hwndFrame, HWND_DESKTOP, &ptlPoints, 1);
1502 ly = ptlPoints.y + swpClient.cy - ((y*swpClient.cy) / _this->hidden->SrcBufferDesc.uiYResolution) - 1; 1556 lx = ptlPoints.x +
1503 1557 (x * swpClient.cx) / _this->hidden->SrcBufferDesc.uiXResolution;
1504 SDL_PrivateMouseMotion(0, // Buttons not changed 1558 ly = ptlPoints.y + swpClient.cy -
1505 0, // Absolute position 1559 ((y * swpClient.cy) / _this->hidden->SrcBufferDesc.uiYResolution) - 1;
1506 x, 1560
1507 y); 1561 SDL_PrivateMouseMotion(0, // Buttons not changed
1508 1562 0, // Absolute position
1509 WinSetPointerPos(HWND_DESKTOP, lx, ly); 1563 x, y);
1564
1565 WinSetPointerPos(HWND_DESKTOP, lx, ly);
1510 1566
1511 } 1567 }
1512 1568
1513 /* If not NULL, this is called when a mouse motion event occurs */ 1569 /* If not NULL, this is called when a mouse motion event occurs */
1514 void os2fslib_MoveWMCursor(_THIS, int x, int y) 1570 void
1515 { 1571 os2fslib_MoveWMCursor(_THIS, int x, int y)
1516 /* 1572 {
1517 SDL_Rect rect; 1573 /*
1518 1574 SDL_Rect rect;
1519 #ifdef DEBUG_BUILD 1575
1520 printf("[MoveWMCursor] : at %d ; %d\n", x, y); fflush(stdout); 1576 #ifdef DEBUG_BUILD
1521 #endif 1577 printf("[MoveWMCursor] : at %d ; %d\n", x, y); fflush(stdout);
1522 1578 #endif
1523 rect.x = x; 1579
1524 rect.y = y; 1580 rect.x = x;
1525 rect.w = 32; 1581 rect.y = y;
1526 rect.h = 32; 1582 rect.w = 32;
1527 os2fslib_UpdateRects(_this, 1, &rect); 1583 rect.h = 32;
1528 // TODO! 1584 os2fslib_UpdateRects(_this, 1, &rect);
1529 */ 1585 // TODO!
1586 */
1530 } 1587 }
1531 1588
1532 /* Determine whether the mouse should be in relative mode or not. 1589 /* Determine whether the mouse should be in relative mode or not.
1533 This function is called when the input grab state or cursor 1590 This function is called when the input grab state or cursor
1534 visibility state changes. 1591 visibility state changes.
1535 If the cursor is not visible, and the input is grabbed, the 1592 If the cursor is not visible, and the input is grabbed, the
1536 driver can place the mouse in relative mode, which may result 1593 driver can place the mouse in relative mode, which may result
1537 in higher accuracy sampling of the pointer motion. 1594 in higher accuracy sampling of the pointer motion.
1538 */ 1595 */
1539 void os2fslib_CheckMouseMode(_THIS) 1596 void
1540 { 1597 os2fslib_CheckMouseMode(_THIS)
1541 } 1598 {
1542 1599 }
1543 static void os2fslib_PumpEvents(_THIS) 1600
1544 { 1601 static void
1545 // Notify SDL that if window has been resized! 1602 os2fslib_PumpEvents(_THIS)
1546 if ( 1603 {
1547 (_this->hidden->pSDLSurface) && 1604 // Notify SDL that if window has been resized!
1548 (_this->hidden->pSDLSurface->flags & SDL_RESIZABLE) && 1605 if ((_this->hidden->pSDLSurface) &&
1549 ( 1606 (_this->hidden->pSDLSurface->flags & SDL_RESIZABLE) &&
1550 (_this->hidden->SrcBufferDesc.uiXResolution!=iWindowSizeX) || 1607 ((_this->hidden->SrcBufferDesc.uiXResolution != iWindowSizeX) ||
1551 (_this->hidden->SrcBufferDesc.uiYResolution!=iWindowSizeY) 1608 (_this->hidden->SrcBufferDesc.uiYResolution != iWindowSizeY)) &&
1552 ) && 1609 (iWindowSizeX > 0) && (iWindowSizeY > 0)) {
1553 (iWindowSizeX>0) && 1610 static time_t prev_time;
1554 (iWindowSizeY>0) 1611 time_t curr_time;
1555 ) 1612
1556 { 1613 curr_time = time(NULL);
1557 static time_t prev_time; 1614 if ((difftime(curr_time, prev_time) >= 0.25) || (bWindowResized)) {
1558 time_t curr_time; 1615 // Make sure we won't flood the event queue with resize events,
1559 1616 // only send them at 250 msecs!
1560 curr_time = time(NULL); 1617 // (or when the window is resized)
1561 if ((difftime(curr_time, prev_time)>=0.25) || 1618 #ifdef DEBUG_BUILD
1562 (bWindowResized)) 1619 printf
1563 { 1620 ("[os2fslib_PumpEvents] : Calling PrivateResize (%d %d).\n",
1564 // Make sure we won't flood the event queue with resize events, 1621 iWindowSizeX, iWindowSizeY);
1565 // only send them at 250 msecs! 1622 fflush(stdout);
1566 // (or when the window is resized) 1623 #endif
1567 #ifdef DEBUG_BUILD 1624 // Tell SDL the new size
1568 printf("[os2fslib_PumpEvents] : Calling PrivateResize (%d %d).\n", 1625 SDL_PrivateResize(iWindowSizeX, iWindowSizeY);
1569 iWindowSizeX, iWindowSizeY); 1626 prev_time = curr_time;
1570 fflush(stdout); 1627 bWindowResized = 0;
1571 #endif 1628 }
1572 // Tell SDL the new size 1629 }
1573 SDL_PrivateResize(iWindowSizeX, iWindowSizeY);
1574 prev_time = curr_time;
1575 bWindowResized = 0;
1576 }
1577 }
1578 } 1630 }
1579 1631
1580 /* We don't actually allow hardware surfaces other than the main one */ 1632 /* We don't actually allow hardware surfaces other than the main one */
1581 static int os2fslib_AllocHWSurface(_THIS, SDL_Surface *surface) 1633 static int
1582 { 1634 os2fslib_AllocHWSurface(_THIS, SDL_Surface * surface)
1583 return(-1); 1635 {
1584 } 1636 return (-1);
1585 static void os2fslib_FreeHWSurface(_THIS, SDL_Surface *surface) 1637 }
1586 { 1638 static void
1587 return; 1639 os2fslib_FreeHWSurface(_THIS, SDL_Surface * surface)
1640 {
1641 return;
1588 } 1642 }
1589 1643
1590 /* We need to wait for vertical retrace on page flipped displays */ 1644 /* We need to wait for vertical retrace on page flipped displays */
1591 static int os2fslib_LockHWSurface(_THIS, SDL_Surface *surface) 1645 static int
1592 { 1646 os2fslib_LockHWSurface(_THIS, SDL_Surface * surface)
1593 return(0); 1647 {
1594 } 1648 return (0);
1595 1649 }
1596 static void os2fslib_UnlockHWSurface(_THIS, SDL_Surface *surface) 1650
1597 { 1651 static void
1598 return; 1652 os2fslib_UnlockHWSurface(_THIS, SDL_Surface * surface)
1599 } 1653 {
1600 1654 return;
1601 static int os2fslib_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors) 1655 }
1602 { 1656
1603 printf("[os2fslib_SetColors] : TODO!\n"); fflush(stdout); 1657 static int
1604 // TODO: Implement paletted modes 1658 os2fslib_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color * colors)
1605 return(1); 1659 {
1606 } 1660 printf("[os2fslib_SetColors] : TODO!\n");
1607 1661 fflush(stdout);
1608 static void os2fslib_DestroyIcon(HWND hwndFrame) 1662 // TODO: Implement paletted modes
1609 { 1663 return (1);
1610 if (hptrCurrentIcon) 1664 }
1611 { 1665
1612 WinDestroyPointer(hptrCurrentIcon); 1666 static void
1613 hptrCurrentIcon = NULL; 1667 os2fslib_DestroyIcon(HWND hwndFrame)
1614 1668 {
1615 WinSendMsg(hwndFrame, 1669 if (hptrCurrentIcon) {
1616 WM_SETICON, 1670 WinDestroyPointer(hptrCurrentIcon);
1617 NULL, 1671 hptrCurrentIcon = NULL;
1618 NULL); 1672
1619 } 1673 WinSendMsg(hwndFrame, WM_SETICON, NULL, NULL);
1674 }
1620 1675
1621 } 1676 }
1622 1677
1623 /* Set the window icon image */ 1678 /* Set the window icon image */
1624 void os2fslib_SetIcon(_THIS, SDL_Surface *icon, Uint8 *mask) 1679 void
1625 { 1680 os2fslib_SetIcon(_THIS, SDL_Surface * icon, Uint8 * mask)
1626 HWND hwndFrame; 1681 {
1627 SDL_Surface *icon_rgb; 1682 HWND hwndFrame;
1628 HPOINTER hptrIcon; 1683 SDL_Surface *icon_rgb;
1629 HBITMAP hbm; 1684 HPOINTER hptrIcon;
1630 BITMAPINFOHEADER bmih; 1685 HBITMAP hbm;
1631 BMPINFO bmi; 1686 BITMAPINFOHEADER bmih;
1632 HPS hps; 1687 BMPINFO bmi;
1633 char *pchTemp; 1688 HPS hps;
1634 char *pptr, *mptr, *dptr, *dmptr; 1689 char *pchTemp;
1635 int maxx, maxy, w, h, x, y; 1690 char *pptr, *mptr, *dptr, *dmptr;
1636 SDL_Rect bounds; 1691 int maxx, maxy, w, h, x, y;
1637 1692 SDL_Rect bounds;
1638 #ifdef DEBUG_BUILD 1693
1639 printf("[os2fslib_SetIcon] : Creating and setting new icon\n"); fflush(stdout); 1694 #ifdef DEBUG_BUILD
1640 #endif 1695 printf("[os2fslib_SetIcon] : Creating and setting new icon\n");
1641 1696 fflush(stdout);
1642 hwndFrame = WinQueryWindow(_this->hidden->hwndClient, QW_PARENT); 1697 #endif
1643 1698
1644 // Make sure the old icon resource will be free'd! 1699 hwndFrame = WinQueryWindow(_this->hidden->hwndClient, QW_PARENT);
1645 os2fslib_DestroyIcon(hwndFrame); 1700
1646 1701 // Make sure the old icon resource will be free'd!
1647 if ((!icon) || (!mask)) 1702 os2fslib_DestroyIcon(hwndFrame);
1648 return; 1703
1649 1704 if ((!icon) || (!mask))
1650 w = icon->w; 1705 return;
1651 h = icon->h; 1706
1652 1707 w = icon->w;
1653 maxx = WinQuerySysValue(HWND_DESKTOP, SV_CXICON); 1708 h = icon->h;
1654 maxy = WinQuerySysValue(HWND_DESKTOP, SV_CYICON); 1709
1655 1710 maxx = WinQuerySysValue(HWND_DESKTOP, SV_CXICON);
1656 // Check for max size! 1711 maxy = WinQuerySysValue(HWND_DESKTOP, SV_CYICON);
1657 if ((w>maxx) || (h>maxy)) 1712
1658 return; 1713 // Check for max size!
1659 1714 if ((w > maxx) || (h > maxy))
1660 pchTemp = (char *) SDL_malloc(w * h*2 * 4); 1715 return;
1661 if (!pchTemp) 1716
1662 return; 1717 pchTemp = (char *) SDL_malloc(w * h * 2 * 4);
1663 1718 if (!pchTemp)
1664 SDL_memset(pchTemp, 0, w * h*2 * 4); 1719 return;
1665 1720
1666 // Convert surface to RGB, if it's not RGB yet! 1721 SDL_memset(pchTemp, 0, w * h * 2 * 4);
1667 icon_rgb = SDL_CreateRGBSurface(SDL_SWSURFACE, icon->w, icon->h, 1722
1668 32, 0, 0, 0, 0); 1723 // Convert surface to RGB, if it's not RGB yet!
1669 if ( icon_rgb == NULL ) 1724 icon_rgb = SDL_CreateRGBSurface(SDL_SWSURFACE, icon->w, icon->h,
1670 { 1725 32, 0, 0, 0, 0);
1726 if (icon_rgb == NULL) {
1727 SDL_free(pchTemp);
1728 return;
1729 }
1730 bounds.x = 0;
1731 bounds.y = 0;
1732 bounds.w = icon->w;
1733 bounds.h = icon->h;
1734 if (SDL_LowerBlit(icon, &bounds, icon_rgb, &bounds) < 0) {
1735 SDL_FreeSurface(icon_rgb);
1736 SDL_free(pchTemp);
1737 return;
1738 }
1739
1740 /* Copy pixels upside-down from RGB surface into BMP, masked with the icon mask */
1741
1742 // Pixels
1743 pptr = (char *) (icon_rgb->pixels);
1744 // Mask
1745 mptr = mask;
1746
1747 for (y = 0; y < h; y++) {
1748 unsigned char uchMaskByte;
1749
1750 // Destination
1751 dptr = pchTemp + w * 4 * (h - y - 1);
1752 // Destination mask
1753 dmptr = pchTemp + w * h * 4 + w * 4 * (h - y - 1);
1754
1755 for (x = 0; x < w; x++) {
1756 if (x % 8 == 0) {
1757 uchMaskByte = (unsigned char) (*mptr);
1758 mptr++;
1759 } else
1760 uchMaskByte <<= 1;
1761
1762 if (uchMaskByte & 0x80) {
1763 // Copy RGB
1764 *dptr++ = *pptr++;
1765 *dptr++ = *pptr++;
1766 *dptr++ = *pptr++;
1767 *dptr++ = *pptr++;
1768
1769 *dmptr++ = 0;
1770 *dmptr++ = 0;
1771 *dmptr++ = 0;
1772 *dmptr++ = 0;
1773 } else {
1774 // Set pixels to fully transparent
1775 *dptr++ = 0;
1776 pptr++;
1777 *dptr++ = 0;
1778 pptr++;
1779 *dptr++ = 0;
1780 pptr++;
1781 *dptr++ = 0;
1782 pptr++;
1783
1784 *dmptr++ = 255;
1785 *dmptr++ = 255;
1786 *dmptr++ = 255;
1787 *dmptr++ = 255;
1788 }
1789 }
1790 }
1791
1792 // There is no more need for the RGB surface
1793 SDL_FreeSurface(icon_rgb);
1794
1795 hps = WinGetPS(_this->hidden->hwndClient);
1796
1797 bmi.cbFix = sizeof(BITMAPINFOHEADER);
1798 bmi.cx = w;
1799 bmi.cy = 2 * h;
1800 bmi.cPlanes = 1;
1801 bmi.cBitCount = 32;
1802
1803 SDL_memset(&bmih, 0, sizeof(BITMAPINFOHEADER));
1804 bmih.cbFix = sizeof(BITMAPINFOHEADER);
1805 bmih.cx = w;
1806 bmih.cy = 2 * h;
1807 bmih.cPlanes = 1;
1808 bmih.cBitCount = 32;
1809
1810 hbm =
1811 GpiCreateBitmap(hps, (PBITMAPINFOHEADER2) & bmih, CBM_INIT,
1812 (PBYTE) pchTemp, (PBITMAPINFO2) & bmi);
1813 hptrIcon = WinCreatePointer(HWND_DESKTOP, hbm, FALSE, 0, 0);
1814
1815 WinReleasePS(hps);
1816
1817 // Free pixel array
1671 SDL_free(pchTemp); 1818 SDL_free(pchTemp);
1672 return; 1819
1673 } 1820 // Change icon in frame window
1674 bounds.x = 0; 1821 WinSendMsg(hwndFrame, WM_SETICON, (MPARAM) hptrIcon, NULL);
1675 bounds.y = 0; 1822
1676 bounds.w = icon->w; 1823 /*
1677 bounds.h = icon->h; 1824 // Change icon in switchlist
1678 if ( SDL_LowerBlit(icon, &bounds, icon_rgb, &bounds) < 0 ) 1825 // Seems like it's not needed, the WM_SETICON already does it.
1679 { 1826 {
1680 SDL_FreeSurface(icon_rgb); 1827 PID pidFrame;
1681 SDL_free(pchTemp); 1828 HSWITCH hswitchFrame;
1682 return; 1829 SWCNTRL swctl;
1683 } 1830
1684 1831 WinQueryWindowProcess(hwndFrame, &pidFrame, NULL);
1685 /* Copy pixels upside-down from RGB surface into BMP, masked with the icon mask */ 1832 hswitchFrame = WinQuerySwitchHandle(hwndFrame, pidFrame);
1686 1833 WinQuerySwitchEntry(hswitchFrame, &swctl);
1687 // Pixels 1834
1688 pptr = (char *) (icon_rgb->pixels); 1835 swctl.hwndIcon = hptrIcon;
1689 // Mask 1836
1690 mptr = mask; 1837 WinChangeSwitchEntry(hswitchFrame, &swctl);
1691 1838 }
1692 for (y=0; y<h; y++) 1839 */
1693 { 1840
1694 unsigned char uchMaskByte; 1841 // Store icon handle in global variable
1695 1842 hptrCurrentIcon = hptrIcon;
1696 // Destination
1697 dptr = pchTemp + w*4 * (h-y-1);
1698 // Destination mask
1699 dmptr = pchTemp + w*h*4 + w*4 * (h-y-1);
1700
1701 for (x=0; x<w; x++)
1702 {
1703 if (x%8==0)
1704 {
1705 uchMaskByte = (unsigned char) (*mptr);
1706 mptr++;
1707 } else
1708 uchMaskByte <<= 1;
1709
1710 if (uchMaskByte & 0x80)
1711 {
1712 // Copy RGB
1713 *dptr++ = *pptr++;
1714 *dptr++ = *pptr++;
1715 *dptr++ = *pptr++;
1716 *dptr++ = *pptr++;
1717
1718 *dmptr++ = 0;
1719 *dmptr++ = 0;
1720 *dmptr++ = 0;
1721 *dmptr++ = 0;
1722 } else
1723 {
1724 // Set pixels to fully transparent
1725 *dptr++ = 0; pptr++;
1726 *dptr++ = 0; pptr++;
1727 *dptr++ = 0; pptr++;
1728 *dptr++ = 0; pptr++;
1729
1730 *dmptr++ = 255;
1731 *dmptr++ = 255;
1732 *dmptr++ = 255;
1733 *dmptr++ = 255;
1734 }
1735 }
1736 }
1737
1738 // There is no more need for the RGB surface
1739 SDL_FreeSurface(icon_rgb);
1740
1741 hps = WinGetPS(_this->hidden->hwndClient);
1742
1743 bmi.cbFix = sizeof(BITMAPINFOHEADER);
1744 bmi.cx = w;
1745 bmi.cy = 2*h;
1746 bmi.cPlanes = 1;
1747 bmi.cBitCount = 32;
1748
1749 SDL_memset(&bmih, 0, sizeof(BITMAPINFOHEADER));
1750 bmih.cbFix = sizeof(BITMAPINFOHEADER);
1751 bmih.cx = w;
1752 bmih.cy = 2*h;
1753 bmih.cPlanes = 1;
1754 bmih.cBitCount = 32;
1755
1756 hbm = GpiCreateBitmap(hps, (PBITMAPINFOHEADER2)&bmih, CBM_INIT, (PBYTE) pchTemp, (PBITMAPINFO2)&bmi);
1757 hptrIcon = WinCreatePointer(HWND_DESKTOP, hbm, FALSE, 0, 0);
1758
1759 WinReleasePS(hps);
1760
1761 // Free pixel array
1762 SDL_free(pchTemp);
1763
1764 // Change icon in frame window
1765 WinSendMsg(hwndFrame,
1766 WM_SETICON,
1767 (MPARAM) hptrIcon,
1768 NULL);
1769
1770 /*
1771 // Change icon in switchlist
1772 // Seems like it's not needed, the WM_SETICON already does it.
1773 {
1774 PID pidFrame;
1775 HSWITCH hswitchFrame;
1776 SWCNTRL swctl;
1777
1778 WinQueryWindowProcess(hwndFrame, &pidFrame, NULL);
1779 hswitchFrame = WinQuerySwitchHandle(hwndFrame, pidFrame);
1780 WinQuerySwitchEntry(hswitchFrame, &swctl);
1781
1782 swctl.hwndIcon = hptrIcon;
1783
1784 WinChangeSwitchEntry(hswitchFrame, &swctl);
1785 }
1786 */
1787
1788 // Store icon handle in global variable
1789 hptrCurrentIcon = hptrIcon;
1790 } 1843 }
1791 1844
1792 // ------------------------ REAL FUNCTIONS ----------------- 1845 // ------------------------ REAL FUNCTIONS -----------------
1793 1846
1794 1847
1795 static void os2fslib_SetCursorManagementFunctions(_THIS, int iForWindowedMode) 1848 static void
1796 { 1849 os2fslib_SetCursorManagementFunctions(_THIS, int iForWindowedMode)
1797 if (iForWindowedMode) 1850 {
1798 { 1851 if (iForWindowedMode) {
1799 _this->FreeWMCursor = os2fslib_FreeWMCursor; 1852 _this->FreeWMCursor = os2fslib_FreeWMCursor;
1800 _this->CreateWMCursor = os2fslib_CreateWMCursor_Win; 1853 _this->CreateWMCursor = os2fslib_CreateWMCursor_Win;
1801 _this->ShowWMCursor = os2fslib_ShowWMCursor; 1854 _this->ShowWMCursor = os2fslib_ShowWMCursor;
1802 _this->WarpWMCursor = os2fslib_WarpWMCursor; 1855 _this->WarpWMCursor = os2fslib_WarpWMCursor;
1803 _this->MoveWMCursor = os2fslib_MoveWMCursor; 1856 _this->MoveWMCursor = os2fslib_MoveWMCursor;
1804 _this->CheckMouseMode = NULL;//os2fslib_CheckMouseMode; 1857 _this->CheckMouseMode = NULL; //os2fslib_CheckMouseMode;
1805 } else 1858 } else {
1806 { 1859 // We'll have software mouse cursor in FS mode!
1807 // We'll have software mouse cursor in FS mode! 1860 _this->FreeWMCursor = os2fslib_FreeWMCursor;
1808 _this->FreeWMCursor = os2fslib_FreeWMCursor; 1861 _this->CreateWMCursor = os2fslib_CreateWMCursor_FS;
1809 _this->CreateWMCursor = os2fslib_CreateWMCursor_FS; 1862 _this->ShowWMCursor = os2fslib_ShowWMCursor;
1810 _this->ShowWMCursor = os2fslib_ShowWMCursor; 1863 _this->WarpWMCursor = os2fslib_WarpWMCursor;
1811 _this->WarpWMCursor = os2fslib_WarpWMCursor; 1864 _this->MoveWMCursor = os2fslib_MoveWMCursor;
1812 _this->MoveWMCursor = os2fslib_MoveWMCursor; 1865 _this->CheckMouseMode = NULL; //os2fslib_CheckMouseMode;
1813 _this->CheckMouseMode = NULL;//os2fslib_CheckMouseMode; 1866 }
1814 } 1867 }
1815 } 1868
1816 1869 static void
1817 static void os2fslib_InitOSKeymap(_THIS) 1870 os2fslib_InitOSKeymap(_THIS)
1818 { 1871 {
1819 int i; 1872 int i;
1820 1873
1821 iShiftIsPressed = 0; 1874 iShiftIsPressed = 0;
1822 1875
1823 /* Map the VK and CH keysyms */ 1876 /* Map the VK and CH keysyms */
1824 for ( i=0; i<=255; ++i ) 1877 for (i = 0; i <= 255; ++i)
1825 HWScanKeyMap[i] = SDLK_UNKNOWN; 1878 HWScanKeyMap[i] = SDLK_UNKNOWN;
1826 1879
1827 // First line of keyboard: 1880 // First line of keyboard:
1828 HWScanKeyMap[0x1] = SDLK_ESCAPE; 1881 HWScanKeyMap[0x1] = SDLK_ESCAPE;
1829 HWScanKeyMap[0x3b] = SDLK_F1; 1882 HWScanKeyMap[0x3b] = SDLK_F1;
1830 HWScanKeyMap[0x3c] = SDLK_F2; 1883 HWScanKeyMap[0x3c] = SDLK_F2;
1831 HWScanKeyMap[0x3d] = SDLK_F3; 1884 HWScanKeyMap[0x3d] = SDLK_F3;
1832 HWScanKeyMap[0x3e] = SDLK_F4; 1885 HWScanKeyMap[0x3e] = SDLK_F4;
1833 HWScanKeyMap[0x3f] = SDLK_F5; 1886 HWScanKeyMap[0x3f] = SDLK_F5;
1834 HWScanKeyMap[0x40] = SDLK_F6; 1887 HWScanKeyMap[0x40] = SDLK_F6;
1835 HWScanKeyMap[0x41] = SDLK_F7; 1888 HWScanKeyMap[0x41] = SDLK_F7;
1836 HWScanKeyMap[0x42] = SDLK_F8; 1889 HWScanKeyMap[0x42] = SDLK_F8;
1837 HWScanKeyMap[0x43] = SDLK_F9; 1890 HWScanKeyMap[0x43] = SDLK_F9;
1838 HWScanKeyMap[0x44] = SDLK_F10; 1891 HWScanKeyMap[0x44] = SDLK_F10;
1839 HWScanKeyMap[0x57] = SDLK_F11; 1892 HWScanKeyMap[0x57] = SDLK_F11;
1840 HWScanKeyMap[0x58] = SDLK_F12; 1893 HWScanKeyMap[0x58] = SDLK_F12;
1841 HWScanKeyMap[0x5d] = SDLK_PRINT; 1894 HWScanKeyMap[0x5d] = SDLK_PRINT;
1842 HWScanKeyMap[0x46] = SDLK_SCROLLOCK; 1895 HWScanKeyMap[0x46] = SDLK_SCROLLOCK;
1843 HWScanKeyMap[0x5f] = SDLK_PAUSE; 1896 HWScanKeyMap[0x5f] = SDLK_PAUSE;
1844 1897
1845 // Second line of keyboard: 1898 // Second line of keyboard:
1846 HWScanKeyMap[0x29] = SDLK_BACKQUOTE; 1899 HWScanKeyMap[0x29] = SDLK_BACKQUOTE;
1847 HWScanKeyMap[0x2] = SDLK_1; 1900 HWScanKeyMap[0x2] = SDLK_1;
1848 HWScanKeyMap[0x3] = SDLK_2; 1901 HWScanKeyMap[0x3] = SDLK_2;
1849 HWScanKeyMap[0x4] = SDLK_3; 1902 HWScanKeyMap[0x4] = SDLK_3;
1850 HWScanKeyMap[0x5] = SDLK_4; 1903 HWScanKeyMap[0x5] = SDLK_4;
1851 HWScanKeyMap[0x6] = SDLK_5; 1904 HWScanKeyMap[0x6] = SDLK_5;
1852 HWScanKeyMap[0x7] = SDLK_6; 1905 HWScanKeyMap[0x7] = SDLK_6;
1853 HWScanKeyMap[0x8] = SDLK_7; 1906 HWScanKeyMap[0x8] = SDLK_7;
1854 HWScanKeyMap[0x9] = SDLK_8; 1907 HWScanKeyMap[0x9] = SDLK_8;
1855 HWScanKeyMap[0xa] = SDLK_9; 1908 HWScanKeyMap[0xa] = SDLK_9;
1856 HWScanKeyMap[0xb] = SDLK_0; 1909 HWScanKeyMap[0xb] = SDLK_0;
1857 HWScanKeyMap[0xc] = SDLK_MINUS; 1910 HWScanKeyMap[0xc] = SDLK_MINUS;
1858 HWScanKeyMap[0xd] = SDLK_EQUALS; 1911 HWScanKeyMap[0xd] = SDLK_EQUALS;
1859 HWScanKeyMap[0xe] = SDLK_BACKSPACE; 1912 HWScanKeyMap[0xe] = SDLK_BACKSPACE;
1860 HWScanKeyMap[0x68] = SDLK_INSERT; 1913 HWScanKeyMap[0x68] = SDLK_INSERT;
1861 HWScanKeyMap[0x60] = SDLK_HOME; 1914 HWScanKeyMap[0x60] = SDLK_HOME;
1862 HWScanKeyMap[0x62] = SDLK_PAGEUP; 1915 HWScanKeyMap[0x62] = SDLK_PAGEUP;
1863 HWScanKeyMap[0x45] = SDLK_NUMLOCK; 1916 HWScanKeyMap[0x45] = SDLK_NUMLOCK;
1864 HWScanKeyMap[0x5c] = SDLK_KP_DIVIDE; 1917 HWScanKeyMap[0x5c] = SDLK_KP_DIVIDE;
1865 HWScanKeyMap[0x37] = SDLK_KP_MULTIPLY; 1918 HWScanKeyMap[0x37] = SDLK_KP_MULTIPLY;
1866 HWScanKeyMap[0x4a] = SDLK_KP_MINUS; 1919 HWScanKeyMap[0x4a] = SDLK_KP_MINUS;
1867 1920
1868 // Third line of keyboard: 1921 // Third line of keyboard:
1869 HWScanKeyMap[0xf] = SDLK_TAB; 1922 HWScanKeyMap[0xf] = SDLK_TAB;
1870 HWScanKeyMap[0x10] = SDLK_q; 1923 HWScanKeyMap[0x10] = SDLK_q;
1871 HWScanKeyMap[0x11] = SDLK_w; 1924 HWScanKeyMap[0x11] = SDLK_w;
1872 HWScanKeyMap[0x12] = SDLK_e; 1925 HWScanKeyMap[0x12] = SDLK_e;
1873 HWScanKeyMap[0x13] = SDLK_r; 1926 HWScanKeyMap[0x13] = SDLK_r;
1874 HWScanKeyMap[0x14] = SDLK_t; 1927 HWScanKeyMap[0x14] = SDLK_t;
1875 HWScanKeyMap[0x15] = SDLK_y; 1928 HWScanKeyMap[0x15] = SDLK_y;
1876 HWScanKeyMap[0x16] = SDLK_u; 1929 HWScanKeyMap[0x16] = SDLK_u;
1877 HWScanKeyMap[0x17] = SDLK_i; 1930 HWScanKeyMap[0x17] = SDLK_i;
1878 HWScanKeyMap[0x18] = SDLK_o; 1931 HWScanKeyMap[0x18] = SDLK_o;
1879 HWScanKeyMap[0x19] = SDLK_p; 1932 HWScanKeyMap[0x19] = SDLK_p;
1880 HWScanKeyMap[0x1a] = SDLK_LEFTBRACKET; 1933 HWScanKeyMap[0x1a] = SDLK_LEFTBRACKET;
1881 HWScanKeyMap[0x1b] = SDLK_RIGHTBRACKET; 1934 HWScanKeyMap[0x1b] = SDLK_RIGHTBRACKET;
1882 HWScanKeyMap[0x1c] = SDLK_RETURN; 1935 HWScanKeyMap[0x1c] = SDLK_RETURN;
1883 HWScanKeyMap[0x69] = SDLK_DELETE; 1936 HWScanKeyMap[0x69] = SDLK_DELETE;
1884 HWScanKeyMap[0x65] = SDLK_END; 1937 HWScanKeyMap[0x65] = SDLK_END;
1885 HWScanKeyMap[0x67] = SDLK_PAGEDOWN; 1938 HWScanKeyMap[0x67] = SDLK_PAGEDOWN;
1886 HWScanKeyMap[0x47] = SDLK_KP7; 1939 HWScanKeyMap[0x47] = SDLK_KP7;
1887 HWScanKeyMap[0x48] = SDLK_KP8; 1940 HWScanKeyMap[0x48] = SDLK_KP8;
1888 HWScanKeyMap[0x49] = SDLK_KP9; 1941 HWScanKeyMap[0x49] = SDLK_KP9;
1889 HWScanKeyMap[0x4e] = SDLK_KP_PLUS; 1942 HWScanKeyMap[0x4e] = SDLK_KP_PLUS;
1890 1943
1891 // Fourth line of keyboard: 1944 // Fourth line of keyboard:
1892 HWScanKeyMap[0x3a] = SDLK_CAPSLOCK; 1945 HWScanKeyMap[0x3a] = SDLK_CAPSLOCK;
1893 HWScanKeyMap[0x1e] = SDLK_a; 1946 HWScanKeyMap[0x1e] = SDLK_a;
1894 HWScanKeyMap[0x1f] = SDLK_s; 1947 HWScanKeyMap[0x1f] = SDLK_s;
1895 HWScanKeyMap[0x20] = SDLK_d; 1948 HWScanKeyMap[0x20] = SDLK_d;
1896 HWScanKeyMap[0x21] = SDLK_f; 1949 HWScanKeyMap[0x21] = SDLK_f;
1897 HWScanKeyMap[0x22] = SDLK_g; 1950 HWScanKeyMap[0x22] = SDLK_g;
1898 HWScanKeyMap[0x23] = SDLK_h; 1951 HWScanKeyMap[0x23] = SDLK_h;
1899 HWScanKeyMap[0x24] = SDLK_j; 1952 HWScanKeyMap[0x24] = SDLK_j;
1900 HWScanKeyMap[0x25] = SDLK_k; 1953 HWScanKeyMap[0x25] = SDLK_k;
1901 HWScanKeyMap[0x26] = SDLK_l; 1954 HWScanKeyMap[0x26] = SDLK_l;
1902 HWScanKeyMap[0x27] = SDLK_SEMICOLON; 1955 HWScanKeyMap[0x27] = SDLK_SEMICOLON;
1903 HWScanKeyMap[0x28] = SDLK_QUOTE; 1956 HWScanKeyMap[0x28] = SDLK_QUOTE;
1904 HWScanKeyMap[0x2b] = SDLK_BACKSLASH; 1957 HWScanKeyMap[0x2b] = SDLK_BACKSLASH;
1905 HWScanKeyMap[0x4b] = SDLK_KP4; 1958 HWScanKeyMap[0x4b] = SDLK_KP4;
1906 HWScanKeyMap[0x4c] = SDLK_KP5; 1959 HWScanKeyMap[0x4c] = SDLK_KP5;
1907 HWScanKeyMap[0x4d] = SDLK_KP6; 1960 HWScanKeyMap[0x4d] = SDLK_KP6;
1908 1961
1909 // Fifth line of keyboard: 1962 // Fifth line of keyboard:
1910 HWScanKeyMap[0x2a] = SDLK_LSHIFT; 1963 HWScanKeyMap[0x2a] = SDLK_LSHIFT;
1911 HWScanKeyMap[0x56] = SDLK_WORLD_1; // Code 161, letter i' on hungarian keyboard 1964 HWScanKeyMap[0x56] = SDLK_WORLD_1; // Code 161, letter i' on hungarian keyboard
1912 HWScanKeyMap[0x2c] = SDLK_z; 1965 HWScanKeyMap[0x2c] = SDLK_z;
1913 HWScanKeyMap[0x2d] = SDLK_x; 1966 HWScanKeyMap[0x2d] = SDLK_x;
1914 HWScanKeyMap[0x2e] = SDLK_c; 1967 HWScanKeyMap[0x2e] = SDLK_c;
1915 HWScanKeyMap[0x2f] = SDLK_v; 1968 HWScanKeyMap[0x2f] = SDLK_v;
1916 HWScanKeyMap[0x30] = SDLK_b; 1969 HWScanKeyMap[0x30] = SDLK_b;
1917 HWScanKeyMap[0x31] = SDLK_n; 1970 HWScanKeyMap[0x31] = SDLK_n;
1918 HWScanKeyMap[0x32] = SDLK_m; 1971 HWScanKeyMap[0x32] = SDLK_m;
1919 HWScanKeyMap[0x33] = SDLK_COMMA; 1972 HWScanKeyMap[0x33] = SDLK_COMMA;
1920 HWScanKeyMap[0x34] = SDLK_PERIOD; 1973 HWScanKeyMap[0x34] = SDLK_PERIOD;
1921 HWScanKeyMap[0x35] = SDLK_SLASH; 1974 HWScanKeyMap[0x35] = SDLK_SLASH;
1922 HWScanKeyMap[0x36] = SDLK_RSHIFT; 1975 HWScanKeyMap[0x36] = SDLK_RSHIFT;
1923 HWScanKeyMap[0x61] = SDLK_UP; 1976 HWScanKeyMap[0x61] = SDLK_UP;
1924 HWScanKeyMap[0x4f] = SDLK_KP1; 1977 HWScanKeyMap[0x4f] = SDLK_KP1;
1925 HWScanKeyMap[0x50] = SDLK_KP2; 1978 HWScanKeyMap[0x50] = SDLK_KP2;
1926 HWScanKeyMap[0x51] = SDLK_KP3; 1979 HWScanKeyMap[0x51] = SDLK_KP3;
1927 HWScanKeyMap[0x5a] = SDLK_KP_ENTER; 1980 HWScanKeyMap[0x5a] = SDLK_KP_ENTER;
1928 1981
1929 // Sixth line of keyboard: 1982 // Sixth line of keyboard:
1930 HWScanKeyMap[0x1d] = SDLK_LCTRL; 1983 HWScanKeyMap[0x1d] = SDLK_LCTRL;
1931 HWScanKeyMap[0x7e] = SDLK_LSUPER; // Windows key 1984 HWScanKeyMap[0x7e] = SDLK_LSUPER; // Windows key
1932 HWScanKeyMap[0x38] = SDLK_LALT; 1985 HWScanKeyMap[0x38] = SDLK_LALT;
1933 HWScanKeyMap[0x39] = SDLK_SPACE; 1986 HWScanKeyMap[0x39] = SDLK_SPACE;
1934 HWScanKeyMap[0x5e] = SDLK_RALT;// Actually, altgr on my keyboard... 1987 HWScanKeyMap[0x5e] = SDLK_RALT; // Actually, altgr on my keyboard...
1935 HWScanKeyMap[0x7f] = SDLK_RSUPER; 1988 HWScanKeyMap[0x7f] = SDLK_RSUPER;
1936 HWScanKeyMap[0x7c] = SDLK_MENU; 1989 HWScanKeyMap[0x7c] = SDLK_MENU;
1937 HWScanKeyMap[0x5b] = SDLK_RCTRL; 1990 HWScanKeyMap[0x5b] = SDLK_RCTRL;
1938 HWScanKeyMap[0x63] = SDLK_LEFT; 1991 HWScanKeyMap[0x63] = SDLK_LEFT;
1939 HWScanKeyMap[0x66] = SDLK_DOWN; 1992 HWScanKeyMap[0x66] = SDLK_DOWN;
1940 HWScanKeyMap[0x64] = SDLK_RIGHT; 1993 HWScanKeyMap[0x64] = SDLK_RIGHT;
1941 HWScanKeyMap[0x52] = SDLK_KP0; 1994 HWScanKeyMap[0x52] = SDLK_KP0;
1942 HWScanKeyMap[0x53] = SDLK_KP_PERIOD; 1995 HWScanKeyMap[0x53] = SDLK_KP_PERIOD;
1943 } 1996 }
1944 1997
1945 1998
1946 /* Iconify the window. 1999 /* Iconify the window.
1947 This function returns 1 if there is a window manager and the 2000 This function returns 1 if there is a window manager and the
1948 window was actually iconified, it returns 0 otherwise. 2001 window was actually iconified, it returns 0 otherwise.
1949 */ 2002 */
1950 int os2fslib_IconifyWindow(_THIS) 2003 int
1951 { 2004 os2fslib_IconifyWindow(_THIS)
1952 HAB hab; 2005 {
1953 HMQ hmq; 2006 HAB hab;
1954 ERRORID hmqerror; 2007 HMQ hmq;
1955 2008 ERRORID hmqerror;
1956 // If there is no more window, nothing we can do! 2009
1957 if (_this->hidden->iPMThreadStatus!=1) return 0; 2010 // If there is no more window, nothing we can do!
1958 2011 if (_this->hidden->iPMThreadStatus != 1)
1959 // Cannot do anything in fullscreen mode! 2012 return 0;
1960 if (FSLib_QueryFSMode(_this->hidden->hwndClient)) 2013
1961 return 0; 2014 // Cannot do anything in fullscreen mode!
1962 2015 if (FSLib_QueryFSMode(_this->hidden->hwndClient))
1963 // Make sure this thread is prepared for using the Presentation Manager! 2016 return 0;
1964 hab = WinInitialize(0); 2017
1965 hmq = WinCreateMsgQueue(hab,0); 2018 // Make sure this thread is prepared for using the Presentation Manager!
1966 // Remember if there was an error at WinCreateMsgQueue(), because we don't 2019 hab = WinInitialize(0);
1967 // want to destroy somebody else's queue later. :) 2020 hmq = WinCreateMsgQueue(hab, 0);
1968 hmqerror = WinGetLastError(hab); 2021 // Remember if there was an error at WinCreateMsgQueue(), because we don't
1969 2022 // want to destroy somebody else's queue later. :)
1970 WinSetWindowPos(_this->hidden->hwndFrame, HWND_TOP, 2023 hmqerror = WinGetLastError(hab);
1971 0, 0, 0, 0, SWP_MINIMIZE); 2024
1972 2025 WinSetWindowPos(_this->hidden->hwndFrame, HWND_TOP,
1973 // Now destroy the message queue, if we've created it! 2026 0, 0, 0, 0, SWP_MINIMIZE);
1974 if (ERRORIDERROR(hmqerror)==0) 2027
1975 WinDestroyMsgQueue(hmq); 2028 // Now destroy the message queue, if we've created it!
1976 2029 if (ERRORIDERROR(hmqerror) == 0)
1977 return 1; 2030 WinDestroyMsgQueue(hmq);
1978 } 2031
1979 2032 return 1;
1980 static SDL_GrabMode os2fslib_GrabInput(_THIS, SDL_GrabMode mode) 2033 }
1981 { 2034
1982 HAB hab; 2035 static SDL_GrabMode
1983 HMQ hmq; 2036 os2fslib_GrabInput(_THIS, SDL_GrabMode mode)
1984 ERRORID hmqerror; 2037 {
1985 2038 HAB hab;
1986 2039 HMQ hmq;
1987 // If there is no more window, nothing we can do! 2040 ERRORID hmqerror;
1988 if (_this->hidden->iPMThreadStatus!=1) 2041
1989 return SDL_GRAB_OFF; 2042
1990 2043 // If there is no more window, nothing we can do!
1991 // Make sure this thread is prepared for using the Presentation Manager! 2044 if (_this->hidden->iPMThreadStatus != 1)
1992 hab = WinInitialize(0); 2045 return SDL_GRAB_OFF;
1993 hmq = WinCreateMsgQueue(hab,0); 2046
1994 // Remember if there was an error at WinCreateMsgQueue(), because we don't 2047 // Make sure this thread is prepared for using the Presentation Manager!
1995 // want to destroy somebody else's queue later. :) 2048 hab = WinInitialize(0);
1996 hmqerror = WinGetLastError(hab); 2049 hmq = WinCreateMsgQueue(hab, 0);
1997 2050 // Remember if there was an error at WinCreateMsgQueue(), because we don't
1998 2051 // want to destroy somebody else's queue later. :)
1999 if (mode == SDL_GRAB_OFF) 2052 hmqerror = WinGetLastError(hab);
2000 { 2053
2001 #ifdef DEBUG_BUILD 2054
2002 printf("[os2fslib_GrabInput] : Releasing mouse\n"); fflush(stdout); 2055 if (mode == SDL_GRAB_OFF) {
2003 #endif 2056 #ifdef DEBUG_BUILD
2004 2057 printf("[os2fslib_GrabInput] : Releasing mouse\n");
2005 // Release the mouse 2058 fflush(stdout);
2006 bMouseCapturable = 0; 2059 #endif
2007 if (bMouseCaptured) 2060
2008 { 2061 // Release the mouse
2009 WinSetCapture(HWND_DESKTOP, NULLHANDLE); 2062 bMouseCapturable = 0;
2010 bMouseCaptured = 0; 2063 if (bMouseCaptured) {
2011 } 2064 WinSetCapture(HWND_DESKTOP, NULLHANDLE);
2012 } else 2065 bMouseCaptured = 0;
2013 { 2066 }
2014 #ifdef DEBUG_BUILD 2067 } else {
2015 printf("[os2fslib_GrabInput] : Capturing mouse\n"); fflush(stdout); 2068 #ifdef DEBUG_BUILD
2016 #endif 2069 printf("[os2fslib_GrabInput] : Capturing mouse\n");
2017 2070 fflush(stdout);
2018 // Capture the mouse 2071 #endif
2019 bMouseCapturable = 1; 2072
2020 if (WinQueryFocus(HWND_DESKTOP) == _this->hidden->hwndClient) 2073 // Capture the mouse
2021 { 2074 bMouseCapturable = 1;
2022 WinSetCapture(HWND_DESKTOP, _this->hidden->hwndClient); 2075 if (WinQueryFocus(HWND_DESKTOP) == _this->hidden->hwndClient) {
2023 bMouseCaptured = 1; 2076 WinSetCapture(HWND_DESKTOP, _this->hidden->hwndClient);
2024 { 2077 bMouseCaptured = 1;
2025 SWP swpClient; 2078 {
2026 POINTL ptl; 2079 SWP swpClient;
2027 // Center the mouse to the middle of the window! 2080 POINTL ptl;
2028 WinQueryWindowPos(_this->hidden->hwndClient, &swpClient); 2081 // Center the mouse to the middle of the window!
2029 ptl.x = 0; ptl.y = 0; 2082 WinQueryWindowPos(_this->hidden->hwndClient, &swpClient);
2030 WinMapWindowPoints(_this->hidden->hwndClient, HWND_DESKTOP, &ptl, 1); 2083 ptl.x = 0;
2031 _this->hidden->iSkipWMMOUSEMOVE++; /* Don't take next WM_MOUSEMOVE into account! */ 2084 ptl.y = 0;
2032 WinSetPointerPos(HWND_DESKTOP, 2085 WinMapWindowPoints(_this->hidden->hwndClient,
2033 ptl.x + swpClient.cx/2, 2086 HWND_DESKTOP, &ptl, 1);
2034 ptl.y + swpClient.cy/2); 2087 _this->hidden->iSkipWMMOUSEMOVE++; /* Don't take next WM_MOUSEMOVE into account! */
2035 } 2088 WinSetPointerPos(HWND_DESKTOP,
2036 } 2089 ptl.x + swpClient.cx / 2,
2037 } 2090 ptl.y + swpClient.cy / 2);
2038 2091 }
2039 // Now destroy the message queue, if we've created it! 2092 }
2040 if (ERRORIDERROR(hmqerror)==0) 2093 }
2041 WinDestroyMsgQueue(hmq); 2094
2042 2095 // Now destroy the message queue, if we've created it!
2043 return mode; 2096 if (ERRORIDERROR(hmqerror) == 0)
2097 WinDestroyMsgQueue(hmq);
2098
2099 return mode;
2044 } 2100 }
2045 2101
2046 /* Set the title and icon text */ 2102 /* Set the title and icon text */
2047 static void os2fslib_SetCaption(_THIS, const char *title, const char *icon) 2103 static void
2048 { 2104 os2fslib_SetCaption(_THIS, const char *title, const char *icon)
2049 HAB hab; 2105 {
2050 HMQ hmq; 2106 HAB hab;
2051 ERRORID hmqerror; 2107 HMQ hmq;
2052 2108 ERRORID hmqerror;
2053 // If there is no more window, nothing we can do! 2109
2054 if (_this->hidden->iPMThreadStatus!=1) return; 2110 // If there is no more window, nothing we can do!
2055 2111 if (_this->hidden->iPMThreadStatus != 1)
2056 // Make sure this thread is prepared for using the Presentation Manager! 2112 return;
2057 hab = WinInitialize(0); 2113
2058 hmq = WinCreateMsgQueue(hab,0); 2114 // Make sure this thread is prepared for using the Presentation Manager!
2059 // Remember if there was an error at WinCreateMsgQueue(), because we don't 2115 hab = WinInitialize(0);
2060 // want to destroy somebody else's queue later. :) 2116 hmq = WinCreateMsgQueue(hab, 0);
2061 hmqerror = WinGetLastError(hab); 2117 // Remember if there was an error at WinCreateMsgQueue(), because we don't
2062 2118 // want to destroy somebody else's queue later. :)
2063 WinSetWindowText(_this->hidden->hwndFrame, (char *) title); 2119 hmqerror = WinGetLastError(hab);
2064 2120
2065 // Now destroy the message queue, if we've created it! 2121 WinSetWindowText(_this->hidden->hwndFrame, (char *) title);
2066 if (ERRORIDERROR(hmqerror)==0) 2122
2067 WinDestroyMsgQueue(hmq); 2123 // Now destroy the message queue, if we've created it!
2068 } 2124 if (ERRORIDERROR(hmqerror) == 0)
2069 2125 WinDestroyMsgQueue(hmq);
2070 static int os2fslib_ToggleFullScreen(_THIS, int on) 2126 }
2071 { 2127
2072 #ifdef DEBUG_BUILD 2128 static int
2073 printf("[os2fslib_ToggleFullScreen] : %d\n", on); fflush(stdout); 2129 os2fslib_ToggleFullScreen(_THIS, int on)
2074 #endif 2130 {
2075 // If there is no more window, nothing we can do! 2131 #ifdef DEBUG_BUILD
2076 if (_this->hidden->iPMThreadStatus!=1) return 0; 2132 printf("[os2fslib_ToggleFullScreen] : %d\n", on);
2077 2133 fflush(stdout);
2078 FSLib_ToggleFSMode(_this->hidden->hwndClient, on); 2134 #endif
2079 /* Cursor manager functions to Windowed/FS mode*/ 2135 // If there is no more window, nothing we can do!
2080 os2fslib_SetCursorManagementFunctions(_this, !on); 2136 if (_this->hidden->iPMThreadStatus != 1)
2081 return 1; 2137 return 0;
2138
2139 FSLib_ToggleFSMode(_this->hidden->hwndClient, on);
2140 /* Cursor manager functions to Windowed/FS mode */
2141 os2fslib_SetCursorManagementFunctions(_this, !on);
2142 return 1;
2082 } 2143 }
2083 2144
2084 /* This is called after the video mode has been set, to get the 2145 /* This is called after the video mode has been set, to get the
2085 initial mouse state. It should queue events as necessary to 2146 initial mouse state. It should queue events as necessary to
2086 properly represent the current mouse focus and position. 2147 properly represent the current mouse focus and position.
2087 */ 2148 */
2088 static void os2fslib_UpdateMouse(_THIS) 2149 static void
2089 { 2150 os2fslib_UpdateMouse(_THIS)
2090 POINTL ptl; 2151 {
2091 HAB hab; 2152 POINTL ptl;
2092 HMQ hmq; 2153 HAB hab;
2093 ERRORID hmqerror; 2154 HMQ hmq;
2094 SWP swpClient; 2155 ERRORID hmqerror;
2095 2156 SWP swpClient;
2096 // If there is no more window, nothing we can do! 2157
2097 if (_this->hidden->iPMThreadStatus!=1) return; 2158 // If there is no more window, nothing we can do!
2098 2159 if (_this->hidden->iPMThreadStatus != 1)
2099 2160 return;
2100 // Make sure this thread is prepared for using the Presentation Manager! 2161
2101 hab = WinInitialize(0); 2162
2102 hmq = WinCreateMsgQueue(hab,0); 2163 // Make sure this thread is prepared for using the Presentation Manager!
2103 // Remember if there was an error at WinCreateMsgQueue(), because we don't 2164 hab = WinInitialize(0);
2104 // want to destroy somebody else's queue later. :) 2165 hmq = WinCreateMsgQueue(hab, 0);
2105 hmqerror = WinGetLastError(hab); 2166 // Remember if there was an error at WinCreateMsgQueue(), because we don't
2106 2167 // want to destroy somebody else's queue later. :)
2107 2168 hmqerror = WinGetLastError(hab);
2108 2169
2109 if (_this->hidden->fInFocus) 2170
2110 { 2171
2111 // If our app is in focus 2172 if (_this->hidden->fInFocus) {
2112 SDL_PrivateAppActive(1, SDL_APPMOUSEFOCUS); 2173 // If our app is in focus
2113 SDL_PrivateAppActive(1, SDL_APPINPUTFOCUS); 2174 SDL_PrivateAppActive(1, SDL_APPMOUSEFOCUS);
2114 SDL_PrivateAppActive(1, SDL_APPACTIVE); 2175 SDL_PrivateAppActive(1, SDL_APPINPUTFOCUS);
2115 WinQueryPointerPos(HWND_DESKTOP, &ptl); 2176 SDL_PrivateAppActive(1, SDL_APPACTIVE);
2116 WinMapWindowPoints(HWND_DESKTOP, _this->hidden->hwndClient, &ptl, 1); 2177 WinQueryPointerPos(HWND_DESKTOP, &ptl);
2117 WinQueryWindowPos(_this->hidden->hwndClient, &swpClient); 2178 WinMapWindowPoints(HWND_DESKTOP, _this->hidden->hwndClient, &ptl, 1);
2118 // Convert OS/2 mouse position to SDL position, and also scale it! 2179 WinQueryWindowPos(_this->hidden->hwndClient, &swpClient);
2119 ptl.x = ptl.x * _this->hidden->SrcBufferDesc.uiXResolution / swpClient.cx; 2180 // Convert OS/2 mouse position to SDL position, and also scale it!
2120 ptl.y = ptl.y * _this->hidden->SrcBufferDesc.uiYResolution / swpClient.cy; 2181 ptl.x =
2121 ptl.y = _this->hidden->SrcBufferDesc.uiYResolution - ptl.y - 1; 2182 ptl.x * _this->hidden->SrcBufferDesc.uiXResolution / swpClient.cx;
2122 SDL_PrivateMouseMotion(0, 0, (Sint16) (ptl.x), (Sint16) (ptl.y)); 2183 ptl.y =
2123 } else 2184 ptl.y * _this->hidden->SrcBufferDesc.uiYResolution / swpClient.cy;
2124 { 2185 ptl.y = _this->hidden->SrcBufferDesc.uiYResolution - ptl.y - 1;
2125 // If we're not in focus 2186 SDL_PrivateMouseMotion(0, 0, (Sint16) (ptl.x), (Sint16) (ptl.y));
2126 SDL_PrivateAppActive(0, SDL_APPMOUSEFOCUS); 2187 } else {
2127 SDL_PrivateAppActive(0, SDL_APPINPUTFOCUS); 2188 // If we're not in focus
2128 SDL_PrivateAppActive(0, SDL_APPACTIVE); 2189 SDL_PrivateAppActive(0, SDL_APPMOUSEFOCUS);
2129 SDL_PrivateMouseMotion(0, 0, (Sint16) -1, (Sint16) -1); 2190 SDL_PrivateAppActive(0, SDL_APPINPUTFOCUS);
2130 } 2191 SDL_PrivateAppActive(0, SDL_APPACTIVE);
2131 2192 SDL_PrivateMouseMotion(0, 0, (Sint16) - 1, (Sint16) - 1);
2132 // Now destroy the message queue, if we've created it! 2193 }
2133 if (ERRORIDERROR(hmqerror)==0) 2194
2134 WinDestroyMsgQueue(hmq); 2195 // Now destroy the message queue, if we've created it!
2196 if (ERRORIDERROR(hmqerror) == 0)
2197 WinDestroyMsgQueue(hmq);
2135 2198
2136 } 2199 }
2137 2200
2138 /* This pointer should exist in the native video subsystem and should 2201 /* This pointer should exist in the native video subsystem and should
2139 point to an appropriate update function for the current video mode 2202 point to an appropriate update function for the current video mode
2140 */ 2203 */
2141 static void os2fslib_UpdateRects(_THIS, int numrects, SDL_Rect *rects) 2204 static void
2142 { 2205 os2fslib_UpdateRects(_THIS, int numrects, SDL_Rect * rects)
2143 // If there is no more window, nothing we can do! 2206 {
2144 if (_this->hidden->iPMThreadStatus!=1) return; 2207 // If there is no more window, nothing we can do!
2208 if (_this->hidden->iPMThreadStatus != 1)
2209 return;
2145 2210
2146 #ifdef BITBLT_IN_WINMESSAGEPROC 2211 #ifdef BITBLT_IN_WINMESSAGEPROC
2147 WinSendMsg(_this->hidden->hwndClient, 2212 WinSendMsg(_this->hidden->hwndClient,
2148 WM_UPDATERECTSREQUEST, 2213 WM_UPDATERECTSREQUEST, (MPARAM) numrects, (MPARAM) rects);
2149 (MPARAM) numrects,
2150 (MPARAM) rects);
2151 #else 2214 #else
2152 if (DosRequestMutexSem(_this->hidden->hmtxUseSrcBuffer, SEM_INDEFINITE_WAIT)==NO_ERROR) 2215 if (DosRequestMutexSem
2153 { 2216 (_this->hidden->hmtxUseSrcBuffer, SEM_INDEFINITE_WAIT) == NO_ERROR) {
2154 int i; 2217 int i;
2155 2218
2156 if (_this->hidden->pSDLSurface) 2219 if (_this->hidden->pSDLSurface) {
2157 {
2158 #ifndef RESIZE_EVEN_IF_RESIZABLE 2220 #ifndef RESIZE_EVEN_IF_RESIZABLE
2159 SWP swp; 2221 SWP swp;
2160 // But only blit if the window is not resizable, or if 2222 // But only blit if the window is not resizable, or if
2161 // the window is resizable and the source buffer size is the 2223 // the window is resizable and the source buffer size is the
2162 // same as the destination buffer size! 2224 // same as the destination buffer size!
2163 WinQueryWindowPos(_this->hidden->hwndClient, &swp); 2225 WinQueryWindowPos(_this->hidden->hwndClient, &swp);
2164 if ((_this->hidden->pSDLSurface) && 2226 if ((_this->hidden->pSDLSurface) &&
2165 (_this->hidden->pSDLSurface->flags & SDL_RESIZABLE) && 2227 (_this->hidden->pSDLSurface->flags & SDL_RESIZABLE) &&
2166 ((swp.cx != _this->hidden->SrcBufferDesc.uiXResolution) || 2228 ((swp.cx != _this->hidden->SrcBufferDesc.uiXResolution) ||
2167 (swp.cy != _this->hidden->SrcBufferDesc.uiYResolution) 2229 (swp.cy != _this->hidden->SrcBufferDesc.uiYResolution))
2168 ) && 2230 && (!FSLib_QueryFSMode(_this->hidden->hwndClient))) {
2169 (!FSLib_QueryFSMode(_this->hidden->hwndClient)) 2231 // Resizable surface and in resizing!
2170 ) 2232 // So, don't blit now!
2171 { 2233 #ifdef DEBUG_BUILD
2172 // Resizable surface and in resizing! 2234 printf("[UpdateRects] : Skipping blit while resizing!\n");
2173 // So, don't blit now! 2235 fflush(stdout);
2174 #ifdef DEBUG_BUILD 2236 #endif
2175 printf("[UpdateRects] : Skipping blit while resizing!\n"); fflush(stdout); 2237 } else
2176 #endif 2238 #endif
2177 } else 2239 {
2178 #endif 2240 /*
2179 { 2241 // Blit the whole window
2180 /* 2242 FSLIB_BITBLT(_this->hidden->hwndClient, _this->hidden->pchSrcBuffer,
2181 // Blit the whole window 2243 0, 0,
2182 FSLIB_BITBLT(_this->hidden->hwndClient, _this->hidden->pchSrcBuffer, 2244 _this->hidden->SrcBufferDesc.uiXResolution,
2183 0, 0, 2245 _this->hidden->SrcBufferDesc.uiYResolution);
2184 _this->hidden->SrcBufferDesc.uiXResolution, 2246 */
2185 _this->hidden->SrcBufferDesc.uiYResolution); 2247 #ifdef DEBUG_BUILD
2186 */ 2248 printf("[os2fslib_UpdateRects] : Blitting!\n");
2187 #ifdef DEBUG_BUILD 2249 fflush(stdout);
2188 printf("[os2fslib_UpdateRects] : Blitting!\n"); fflush(stdout); 2250 #endif
2189 #endif 2251
2190 2252 // Blit the changed areas
2191 // Blit the changed areas 2253 for (i = 0; i < numrects; i++)
2192 for (i=0; i<numrects; i++) 2254 FSLIB_BITBLT(_this->hidden->hwndClient,
2193 FSLIB_BITBLT(_this->hidden->hwndClient, _this->hidden->pchSrcBuffer, 2255 _this->hidden->pchSrcBuffer,
2194 rects[i].y, rects[i].x, rects[i].w, rects[i].h); 2256 rects[i].y, rects[i].x, rects[i].w,
2195 } 2257 rects[i].h);
2196 } 2258 }
2197 #ifdef DEBUG_BUILD 2259 }
2198 else 2260 #ifdef DEBUG_BUILD
2199 printf("[os2fslib_UpdateRects] : No public surface!\n"); fflush(stdout); 2261 else
2200 #endif 2262 printf("[os2fslib_UpdateRects] : No public surface!\n");
2201 DosReleaseMutexSem(_this->hidden->hmtxUseSrcBuffer); 2263 fflush(stdout);
2202 } 2264 #endif
2203 #ifdef DEBUG_BUILD 2265 DosReleaseMutexSem(_this->hidden->hmtxUseSrcBuffer);
2204 else 2266 }
2205 printf("[os2fslib_UpdateRects] : Error in mutex!\n"); fflush(stdout); 2267 #ifdef DEBUG_BUILD
2268 else
2269 printf("[os2fslib_UpdateRects] : Error in mutex!\n");
2270 fflush(stdout);
2206 #endif 2271 #endif
2207 #endif 2272 #endif
2208 } 2273 }
2209 2274
2210 2275
2211 /* Reverse the effects VideoInit() -- called if VideoInit() fails 2276 /* Reverse the effects VideoInit() -- called if VideoInit() fails
2212 or if the application is shutting down the video subsystem. 2277 or if the application is shutting down the video subsystem.
2213 */ 2278 */
2214 static void os2fslib_VideoQuit(_THIS) 2279 static void
2215 { 2280 os2fslib_VideoQuit(_THIS)
2216 #ifdef DEBUG_BUILD 2281 {
2217 printf("[os2fslib_VideoQuit]\n"); fflush(stdout); 2282 #ifdef DEBUG_BUILD
2218 #endif 2283 printf("[os2fslib_VideoQuit]\n");
2219 // Close PM stuff if running! 2284 fflush(stdout);
2220 if (_this->hidden->iPMThreadStatus == 1) 2285 #endif
2221 { 2286 // Close PM stuff if running!
2222 int iTimeout; 2287 if (_this->hidden->iPMThreadStatus == 1) {
2223 WinPostMsg(_this->hidden->hwndFrame, WM_QUIT, (MPARAM) 0, (MPARAM) 0); 2288 int iTimeout;
2224 // HACK: We had this line before: 2289 WinPostMsg(_this->hidden->hwndFrame, WM_QUIT, (MPARAM) 0, (MPARAM) 0);
2225 //DosWaitThread((TID *) &(_this->hidden->tidPMThread), DCWW_WAIT); 2290 // HACK: We had this line before:
2226 // We don't use it, because the PMThread will never stop, or if it stops, 2291 //DosWaitThread((TID *) &(_this->hidden->tidPMThread), DCWW_WAIT);
2227 // it will kill the whole process as a emergency fallback. 2292 // We don't use it, because the PMThread will never stop, or if it stops,
2228 // So, we only check for the iPMThreadStatus stuff! 2293 // it will kill the whole process as a emergency fallback.
2229 #ifdef DEBUG_BUILD 2294 // So, we only check for the iPMThreadStatus stuff!
2230 printf("[os2fslib_VideoQuit] : Waiting for PM thread to die\n"); fflush(stdout); 2295 #ifdef DEBUG_BUILD
2231 #endif 2296 printf("[os2fslib_VideoQuit] : Waiting for PM thread to die\n");
2232 2297 fflush(stdout);
2233 iTimeout=0; 2298 #endif
2234 while ((_this->hidden->iPMThreadStatus == 1) && (iTimeout<100)) 2299
2235 { 2300 iTimeout = 0;
2236 iTimeout++; 2301 while ((_this->hidden->iPMThreadStatus == 1) && (iTimeout < 100)) {
2237 DosSleep(64); 2302 iTimeout++;
2238 } 2303 DosSleep(64);
2239 2304 }
2240 #ifdef DEBUG_BUILD 2305
2241 printf("[os2fslib_VideoQuit] : End of wait.\n"); fflush(stdout); 2306 #ifdef DEBUG_BUILD
2242 #endif 2307 printf("[os2fslib_VideoQuit] : End of wait.\n");
2243 2308 fflush(stdout);
2244 if (_this->hidden->iPMThreadStatus == 1) 2309 #endif
2245 { 2310
2246 #ifdef DEBUG_BUILD 2311 if (_this->hidden->iPMThreadStatus == 1) {
2247 printf("[os2fslib_VideoQuit] : Killing PM thread!\n"); fflush(stdout); 2312 #ifdef DEBUG_BUILD
2248 #endif 2313 printf("[os2fslib_VideoQuit] : Killing PM thread!\n");
2249 2314 fflush(stdout);
2250 _this->hidden->iPMThreadStatus = 0; 2315 #endif
2251 DosKillThread(_this->hidden->tidPMThread); 2316
2252 2317 _this->hidden->iPMThreadStatus = 0;
2253 if (_this->hidden->hwndFrame) 2318 DosKillThread(_this->hidden->tidPMThread);
2254 { 2319
2255 #ifdef DEBUG_BUILD 2320 if (_this->hidden->hwndFrame) {
2256 printf("[os2fslib_VideoQuit] : Destroying PM window!\n"); fflush(stdout); 2321 #ifdef DEBUG_BUILD
2257 #endif 2322 printf("[os2fslib_VideoQuit] : Destroying PM window!\n");
2258 2323 fflush(stdout);
2259 WinDestroyWindow(_this->hidden->hwndFrame); _this->hidden->hwndFrame=NULL; 2324 #endif
2260 } 2325
2261 } 2326 WinDestroyWindow(_this->hidden->hwndFrame);
2262 2327 _this->hidden->hwndFrame = NULL;
2263 } 2328 }
2264 2329 }
2265 // Free result of an old ListModes() call, because there is 2330
2266 // no FreeListModes() call in SDL! 2331 }
2267 if (_this->hidden->pListModesResult) 2332 // Free result of an old ListModes() call, because there is
2268 { 2333 // no FreeListModes() call in SDL!
2269 SDL_free(_this->hidden->pListModesResult); _this->hidden->pListModesResult = NULL; 2334 if (_this->hidden->pListModesResult) {
2270 } 2335 SDL_free(_this->hidden->pListModesResult);
2271 2336 _this->hidden->pListModesResult = NULL;
2272 // Free list of available fullscreen modes 2337 }
2273 if (_this->hidden->pAvailableFSLibVideoModes) 2338 // Free list of available fullscreen modes
2274 { 2339 if (_this->hidden->pAvailableFSLibVideoModes) {
2275 FSLib_FreeVideoModeList(_this->hidden->pAvailableFSLibVideoModes); 2340 FSLib_FreeVideoModeList(_this->hidden->pAvailableFSLibVideoModes);
2276 _this->hidden->pAvailableFSLibVideoModes = NULL; 2341 _this->hidden->pAvailableFSLibVideoModes = NULL;
2277 } 2342 }
2278 2343 // Free application icon if we had one
2279 // Free application icon if we had one 2344 if (hptrCurrentIcon) {
2280 if (hptrCurrentIcon) 2345 WinDestroyPointer(hptrCurrentIcon);
2281 { 2346 hptrCurrentIcon = NULL;
2282 WinDestroyPointer(hptrCurrentIcon); 2347 }
2283 hptrCurrentIcon = NULL;
2284 }
2285 } 2348 }
2286 2349
2287 /* Set the requested video mode, returning a surface which will be 2350 /* Set the requested video mode, returning a surface which will be
2288 set to the SDL_VideoSurface. The width and height will already 2351 set to the SDL_VideoSurface. The width and height will already
2289 be verified by ListModes(), and the video subsystem is free to 2352 be verified by ListModes(), and the video subsystem is free to
2290 set the mode to a supported bit depth different from the one 2353 set the mode to a supported bit depth different from the one
2291 specified -- the desired bpp will be emulated with a shadow 2354 specified -- the desired bpp will be emulated with a shadow
2292 surface if necessary. If a new mode is returned, this function 2355 surface if necessary. If a new mode is returned, this function
2293 should take care of cleaning up the current mode. 2356 should take care of cleaning up the current mode.
2294 */ 2357 */
2295 static SDL_Surface *os2fslib_SetVideoMode(_THIS, SDL_Surface *current, 2358 static SDL_Surface *
2296 int width, int height, int bpp, Uint32 flags) 2359 os2fslib_SetVideoMode(_THIS, SDL_Surface * current,
2297 { 2360 int width, int height, int bpp, Uint32 flags)
2298 static int bFirstCall = 1; 2361 {
2299 FSLib_VideoMode_p pModeInfo, pModeInfoFound; 2362 static int bFirstCall = 1;
2300 FSLib_VideoMode TempModeInfo; 2363 FSLib_VideoMode_p pModeInfo, pModeInfoFound;
2301 HAB hab; 2364 FSLib_VideoMode TempModeInfo;
2302 HMQ hmq; 2365 HAB hab;
2303 ERRORID hmqerror; 2366 HMQ hmq;
2304 RECTL rectl; 2367 ERRORID hmqerror;
2305 SDL_Surface *pResult; 2368 RECTL rectl;
2306 2369 SDL_Surface *pResult;
2307 // If there is no more window, nothing we can do! 2370
2308 if (_this->hidden->iPMThreadStatus!=1) return NULL; 2371 // If there is no more window, nothing we can do!
2309 2372 if (_this->hidden->iPMThreadStatus != 1)
2310 #ifdef DEBUG_BUILD 2373 return NULL;
2311 printf("[os2fslib_SetVideoMode] : Request for %dx%d @ %dBPP, flags=0x%x\n", width, height, bpp, flags); fflush(stdout); 2374
2312 #endif 2375 #ifdef DEBUG_BUILD
2313 2376 printf
2314 // We don't support palette modes! 2377 ("[os2fslib_SetVideoMode] : Request for %dx%d @ %dBPP, flags=0x%x\n",
2315 if (bpp==8) bpp=32; 2378 width, height, bpp, flags);
2316 2379 fflush(stdout);
2317 // Also, we don't support resizable modes in fullscreen mode. 2380 #endif
2318 if (flags & SDL_RESIZABLE) 2381
2319 flags &= ~SDL_FULLSCREEN; 2382 // We don't support palette modes!
2320 2383 if (bpp == 8)
2321 // No double buffered mode 2384 bpp = 32;
2322 if (flags & SDL_DOUBLEBUF) 2385
2323 flags &= ~SDL_DOUBLEBUF; 2386 // Also, we don't support resizable modes in fullscreen mode.
2324 2387 if (flags & SDL_RESIZABLE)
2325 // And, we don't support HWSURFACE yet. 2388 flags &= ~SDL_FULLSCREEN;
2326 if (flags & SDL_HWSURFACE) 2389
2327 { 2390 // No double buffered mode
2328 flags &= ~SDL_HWSURFACE; 2391 if (flags & SDL_DOUBLEBUF)
2329 flags |= SDL_SWSURFACE; 2392 flags &= ~SDL_DOUBLEBUF;
2330 } 2393
2331 2394 // And, we don't support HWSURFACE yet.
2332 #ifdef DEBUG_BUILD 2395 if (flags & SDL_HWSURFACE) {
2333 printf("[os2fslib_SetVideoMode] : Changed request to %dx%d @ %dBPP, flags=0x%x\n", width, height, bpp, flags); fflush(stdout); 2396 flags &= ~SDL_HWSURFACE;
2334 #endif 2397 flags |= SDL_SWSURFACE;
2335 2398 }
2336 // First check if there is such a video mode they want! 2399 #ifdef DEBUG_BUILD
2337 pModeInfoFound = NULL; 2400 printf
2338 2401 ("[os2fslib_SetVideoMode] : Changed request to %dx%d @ %dBPP, flags=0x%x\n",
2339 // For fullscreen mode we don't support every resolution! 2402 width, height, bpp, flags);
2340 // So, go through the video modes, and check for such a resolution! 2403 fflush(stdout);
2341 pModeInfoFound = NULL; 2404 #endif
2342 pModeInfo = _this->hidden->pAvailableFSLibVideoModes; 2405
2343 2406 // First check if there is such a video mode they want!
2344 while (pModeInfo) 2407 pModeInfoFound = NULL;
2345 { 2408
2346 // Check all available fullscreen modes for this resolution 2409 // For fullscreen mode we don't support every resolution!
2347 if ((pModeInfo->uiXResolution == width) && 2410 // So, go through the video modes, and check for such a resolution!
2348 (pModeInfo->uiYResolution == height) && 2411 pModeInfoFound = NULL;
2349 (pModeInfo->uiBPP!=8)) // palettized modes not yet supported
2350 {
2351 // If good resolution, try to find the exact BPP, or at least
2352 // something similar...
2353 if (!pModeInfoFound)
2354 pModeInfoFound = pModeInfo;
2355 else
2356 if ((pModeInfoFound->uiBPP!=bpp) &&
2357 (pModeInfoFound->uiBPP<pModeInfo->uiBPP))
2358 pModeInfoFound = pModeInfo;
2359 }
2360 pModeInfo = pModeInfo->pNext;
2361 }
2362
2363 // If we did not find a good fullscreen mode, then try a similar
2364 if (!pModeInfoFound)
2365 {
2366 #ifdef DEBUG_BUILD
2367 printf("[os2fslib_SetVideoMode] : Requested video mode not found, looking for a similar one!\n"); fflush(stdout);
2368 #endif
2369 // Go through the video modes again, and find a similar resolution!
2370 pModeInfo = _this->hidden->pAvailableFSLibVideoModes; 2412 pModeInfo = _this->hidden->pAvailableFSLibVideoModes;
2371 while (pModeInfo) 2413
2372 { 2414 while (pModeInfo) {
2373 // Check all available fullscreen modes for this resolution 2415 // Check all available fullscreen modes for this resolution
2374 if ((pModeInfo->uiXResolution >= width) && 2416 if ((pModeInfo->uiXResolution == width) && (pModeInfo->uiYResolution == height) && (pModeInfo->uiBPP != 8)) // palettized modes not yet supported
2375 (pModeInfo->uiYResolution >= height) &&
2376 (pModeInfo->uiBPP == bpp))
2377 {
2378 if (!pModeInfoFound)
2379 pModeInfoFound = pModeInfo;
2380 else
2381 if (((pModeInfoFound->uiXResolution-width)*(pModeInfoFound->uiYResolution-height))>
2382 ((pModeInfo->uiXResolution-width)*(pModeInfo->uiYResolution-height)))
2383 { 2417 {
2384 // Found a mode which is closer than the current one 2418 // If good resolution, try to find the exact BPP, or at least
2385 pModeInfoFound = pModeInfo; 2419 // something similar...
2386 } 2420 if (!pModeInfoFound)
2387 } 2421 pModeInfoFound = pModeInfo;
2388 pModeInfo = pModeInfo->pNext; 2422 else if ((pModeInfoFound->uiBPP != bpp) &&
2389 } 2423 (pModeInfoFound->uiBPP < pModeInfo->uiBPP))
2390 } 2424 pModeInfoFound = pModeInfo;
2391 2425 }
2392 // If we did not find a good fullscreen mode, then return NULL 2426 pModeInfo = pModeInfo->pNext;
2393 if (!pModeInfoFound) 2427 }
2394 { 2428
2395 #ifdef DEBUG_BUILD 2429 // If we did not find a good fullscreen mode, then try a similar
2396 printf("[os2fslib_SetVideoMode] : Requested video mode not found!\n"); fflush(stdout); 2430 if (!pModeInfoFound) {
2397 #endif 2431 #ifdef DEBUG_BUILD
2398 return NULL; 2432 printf
2399 } 2433 ("[os2fslib_SetVideoMode] : Requested video mode not found, looking for a similar one!\n");
2400 2434 fflush(stdout);
2401 #ifdef DEBUG_BUILD 2435 #endif
2402 printf("[os2fslib_SetVideoMode] : Found mode!\n"); fflush(stdout); 2436 // Go through the video modes again, and find a similar resolution!
2403 #endif 2437 pModeInfo = _this->hidden->pAvailableFSLibVideoModes;
2404 2438 while (pModeInfo) {
2405 // We'll possibly adjust the structure, so copy out the values 2439 // Check all available fullscreen modes for this resolution
2406 // into TempModeInfo! 2440 if ((pModeInfo->uiXResolution >= width) &&
2407 SDL_memcpy(&TempModeInfo, pModeInfoFound, sizeof(TempModeInfo)); 2441 (pModeInfo->uiYResolution >= height) &&
2408 pModeInfoFound = &TempModeInfo; 2442 (pModeInfo->uiBPP == bpp)) {
2409 2443 if (!pModeInfoFound)
2410 if (flags & SDL_RESIZABLE) 2444 pModeInfoFound = pModeInfo;
2411 { 2445 else if (((pModeInfoFound->uiXResolution -
2412 #ifdef DEBUG_BUILD 2446 width) * (pModeInfoFound->uiYResolution -
2413 printf("[os2fslib_SetVideoMode] : Requested mode is resizable, changing width/height\n"); fflush(stdout); 2447 height)) >
2414 #endif 2448 ((pModeInfo->uiXResolution -
2415 // Change width and height to requested one! 2449 width) * (pModeInfo->uiYResolution - height))) {
2416 TempModeInfo.uiXResolution = width; 2450 // Found a mode which is closer than the current one
2417 TempModeInfo.uiYResolution = height; 2451 pModeInfoFound = pModeInfo;
2418 TempModeInfo.uiScanLineSize = width * ((TempModeInfo.uiBPP+7)/8); 2452 }
2419 } 2453 }
2420 2454 pModeInfo = pModeInfo->pNext;
2421 // We can try create new surface! 2455 }
2422 2456 }
2423 // Make sure this thread is prepared for using the Presentation Manager! 2457 // If we did not find a good fullscreen mode, then return NULL
2424 hab = WinInitialize(0); 2458 if (!pModeInfoFound) {
2425 hmq = WinCreateMsgQueue(hab,0); 2459 #ifdef DEBUG_BUILD
2426 // Remember if there was an error at WinCreateMsgQueue(), because we don't 2460 printf("[os2fslib_SetVideoMode] : Requested video mode not found!\n");
2427 // want to destroy somebody else's queue later. :) 2461 fflush(stdout);
2428 hmqerror = WinGetLastError(hab); 2462 #endif
2429 2463 return NULL;
2430 2464 }
2431 2465 #ifdef DEBUG_BUILD
2432 if (DosRequestMutexSem(_this->hidden->hmtxUseSrcBuffer, SEM_INDEFINITE_WAIT)==NO_ERROR) 2466 printf("[os2fslib_SetVideoMode] : Found mode!\n");
2433 { 2467 fflush(stdout);
2434 #ifdef DEBUG_BUILD 2468 #endif
2435 printf("[os2fslib_SetVideoMode] : Creating new SW surface\n"); fflush(stdout); 2469
2436 #endif 2470 // We'll possibly adjust the structure, so copy out the values
2437 2471 // into TempModeInfo!
2438 // Create new software surface! 2472 SDL_memcpy(&TempModeInfo, pModeInfoFound, sizeof(TempModeInfo));
2439 pResult = SDL_CreateRGBSurface(SDL_SWSURFACE, 2473 pModeInfoFound = &TempModeInfo;
2440 pModeInfoFound->uiXResolution, 2474
2441 pModeInfoFound->uiYResolution, 2475 if (flags & SDL_RESIZABLE) {
2442 pModeInfoFound->uiBPP, 2476 #ifdef DEBUG_BUILD
2443 ((unsigned int) pModeInfoFound->PixelFormat.ucRedMask) << pModeInfoFound->PixelFormat.ucRedPosition, 2477 printf
2444 ((unsigned int) pModeInfoFound->PixelFormat.ucGreenMask) << pModeInfoFound->PixelFormat.ucGreenPosition, 2478 ("[os2fslib_SetVideoMode] : Requested mode is resizable, changing width/height\n");
2445 ((unsigned int) pModeInfoFound->PixelFormat.ucBlueMask) << pModeInfoFound->PixelFormat.ucBluePosition, 2479 fflush(stdout);
2446 ((unsigned int) pModeInfoFound->PixelFormat.ucAlphaMask) << pModeInfoFound->PixelFormat.ucAlphaPosition); 2480 #endif
2447 2481 // Change width and height to requested one!
2448 if (pResult == NULL) 2482 TempModeInfo.uiXResolution = width;
2449 { 2483 TempModeInfo.uiYResolution = height;
2450 DosReleaseMutexSem(_this->hidden->hmtxUseSrcBuffer); 2484 TempModeInfo.uiScanLineSize = width * ((TempModeInfo.uiBPP + 7) / 8);
2451 SDL_OutOfMemory(); 2485 }
2452 return NULL; 2486 // We can try create new surface!
2453 } 2487
2454 2488 // Make sure this thread is prepared for using the Presentation Manager!
2455 #ifdef DEBUG_BUILD 2489 hab = WinInitialize(0);
2456 printf("[os2fslib_SetVideoMode] : Adjusting pixel format\n"); fflush(stdout); 2490 hmq = WinCreateMsgQueue(hab, 0);
2457 #endif 2491 // Remember if there was an error at WinCreateMsgQueue(), because we don't
2458 2492 // want to destroy somebody else's queue later. :)
2459 // Adjust pixel format mask! 2493 hmqerror = WinGetLastError(hab);
2460 pResult->format->Rmask = ((unsigned int) pModeInfoFound->PixelFormat.ucRedMask) << pModeInfoFound->PixelFormat.ucRedPosition; 2494
2461 pResult->format->Rshift = pModeInfoFound->PixelFormat.ucRedPosition; 2495
2462 pResult->format->Rloss = pModeInfoFound->PixelFormat.ucRedAdjust; 2496
2463 pResult->format->Gmask = ((unsigned int) pModeInfoFound->PixelFormat.ucGreenMask) << pModeInfoFound->PixelFormat.ucGreenPosition; 2497 if (DosRequestMutexSem
2464 pResult->format->Gshift = pModeInfoFound->PixelFormat.ucGreenPosition; 2498 (_this->hidden->hmtxUseSrcBuffer, SEM_INDEFINITE_WAIT) == NO_ERROR) {
2465 pResult->format->Gloss = pModeInfoFound->PixelFormat.ucGreenAdjust; 2499 #ifdef DEBUG_BUILD
2466 pResult->format->Bmask = ((unsigned int) pModeInfoFound->PixelFormat.ucBlueMask) << pModeInfoFound->PixelFormat.ucBluePosition; 2500 printf("[os2fslib_SetVideoMode] : Creating new SW surface\n");
2467 pResult->format->Bshift = pModeInfoFound->PixelFormat.ucBluePosition; 2501 fflush(stdout);
2468 pResult->format->Bloss = pModeInfoFound->PixelFormat.ucBlueAdjust; 2502 #endif
2469 pResult->format->Amask = ((unsigned int) pModeInfoFound->PixelFormat.ucAlphaMask) << pModeInfoFound->PixelFormat.ucAlphaPosition; 2503
2470 pResult->format->Ashift = pModeInfoFound->PixelFormat.ucAlphaPosition; 2504 // Create new software surface!
2471 pResult->format->Aloss = pModeInfoFound->PixelFormat.ucAlphaAdjust; 2505 pResult = SDL_CreateRGBSurface(SDL_SWSURFACE,
2506 pModeInfoFound->uiXResolution,
2507 pModeInfoFound->uiYResolution,
2508 pModeInfoFound->uiBPP,
2509 ((unsigned int) pModeInfoFound->
2510 PixelFormat.
2511 ucRedMask) << pModeInfoFound->
2512 PixelFormat.ucRedPosition,
2513 ((unsigned int) pModeInfoFound->
2514 PixelFormat.
2515 ucGreenMask) << pModeInfoFound->
2516 PixelFormat.ucGreenPosition,
2517 ((unsigned int) pModeInfoFound->
2518 PixelFormat.
2519 ucBlueMask) << pModeInfoFound->
2520 PixelFormat.ucBluePosition,
2521 ((unsigned int) pModeInfoFound->
2522 PixelFormat.
2523 ucAlphaMask) << pModeInfoFound->
2524 PixelFormat.ucAlphaPosition);
2525
2526 if (pResult == NULL) {
2527 DosReleaseMutexSem(_this->hidden->hmtxUseSrcBuffer);
2528 SDL_OutOfMemory();
2529 return NULL;
2530 }
2531 #ifdef DEBUG_BUILD
2532 printf("[os2fslib_SetVideoMode] : Adjusting pixel format\n");
2533 fflush(stdout);
2534 #endif
2535
2536 // Adjust pixel format mask!
2537 pResult->format->Rmask =
2538 ((unsigned int) pModeInfoFound->PixelFormat.
2539 ucRedMask) << pModeInfoFound->PixelFormat.ucRedPosition;
2540 pResult->format->Rshift = pModeInfoFound->PixelFormat.ucRedPosition;
2541 pResult->format->Rloss = pModeInfoFound->PixelFormat.ucRedAdjust;
2542 pResult->format->Gmask =
2543 ((unsigned int) pModeInfoFound->PixelFormat.
2544 ucGreenMask) << pModeInfoFound->PixelFormat.ucGreenPosition;
2545 pResult->format->Gshift = pModeInfoFound->PixelFormat.ucGreenPosition;
2546 pResult->format->Gloss = pModeInfoFound->PixelFormat.ucGreenAdjust;
2547 pResult->format->Bmask =
2548 ((unsigned int) pModeInfoFound->PixelFormat.
2549 ucBlueMask) << pModeInfoFound->PixelFormat.ucBluePosition;
2550 pResult->format->Bshift = pModeInfoFound->PixelFormat.ucBluePosition;
2551 pResult->format->Bloss = pModeInfoFound->PixelFormat.ucBlueAdjust;
2552 pResult->format->Amask =
2553 ((unsigned int) pModeInfoFound->PixelFormat.
2554 ucAlphaMask) << pModeInfoFound->PixelFormat.ucAlphaPosition;
2555 pResult->format->Ashift = pModeInfoFound->PixelFormat.ucAlphaPosition;
2556 pResult->format->Aloss = pModeInfoFound->PixelFormat.ucAlphaAdjust;
2472 2557
2473 #ifdef REPORT_EMPTY_ALPHA_MASK 2558 #ifdef REPORT_EMPTY_ALPHA_MASK
2474 pResult->format->Amask = 2559 pResult->format->Amask =
2475 pResult->format->Ashift = 2560 pResult->format->Ashift = pResult->format->Aloss = 0;
2476 pResult->format->Aloss = 0; 2561 #endif
2477 #endif 2562
2478 2563 // Adjust surface flags
2479 // Adjust surface flags 2564 pResult->flags |= (flags & SDL_FULLSCREEN);
2480 pResult->flags |= (flags & SDL_FULLSCREEN); 2565 pResult->flags |= (flags & SDL_RESIZABLE);
2481 pResult->flags |= (flags & SDL_RESIZABLE); 2566
2482 2567 // It might be that the software surface pitch is not the same as
2483 // It might be that the software surface pitch is not the same as 2568 // the pitch we have, so adjust that!
2484 // the pitch we have, so adjust that! 2569 pModeInfoFound->uiScanLineSize = pResult->pitch;
2485 pModeInfoFound->uiScanLineSize = pResult->pitch; 2570
2486 2571 // Store new source buffer parameters!
2487 // Store new source buffer parameters! 2572 SDL_memcpy(&(_this->hidden->SrcBufferDesc), pModeInfoFound,
2488 SDL_memcpy(&(_this->hidden->SrcBufferDesc), pModeInfoFound, sizeof(*pModeInfoFound)); 2573 sizeof(*pModeInfoFound));
2489 _this->hidden->pchSrcBuffer = pResult->pixels; 2574 _this->hidden->pchSrcBuffer = pResult->pixels;
2490 2575
2491 #ifdef DEBUG_BUILD 2576 #ifdef DEBUG_BUILD
2492 printf("[os2fslib_SetVideoMode] : Telling FSLib the stuffs\n"); fflush(stdout); 2577 printf("[os2fslib_SetVideoMode] : Telling FSLib the stuffs\n");
2493 #endif 2578 fflush(stdout);
2494 2579 #endif
2495 // Tell the FSLib window the new source image format 2580
2496 FSLib_SetSrcBufferDesc(_this->hidden->hwndClient, &(_this->hidden->SrcBufferDesc)); 2581 // Tell the FSLib window the new source image format
2497 2582 FSLib_SetSrcBufferDesc(_this->hidden->hwndClient,
2498 if ( 2583 &(_this->hidden->SrcBufferDesc));
2499 ((flags & SDL_RESIZABLE)==0) || 2584
2500 (bFirstCall) 2585 if (((flags & SDL_RESIZABLE) == 0) || (bFirstCall)) {
2501 ) 2586 bFirstCall = 0;
2502 { 2587 #ifdef DEBUG_BUILD
2503 bFirstCall = 0; 2588 printf("[os2fslib_SetVideoMode] : Modifying window size\n");
2504 #ifdef DEBUG_BUILD 2589 fflush(stdout);
2505 printf("[os2fslib_SetVideoMode] : Modifying window size\n"); fflush(stdout); 2590 #endif
2506 #endif 2591
2507 2592 // Calculate frame window size from client window size
2508 // Calculate frame window size from client window size 2593 rectl.xLeft = 0;
2509 rectl.xLeft = 0; 2594 rectl.yBottom = 0;
2510 rectl.yBottom = 0; 2595 rectl.xRight = pModeInfoFound->uiXResolution; // Noninclusive
2511 rectl.xRight = pModeInfoFound->uiXResolution; // Noninclusive 2596 rectl.yTop = pModeInfoFound->uiYResolution; // Noninclusive
2512 rectl.yTop = pModeInfoFound->uiYResolution; // Noninclusive 2597 WinCalcFrameRect(_this->hidden->hwndFrame, &rectl, FALSE);
2513 WinCalcFrameRect(_this->hidden->hwndFrame, &rectl, FALSE); 2598
2514 2599 // Set the new size of the main window
2515 // Set the new size of the main window 2600 SetAccessableWindowPos(_this->hidden->hwndFrame,
2516 SetAccessableWindowPos(_this->hidden->hwndFrame, 2601 HWND_TOP,
2517 HWND_TOP, 2602 0, 0,
2518 0, 0, 2603 (rectl.xRight - rectl.xLeft),
2519 (rectl.xRight-rectl.xLeft), 2604 (rectl.yTop - rectl.yBottom),
2520 (rectl.yTop-rectl.yBottom), 2605 SWP_SIZE | SWP_ACTIVATE | SWP_SHOW);
2521 SWP_SIZE | SWP_ACTIVATE | SWP_SHOW); 2606 }
2522 } 2607 // Set fullscreen mode flag, and switch to fullscreen if needed!
2523 2608 if (flags & SDL_FULLSCREEN) {
2524 // Set fullscreen mode flag, and switch to fullscreen if needed! 2609 #ifdef DEBUG_BUILD
2525 if (flags & SDL_FULLSCREEN) 2610 printf
2526 { 2611 ("[os2fslib_SetVideoMode] : Also trying to switch to fullscreen\n");
2527 #ifdef DEBUG_BUILD 2612 fflush(stdout);
2528 printf("[os2fslib_SetVideoMode] : Also trying to switch to fullscreen\n"); 2613 #endif
2529 fflush(stdout); 2614 FSLib_ToggleFSMode(_this->hidden->hwndClient, 1);
2530 #endif 2615 /* Cursor manager functions to FS mode */
2531 FSLib_ToggleFSMode(_this->hidden->hwndClient, 1); 2616 os2fslib_SetCursorManagementFunctions(_this, 0);
2532 /* Cursor manager functions to FS mode*/ 2617 } else {
2533 os2fslib_SetCursorManagementFunctions(_this, 0); 2618 #ifdef DEBUG_BUILD
2534 } else 2619 printf
2535 { 2620 ("[os2fslib_SetVideoMode] : Also trying to switch to desktop mode\n");
2536 #ifdef DEBUG_BUILD 2621 fflush(stdout);
2537 printf("[os2fslib_SetVideoMode] : Also trying to switch to desktop mode\n"); 2622 #endif
2538 fflush(stdout); 2623 FSLib_ToggleFSMode(_this->hidden->hwndClient, 0);
2539 #endif 2624 /* Cursor manager functions to Windowed mode */
2540 FSLib_ToggleFSMode(_this->hidden->hwndClient, 0); 2625 os2fslib_SetCursorManagementFunctions(_this, 1);
2541 /* Cursor manager functions to Windowed mode*/ 2626 }
2542 os2fslib_SetCursorManagementFunctions(_this, 1); 2627
2543 } 2628 _this->hidden->pSDLSurface = pResult;
2544 2629
2545 _this->hidden->pSDLSurface = pResult; 2630 DosReleaseMutexSem(_this->hidden->hmtxUseSrcBuffer);
2546 2631 } else {
2547 DosReleaseMutexSem(_this->hidden->hmtxUseSrcBuffer); 2632 #ifdef DEBUG_BUILD
2548 } else 2633 printf("[os2fslib_SetVideoMode] : Could not get hmtxUseSrcBuffer!\n");
2549 { 2634 fflush(stdout);
2550 #ifdef DEBUG_BUILD 2635 #endif
2551 printf("[os2fslib_SetVideoMode] : Could not get hmtxUseSrcBuffer!\n"); fflush(stdout); 2636
2552 #endif 2637 pResult = NULL;
2553 2638 }
2554 pResult = NULL; 2639
2555 } 2640 // As we have the new surface, we don't need the current one anymore!
2556 2641 if ((pResult) && (current)) {
2557 // As we have the new surface, we don't need the current one anymore! 2642 #ifdef DEBUG_BUILD
2558 if ((pResult) && (current)) 2643 printf("[os2fslib_SetVideoMode] : Freeing old surface\n");
2559 { 2644 fflush(stdout);
2560 #ifdef DEBUG_BUILD 2645 #endif
2561 printf("[os2fslib_SetVideoMode] : Freeing old surface\n"); fflush(stdout); 2646 SDL_FreeSurface(current);
2562 #endif 2647 }
2563 SDL_FreeSurface(current); 2648 // Redraw window
2564 } 2649 WinInvalidateRegion(_this->hidden->hwndClient, NULL, TRUE);
2565 2650
2566 // Redraw window 2651 // Now destroy the message queue, if we've created it!
2567 WinInvalidateRegion(_this->hidden->hwndClient, NULL, TRUE); 2652 if (ERRORIDERROR(hmqerror) == 0) {
2568 2653 #ifdef DEBUG_BUILD
2569 // Now destroy the message queue, if we've created it! 2654 printf("[os2fslib_SetVideoMode] : Destroying message queue\n");
2570 if (ERRORIDERROR(hmqerror)==0) 2655 fflush(stdout);
2571 { 2656 #endif
2572 #ifdef DEBUG_BUILD 2657 WinDestroyMsgQueue(hmq);
2573 printf("[os2fslib_SetVideoMode] : Destroying message queue\n"); fflush(stdout); 2658 }
2574 #endif 2659 #ifdef DEBUG_BUILD
2575 WinDestroyMsgQueue(hmq); 2660 printf("[os2fslib_SetVideoMode] : Done\n");
2576 } 2661 fflush(stdout);
2577 2662 #endif
2578 #ifdef DEBUG_BUILD 2663
2579 printf("[os2fslib_SetVideoMode] : Done\n"); fflush(stdout); 2664 /* We're done */
2580 #endif 2665
2581 2666 // Return with the new surface!
2582 /* We're done */ 2667 return pResult;
2583
2584 // Return with the new surface!
2585 return pResult;
2586 } 2668 }
2587 2669
2588 /* List the available video modes for the given pixel format, sorted 2670 /* List the available video modes for the given pixel format, sorted
2589 from largest to smallest. 2671 from largest to smallest.
2590 */ 2672 */
2591 static SDL_Rect **os2fslib_ListModes(_THIS, SDL_PixelFormat *format, Uint32 flags) 2673 static SDL_Rect **
2592 { 2674 os2fslib_ListModes(_THIS, SDL_PixelFormat * format, Uint32 flags)
2593 #ifdef DEBUG_BUILD 2675 {
2594 printf("[os2fslib_ListModes] : ListModes of %d Bpp\n", format->BitsPerPixel); 2676 #ifdef DEBUG_BUILD
2595 #endif 2677 printf("[os2fslib_ListModes] : ListModes of %d Bpp\n",
2596 // Destroy result of previous call, if there is any 2678 format->BitsPerPixel);
2597 if (_this->hidden->pListModesResult) 2679 #endif
2598 { 2680 // Destroy result of previous call, if there is any
2599 SDL_free(_this->hidden->pListModesResult); _this->hidden->pListModesResult = NULL; 2681 if (_this->hidden->pListModesResult) {
2600 } 2682 SDL_free(_this->hidden->pListModesResult);
2601 2683 _this->hidden->pListModesResult = NULL;
2602 // For resizable and windowed mode we support every resolution! 2684 }
2603 if ((flags & SDL_RESIZABLE) && ((flags & SDL_FULLSCREEN) == 0)) 2685 // For resizable and windowed mode we support every resolution!
2604 return (SDL_Rect **)-1; 2686 if ((flags & SDL_RESIZABLE) && ((flags & SDL_FULLSCREEN) == 0))
2605 2687 return (SDL_Rect **) - 1;
2606 // Check if they need fullscreen or non-fullscreen video modes! 2688
2607 if ((flags & SDL_FULLSCREEN) == 0) 2689 // Check if they need fullscreen or non-fullscreen video modes!
2608 2690 if ((flags & SDL_FULLSCREEN) == 0) {
2609 { 2691 // For windowed mode we support every resolution!
2610 // For windowed mode we support every resolution! 2692 return (SDL_Rect **) - 1;
2611 return (SDL_Rect **)-1; 2693 } else {
2612 } else 2694 FSLib_VideoMode_p pFSMode;
2613 { 2695 // For fullscreen mode we don't support every resolution!
2614 FSLib_VideoMode_p pFSMode; 2696 // Now create a new list
2615 // For fullscreen mode we don't support every resolution! 2697 pFSMode = _this->hidden->pAvailableFSLibVideoModes;
2616 // Now create a new list 2698 while (pFSMode) {
2617 pFSMode = _this->hidden->pAvailableFSLibVideoModes; 2699 if (pFSMode->uiBPP == format->BitsPerPixel) {
2618 while (pFSMode) 2700 SDL_Rect *pRect = (SDL_Rect *) SDL_malloc(sizeof(SDL_Rect));
2619 { 2701 if (pRect) {
2620 if (pFSMode->uiBPP == format->BitsPerPixel) 2702 // Fill description
2621 { 2703 pRect->x = 0;
2622 SDL_Rect *pRect = (SDL_Rect *) SDL_malloc(sizeof(SDL_Rect)); 2704 pRect->y = 0;
2623 if (pRect) 2705 pRect->w = pFSMode->uiXResolution;
2624 { 2706 pRect->h = pFSMode->uiYResolution;
2625 // Fill description
2626 pRect->x = 0;
2627 pRect->y = 0;
2628 pRect->w = pFSMode->uiXResolution;
2629 pRect->h = pFSMode->uiYResolution;
2630 #ifdef DEBUG_BUILD 2707 #ifdef DEBUG_BUILD
2631 // printf("!!! Seems to be good!\n"); 2708 // printf("!!! Seems to be good!\n");
2632 // printf("F: %dx%d\n", pRect->w, pRect->h); 2709 // printf("F: %dx%d\n", pRect->w, pRect->h);
2633 #endif 2710 #endif
2634 // And insert into list of pRects 2711 // And insert into list of pRects
2635 if (!(_this->hidden->pListModesResult)) 2712 if (!(_this->hidden->pListModesResult)) {
2636 {
2637 #ifdef DEBUG_BUILD 2713 #ifdef DEBUG_BUILD
2638 // printf("!!! Inserting to beginning\n"); 2714 // printf("!!! Inserting to beginning\n");
2639 #endif 2715 #endif
2640 2716
2641 // We're the first one to be inserted! 2717 // We're the first one to be inserted!
2642 _this->hidden->pListModesResult = (SDL_Rect**) SDL_malloc(2*sizeof(SDL_Rect*)); 2718 _this->hidden->pListModesResult =
2643 if (_this->hidden->pListModesResult) 2719 (SDL_Rect **) SDL_malloc(2 * sizeof(SDL_Rect *));
2644 { 2720 if (_this->hidden->pListModesResult) {
2645 _this->hidden->pListModesResult[0] = pRect; 2721 _this->hidden->pListModesResult[0] = pRect;
2646 _this->hidden->pListModesResult[1] = NULL; 2722 _this->hidden->pListModesResult[1] = NULL;
2647 } else 2723 } else {
2648 { 2724 SDL_free(pRect);
2649 SDL_free(pRect); 2725 }
2726 } else {
2727 // We're not the first ones, so find the place where we
2728 // have to insert ourselves
2729 SDL_Rect **pNewList;
2730 int iPlace, iNumOfSlots, i;
2731
2732 #ifdef DEBUG_BUILD
2733 // printf("!!! Searching where to insert\n");
2734 #endif
2735
2736 iPlace = -1;
2737 iNumOfSlots = 1; // Count the last NULL too!
2738 for (i = 0; _this->hidden->pListModesResult[i]; i++) {
2739 iNumOfSlots++;
2740 if (iPlace == -1) {
2741 if ((_this->hidden->
2742 pListModesResult[i]->w *
2743 _this->hidden->
2744 pListModesResult[i]->h) <
2745 (pRect->w * pRect->h)) {
2746 iPlace = i;
2747 }
2748 }
2749 }
2750 if (iPlace == -1)
2751 iPlace = iNumOfSlots - 1;
2752
2753 #ifdef DEBUG_BUILD
2754 // printf("!!! From %d slots, it will be at %d\n", iNumOfSlots, iPlace);
2755 #endif
2756
2757 pNewList =
2758 (SDL_Rect **) SDL_realloc(_this->
2759 hidden->
2760 pListModesResult,
2761 (iNumOfSlots
2762 +
2763 1) *
2764 sizeof(SDL_Rect *));
2765 if (pNewList) {
2766 for (i = iNumOfSlots; i > iPlace; i--)
2767 pNewList[i] = pNewList[i - 1];
2768 pNewList[iPlace] = pRect;
2769 _this->hidden->pListModesResult = pNewList;
2770 } else {
2771 SDL_free(pRect);
2772 }
2773 }
2774 }
2650 } 2775 }
2651 } else 2776 pFSMode = pFSMode->pNext;
2652 { 2777 }
2653 // We're not the first ones, so find the place where we 2778 }
2654 // have to insert ourselves
2655 SDL_Rect **pNewList;
2656 int iPlace, iNumOfSlots, i;
2657
2658 #ifdef DEBUG_BUILD
2659 // printf("!!! Searching where to insert\n");
2660 #endif
2661
2662 iPlace = -1; iNumOfSlots = 1; // Count the last NULL too!
2663 for (i=0; _this->hidden->pListModesResult[i]; i++)
2664 {
2665 iNumOfSlots++;
2666 if (iPlace==-1)
2667 {
2668 if ((_this->hidden->pListModesResult[i]->w*_this->hidden->pListModesResult[i]->h)<
2669 (pRect->w*pRect->h))
2670 {
2671 iPlace = i;
2672 }
2673 }
2674 }
2675 if (iPlace==-1) iPlace = iNumOfSlots-1;
2676
2677 #ifdef DEBUG_BUILD
2678 // printf("!!! From %d slots, it will be at %d\n", iNumOfSlots, iPlace);
2679 #endif
2680
2681 pNewList = (SDL_Rect**) SDL_realloc(_this->hidden->pListModesResult, (iNumOfSlots+1)*sizeof(SDL_Rect*));
2682 if (pNewList)
2683 {
2684 for (i=iNumOfSlots;i>iPlace;i--)
2685 pNewList[i] = pNewList[i-1];
2686 pNewList[iPlace] = pRect;
2687 _this->hidden->pListModesResult = pNewList;
2688 } else
2689 {
2690 SDL_free(pRect);
2691 }
2692 }
2693 }
2694 }
2695 pFSMode = pFSMode->pNext;
2696 }
2697 }
2698 #ifdef DEBUG_BUILD 2779 #ifdef DEBUG_BUILD
2699 // printf("Returning list\n"); 2780 // printf("Returning list\n");
2700 #endif 2781 #endif
2701 return _this->hidden->pListModesResult; 2782 return _this->hidden->pListModesResult;
2702 } 2783 }
2703 2784
2704 /* Initialize the native video subsystem, filling 'vformat' with the 2785 /* Initialize the native video subsystem, filling 'vformat' with the
2705 "best" display pixel format, returning 0 or -1 if there's an error. 2786 "best" display pixel format, returning 0 or -1 if there's an error.
2706 */ 2787 */
2707 static int os2fslib_VideoInit(_THIS, SDL_PixelFormat *vformat) 2788 static int
2708 { 2789 os2fslib_VideoInit(_THIS, SDL_PixelFormat * vformat)
2709 FSLib_VideoMode_p pDesktopMode; 2790 {
2710 2791 FSLib_VideoMode_p pDesktopMode;
2711 #ifdef DEBUG_BUILD 2792
2712 printf("[os2fslib_VideoInit] : Enter\n"); fflush(stdout); 2793 #ifdef DEBUG_BUILD
2713 #endif 2794 printf("[os2fslib_VideoInit] : Enter\n");
2714 2795 fflush(stdout);
2715 // Report the best pixel format. For this, 2796 #endif
2716 // we'll use the current desktop format. 2797
2717 pDesktopMode = FSLib_GetDesktopVideoMode(); 2798 // Report the best pixel format. For this,
2718 if (!pDesktopMode) 2799 // we'll use the current desktop format.
2719 { 2800 pDesktopMode = FSLib_GetDesktopVideoMode();
2720 SDL_SetError("Could not query desktop video mode!"); 2801 if (!pDesktopMode) {
2721 #ifdef DEBUG_BUILD 2802 SDL_SetError("Could not query desktop video mode!");
2722 printf("[os2fslib_VideoInit] : Could not query desktop video mode!\n"); 2803 #ifdef DEBUG_BUILD
2723 #endif 2804 printf
2724 return -1; 2805 ("[os2fslib_VideoInit] : Could not query desktop video mode!\n");
2725 } 2806 #endif
2726 2807 return -1;
2727 /* Determine the current screen size */ 2808 }
2728 _this->info.current_w = pDesktopMode->uiXResolution; 2809
2729 _this->info.current_h = pDesktopMode->uiYResolution; 2810 /* Determine the current screen size */
2730 2811 _this->info.current_w = pDesktopMode->uiXResolution;
2731 /* Determine the screen depth */ 2812 _this->info.current_h = pDesktopMode->uiYResolution;
2732 vformat->BitsPerPixel = pDesktopMode->uiBPP; 2813
2733 vformat->BytesPerPixel = (vformat->BitsPerPixel+7)/8; 2814 /* Determine the screen depth */
2734 2815 vformat->BitsPerPixel = pDesktopMode->uiBPP;
2735 vformat->Rmask = ((unsigned int) pDesktopMode->PixelFormat.ucRedMask) << pDesktopMode->PixelFormat.ucRedPosition; 2816 vformat->BytesPerPixel = (vformat->BitsPerPixel + 7) / 8;
2736 vformat->Rshift = pDesktopMode->PixelFormat.ucRedPosition; 2817
2737 vformat->Rloss = pDesktopMode->PixelFormat.ucRedAdjust; 2818 vformat->Rmask =
2738 vformat->Gmask = ((unsigned int) pDesktopMode->PixelFormat.ucGreenMask) << pDesktopMode->PixelFormat.ucGreenPosition; 2819 ((unsigned int) pDesktopMode->PixelFormat.ucRedMask) << pDesktopMode->
2739 vformat->Gshift = pDesktopMode->PixelFormat.ucGreenPosition; 2820 PixelFormat.ucRedPosition;
2740 vformat->Gloss = pDesktopMode->PixelFormat.ucGreenAdjust; 2821 vformat->Rshift = pDesktopMode->PixelFormat.ucRedPosition;
2741 vformat->Bmask = ((unsigned int) pDesktopMode->PixelFormat.ucBlueMask) << pDesktopMode->PixelFormat.ucBluePosition; 2822 vformat->Rloss = pDesktopMode->PixelFormat.ucRedAdjust;
2742 vformat->Bshift = pDesktopMode->PixelFormat.ucBluePosition; 2823 vformat->Gmask =
2743 vformat->Bloss = pDesktopMode->PixelFormat.ucBlueAdjust; 2824 ((unsigned int) pDesktopMode->PixelFormat.
2744 vformat->Amask = ((unsigned int) pDesktopMode->PixelFormat.ucAlphaMask) << pDesktopMode->PixelFormat.ucAlphaPosition; 2825 ucGreenMask) << pDesktopMode->PixelFormat.ucGreenPosition;
2745 vformat->Ashift = pDesktopMode->PixelFormat.ucAlphaPosition; 2826 vformat->Gshift = pDesktopMode->PixelFormat.ucGreenPosition;
2746 vformat->Aloss = pDesktopMode->PixelFormat.ucAlphaAdjust; 2827 vformat->Gloss = pDesktopMode->PixelFormat.ucGreenAdjust;
2828 vformat->Bmask =
2829 ((unsigned int) pDesktopMode->PixelFormat.
2830 ucBlueMask) << pDesktopMode->PixelFormat.ucBluePosition;
2831 vformat->Bshift = pDesktopMode->PixelFormat.ucBluePosition;
2832 vformat->Bloss = pDesktopMode->PixelFormat.ucBlueAdjust;
2833 vformat->Amask =
2834 ((unsigned int) pDesktopMode->PixelFormat.
2835 ucAlphaMask) << pDesktopMode->PixelFormat.ucAlphaPosition;
2836 vformat->Ashift = pDesktopMode->PixelFormat.ucAlphaPosition;
2837 vformat->Aloss = pDesktopMode->PixelFormat.ucAlphaAdjust;
2747 2838
2748 #ifdef REPORT_EMPTY_ALPHA_MASK 2839 #ifdef REPORT_EMPTY_ALPHA_MASK
2749 vformat->Amask = 2840 vformat->Amask = vformat->Ashift = vformat->Aloss = 0;
2750 vformat->Ashift = 2841 #endif
2751 vformat->Aloss = 0; 2842
2752 #endif 2843 // Fill in some window manager capabilities
2753 2844 _this->info.wm_available = 1;
2754 // Fill in some window manager capabilities 2845
2755 _this->info.wm_available = 1; 2846 // Initialize some internal variables
2756 2847 _this->hidden->pListModesResult = NULL;
2757 // Initialize some internal variables 2848 _this->hidden->fInFocus = 0;
2758 _this->hidden->pListModesResult = NULL; 2849 _this->hidden->iSkipWMMOUSEMOVE = 0;
2759 _this->hidden->fInFocus = 0; 2850 _this->hidden->iMouseVisible = 1;
2760 _this->hidden->iSkipWMMOUSEMOVE = 0; 2851
2761 _this->hidden->iMouseVisible = 1; 2852 if (getenv("SDL_USE_PROPORTIONAL_WINDOW"))
2762 2853 _this->hidden->bProportionalResize = 1;
2763 if (getenv("SDL_USE_PROPORTIONAL_WINDOW")) 2854 else {
2764 _this->hidden->bProportionalResize = 1; 2855 PPIB pib;
2765 else 2856 PTIB tib;
2766 { 2857 char *pchFileName, *pchTemp;
2858 char achConfigFile[CCHMAXPATH];
2859 FILE *hFile;
2860
2861 /* No environment variable to have proportional window.
2862 * Ok, let's check if this executable is in config file!
2863 */
2864 _this->hidden->bProportionalResize = 0;
2865
2866 DosGetInfoBlocks(&tib, &pib);
2867 pchTemp = pchFileName = pib->pib_pchcmd;
2868 while (*pchTemp) {
2869 if (*pchTemp == '\\')
2870 pchFileName = pchTemp + 1;
2871 pchTemp++;
2872 }
2873 if (getenv("HOME")) {
2874 sprintf(achConfigFile, "%s\\.sdl.proportionals", getenv("HOME"));
2875 hFile = fopen(achConfigFile, "rt");
2876 if (!hFile) {
2877 /* Seems like the file cannot be opened or does not exist.
2878 * Let's try to create it with defaults!
2879 */
2880 hFile = fopen(achConfigFile, "wt");
2881 if (hFile) {
2882 fprintf(hFile,
2883 "; This file is a config file of SDL/2, containing\n");
2884 fprintf(hFile,
2885 "; the list of executables that must have proportional\n");
2886 fprintf(hFile, "; windows.\n");
2887 fprintf(hFile, ";\n");
2888 fprintf(hFile,
2889 "; You can add executable filenames into this file,\n");
2890 fprintf(hFile,
2891 "; one under the other. If SDL finds that a given\n");
2892 fprintf(hFile,
2893 "; program is in this list, then that application\n");
2894 fprintf(hFile,
2895 "; will have proportional windows, just like if\n");
2896 fprintf(hFile,
2897 "; the SET SDL_USE_PROPORTIONAL_WINDOW env. variable\n");
2898 fprintf(hFile,
2899 "; would have been set for that process.\n");
2900 fprintf(hFile, ";\n");
2901 fprintf(hFile, "\n");
2902 fprintf(hFile, "dosbox.exe\n");
2903 fclose(hFile);
2904 }
2905
2906 hFile = fopen(achConfigFile, "rt");
2907 }
2908
2909 if (hFile) {
2910 while (fgets(achConfigFile, sizeof(achConfigFile), hFile)) {
2911 /* Cut \n from end of string */
2912
2913 while (achConfigFile[strlen(achConfigFile) - 1]
2914 == '\n')
2915 achConfigFile[strlen(achConfigFile) - 1] = 0;
2916
2917 /* Compare... */
2918 if (stricmp(achConfigFile, pchFileName) == 0) {
2919 /* Found it in config file! */
2920 _this->hidden->bProportionalResize = 1;
2921 break;
2922 }
2923 }
2924 fclose(hFile);
2925 }
2926 }
2927 }
2928
2929 DosCreateMutexSem(NULL, &(_this->hidden->hmtxUseSrcBuffer), 0, FALSE);
2930
2931 // Now create our window with a default size
2932
2933 // For this, we select the first available fullscreen mode as
2934 // current window size!
2935 SDL_memcpy(&(_this->hidden->SrcBufferDesc),
2936 _this->hidden->pAvailableFSLibVideoModes,
2937 sizeof(_this->hidden->SrcBufferDesc));
2938 // Allocate new video buffer!
2939 _this->hidden->pchSrcBuffer =
2940 (char *) SDL_malloc(_this->hidden->pAvailableFSLibVideoModes->
2941 uiScanLineSize *
2942 _this->hidden->pAvailableFSLibVideoModes->
2943 uiYResolution);
2944 if (!_this->hidden->pchSrcBuffer) {
2945 #ifdef DEBUG_BUILD
2946 printf
2947 ("[os2fslib_VideoInit] : Yikes, not enough memory for new video buffer!\n");
2948 fflush(stdout);
2949 #endif
2950 SDL_SetError("Not enough memory for new video buffer!\n");
2951 return -1;
2952 }
2953 // For this, we need a message processing thread.
2954 // We'll create a new thread for this, which will do everything
2955 // what is related to PM
2956 _this->hidden->iPMThreadStatus = 0;
2957 _this->hidden->tidPMThread =
2958 _beginthread(PMThreadFunc, NULL, 65536, (void *) _this);
2959 if (_this->hidden->tidPMThread <= 0) {
2960 #ifdef DEBUG_BUILD
2961 printf("[os2fslib_VideoInit] : Could not create PM thread!\n");
2962 #endif
2963 SDL_SetError("Could not create PM thread");
2964 return -1;
2965 }
2966 #ifdef USE_DOSSETPRIORITY
2967 // Burst the priority of PM Thread!
2968 DosSetPriority(PRTYS_THREAD, PRTYC_TIMECRITICAL, 0,
2969 _this->hidden->tidPMThread);
2970 #endif
2971 // Wait for the PM thread to initialize!
2972 while (_this->hidden->iPMThreadStatus == 0)
2973 DosSleep(32);
2974 // If the PM thread could not set up everything, then
2975 // report an error!
2976 if (_this->hidden->iPMThreadStatus != 1) {
2977 #ifdef DEBUG_BUILD
2978 printf("[os2fslib_VideoInit] : PMThread reported an error : %d\n",
2979 _this->hidden->iPMThreadStatus);
2980 #endif
2981 SDL_SetError("Error initializing PM thread");
2982 return -1;
2983 }
2984
2985 return 0;
2986 }
2987
2988
2989 static void
2990 os2fslib_DeleteDevice(_THIS)
2991 {
2992 #ifdef DEBUG_BUILD
2993 printf("[os2fslib_DeleteDevice]\n");
2994 fflush(stdout);
2995 #endif
2996 // Free used memory
2997 FSLib_FreeVideoModeList(_this->hidden->pAvailableFSLibVideoModes);
2998 if (_this->hidden->pListModesResult)
2999 SDL_free(_this->hidden->pListModesResult);
3000 if (_this->hidden->pchSrcBuffer)
3001 SDL_free(_this->hidden->pchSrcBuffer);
3002 DosCloseMutexSem(_this->hidden->hmtxUseSrcBuffer);
3003 SDL_free(_this->hidden);
3004 SDL_free(_this);
3005 FSLib_Uninitialize();
3006 }
3007
3008 static int
3009 os2fslib_Available(void)
3010 {
3011
3012 // If we can run, it means that we could load FSLib,
3013 // so we assume that it's available then!
3014 return 1;
3015 }
3016
3017 static void
3018 os2fslib_MorphToPM()
3019 {
2767 PPIB pib; 3020 PPIB pib;
2768 PTIB tib; 3021 PTIB tib;
2769 char *pchFileName, *pchTemp;
2770 char achConfigFile[CCHMAXPATH];
2771 FILE *hFile;
2772
2773 /* No environment variable to have proportional window.
2774 * Ok, let's check if this executable is in config file!
2775 */
2776 _this->hidden->bProportionalResize = 0;
2777 3022
2778 DosGetInfoBlocks(&tib, &pib); 3023 DosGetInfoBlocks(&tib, &pib);
2779 pchTemp = pchFileName = pib->pib_pchcmd; 3024
2780 while (*pchTemp) 3025 // Change flag from VIO to PM:
2781 { 3026 if (pib->pib_ultype == 2)
2782 if (*pchTemp=='\\') 3027 pib->pib_ultype = 3;
2783 pchFileName = pchTemp+1; 3028 }
2784 pchTemp++; 3029
2785 } 3030 static SDL_VideoDevice *
2786 if (getenv("HOME")) 3031 os2fslib_CreateDevice(int devindex)
2787 { 3032 {
2788 sprintf(achConfigFile, "%s\\.sdl.proportionals", getenv("HOME")); 3033 SDL_VideoDevice *device;
2789 hFile = fopen(achConfigFile, "rt"); 3034
2790 if (!hFile) 3035 #ifdef DEBUG_BUILD
2791 { 3036 printf("[os2fslib_CreateDevice] : Enter\n");
2792 /* Seems like the file cannot be opened or does not exist. 3037 fflush(stdout);
2793 * Let's try to create it with defaults! 3038 #endif
2794 */ 3039
2795 hFile = fopen(achConfigFile, "wt"); 3040 /* Initialize all variables that we clean on shutdown */
2796 if (hFile) 3041 device = (SDL_VideoDevice *) SDL_malloc(sizeof(SDL_VideoDevice));
2797 { 3042 if (device) {
2798 fprintf(hFile, "; This file is a config file of SDL/2, containing\n"); 3043 SDL_memset(device, 0, (sizeof *device));
2799 fprintf(hFile, "; the list of executables that must have proportional\n"); 3044 // Also allocate memory for private data
2800 fprintf(hFile, "; windows.\n"); 3045 device->hidden = (struct SDL_PrivateVideoData *)
2801 fprintf(hFile, ";\n"); 3046 SDL_malloc((sizeof(struct SDL_PrivateVideoData)));
2802 fprintf(hFile, "; You can add executable filenames into this file,\n"); 3047 }
2803 fprintf(hFile, "; one under the other. If SDL finds that a given\n"); 3048 if ((device == NULL) || (device->hidden == NULL)) {
2804 fprintf(hFile, "; program is in this list, then that application\n"); 3049 SDL_OutOfMemory();
2805 fprintf(hFile, "; will have proportional windows, just like if\n"); 3050 if (device)
2806 fprintf(hFile, "; the SET SDL_USE_PROPORTIONAL_WINDOW env. variable\n"); 3051 SDL_free(device);
2807 fprintf(hFile, "; would have been set for that process.\n"); 3052 return NULL;
2808 fprintf(hFile, ";\n"); 3053 }
2809 fprintf(hFile, "\n"); 3054 SDL_memset(device->hidden, 0, (sizeof *device->hidden));
2810 fprintf(hFile, "dosbox.exe\n"); 3055
2811 fclose(hFile); 3056 /* Set the function pointers */
2812 } 3057 #ifdef DEBUG_BUILD
2813 3058 printf("[os2fslib_CreateDevice] : VideoInit is %p\n", os2fslib_VideoInit);
2814 hFile = fopen(achConfigFile, "rt"); 3059 fflush(stdout);
2815 } 3060 #endif
2816 3061
2817 if (hFile) 3062 /* Initialization/Query functions */
2818 { 3063 device->VideoInit = os2fslib_VideoInit;
2819 while (fgets(achConfigFile, sizeof(achConfigFile), hFile)) 3064 device->ListModes = os2fslib_ListModes;
2820 { 3065 device->SetVideoMode = os2fslib_SetVideoMode;
2821 /* Cut \n from end of string */ 3066 device->ToggleFullScreen = os2fslib_ToggleFullScreen;
2822 3067 device->UpdateMouse = os2fslib_UpdateMouse;
2823 while (achConfigFile[strlen(achConfigFile)-1] == '\n') 3068 device->CreateYUVOverlay = NULL;
2824 achConfigFile[strlen(achConfigFile)-1] = 0; 3069 device->SetColors = os2fslib_SetColors;
2825 3070 device->UpdateRects = os2fslib_UpdateRects;
2826 /* Compare... */ 3071 device->VideoQuit = os2fslib_VideoQuit;
2827 if (stricmp(achConfigFile, pchFileName)==0) 3072 /* Hardware acceleration functions */
2828 { 3073 device->AllocHWSurface = os2fslib_AllocHWSurface;
2829 /* Found it in config file! */ 3074 device->CheckHWBlit = NULL;
2830 _this->hidden->bProportionalResize = 1; 3075 device->FillHWRect = NULL;
2831 break; 3076 device->SetHWColorKey = NULL;
2832 } 3077 device->SetHWAlpha = NULL;
2833 } 3078 device->LockHWSurface = os2fslib_LockHWSurface;
2834 fclose(hFile); 3079 device->UnlockHWSurface = os2fslib_UnlockHWSurface;
2835 } 3080 device->FlipHWSurface = NULL;
2836 } 3081 device->FreeHWSurface = os2fslib_FreeHWSurface;
2837 } 3082 /* Window manager functions */
2838 3083 device->SetCaption = os2fslib_SetCaption;
2839 DosCreateMutexSem(NULL, &(_this->hidden->hmtxUseSrcBuffer), 0, FALSE); 3084 device->SetIcon = os2fslib_SetIcon;
2840 3085 device->IconifyWindow = os2fslib_IconifyWindow;
2841 // Now create our window with a default size 3086 device->GrabInput = os2fslib_GrabInput;
2842 3087 device->GetWMInfo = NULL;
2843 // For this, we select the first available fullscreen mode as 3088 /* Cursor manager functions to Windowed mode */
2844 // current window size! 3089 os2fslib_SetCursorManagementFunctions(device, 1);
2845 SDL_memcpy(&(_this->hidden->SrcBufferDesc), _this->hidden->pAvailableFSLibVideoModes, sizeof(_this->hidden->SrcBufferDesc)); 3090 /* Event manager functions */
2846 // Allocate new video buffer! 3091 device->InitOSKeymap = os2fslib_InitOSKeymap;
2847 _this->hidden->pchSrcBuffer = (char *) SDL_malloc(_this->hidden->pAvailableFSLibVideoModes->uiScanLineSize * _this->hidden->pAvailableFSLibVideoModes->uiYResolution); 3092 device->PumpEvents = os2fslib_PumpEvents;
2848 if (!_this->hidden->pchSrcBuffer) 3093 /* The function used to dispose of this structure */
2849 { 3094 device->free = os2fslib_DeleteDevice;
2850 #ifdef DEBUG_BUILD 3095
2851 printf("[os2fslib_VideoInit] : Yikes, not enough memory for new video buffer!\n"); fflush(stdout); 3096 // Make sure we'll be able to use Win* API even if the application
2852 #endif 3097 // was linked to be a VIO application!
2853 SDL_SetError("Not enough memory for new video buffer!\n"); 3098 os2fslib_MorphToPM();
2854 return -1; 3099
2855 } 3100 // Now initialize FSLib, and query available video modes!
2856 3101 if (!FSLib_Initialize()) {
2857 // For this, we need a message processing thread. 3102 // Could not initialize FSLib!
2858 // We'll create a new thread for this, which will do everything 3103 #ifdef DEBUG_BUILD
2859 // what is related to PM 3104 printf("[os2fslib_CreateDevice] : Could not initialize FSLib!\n");
2860 _this->hidden->iPMThreadStatus = 0; 3105 #endif
2861 _this->hidden->tidPMThread = _beginthread(PMThreadFunc, NULL, 65536, (void *) _this); 3106 SDL_SetError("Could not initialize FSLib!");
2862 if (_this->hidden->tidPMThread <= 0) 3107 SDL_free(device->hidden);
2863 { 3108 SDL_free(device);
2864 #ifdef DEBUG_BUILD 3109 return NULL;
2865 printf("[os2fslib_VideoInit] : Could not create PM thread!\n"); 3110 }
2866 #endif 3111 device->hidden->pAvailableFSLibVideoModes = FSLib_GetVideoModeList();
2867 SDL_SetError("Could not create PM thread"); 3112
2868 return -1; 3113 return device;
2869 }
2870 #ifdef USE_DOSSETPRIORITY
2871 // Burst the priority of PM Thread!
2872 DosSetPriority(PRTYS_THREAD, PRTYC_TIMECRITICAL, 0, _this->hidden->tidPMThread);
2873 #endif
2874 // Wait for the PM thread to initialize!
2875 while (_this->hidden->iPMThreadStatus==0)
2876 DosSleep(32);
2877 // If the PM thread could not set up everything, then
2878 // report an error!
2879 if (_this->hidden->iPMThreadStatus!=1)
2880 {
2881 #ifdef DEBUG_BUILD
2882 printf("[os2fslib_VideoInit] : PMThread reported an error : %d\n", _this->hidden->iPMThreadStatus);
2883 #endif
2884 SDL_SetError("Error initializing PM thread");
2885 return -1;
2886 }
2887
2888 return 0;
2889 }
2890
2891
2892 static void os2fslib_DeleteDevice(_THIS)
2893 {
2894 #ifdef DEBUG_BUILD
2895 printf("[os2fslib_DeleteDevice]\n"); fflush(stdout);
2896 #endif
2897 // Free used memory
2898 FSLib_FreeVideoModeList(_this->hidden->pAvailableFSLibVideoModes);
2899 if (_this->hidden->pListModesResult)
2900 SDL_free(_this->hidden->pListModesResult);
2901 if (_this->hidden->pchSrcBuffer)
2902 SDL_free(_this->hidden->pchSrcBuffer);
2903 DosCloseMutexSem(_this->hidden->hmtxUseSrcBuffer);
2904 SDL_free(_this->hidden);
2905 SDL_free(_this);
2906 FSLib_Uninitialize();
2907 }
2908
2909 static int os2fslib_Available(void)
2910 {
2911
2912 // If we can run, it means that we could load FSLib,
2913 // so we assume that it's available then!
2914 return 1;
2915 }
2916
2917 static void os2fslib_MorphToPM()
2918 {
2919 PPIB pib;
2920 PTIB tib;
2921
2922 DosGetInfoBlocks(&tib, &pib);
2923
2924 // Change flag from VIO to PM:
2925 if (pib->pib_ultype==2) pib->pib_ultype = 3;
2926 }
2927
2928 static SDL_VideoDevice *os2fslib_CreateDevice(int devindex)
2929 {
2930 SDL_VideoDevice *device;
2931
2932 #ifdef DEBUG_BUILD
2933 printf("[os2fslib_CreateDevice] : Enter\n"); fflush(stdout);
2934 #endif
2935
2936 /* Initialize all variables that we clean on shutdown */
2937 device = (SDL_VideoDevice *)SDL_malloc(sizeof(SDL_VideoDevice));
2938 if ( device )
2939 {
2940 SDL_memset(device, 0, (sizeof *device));
2941 // Also allocate memory for private data
2942 device->hidden = (struct SDL_PrivateVideoData *) SDL_malloc((sizeof(struct SDL_PrivateVideoData)));
2943 }
2944 if ( (device == NULL) || (device->hidden == NULL) )
2945 {
2946 SDL_OutOfMemory();
2947 if ( device )
2948 SDL_free(device);
2949 return NULL;
2950 }
2951 SDL_memset(device->hidden, 0, (sizeof *device->hidden));
2952
2953 /* Set the function pointers */
2954 #ifdef DEBUG_BUILD
2955 printf("[os2fslib_CreateDevice] : VideoInit is %p\n", os2fslib_VideoInit); fflush(stdout);
2956 #endif
2957
2958 /* Initialization/Query functions */
2959 device->VideoInit = os2fslib_VideoInit;
2960 device->ListModes = os2fslib_ListModes;
2961 device->SetVideoMode = os2fslib_SetVideoMode;
2962 device->ToggleFullScreen = os2fslib_ToggleFullScreen;
2963 device->UpdateMouse = os2fslib_UpdateMouse;
2964 device->CreateYUVOverlay = NULL;
2965 device->SetColors = os2fslib_SetColors;
2966 device->UpdateRects = os2fslib_UpdateRects;
2967 device->VideoQuit = os2fslib_VideoQuit;
2968 /* Hardware acceleration functions */
2969 device->AllocHWSurface = os2fslib_AllocHWSurface;
2970 device->CheckHWBlit = NULL;
2971 device->FillHWRect = NULL;
2972 device->SetHWColorKey = NULL;
2973 device->SetHWAlpha = NULL;
2974 device->LockHWSurface = os2fslib_LockHWSurface;
2975 device->UnlockHWSurface = os2fslib_UnlockHWSurface;
2976 device->FlipHWSurface = NULL;
2977 device->FreeHWSurface = os2fslib_FreeHWSurface;
2978 /* Window manager functions */
2979 device->SetCaption = os2fslib_SetCaption;
2980 device->SetIcon = os2fslib_SetIcon;
2981 device->IconifyWindow = os2fslib_IconifyWindow;
2982 device->GrabInput = os2fslib_GrabInput;
2983 device->GetWMInfo = NULL;
2984 /* Cursor manager functions to Windowed mode*/
2985 os2fslib_SetCursorManagementFunctions(device, 1);
2986 /* Event manager functions */
2987 device->InitOSKeymap = os2fslib_InitOSKeymap;
2988 device->PumpEvents = os2fslib_PumpEvents;
2989 /* The function used to dispose of this structure */
2990 device->free = os2fslib_DeleteDevice;
2991
2992 // Make sure we'll be able to use Win* API even if the application
2993 // was linked to be a VIO application!
2994 os2fslib_MorphToPM();
2995
2996 // Now initialize FSLib, and query available video modes!
2997 if (!FSLib_Initialize())
2998 {
2999 // Could not initialize FSLib!
3000 #ifdef DEBUG_BUILD
3001 printf("[os2fslib_CreateDevice] : Could not initialize FSLib!\n");
3002 #endif
3003 SDL_SetError("Could not initialize FSLib!");
3004 SDL_free(device->hidden);
3005 SDL_free(device);
3006 return NULL;
3007 }
3008 device->hidden->pAvailableFSLibVideoModes =
3009 FSLib_GetVideoModeList();
3010
3011 return device;
3012 } 3114 }
3013 3115
3014 VideoBootStrap OS2FSLib_bootstrap = { 3116 VideoBootStrap OS2FSLib_bootstrap = {
3015 "os2fslib", "OS/2 Video Output using FSLib", 3117 "os2fslib", "OS/2 Video Output using FSLib",
3016 os2fslib_Available, os2fslib_CreateDevice 3118 os2fslib_Available, os2fslib_CreateDevice
3017 }; 3119 };
3018 3120
3121 /* vi: set ts=4 sw=4 expandtab: */