Imported Upstream version 2.0.14
[platform/upstream/SDL.git] / src / video / os2 / SDL_os2messagebox.c
1 /*
2   Simple DirectMedia Layer
3   Copyright (C) 1997-2020 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
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 (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
179 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
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)? 0 : strlen(pszTitle);
210     PSZ                 pszText = OS2_UTF8ToSys((PSZ) messageboxdata->message);
211     ULONG               cbText = (pszText == NULL)? 0 : strlen(pszText);
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     const SDL_MessageBoxColor* pSDLColors = (messageboxdata->colorScheme == NULL)?
222                                        NULL : messageboxdata->colorScheme->colors;
223     const SDL_MessageBoxColor* pSDLColor;
224     MSGBOXDLGDATA       stDlgData;
225
226     /* Build a dialog tamplate in memory */
227
228     /* Size of template (cbTemplate). */
229     cbTemplate = sizeof(DLGTEMPLATE) + ((2 + cSDLBtnData) * sizeof(DLGTITEM)) +
230                  sizeof(ULONG) +  /* First item data - frame control data. */
231                  cbTitle + 1 +    /* First item data - frame title + ZERO. */
232                  cbText + 1 +     /* Second item data - ststic text + ZERO.*/
233                  3;               /* Third item data - system icon Id.     */
234     /* Button items datas - text for buttons. */
235     for (ulIdx = 0; ulIdx < cSDLBtnData; ulIdx++) {
236         pszBtnText = (PSZ)pSDLBtnData[ulIdx].text;
237         cbTemplate += (pszBtnText == NULL)? 1 : (strlen(pszBtnText) + 1);
238     }
239     /* Presentation parameter space. */
240     if (pSDLColors != NULL)
241         cbTemplate += 26 /* PP for frame. */ + 26 /* PP for static text. */ +
242                      (48 * cSDLBtnData); /* PP for buttons. */
243
244     /* Allocate memory for the dialog template. */
245     pTemplate = (PDLGTEMPLATE) SDL_malloc(cbTemplate);
246     /* Pointer on data for dialog items in allocated memory. */
247     pcDlgData = &((PCHAR)pTemplate)[sizeof(DLGTEMPLATE) +
248                                     ((2 + cSDLBtnData) * sizeof(DLGTITEM))];
249
250     /* Header info */
251     pTemplate->cbTemplate = cbTemplate; /* size of dialog template to pass to WinCreateDlg() */
252     pTemplate->type = 0;                /* Currently always 0. */
253     pTemplate->codepage = 0;
254     pTemplate->offadlgti = 14;          /* Offset to array of DLGTITEMs. */
255     pTemplate->fsTemplateStatus = 0;    /* Reserved field?  */
256
257     /* Index in array of dlg items of item to get focus,          */
258     /* if 0 then focus goes to first control that can have focus. */
259     pTemplate->iItemFocus = 0;
260     pTemplate->coffPresParams = 0;
261
262     /* First item info - frame */
263     pDlgItem = pTemplate->adlgti;
264     pDlgItem->fsItemStatus = 0;  /* Reserved? */
265     /* Number of dialog item child windows owned by this item. */
266     pDlgItem->cChildren = 2 + cSDLBtnData; /* Ststic text + buttons. */
267     /* Length of class name, if 0 then offClassname contains a WC_ value. */
268     pDlgItem->cchClassName = 0;
269     pDlgItem->offClassName = (USHORT)WC_FRAME;
270     /* Length of text. */
271     pDlgItem->cchText = cbTitle + 1; /* +1 - trailing ZERO. */
272     pDlgItem->offText = pcDlgData - (PCHAR)pTemplate; /* Offset to title text.  */
273     /* Copy text for the title into the dialog template. */
274     if (pszTitle != NULL) {
275         strcpy(pcDlgData, pszTitle);
276     } else {
277         *pcDlgData = '\0';
278     }
279     pcDlgData += pDlgItem->cchText;
280
281     pDlgItem->flStyle = WS_GROUP | WS_VISIBLE | WS_CLIPSIBLINGS | 
282                         FS_DLGBORDER | WS_SAVEBITS;
283     pDlgItem->x  = 100;
284     pDlgItem->y  = 100;
285     pDlgItem->cx = 175;
286     pDlgItem->cy = 65;
287     pDlgItem->id = DID_OK; /* An ID value? */
288     if (pSDLColors == NULL)
289         pDlgItem->offPresParams = 0;
290     else {
291         /* Presentation parameter for the frame - dialog colors. */
292         pDlgItem->offPresParams = pcDlgData - (PCHAR)pTemplate;
293         ((PPRESPARAMS)pcDlgData)->cb = 22;
294         pcDlgData += 4;
295         ((PPARAM)pcDlgData)->id = PP_FOREGROUNDCOLOR;
296         ((PPARAM)pcDlgData)->cb = 3;
297         ((PPARAM)pcDlgData)->ab[0] = pSDLColors[SDL_MESSAGEBOX_COLOR_TEXT].b;
298         ((PPARAM)pcDlgData)->ab[1] = pSDLColors[SDL_MESSAGEBOX_COLOR_TEXT].g;
299         ((PPARAM)pcDlgData)->ab[2] = pSDLColors[SDL_MESSAGEBOX_COLOR_TEXT].r;
300         pcDlgData += 11;
301         ((PPARAM)pcDlgData)->id = PP_BACKGROUNDCOLOR;
302         ((PPARAM)pcDlgData)->cb = 3;
303         ((PPARAM)pcDlgData)->ab[0] = pSDLColors[SDL_MESSAGEBOX_COLOR_BACKGROUND].b;
304         ((PPARAM)pcDlgData)->ab[1] = pSDLColors[SDL_MESSAGEBOX_COLOR_BACKGROUND].g;
305         ((PPARAM)pcDlgData)->ab[2] = pSDLColors[SDL_MESSAGEBOX_COLOR_BACKGROUND].r;
306         pcDlgData += 11;
307     }
308
309     /* Offset to ctl data. */
310     pDlgItem->offCtlData = pcDlgData - (PCHAR)pTemplate;
311     /* Put CtlData for the dialog in here */
312     *((PULONG)pcDlgData) = FCF_TITLEBAR | FCF_SYSMENU;
313     pcDlgData += sizeof(ULONG);
314
315     /* Second item info - static text (message). */
316     pDlgItem++;
317     pDlgItem->fsItemStatus = 0;
318     /* No children since its a control, it could have child control */
319     /* (ex. a group box).                                           */
320     pDlgItem->cChildren = 0;
321     /* Length of class name, 0 - offClassname contains a WC_ constant. */
322     pDlgItem->cchClassName = 0;
323     pDlgItem->offClassName = (USHORT)WC_STATIC;
324
325     pDlgItem->cchText = cbText + 1;
326     pDlgItem->offText = pcDlgData - (PCHAR)pTemplate;   /* Offset to the text. */
327     /* Copy message text into the dialog template. */
328     if (pszText != NULL) {
329         strcpy(pcDlgData, pszText);
330     } else {
331       *pcDlgData = '\0';
332     }
333     pcDlgData += pDlgItem->cchText;
334
335     pDlgItem->flStyle = SS_TEXT | DT_TOP | DT_LEFT | DT_WORDBREAK | WS_VISIBLE;
336     /* It will be really set in _wmInitDlg(). */
337     pDlgItem->x = 25;
338     pDlgItem->y = 13;
339     pDlgItem->cx = 147;
340     pDlgItem->cy = 62;  /* It will be used. */
341
342     pDlgItem->id = IDD_TEXT_MESSAGE;      /* an ID value */
343     if (pSDLColors == NULL)
344         pDlgItem->offPresParams = 0;
345     else {
346         /* Presentation parameter for the static text - dialog colors. */
347         pDlgItem->offPresParams = pcDlgData - (PCHAR)pTemplate;
348         ((PPRESPARAMS)pcDlgData)->cb = 22;
349         pcDlgData += 4;
350         ((PPARAM)pcDlgData)->id = PP_FOREGROUNDCOLOR;
351         ((PPARAM)pcDlgData)->cb = 3;
352         ((PPARAM)pcDlgData)->ab[0] = pSDLColors[SDL_MESSAGEBOX_COLOR_TEXT].b;
353         ((PPARAM)pcDlgData)->ab[1] = pSDLColors[SDL_MESSAGEBOX_COLOR_TEXT].g;
354         ((PPARAM)pcDlgData)->ab[2] = pSDLColors[SDL_MESSAGEBOX_COLOR_TEXT].r;
355         pcDlgData += 11;
356         ((PPARAM)pcDlgData)->id = PP_BACKGROUNDCOLOR;
357         ((PPARAM)pcDlgData)->cb = 3;
358         ((PPARAM)pcDlgData)->ab[0] = pSDLColors[SDL_MESSAGEBOX_COLOR_BACKGROUND].b;
359         ((PPARAM)pcDlgData)->ab[1] = pSDLColors[SDL_MESSAGEBOX_COLOR_BACKGROUND].g;
360         ((PPARAM)pcDlgData)->ab[2] = pSDLColors[SDL_MESSAGEBOX_COLOR_BACKGROUND].r;
361         pcDlgData += 11;
362     }
363     pDlgItem->offCtlData = 0;
364
365     /* Third item info - static bitmap. */
366     pDlgItem++;
367     pDlgItem->fsItemStatus = 0;
368     pDlgItem->cChildren = 0;
369     pDlgItem->cchClassName = 0;
370     pDlgItem->offClassName = (USHORT)WC_STATIC;
371
372     pDlgItem->cchText = 3; /* 0xFF, low byte of the icon Id, high byte of icon Id. */
373     pDlgItem->offText = pcDlgData - (PCHAR)pTemplate;   /* Offset to the Id. */
374     /* Write susyem icon ID into dialog template. */
375     *pcDlgData = 0xFF; /* First byte is 0xFF - next 2 bytes is system pointer Id. */
376     pcDlgData++;
377     *((PUSHORT)pcDlgData) = ((messageboxdata->flags & SDL_MESSAGEBOX_ERROR) != 0)?
378                               SPTR_ICONERROR :
379                                 ((messageboxdata->flags & SDL_MESSAGEBOX_WARNING) != 0)?
380                                   SPTR_ICONWARNING : SPTR_ICONINFORMATION;
381     pcDlgData += 2;
382
383     pDlgItem->flStyle = SS_SYSICON | WS_VISIBLE;
384
385     pDlgItem->x = 4;
386     pDlgItem->y = 45; /* It will be really set in _wmInitDlg(). */
387     pDlgItem->cx = 0;
388     pDlgItem->cy = 0;
389
390     pDlgItem->id = IDD_BITMAP;
391     pDlgItem->offPresParams = 0;
392     pDlgItem->offCtlData = 0;
393
394     /* Next items - buttons. */
395     for (ulIdx = 0; ulIdx < cSDLBtnData; ulIdx++) {
396         pDlgItem++;
397
398         pDlgItem->fsItemStatus = 0;
399         pDlgItem->cChildren = 0;     /* No children. */
400         pDlgItem->cchClassName = 0;  /* 0 - offClassname is WC_ constant. */
401         pDlgItem->offClassName = (USHORT)WC_BUTTON;
402
403         pszBtnText = OS2_UTF8ToSys((PSZ)pSDLBtnData[ulIdx].text);
404         cbBtnText = (pszBtnText == NULL)? 0 : strlen(pszBtnText);
405         pDlgItem->cchText = cbBtnText + 1;
406         pDlgItem->offText = pcDlgData - (PCHAR)pTemplate; /* Offset to the text. */
407         /* Copy text for the button into the dialog template. */
408         if (pszBtnText != NULL) {
409             strcpy(pcDlgData, pszBtnText);
410         } else {
411             *pcDlgData = '\0';
412         }
413         pcDlgData += pDlgItem->cchText;
414         SDL_free(pszBtnText);
415
416         pDlgItem->flStyle = BS_PUSHBUTTON | WS_TABSTOP | WS_VISIBLE;
417         if (pSDLBtnData[ulIdx].flags == SDL_MESSAGEBOX_BUTTON_RETURNKEY_DEFAULT) {
418             pDlgItem->flStyle |= BS_DEFAULT;
419             pTemplate->iItemFocus = ulIdx + 3; /* +3 - frame, static text and icon. */
420             pSDLColor = &pSDLColors[SDL_MESSAGEBOX_COLOR_BUTTON_SELECTED];
421         } else {
422             pSDLColor = &pSDLColors[SDL_MESSAGEBOX_COLOR_TEXT];
423         }
424
425         /* It will be really set in _wmInitDlg() */
426         pDlgItem->x = 10;
427         pDlgItem->y = 10;
428         pDlgItem->cx = 70;
429         pDlgItem->cy = 15;
430
431         pDlgItem->id = IDD_PB_FIRST + ulIdx;  /* an ID value */
432         if (pSDLColors == NULL)
433           pDlgItem->offPresParams = 0;
434         else {
435             /* Presentation parameter for the button - dialog colors. */
436             pDlgItem->offPresParams = pcDlgData - (PCHAR)pTemplate;
437             ((PPRESPARAMS)pcDlgData)->cb = 44;
438             pcDlgData += 4;
439             ((PPARAM)pcDlgData)->id = PP_FOREGROUNDCOLOR;
440             ((PPARAM)pcDlgData)->cb = 3;
441             ((PPARAM)pcDlgData)->ab[0] = pSDLColor->b;
442             ((PPARAM)pcDlgData)->ab[1] = pSDLColor->g;
443             ((PPARAM)pcDlgData)->ab[2] = pSDLColor->r;
444             pcDlgData += 11;
445             ((PPARAM)pcDlgData)->id = PP_BACKGROUNDCOLOR;
446             ((PPARAM)pcDlgData)->cb = 3;
447             ((PPARAM)pcDlgData)->ab[0] = pSDLColors[SDL_MESSAGEBOX_COLOR_BUTTON_BACKGROUND].b;
448             ((PPARAM)pcDlgData)->ab[1] = pSDLColors[SDL_MESSAGEBOX_COLOR_BUTTON_BACKGROUND].g;
449             ((PPARAM)pcDlgData)->ab[2] = pSDLColors[SDL_MESSAGEBOX_COLOR_BUTTON_BACKGROUND].r;
450             pcDlgData += 11;
451             ((PPARAM)pcDlgData)->id = PP_BORDERLIGHTCOLOR;
452             ((PPARAM)pcDlgData)->cb = 3;
453             ((PPARAM)pcDlgData)->ab[0] = pSDLColors[SDL_MESSAGEBOX_COLOR_BUTTON_BORDER].b;
454             ((PPARAM)pcDlgData)->ab[1] = pSDLColors[SDL_MESSAGEBOX_COLOR_BUTTON_BORDER].g;
455             ((PPARAM)pcDlgData)->ab[2] = pSDLColors[SDL_MESSAGEBOX_COLOR_BUTTON_BORDER].r;
456             pcDlgData += 11;
457             ((PPARAM)pcDlgData)->id = PP_BORDERDARKCOLOR;
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         }
464         pDlgItem->offCtlData = 0;
465     }
466     /* Check, end of templ. data: &((PCHAR)pTemplate)[cbTemplate] == pcDlgData */
467
468     /* Create the dialog from template. */
469     stDlgData.cb = sizeof(MSGBOXDLGDATA);
470     stDlgData.hwndUnder = (messageboxdata->window != NULL && messageboxdata->window->driverdata != NULL)?
471                             ((WINDATA *)messageboxdata->window->driverdata)->hwnd : HWND_DESKTOP;
472
473     hwnd = WinCreateDlg(HWND_DESKTOP, /* Parent is desktop. */
474                         stDlgData.hwndUnder,
475                         (PFNWP)DynDlgProc, pTemplate, &stDlgData);
476     SDL_free(pTemplate);
477     SDL_free(pszTitle);
478     SDL_free(pszText);
479
480     return hwnd;
481 }
482
483
484 int OS2_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonid)
485 {
486     HWND    hwnd;
487     ULONG   ulRC;
488     SDL_MessageBoxButtonData
489             *pSDLBtnData = (SDL_MessageBoxButtonData *)messageboxdata->buttons;
490     ULONG   cSDLBtnData = messageboxdata->numbuttons;
491     BOOL    fVideoInitialized = SDL_WasInit(SDL_INIT_VIDEO);
492     HAB     hab;
493     HMQ     hmq;
494     BOOL    fSuccess = FALSE;
495
496     if (!fVideoInitialized) {
497         PTIB    tib;
498         PPIB    pib;
499
500         DosGetInfoBlocks(&tib, &pib);
501         if (pib->pib_ultype == 2 || pib->pib_ultype == 0) {
502             /* VIO windowable or fullscreen protect-mode session */
503             pib->pib_ultype = 3; /* Presentation Manager protect-mode session */
504         }
505
506         hab = WinInitialize(0);
507         if (hab == NULLHANDLE) {
508             debug_os2("WinInitialize() failed");
509             return -1;
510         }
511         hmq = WinCreateMsgQueue(hab, 0);
512         if (hmq == NULLHANDLE) {
513             debug_os2("WinCreateMsgQueue() failed");
514             return -1;
515         }
516     }
517
518     /* Create dynamic dialog. */
519     hwnd = _makeDlg(messageboxdata);
520     /* Show dialog and obtain button Id. */
521     ulRC = WinProcessDlg(hwnd);
522     /* Destroy dialog, */
523     WinDestroyWindow(hwnd);
524
525     if (ulRC == DID_CANCEL) {
526         /* Window closed by ESC, Alt+F4 or system menu. */
527         ULONG   ulIdx;
528
529         for (ulIdx = 0; ulIdx < cSDLBtnData; ulIdx++, pSDLBtnData++) {
530             if (pSDLBtnData->flags == SDL_MESSAGEBOX_BUTTON_ESCAPEKEY_DEFAULT) {
531                 *buttonid = pSDLBtnData->buttonid;
532                 fSuccess = TRUE;
533                 break;
534             }
535         }
536     } else {
537         /* Button pressed. */
538         ulRC -= IDD_PB_FIRST;
539         if (ulRC < cSDLBtnData) {
540             *buttonid = pSDLBtnData[ulRC].buttonid;
541             fSuccess = TRUE;
542         }
543     }
544
545     if (!fVideoInitialized) {
546         WinDestroyMsgQueue(hmq);
547         WinTerminate(hab);
548     }
549
550     return (fSuccess)? 0 : -1;
551 }
552
553 #endif /* SDL_VIDEO_DRIVER_OS2 */
554
555 /* vi: set ts=4 sw=4 expandtab: */