sdl

FORK: Simple Directmedia Layer
git clone https://git.neptards.moe/neptards/sdl.git
Log | Files | Refs

SDL_os2messagebox.c (21871B)


      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: */