1 /*
2 Simple DirectMedia Layer
3 Copyright (C) 1997-2021 Sam Lantinga <slouken@libsdl.org>
4
5 This software is provided 'as-is', without any express or implied
6 warranty. In no event will the authors be held liable for any damages
7 arising from the use of this software.
8
9 Permission is granted to anyone to use this software for any purpose,
10 including commercial applications, and to alter it and redistribute it
11 freely, subject to the following restrictions:
12
13 1. The origin of this software must not be misrepresented; you must not
14 claim that you wrote the original software. If you use this software
15 in a product, an acknowledgment in the product documentation would be
16 appreciated but is not required.
17 2. Altered source versions must be plainly marked as such, and must not be
18 misrepresented as being the original software.
19 3. This notice may not be removed or altered from any source distribution.
20 */
21 #include "../../SDL_internal.h"
22
23 #if SDL_VIDEO_DRIVER_OS2
24
25 /* Display a OS/2 message box */
26
27 #include "SDL.h"
28 #include "../../core/os2/SDL_os2.h"
29 #include "SDL_os2video.h"
30 #define INCL_WIN
31 #include <os2.h>
32
33 #define IDD_TEXT_MESSAGE 1001
34 #define IDD_BITMAP 1002
35 #define IDD_PB_FIRST 1003
36
37 typedef struct _MSGBOXDLGDATA {
38 USHORT cb;
39 HWND hwndUnder;
40 } MSGBOXDLGDATA;
41
_wmInitDlg(HWND hwnd,MSGBOXDLGDATA * pDlgData)42 static VOID _wmInitDlg(HWND hwnd, MSGBOXDLGDATA *pDlgData)
43 {
44 HPS hps = WinGetPS(hwnd);
45 POINTL aptText[TXTBOX_COUNT];
46 HENUM hEnum;
47 HWND hWndNext;
48 CHAR acBuf[256];
49 ULONG cbBuf;
50 ULONG cButtons = 0;
51 ULONG ulButtonsCY = 0;
52 ULONG ulButtonsCX = 0;
53 RECTL rectl;
54 ULONG ulX;
55 ULONG ulIdx;
56 struct _BUTTON {
57 HWND hwnd; /* Button window handle. */
58 ULONG ulCX; /* Button width in dialog coordinates. */
59 } aButtons[32];
60 RECTL rectlItem;
61 HAB hab = WinQueryAnchorBlock(hwnd);
62
63 /* --- Align the buttons to the right/bottom. --- */
64
65 /* Collect window handles of all buttons in dialog. */
66 hEnum = WinBeginEnumWindows(hwnd);
67
68 while ((hWndNext = WinGetNextWindow(hEnum)) != NULLHANDLE) {
69 if (WinQueryClassName(hWndNext, sizeof(acBuf), acBuf) == 0) {
70 continue;
71 }
72 if (SDL_strcmp(acBuf, "#3") == 0) { /* Class name of button. */
73 if (cButtons < sizeof(aButtons) / sizeof(struct _BUTTON)) {
74 aButtons[cButtons].hwnd = hWndNext;
75 cButtons++;
76 }
77 }
78 }
79 WinEndEnumWindows(hEnum);
80
81 /* Query size of text for each button, get width of each button, total
82 * buttons width (ulButtonsCX) and max. height (ulButtonsCX) in _dialog
83 * coordinates_. */
84 hps = WinGetPS(hwnd);
85
86 for(ulIdx = 0; ulIdx < cButtons; ulIdx++) {
87 /* Query size of text in window coordinates. */
88 cbBuf = WinQueryWindowText(aButtons[ulIdx].hwnd, sizeof(acBuf), acBuf);
89 GpiQueryTextBox(hps, cbBuf, acBuf, TXTBOX_COUNT, aptText);
90 aptText[TXTBOX_TOPRIGHT].x -= aptText[TXTBOX_BOTTOMLEFT].x;
91 aptText[TXTBOX_TOPRIGHT].y -= aptText[TXTBOX_BOTTOMLEFT].y;
92 /* Convert text size to dialog coordinates. */
93 WinMapDlgPoints(hwnd, &aptText[TXTBOX_TOPRIGHT], 1, FALSE);
94 /* Add vertical and horizontal space for button's frame (dialog coord.). */
95 if (aptText[TXTBOX_TOPRIGHT].x < 30) { /* Minimal button width. */
96 aptText[TXTBOX_TOPRIGHT].x = 30;
97 } else {
98 aptText[TXTBOX_TOPRIGHT].x += 4;
99 }
100 aptText[TXTBOX_TOPRIGHT].y += 3;
101
102 aButtons[ulIdx].ulCX = aptText[TXTBOX_TOPRIGHT].x; /* Store button width */
103 ulButtonsCX += aptText[TXTBOX_TOPRIGHT].x + 2; /* Add total btn. width */
104 /* Get max. height for buttons. */
105 if (ulButtonsCY < aptText[TXTBOX_TOPRIGHT].y)
106 ulButtonsCY = aptText[TXTBOX_TOPRIGHT].y + 1;
107 }
108
109 WinReleasePS(hps);
110
111 /* Expand horizontal size of the window to fit all buttons and move window
112 * to the center of parent window. */
113
114 /* Convert total width of buttons to window coordinates. */
115 aptText[0].x = ulButtonsCX + 4;
116 WinMapDlgPoints(hwnd, &aptText[0], 1, TRUE);
117 /* Check width of the window and expand as needed. */
118 WinQueryWindowRect(hwnd, &rectlItem);
119 if (rectlItem.xRight <= aptText[0].x)
120 rectlItem.xRight = aptText[0].x;
121
122 /* Move window rectangle to the center of owner window. */
123 WinQueryWindowRect(pDlgData->hwndUnder, &rectl);
124 /* Left-bottom point of centered dialog on owner window. */
125 rectl.xLeft = (rectl.xRight - rectlItem.xRight) / 2;
126 rectl.yBottom = (rectl.yTop - rectlItem.yTop) / 2;
127 /* Map left-bottom point to desktop. */
128 WinMapWindowPoints(pDlgData->hwndUnder, HWND_DESKTOP, (PPOINTL)&rectl, 1);
129 WinOffsetRect(hab, &rectlItem, rectl.xLeft, rectl.yBottom);
130
131 /* Set new rectangle for the window. */
132 WinSetWindowPos(hwnd, HWND_TOP, rectlItem.xLeft, rectlItem.yBottom,
133 rectlItem.xRight - rectlItem.xLeft,
134 rectlItem.yTop - rectlItem.yBottom,
135 SWP_SIZE | SWP_MOVE);
136
137 /* Set buttons positions. */
138
139 /* Get horizontal position for the first button. */
140 WinMapDlgPoints(hwnd, (PPOINTL)&rectlItem, 2, FALSE); /* Win size to dlg coord. */
141 ulX = rectlItem.xRight - rectlItem.xLeft - ulButtonsCX - 2; /* First button position. */
142
143 /* Set positions and sizes for all buttons. */
144 for (ulIdx = 0; ulIdx < cButtons; ulIdx++) {
145 /* Get poisition and size for the button in dialog coordinates. */
146 aptText[0].x = ulX;
147 aptText[0].y = 2;
148 aptText[1].x = aButtons[ulIdx].ulCX;
149 aptText[1].y = ulButtonsCY;
150 /* Convert to window coordinates. */
151 WinMapDlgPoints(hwnd, aptText, 2, TRUE);
152
153 WinSetWindowPos(aButtons[ulIdx].hwnd, HWND_TOP,
154 aptText[0].x, aptText[0].y, aptText[1].x, aptText[1].y,
155 SWP_MOVE | SWP_SIZE);
156
157 /* Offset horizontal position for the next button. */
158 ulX += aButtons[ulIdx].ulCX + 2;
159 }
160
161 /* Set right bound of the text to right bound of the last button and
162 * bottom bound of the text just above the buttons. */
163
164 aptText[2].x = 25; /* Left bound of text in dlg coordinates. */
165 aptText[2].y = ulButtonsCY + 3; /* Bottom bound of the text in dlg coords. */
166 WinMapDlgPoints(hwnd, &aptText[2], 1, TRUE); /* Convert ^^^ to win. coords */
167 hWndNext = WinWindowFromID(hwnd, IDD_TEXT_MESSAGE);
168 WinQueryWindowRect(hWndNext, &rectlItem);
169 rectlItem.xLeft = aptText[2].x;
170 rectlItem.yBottom = aptText[2].y;
171 /* Right bound of the text equals right bound of the last button. */
172 rectlItem.xRight = aptText[0].x + aptText[1].x;
173 WinSetWindowPos(hWndNext, HWND_TOP, rectlItem.xLeft, rectlItem.yBottom,
174 rectlItem.xRight - rectlItem.xLeft,
175 rectlItem.yTop - rectlItem.yBottom,
176 SWP_MOVE | SWP_SIZE);
177 }
178
DynDlgProc(HWND hwnd,USHORT message,MPARAM mp1,MPARAM mp2)179 static MRESULT EXPENTRY DynDlgProc(HWND hwnd, USHORT message, MPARAM mp1, MPARAM mp2)
180 {
181 switch (message) {
182 case WM_INITDLG:
183 _wmInitDlg(hwnd, (MSGBOXDLGDATA*)mp2);
184 break;
185
186 case WM_COMMAND:
187 switch (SHORT1FROMMP(mp1)) {
188 case DID_OK:
189 WinDismissDlg(hwnd, FALSE);
190 break;
191 default:
192 break;
193 }
194
195 default:
196 return(WinDefDlgProc(hwnd, message, mp1, mp2));
197 }
198
199 return FALSE;
200 }
201
_makeDlg(const SDL_MessageBoxData * messageboxdata)202 static HWND _makeDlg(const SDL_MessageBoxData *messageboxdata)
203 {
204 SDL_MessageBoxButtonData*
205 pSDLBtnData = (SDL_MessageBoxButtonData *)messageboxdata->buttons;
206 ULONG cSDLBtnData = messageboxdata->numbuttons;
207
208 PSZ pszTitle = OS2_UTF8ToSys((PSZ) messageboxdata->title);
209 ULONG cbTitle = (pszTitle == NULL)? 1 : (SDL_strlen(pszTitle) + 1);
210 PSZ pszText = OS2_UTF8ToSys((PSZ) messageboxdata->message);
211 ULONG cbText = (pszText == NULL)? 1 : (SDL_strlen(pszText) + 1);
212
213 PDLGTEMPLATE pTemplate;
214 ULONG cbTemplate;
215 ULONG ulIdx;
216 PCHAR pcDlgData;
217 PDLGTITEM pDlgItem;
218 PSZ pszBtnText;
219 ULONG cbBtnText;
220 HWND hwnd;
221
222 const SDL_MessageBoxColor* pSDLColors = (messageboxdata->colorScheme == NULL)?
223 NULL : messageboxdata->colorScheme->colors;
224 const SDL_MessageBoxColor* pSDLColor;
225
226 MSGBOXDLGDATA stDlgData;
227
228 /* Build a dialog tamplate in memory */
229
230 /* Size of template */
231 cbTemplate = sizeof(DLGTEMPLATE) + ((2 + cSDLBtnData) * sizeof(DLGTITEM)) +
232 sizeof(ULONG) + /* First item data - frame control data. */
233 cbTitle + /* First item data - frame title + ZERO. */
234 cbText + /* Second item data - ststic text + ZERO.*/
235 3; /* Third item data - system icon Id. */
236
237 /* Button items datas - text for buttons. */
238 for (ulIdx = 0; ulIdx < cSDLBtnData; ulIdx++) {
239 pszBtnText = (PSZ)pSDLBtnData[ulIdx].text;
240 cbTemplate += (pszBtnText == NULL)? 1 : (SDL_strlen(pszBtnText) + 1);
241 }
242
243 /* Presentation parameter space. */
244 if (pSDLColors != NULL) {
245 cbTemplate += 26 /* PP for frame. */ +
246 26 /* PP for static text. */ +
247 (48 * cSDLBtnData); /* PP for buttons. */
248 }
249
250 /* Allocate memory for the dialog template. */
251 pTemplate = (PDLGTEMPLATE) SDL_malloc(cbTemplate);
252 /* Pointer on data for dialog items in allocated memory. */
253 pcDlgData = &((PCHAR)pTemplate)[sizeof(DLGTEMPLATE) +
254 ((2 + cSDLBtnData) * sizeof(DLGTITEM))];
255
256 /* Header info */
257 pTemplate->cbTemplate = cbTemplate; /* size of dialog template to pass to WinCreateDlg() */
258 pTemplate->type = 0; /* Currently always 0. */
259 pTemplate->codepage = 0;
260 pTemplate->offadlgti = 14; /* Offset to array of DLGTITEMs. */
261 pTemplate->fsTemplateStatus = 0; /* Reserved field? */
262
263 /* Index in array of dlg items of item to get focus, */
264 /* if 0 then focus goes to first control that can have focus. */
265 pTemplate->iItemFocus = 0;
266 pTemplate->coffPresParams = 0;
267
268 /* First item info - frame */
269 pDlgItem = pTemplate->adlgti;
270 pDlgItem->fsItemStatus = 0; /* Reserved? */
271 /* Number of dialog item child windows owned by this item. */
272 pDlgItem->cChildren = 2 + cSDLBtnData; /* Ststic text + buttons. */
273 /* Length of class name, if 0 then offClassname contains a WC_ value. */
274 pDlgItem->cchClassName = 0;
275 pDlgItem->offClassName = (USHORT)WC_FRAME;
276 /* Length of text. */
277 pDlgItem->cchText = cbTitle;
278 pDlgItem->offText = pcDlgData - (PCHAR)pTemplate; /* Offset to title text. */
279 /* Copy text for the title into the dialog template. */
280 if (pszTitle != NULL) {
281 SDL_memcpy(pcDlgData, pszTitle, cbTitle);
282 } else {
283 *pcDlgData = '\0';
284 }
285 pcDlgData += pDlgItem->cchText;
286
287 pDlgItem->flStyle = WS_GROUP | WS_VISIBLE | WS_CLIPSIBLINGS |
288 FS_DLGBORDER | WS_SAVEBITS;
289 pDlgItem->x = 100;
290 pDlgItem->y = 100;
291 pDlgItem->cx = 175;
292 pDlgItem->cy = 65;
293 pDlgItem->id = DID_OK; /* An ID value? */
294 if (pSDLColors == NULL)
295 pDlgItem->offPresParams = 0;
296 else {
297 /* Presentation parameter for the frame - dialog colors. */
298 pDlgItem->offPresParams = pcDlgData - (PCHAR)pTemplate;
299 ((PPRESPARAMS)pcDlgData)->cb = 22;
300 pcDlgData += 4;
301 ((PPARAM)pcDlgData)->id = PP_FOREGROUNDCOLOR;
302 ((PPARAM)pcDlgData)->cb = 3;
303 ((PPARAM)pcDlgData)->ab[0] = pSDLColors[SDL_MESSAGEBOX_COLOR_TEXT].b;
304 ((PPARAM)pcDlgData)->ab[1] = pSDLColors[SDL_MESSAGEBOX_COLOR_TEXT].g;
305 ((PPARAM)pcDlgData)->ab[2] = pSDLColors[SDL_MESSAGEBOX_COLOR_TEXT].r;
306 pcDlgData += 11;
307 ((PPARAM)pcDlgData)->id = PP_BACKGROUNDCOLOR;
308 ((PPARAM)pcDlgData)->cb = 3;
309 ((PPARAM)pcDlgData)->ab[0] = pSDLColors[SDL_MESSAGEBOX_COLOR_BACKGROUND].b;
310 ((PPARAM)pcDlgData)->ab[1] = pSDLColors[SDL_MESSAGEBOX_COLOR_BACKGROUND].g;
311 ((PPARAM)pcDlgData)->ab[2] = pSDLColors[SDL_MESSAGEBOX_COLOR_BACKGROUND].r;
312 pcDlgData += 11;
313 }
314
315 /* Offset to ctl data. */
316 pDlgItem->offCtlData = pcDlgData - (PCHAR)pTemplate;
317 /* Put CtlData for the dialog in here */
318 *((PULONG)pcDlgData) = FCF_TITLEBAR | FCF_SYSMENU;
319 pcDlgData += sizeof(ULONG);
320
321 /* Second item info - static text (message). */
322 pDlgItem++;
323 pDlgItem->fsItemStatus = 0;
324 /* No children since its a control, it could have child control */
325 /* (ex. a group box). */
326 pDlgItem->cChildren = 0;
327 /* Length of class name, 0 - offClassname contains a WC_ constant. */
328 pDlgItem->cchClassName = 0;
329 pDlgItem->offClassName = (USHORT)WC_STATIC;
330
331 pDlgItem->cchText = cbText;
332 pDlgItem->offText = pcDlgData - (PCHAR)pTemplate; /* Offset to the text. */
333 /* Copy message text into the dialog template. */
334 if (pszText != NULL) {
335 SDL_memcpy(pcDlgData, pszText, cbText);
336 } else {
337 *pcDlgData = '\0';
338 }
339 pcDlgData += pDlgItem->cchText;
340
341 pDlgItem->flStyle = SS_TEXT | DT_TOP | DT_LEFT | DT_WORDBREAK | WS_VISIBLE;
342 /* It will be really set in _wmInitDlg(). */
343 pDlgItem->x = 25;
344 pDlgItem->y = 13;
345 pDlgItem->cx = 147;
346 pDlgItem->cy = 62; /* It will be used. */
347
348 pDlgItem->id = IDD_TEXT_MESSAGE; /* an ID value */
349 if (pSDLColors == NULL)
350 pDlgItem->offPresParams = 0;
351 else {
352 /* Presentation parameter for the static text - dialog colors. */
353 pDlgItem->offPresParams = pcDlgData - (PCHAR)pTemplate;
354 ((PPRESPARAMS)pcDlgData)->cb = 22;
355 pcDlgData += 4;
356 ((PPARAM)pcDlgData)->id = PP_FOREGROUNDCOLOR;
357 ((PPARAM)pcDlgData)->cb = 3;
358 ((PPARAM)pcDlgData)->ab[0] = pSDLColors[SDL_MESSAGEBOX_COLOR_TEXT].b;
359 ((PPARAM)pcDlgData)->ab[1] = pSDLColors[SDL_MESSAGEBOX_COLOR_TEXT].g;
360 ((PPARAM)pcDlgData)->ab[2] = pSDLColors[SDL_MESSAGEBOX_COLOR_TEXT].r;
361 pcDlgData += 11;
362 ((PPARAM)pcDlgData)->id = PP_BACKGROUNDCOLOR;
363 ((PPARAM)pcDlgData)->cb = 3;
364 ((PPARAM)pcDlgData)->ab[0] = pSDLColors[SDL_MESSAGEBOX_COLOR_BACKGROUND].b;
365 ((PPARAM)pcDlgData)->ab[1] = pSDLColors[SDL_MESSAGEBOX_COLOR_BACKGROUND].g;
366 ((PPARAM)pcDlgData)->ab[2] = pSDLColors[SDL_MESSAGEBOX_COLOR_BACKGROUND].r;
367 pcDlgData += 11;
368 }
369 pDlgItem->offCtlData = 0;
370
371 /* Third item info - static bitmap. */
372 pDlgItem++;
373 pDlgItem->fsItemStatus = 0;
374 pDlgItem->cChildren = 0;
375 pDlgItem->cchClassName = 0;
376 pDlgItem->offClassName = (USHORT)WC_STATIC;
377
378 pDlgItem->cchText = 3; /* 0xFF, low byte of the icon Id, high byte of icon Id. */
379 pDlgItem->offText = pcDlgData - (PCHAR)pTemplate; /* Offset to the Id. */
380 /* Write susyem icon ID into dialog template. */
381 *pcDlgData = 0xFF; /* First byte is 0xFF - next 2 bytes is system pointer Id. */
382 pcDlgData++;
383 *((PUSHORT)pcDlgData) = ((messageboxdata->flags & SDL_MESSAGEBOX_ERROR) != 0)?
384 SPTR_ICONERROR :
385 ((messageboxdata->flags & SDL_MESSAGEBOX_WARNING) != 0)?
386 SPTR_ICONWARNING : SPTR_ICONINFORMATION;
387 pcDlgData += 2;
388
389 pDlgItem->flStyle = SS_SYSICON | WS_VISIBLE;
390
391 pDlgItem->x = 4;
392 pDlgItem->y = 45; /* It will be really set in _wmInitDlg(). */
393 pDlgItem->cx = 0;
394 pDlgItem->cy = 0;
395
396 pDlgItem->id = IDD_BITMAP;
397 pDlgItem->offPresParams = 0;
398 pDlgItem->offCtlData = 0;
399
400 /* Next items - buttons. */
401 for (ulIdx = 0; ulIdx < cSDLBtnData; ulIdx++) {
402 pDlgItem++;
403
404 pDlgItem->fsItemStatus = 0;
405 pDlgItem->cChildren = 0; /* No children. */
406 pDlgItem->cchClassName = 0; /* 0 - offClassname is WC_ constant. */
407 pDlgItem->offClassName = (USHORT)WC_BUTTON;
408
409 pszBtnText = OS2_UTF8ToSys((PSZ)pSDLBtnData[ulIdx].text);
410 cbBtnText = (pszBtnText == NULL)? 1 : (SDL_strlen(pszBtnText) + 1);
411 pDlgItem->cchText = cbBtnText;
412 pDlgItem->offText = pcDlgData - (PCHAR)pTemplate; /* Offset to the text. */
413 /* Copy text for the button into the dialog template. */
414 if (pszBtnText != NULL) {
415 SDL_memcpy(pcDlgData, pszBtnText, cbBtnText);
416 } else {
417 *pcDlgData = '\0';
418 }
419 pcDlgData += pDlgItem->cchText;
420 SDL_free(pszBtnText);
421
422 pDlgItem->flStyle = BS_PUSHBUTTON | WS_TABSTOP | WS_VISIBLE;
423 if (pSDLBtnData[ulIdx].flags == SDL_MESSAGEBOX_BUTTON_RETURNKEY_DEFAULT) {
424 pDlgItem->flStyle |= BS_DEFAULT;
425 pTemplate->iItemFocus = ulIdx + 3; /* +3 - frame, static text and icon. */
426 pSDLColor = &pSDLColors[SDL_MESSAGEBOX_COLOR_BUTTON_SELECTED];
427 } else {
428 pSDLColor = &pSDLColors[SDL_MESSAGEBOX_COLOR_TEXT];
429 }
430
431 /* It will be really set in _wmInitDlg() */
432 pDlgItem->x = 10;
433 pDlgItem->y = 10;
434 pDlgItem->cx = 70;
435 pDlgItem->cy = 15;
436
437 pDlgItem->id = IDD_PB_FIRST + ulIdx; /* an ID value */
438 if (pSDLColors == NULL)
439 pDlgItem->offPresParams = 0;
440 else {
441 /* Presentation parameter for the button - dialog colors. */
442 pDlgItem->offPresParams = pcDlgData - (PCHAR)pTemplate;
443 ((PPRESPARAMS)pcDlgData)->cb = 44;
444 pcDlgData += 4;
445 ((PPARAM)pcDlgData)->id = PP_FOREGROUNDCOLOR;
446 ((PPARAM)pcDlgData)->cb = 3;
447 ((PPARAM)pcDlgData)->ab[0] = pSDLColor->b;
448 ((PPARAM)pcDlgData)->ab[1] = pSDLColor->g;
449 ((PPARAM)pcDlgData)->ab[2] = pSDLColor->r;
450 pcDlgData += 11;
451 ((PPARAM)pcDlgData)->id = PP_BACKGROUNDCOLOR;
452 ((PPARAM)pcDlgData)->cb = 3;
453 ((PPARAM)pcDlgData)->ab[0] = pSDLColors[SDL_MESSAGEBOX_COLOR_BUTTON_BACKGROUND].b;
454 ((PPARAM)pcDlgData)->ab[1] = pSDLColors[SDL_MESSAGEBOX_COLOR_BUTTON_BACKGROUND].g;
455 ((PPARAM)pcDlgData)->ab[2] = pSDLColors[SDL_MESSAGEBOX_COLOR_BUTTON_BACKGROUND].r;
456 pcDlgData += 11;
457 ((PPARAM)pcDlgData)->id = PP_BORDERLIGHTCOLOR;
458 ((PPARAM)pcDlgData)->cb = 3;
459 ((PPARAM)pcDlgData)->ab[0] = pSDLColors[SDL_MESSAGEBOX_COLOR_BUTTON_BORDER].b;
460 ((PPARAM)pcDlgData)->ab[1] = pSDLColors[SDL_MESSAGEBOX_COLOR_BUTTON_BORDER].g;
461 ((PPARAM)pcDlgData)->ab[2] = pSDLColors[SDL_MESSAGEBOX_COLOR_BUTTON_BORDER].r;
462 pcDlgData += 11;
463 ((PPARAM)pcDlgData)->id = PP_BORDERDARKCOLOR;
464 ((PPARAM)pcDlgData)->cb = 3;
465 ((PPARAM)pcDlgData)->ab[0] = pSDLColors[SDL_MESSAGEBOX_COLOR_BUTTON_BORDER].b;
466 ((PPARAM)pcDlgData)->ab[1] = pSDLColors[SDL_MESSAGEBOX_COLOR_BUTTON_BORDER].g;
467 ((PPARAM)pcDlgData)->ab[2] = pSDLColors[SDL_MESSAGEBOX_COLOR_BUTTON_BORDER].r;
468 pcDlgData += 11;
469 }
470 pDlgItem->offCtlData = 0;
471 }
472 /* Check, end of templ. data: &((PCHAR)pTemplate)[cbTemplate] == pcDlgData */
473
474 /* Create the dialog from template. */
475 stDlgData.cb = sizeof(MSGBOXDLGDATA);
476 stDlgData.hwndUnder = (messageboxdata->window != NULL && messageboxdata->window->driverdata != NULL)?
477 ((WINDATA *)messageboxdata->window->driverdata)->hwnd : HWND_DESKTOP;
478
479 hwnd = WinCreateDlg(HWND_DESKTOP, /* Parent is desktop. */
480 stDlgData.hwndUnder,
481 (PFNWP)DynDlgProc, pTemplate, &stDlgData);
482 SDL_free(pTemplate);
483 SDL_free(pszTitle);
484 SDL_free(pszText);
485
486 return hwnd;
487 }
488
489
OS2_ShowMessageBox(const SDL_MessageBoxData * messageboxdata,int * buttonid)490 int OS2_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonid)
491 {
492 HWND hwnd;
493 ULONG ulRC;
494 SDL_MessageBoxButtonData
495 *pSDLBtnData = (SDL_MessageBoxButtonData *)messageboxdata->buttons;
496 ULONG cSDLBtnData = messageboxdata->numbuttons;
497 BOOL fVideoInitialized = SDL_WasInit(SDL_INIT_VIDEO);
498 HAB hab;
499 HMQ hmq;
500 BOOL fSuccess = FALSE;
501
502 if (!fVideoInitialized) {
503 PTIB tib;
504 PPIB pib;
505
506 DosGetInfoBlocks(&tib, &pib);
507 if (pib->pib_ultype == 2 || pib->pib_ultype == 0) {
508 /* VIO windowable or fullscreen protect-mode session */
509 pib->pib_ultype = 3; /* Presentation Manager protect-mode session */
510 }
511
512 hab = WinInitialize(0);
513 if (hab == NULLHANDLE) {
514 debug_os2("WinInitialize() failed");
515 return -1;
516 }
517 hmq = WinCreateMsgQueue(hab, 0);
518 if (hmq == NULLHANDLE) {
519 debug_os2("WinCreateMsgQueue() failed");
520 return -1;
521 }
522 }
523
524 /* Create dynamic dialog. */
525 hwnd = _makeDlg(messageboxdata);
526 /* Show dialog and obtain button Id. */
527 ulRC = WinProcessDlg(hwnd);
528 /* Destroy dialog, */
529 WinDestroyWindow(hwnd);
530
531 if (ulRC == DID_CANCEL) {
532 /* Window closed by ESC, Alt+F4 or system menu. */
533 ULONG ulIdx;
534
535 for (ulIdx = 0; ulIdx < cSDLBtnData; ulIdx++, pSDLBtnData++) {
536 if (pSDLBtnData->flags == SDL_MESSAGEBOX_BUTTON_ESCAPEKEY_DEFAULT) {
537 *buttonid = pSDLBtnData->buttonid;
538 fSuccess = TRUE;
539 break;
540 }
541 }
542 } else {
543 /* Button pressed. */
544 ulRC -= IDD_PB_FIRST;
545 if (ulRC < cSDLBtnData) {
546 *buttonid = pSDLBtnData[ulRC].buttonid;
547 fSuccess = TRUE;
548 }
549 }
550
551 if (!fVideoInitialized) {
552 WinDestroyMsgQueue(hmq);
553 WinTerminate(hab);
554 }
555
556 return (fSuccess)? 0 : -1;
557 }
558
559 #endif /* SDL_VIDEO_DRIVER_OS2 */
560
561 /* vi: set ts=4 sw=4 expandtab: */
562