SDL  2.0
SDL_os2messagebox.c
Go to the documentation of this file.
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 {
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;
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: */
#define SDL_INIT_VIDEO
Definition: SDL.h:82
#define SDL_WasInit
#define SDL_malloc
#define SDL_free
@ SDL_MESSAGEBOX_COLOR_BUTTON_BACKGROUND
@ SDL_MESSAGEBOX_COLOR_BUTTON_SELECTED
@ SDL_MESSAGEBOX_COLOR_BACKGROUND
@ SDL_MESSAGEBOX_COLOR_TEXT
@ SDL_MESSAGEBOX_COLOR_BUTTON_BORDER
@ SDL_MESSAGEBOX_ERROR
@ SDL_MESSAGEBOX_WARNING
@ SDL_MESSAGEBOX_BUTTON_RETURNKEY_DEFAULT
@ SDL_MESSAGEBOX_BUTTON_ESCAPEKEY_DEFAULT
GLint GLint GLint GLint GLint GLint y
Definition: SDL_opengl.h:1574
GLint GLint GLint GLint GLint x
Definition: SDL_opengl.h:1574
GLuint GLsizei const GLchar * message
GLbitfield flags
#define debug_os2(s,...)
Definition: SDL_os2.h:38
#define OS2_UTF8ToSys(S)
Definition: SDL_os2.h:45
#define NULL
Definition: begin_code.h:163
#define TRUE
Definition: edid-parse.c:33
#define FALSE
Definition: edid-parse.c:34
Individual button data.
RGB value used in a message box color scheme.
SDL_MessageBoxColor colors[SDL_MESSAGEBOX_COLOR_MAX]
MessageBox structure containing title, text, window, etc.
const SDL_MessageBoxColorScheme * colorScheme
const SDL_MessageBoxButtonData * buttons
SDL_Window * window
const char * title
const char * message
void * driverdata
Definition: SDL_sysvideo.h:112
static char text[MAX_TEXT_LENGTH]
Definition: testime.c:47