#include "../../SDL_internal.h"
#if SDL_VIDEO_DRIVER_OS2
#include "SDL.h"
#include "../../core/os2/SDL_os2.h"
#include "SDL_os2video.h"
#define INCL_WIN
#include <os2.h>
#define IDD_TEXT_MESSAGE 1001
#define IDD_BITMAP 1002
#define IDD_PB_FIRST 1003
typedef struct _MSGBOXDLGDATA {
USHORT cb;
HWND hwndUnder;
} MSGBOXDLGDATA;
static VOID _wmInitDlg(HWND hwnd, MSGBOXDLGDATA *pDlgData)
{
HPS hps = WinGetPS(hwnd);
POINTL aptText[TXTBOX_COUNT];
HENUM hEnum;
HWND hWndNext;
CHAR acBuf[256];
ULONG cbBuf;
ULONG cButtons = 0;
ULONG ulButtonsCY = 0;
ULONG ulButtonsCX = 0;
RECTL rectl;
ULONG ulX;
ULONG ulIdx;
struct _BUTTON {
HWND hwnd;
ULONG ulCX;
} aButtons[32];
RECTL rectlItem;
HAB hab = WinQueryAnchorBlock(hwnd);
hEnum = WinBeginEnumWindows(hwnd);
while ((hWndNext = WinGetNextWindow(hEnum)) != NULLHANDLE) {
if (WinQueryClassName(hWndNext, sizeof(acBuf), acBuf) == 0) {
continue;
}
if (SDL_strcmp(acBuf, "#3") == 0) {
if (cButtons < sizeof(aButtons) / sizeof(struct _BUTTON)) {
aButtons[cButtons].hwnd = hWndNext;
cButtons++;
}
}
}
WinEndEnumWindows(hEnum);
hps = WinGetPS(hwnd);
for(ulIdx = 0; ulIdx < cButtons; ulIdx++) {
cbBuf = WinQueryWindowText(aButtons[ulIdx].hwnd, sizeof(acBuf), acBuf);
GpiQueryTextBox(hps, cbBuf, acBuf, TXTBOX_COUNT, aptText);
aptText[TXTBOX_TOPRIGHT].x -= aptText[TXTBOX_BOTTOMLEFT].x;
aptText[TXTBOX_TOPRIGHT].y -= aptText[TXTBOX_BOTTOMLEFT].y;
WinMapDlgPoints(hwnd, &aptText[TXTBOX_TOPRIGHT], 1, FALSE);
if (aptText[TXTBOX_TOPRIGHT].x < 30) {
aptText[TXTBOX_TOPRIGHT].x = 30;
} else {
aptText[TXTBOX_TOPRIGHT].x += 4;
}
aptText[TXTBOX_TOPRIGHT].y += 3;
aButtons[ulIdx].ulCX = aptText[TXTBOX_TOPRIGHT].x;
ulButtonsCX += aptText[TXTBOX_TOPRIGHT].x + 2;
if (ulButtonsCY < aptText[TXTBOX_TOPRIGHT].y)
ulButtonsCY = aptText[TXTBOX_TOPRIGHT].y + 1;
}
WinReleasePS(hps);
aptText[0].x = ulButtonsCX + 4;
WinMapDlgPoints(hwnd, &aptText[0], 1, TRUE);
WinQueryWindowRect(hwnd, &rectlItem);
if (rectlItem.xRight <= aptText[0].x)
rectlItem.xRight = aptText[0].x;
WinQueryWindowRect(pDlgData->hwndUnder, &rectl);
rectl.xLeft = (rectl.xRight - rectlItem.xRight) / 2;
rectl.yBottom = (rectl.yTop - rectlItem.yTop) / 2;
WinMapWindowPoints(pDlgData->hwndUnder, HWND_DESKTOP, (PPOINTL)&rectl, 1);
WinOffsetRect(hab, &rectlItem, rectl.xLeft, rectl.yBottom);
WinSetWindowPos(hwnd, HWND_TOP, rectlItem.xLeft, rectlItem.yBottom,
rectlItem.xRight - rectlItem.xLeft,
rectlItem.yTop - rectlItem.yBottom,
SWP_SIZE | SWP_MOVE);
WinMapDlgPoints(hwnd, (PPOINTL)&rectlItem, 2, FALSE);
ulX = rectlItem.xRight - rectlItem.xLeft - ulButtonsCX - 2;
for (ulIdx = 0; ulIdx < cButtons; ulIdx++) {
aptText[0].x = ulX;
aptText[0].y = 2;
aptText[1].x = aButtons[ulIdx].ulCX;
aptText[1].y = ulButtonsCY;
WinMapDlgPoints(hwnd, aptText, 2, TRUE);
WinSetWindowPos(aButtons[ulIdx].hwnd, HWND_TOP,
aptText[0].x, aptText[0].y, aptText[1].x, aptText[1].y,
SWP_MOVE | SWP_SIZE);
ulX += aButtons[ulIdx].ulCX + 2;
}
aptText[2].x = 25;
aptText[2].y = ulButtonsCY + 3;
WinMapDlgPoints(hwnd, &aptText[2], 1, TRUE);
hWndNext = WinWindowFromID(hwnd, IDD_TEXT_MESSAGE);
WinQueryWindowRect(hWndNext, &rectlItem);
rectlItem.xLeft = aptText[2].x;
rectlItem.yBottom = aptText[2].y;
rectlItem.xRight = aptText[0].x + aptText[1].x;
WinSetWindowPos(hWndNext, HWND_TOP, rectlItem.xLeft, rectlItem.yBottom,
rectlItem.xRight - rectlItem.xLeft,
rectlItem.yTop - rectlItem.yBottom,
SWP_MOVE | SWP_SIZE);
}
static MRESULT EXPENTRY DynDlgProc(HWND hwnd, USHORT message, MPARAM mp1, MPARAM mp2)
{
switch (message) {
case WM_INITDLG:
_wmInitDlg(hwnd, (MSGBOXDLGDATA*)mp2);
break;
case WM_COMMAND:
switch (SHORT1FROMMP(mp1)) {
case DID_OK:
WinDismissDlg(hwnd, FALSE);
break;
default:
break;
}
default:
return(WinDefDlgProc(hwnd, message, mp1, mp2));
}
return FALSE;
}
static HWND _makeDlg(const SDL_MessageBoxData *messageboxdata)
{
SDL_MessageBoxButtonData*
pSDLBtnData = (SDL_MessageBoxButtonData *)messageboxdata->buttons;
ULONG cSDLBtnData = messageboxdata->numbuttons;
PSZ pszTitle = OS2_UTF8ToSys(messageboxdata->title);
ULONG cbTitle = (pszTitle == NULL)? 1 : (SDL_strlen(pszTitle) + 1);
PSZ pszText = OS2_UTF8ToSys(messageboxdata->message);
ULONG cbText = (pszText == NULL)? 1 : (SDL_strlen(pszText) + 1);
PDLGTEMPLATE pTemplate;
ULONG cbTemplate;
ULONG ulIdx;
PCHAR pcDlgData;
PDLGTITEM pDlgItem;
PSZ pszBtnText;
ULONG cbBtnText;
HWND hwnd;
const SDL_MessageBoxColor* pSDLColors = (messageboxdata->colorScheme == NULL)?
NULL : messageboxdata->colorScheme->colors;
const SDL_MessageBoxColor* pSDLColor;
MSGBOXDLGDATA stDlgData;
cbTemplate = sizeof(DLGTEMPLATE) + ((2 + cSDLBtnData) * sizeof(DLGTITEM)) +
sizeof(ULONG) +
cbTitle +
cbText +
3;
for (ulIdx = 0; ulIdx < cSDLBtnData; ulIdx++) {
pszBtnText = (PSZ)pSDLBtnData[ulIdx].text;
cbTemplate += (pszBtnText == NULL)? 1 : (SDL_strlen(pszBtnText) + 1);
}
if (pSDLColors != NULL) {
cbTemplate += 26 +
26 +
(48 * cSDLBtnData);
}
pTemplate = (PDLGTEMPLATE) SDL_malloc(cbTemplate);
pcDlgData = &((PCHAR)pTemplate)[sizeof(DLGTEMPLATE) +
((2 + cSDLBtnData) * sizeof(DLGTITEM))];
pTemplate->cbTemplate = cbTemplate;
pTemplate->type = 0;
pTemplate->codepage = 0;
pTemplate->offadlgti = 14;
pTemplate->fsTemplateStatus = 0;
pTemplate->iItemFocus = 0;
pTemplate->coffPresParams = 0;
pDlgItem = pTemplate->adlgti;
pDlgItem->fsItemStatus = 0;
pDlgItem->cChildren = 2 + cSDLBtnData;
pDlgItem->cchClassName = 0;
pDlgItem->offClassName = (USHORT)WC_FRAME;
pDlgItem->cchText = cbTitle;
pDlgItem->offText = pcDlgData - (PCHAR)pTemplate;
if (pszTitle != NULL) {
SDL_memcpy(pcDlgData, pszTitle, cbTitle);
} else {
*pcDlgData = '\0';
}
pcDlgData += pDlgItem->cchText;
pDlgItem->flStyle = WS_GROUP | WS_VISIBLE | WS_CLIPSIBLINGS |
FS_DLGBORDER | WS_SAVEBITS;
pDlgItem->x = 100;
pDlgItem->y = 100;
pDlgItem->cx = 175;
pDlgItem->cy = 65;
pDlgItem->id = DID_OK;
if (pSDLColors == NULL)
pDlgItem->offPresParams = 0;
else {
pDlgItem->offPresParams = pcDlgData - (PCHAR)pTemplate;
((PPRESPARAMS)pcDlgData)->cb = 22;
pcDlgData += 4;
((PPARAM)pcDlgData)->id = PP_FOREGROUNDCOLOR;
((PPARAM)pcDlgData)->cb = 3;
((PPARAM)pcDlgData)->ab[0] = pSDLColors[SDL_MESSAGEBOX_COLOR_TEXT].b;
((PPARAM)pcDlgData)->ab[1] = pSDLColors[SDL_MESSAGEBOX_COLOR_TEXT].g;
((PPARAM)pcDlgData)->ab[2] = pSDLColors[SDL_MESSAGEBOX_COLOR_TEXT].r;
pcDlgData += 11;
((PPARAM)pcDlgData)->id = PP_BACKGROUNDCOLOR;
((PPARAM)pcDlgData)->cb = 3;
((PPARAM)pcDlgData)->ab[0] = pSDLColors[SDL_MESSAGEBOX_COLOR_BACKGROUND].b;
((PPARAM)pcDlgData)->ab[1] = pSDLColors[SDL_MESSAGEBOX_COLOR_BACKGROUND].g;
((PPARAM)pcDlgData)->ab[2] = pSDLColors[SDL_MESSAGEBOX_COLOR_BACKGROUND].r;
pcDlgData += 11;
}
pDlgItem->offCtlData = pcDlgData - (PCHAR)pTemplate;
*((PULONG)pcDlgData) = FCF_TITLEBAR | FCF_SYSMENU;
pcDlgData += sizeof(ULONG);
pDlgItem++;
pDlgItem->fsItemStatus = 0;
pDlgItem->cChildren = 0;
pDlgItem->cchClassName = 0;
pDlgItem->offClassName = (USHORT)WC_STATIC;
pDlgItem->cchText = cbText;
pDlgItem->offText = pcDlgData - (PCHAR)pTemplate;
if (pszText != NULL) {
SDL_memcpy(pcDlgData, pszText, cbText);
} else {
*pcDlgData = '\0';
}
pcDlgData += pDlgItem->cchText;
pDlgItem->flStyle = SS_TEXT | DT_TOP | DT_LEFT | DT_WORDBREAK | WS_VISIBLE;
pDlgItem->x = 25;
pDlgItem->y = 13;
pDlgItem->cx = 147;
pDlgItem->cy = 62;
pDlgItem->id = IDD_TEXT_MESSAGE;
if (pSDLColors == NULL)
pDlgItem->offPresParams = 0;
else {
pDlgItem->offPresParams = pcDlgData - (PCHAR)pTemplate;
((PPRESPARAMS)pcDlgData)->cb = 22;
pcDlgData += 4;
((PPARAM)pcDlgData)->id = PP_FOREGROUNDCOLOR;
((PPARAM)pcDlgData)->cb = 3;
((PPARAM)pcDlgData)->ab[0] = pSDLColors[SDL_MESSAGEBOX_COLOR_TEXT].b;
((PPARAM)pcDlgData)->ab[1] = pSDLColors[SDL_MESSAGEBOX_COLOR_TEXT].g;
((PPARAM)pcDlgData)->ab[2] = pSDLColors[SDL_MESSAGEBOX_COLOR_TEXT].r;
pcDlgData += 11;
((PPARAM)pcDlgData)->id = PP_BACKGROUNDCOLOR;
((PPARAM)pcDlgData)->cb = 3;
((PPARAM)pcDlgData)->ab[0] = pSDLColors[SDL_MESSAGEBOX_COLOR_BACKGROUND].b;
((PPARAM)pcDlgData)->ab[1] = pSDLColors[SDL_MESSAGEBOX_COLOR_BACKGROUND].g;
((PPARAM)pcDlgData)->ab[2] = pSDLColors[SDL_MESSAGEBOX_COLOR_BACKGROUND].r;
pcDlgData += 11;
}
pDlgItem->offCtlData = 0;
pDlgItem++;
pDlgItem->fsItemStatus = 0;
pDlgItem->cChildren = 0;
pDlgItem->cchClassName = 0;
pDlgItem->offClassName = (USHORT)WC_STATIC;
pDlgItem->cchText = 3;
pDlgItem->offText = pcDlgData - (PCHAR)pTemplate;
*((PBYTE)pcDlgData) = 0xFF;
pcDlgData++;
*((PUSHORT)pcDlgData) = ((messageboxdata->flags & SDL_MESSAGEBOX_ERROR) != 0)?
SPTR_ICONERROR :
((messageboxdata->flags & SDL_MESSAGEBOX_WARNING) != 0)?
SPTR_ICONWARNING : SPTR_ICONINFORMATION;
pcDlgData += 2;
pDlgItem->flStyle = SS_SYSICON | WS_VISIBLE;
pDlgItem->x = 4;
pDlgItem->y = 45;
pDlgItem->cx = 0;
pDlgItem->cy = 0;
pDlgItem->id = IDD_BITMAP;
pDlgItem->offPresParams = 0;
pDlgItem->offCtlData = 0;
for (ulIdx = 0; ulIdx < cSDLBtnData; ulIdx++) {
pDlgItem++;
pDlgItem->fsItemStatus = 0;
pDlgItem->cChildren = 0;
pDlgItem->cchClassName = 0;
pDlgItem->offClassName = (USHORT)WC_BUTTON;
pszBtnText = OS2_UTF8ToSys(pSDLBtnData[ulIdx].text);
cbBtnText = (pszBtnText == NULL)? 1 : (SDL_strlen(pszBtnText) + 1);
pDlgItem->cchText = cbBtnText;
pDlgItem->offText = pcDlgData - (PCHAR)pTemplate;
if (pszBtnText != NULL) {
SDL_memcpy(pcDlgData, pszBtnText, cbBtnText);
} else {
*pcDlgData = '\0';
}
pcDlgData += pDlgItem->cchText;
SDL_free(pszBtnText);
pDlgItem->flStyle = BS_PUSHBUTTON | WS_TABSTOP | WS_VISIBLE;
if (pSDLBtnData[ulIdx].flags == SDL_MESSAGEBOX_BUTTON_RETURNKEY_DEFAULT) {
pDlgItem->flStyle |= BS_DEFAULT;
pTemplate->iItemFocus = ulIdx + 3;
pSDLColor = &pSDLColors[SDL_MESSAGEBOX_COLOR_BUTTON_SELECTED];
} else {
pSDLColor = &pSDLColors[SDL_MESSAGEBOX_COLOR_TEXT];
}
pDlgItem->x = 10;
pDlgItem->y = 10;
pDlgItem->cx = 70;
pDlgItem->cy = 15;
pDlgItem->id = IDD_PB_FIRST + ulIdx;
if (pSDLColors == NULL)
pDlgItem->offPresParams = 0;
else {
pDlgItem->offPresParams = pcDlgData - (PCHAR)pTemplate;
((PPRESPARAMS)pcDlgData)->cb = 44;
pcDlgData += 4;
((PPARAM)pcDlgData)->id = PP_FOREGROUNDCOLOR;
((PPARAM)pcDlgData)->cb = 3;
((PPARAM)pcDlgData)->ab[0] = pSDLColor->b;
((PPARAM)pcDlgData)->ab[1] = pSDLColor->g;
((PPARAM)pcDlgData)->ab[2] = pSDLColor->r;
pcDlgData += 11;
((PPARAM)pcDlgData)->id = PP_BACKGROUNDCOLOR;
((PPARAM)pcDlgData)->cb = 3;
((PPARAM)pcDlgData)->ab[0] = pSDLColors[SDL_MESSAGEBOX_COLOR_BUTTON_BACKGROUND].b;
((PPARAM)pcDlgData)->ab[1] = pSDLColors[SDL_MESSAGEBOX_COLOR_BUTTON_BACKGROUND].g;
((PPARAM)pcDlgData)->ab[2] = pSDLColors[SDL_MESSAGEBOX_COLOR_BUTTON_BACKGROUND].r;
pcDlgData += 11;
((PPARAM)pcDlgData)->id = PP_BORDERLIGHTCOLOR;
((PPARAM)pcDlgData)->cb = 3;
((PPARAM)pcDlgData)->ab[0] = pSDLColors[SDL_MESSAGEBOX_COLOR_BUTTON_BORDER].b;
((PPARAM)pcDlgData)->ab[1] = pSDLColors[SDL_MESSAGEBOX_COLOR_BUTTON_BORDER].g;
((PPARAM)pcDlgData)->ab[2] = pSDLColors[SDL_MESSAGEBOX_COLOR_BUTTON_BORDER].r;
pcDlgData += 11;
((PPARAM)pcDlgData)->id = PP_BORDERDARKCOLOR;
((PPARAM)pcDlgData)->cb = 3;
((PPARAM)pcDlgData)->ab[0] = pSDLColors[SDL_MESSAGEBOX_COLOR_BUTTON_BORDER].b;
((PPARAM)pcDlgData)->ab[1] = pSDLColors[SDL_MESSAGEBOX_COLOR_BUTTON_BORDER].g;
((PPARAM)pcDlgData)->ab[2] = pSDLColors[SDL_MESSAGEBOX_COLOR_BUTTON_BORDER].r;
pcDlgData += 11;
}
pDlgItem->offCtlData = 0;
}
stDlgData.cb = sizeof(MSGBOXDLGDATA);
stDlgData.hwndUnder = (messageboxdata->window != NULL && messageboxdata->window->driverdata != NULL)?
((WINDATA *)messageboxdata->window->driverdata)->hwnd : HWND_DESKTOP;
hwnd = WinCreateDlg(HWND_DESKTOP,
stDlgData.hwndUnder,
(PFNWP)DynDlgProc, pTemplate, &stDlgData);
SDL_free(pTemplate);
SDL_free(pszTitle);
SDL_free(pszText);
return hwnd;
}
int OS2_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonid)
{
HWND hwnd;
ULONG ulRC;
SDL_MessageBoxButtonData
*pSDLBtnData = (SDL_MessageBoxButtonData *)messageboxdata->buttons;
ULONG cSDLBtnData = messageboxdata->numbuttons;
BOOL fVideoInitialized = SDL_WasInit(SDL_INIT_VIDEO);
HAB hab;
HMQ hmq;
BOOL fSuccess = FALSE;
if (!fVideoInitialized) {
PTIB tib;
PPIB pib;
DosGetInfoBlocks(&tib, &pib);
if (pib->pib_ultype == 2 || pib->pib_ultype == 0) {
pib->pib_ultype = 3;
}
hab = WinInitialize(0);
if (hab == NULLHANDLE) {
debug_os2("WinInitialize() failed");
return -1;
}
hmq = WinCreateMsgQueue(hab, 0);
if (hmq == NULLHANDLE) {
debug_os2("WinCreateMsgQueue() failed");
return -1;
}
}
hwnd = _makeDlg(messageboxdata);
ulRC = WinProcessDlg(hwnd);
WinDestroyWindow(hwnd);
if (ulRC == DID_CANCEL) {
ULONG ulIdx;
for (ulIdx = 0; ulIdx < cSDLBtnData; ulIdx++, pSDLBtnData++) {
if (pSDLBtnData->flags == SDL_MESSAGEBOX_BUTTON_ESCAPEKEY_DEFAULT) {
*buttonid = pSDLBtnData->buttonid;
fSuccess = TRUE;
break;
}
}
} else {
ulRC -= IDD_PB_FIRST;
if (ulRC < cSDLBtnData) {
*buttonid = pSDLBtnData[ulRC].buttonid;
fSuccess = TRUE;
}
}
if (!fVideoInitialized) {
WinDestroyMsgQueue(hmq);
WinTerminate(hab);
}
return (fSuccess)? 0 : -1;
}
#endif