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