X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/06298235850b7e576ef77a9a95b521534f18a4d9..c921fd5994d6d22b08ec98512eb59ee6f8939460:/src/os2/utils.cpp diff --git a/src/os2/utils.cpp b/src/os2/utils.cpp index 34cb8a977f..9db762aa23 100644 --- a/src/os2/utils.cpp +++ b/src/os2/utils.cpp @@ -26,8 +26,6 @@ #include #ifdef __EMX__ #include -#else -#include #endif #include "wx/log.h" @@ -40,11 +38,8 @@ #include #include -#define INCL_DOS -#define INCL_PM -#define INCL_GPI -#include #define PURE_32 + #ifndef __EMX__ #include #include @@ -110,7 +105,7 @@ bool wxGetUserId( , int nType ) { -#ifndef __EMX__ +#if defined(__VISAGECPP__) long lrc; // UPM procs return 0 on success lrc = U32ELOCU((unsigned char*)zBuf, (unsigned long *)&nType); @@ -136,7 +131,8 @@ bool wxGetUserName( int wxKill( long lPid -, int nSig +, wxSignal eSig +, wxKillError* peError ) { return((int)::DosKillProcess(0, (PID)lPid)); @@ -202,6 +198,13 @@ bool wxShell( return (rc != 0); } +// Shutdown or reboot the PC +bool wxShutdown(wxShutdownFlags wFlags) +{ + // TODO + return FALSE; +} + // Get free memory in bytes, or -1 if cannot determine amount (e.g. on UNIX) long wxGetFreeMemory() { @@ -217,6 +220,49 @@ long wxGetFreeMemory() return (long)lSize; } +// ---------------------------------------------------------------------------- +// env vars +// ---------------------------------------------------------------------------- + +bool wxGetEnv(const wxString& var, wxString *value) +{ + // wxGetenv is defined as getenv() + wxChar *p = wxGetenv(var); + if ( !p ) + return FALSE; + + if ( value ) + { + *value = p; + } + + return TRUE; +} + +bool wxSetEnv(const wxString& variable, const wxChar *value) +{ +#if defined(HAVE_SETENV) + return setenv(variable.mb_str(), value ? wxString(value).mb_str().data() + : NULL, 1 /* overwrite */) == 0; +#elif defined(HAVE_PUTENV) + wxString s = variable; + if ( value ) + s << _T('=') << value; + + // transform to ANSI + const char *p = s.mb_str(); + + // the string will be free()d by libc + char *buf = (char *)malloc(strlen(p) + 1); + strcpy(buf, p); + + return putenv(buf) == 0; +#else // no way to set an env var + return FALSE; +#endif +} + + // Sleep for nSecs seconds. Attempt a Windows implementation using timers. static bool inTimer = FALSE; @@ -236,7 +282,7 @@ void wxUsleep( unsigned long ulMilliseconds ) { - ::DosSleep(ulMilliseconds); + ::DosSleep(ulMilliseconds/1000l); } void wxSleep( @@ -252,6 +298,8 @@ void wxFlushEvents() // wxYield(); } +#if WXWIN_COMPATIBILITY_2_2 + // Output a debug mess., in a system dependent fashion. void wxDebugMsg( const wxChar* zFmt ... @@ -304,6 +352,8 @@ void wxFatalError( DosExit(EXIT_PROCESS, ulRc); } +#endif // WXWIN_COMPATIBILITY_2_2 + // Emit a beeeeeep void wxBell() { @@ -660,7 +710,7 @@ wxChar* wxGetUserHome ( if ((zHome = wxGetenv(_T("HOME"))) != NULL) { wxStrcpy(wxBuffer, zHome); - Unix2DosFilename(wxBuffer); + wxUnix2DosFilename(wxBuffer); wxStrcpy(zHome, wxBuffer); delete[] wxBuffer; return zHome; @@ -711,6 +761,7 @@ void wxGetMousePosition( // Return TRUE if we have a colour display bool wxColourDisplay() { +#if 0 HPS hpsScreen; HDC hdcScreen; LONG lColors; @@ -719,6 +770,11 @@ bool wxColourDisplay() hdcScreen = ::GpiQueryDevice(hpsScreen); ::DevQueryCaps(hdcScreen, CAPS_COLORS, 1L, &lColors); return(lColors > 1L); +#else + // I don't see how the PM display could not be color. Besides, this + // was leaking DCs and PSs!!! MN + return TRUE; +#endif } // Returns depth of screen @@ -728,15 +784,20 @@ int wxDisplayDepth() HDC hdcScreen; LONG lPlanes; LONG lBitsPerPixel; - LONG nDepth; - - hpsScreen = ::WinGetScreenPS(HWND_DESKTOP); - hdcScreen = ::GpiQueryDevice(hpsScreen); - ::DevQueryCaps(hdcScreen, CAPS_COLOR_PLANES, 1L, &lPlanes); - ::DevQueryCaps(hdcScreen, CAPS_COLOR_BITCOUNT, 1L, &lBitsPerPixel); - - nDepth = (int)(lPlanes * lBitsPerPixel); - DevCloseDC(hdcScreen); + static LONG nDepth = 0; + + // The screen colordepth ain't gonna change. No reason to query + // it over and over! + if (!nDepth) { + hpsScreen = ::WinGetScreenPS(HWND_DESKTOP); + hdcScreen = ::GpiQueryDevice(hpsScreen); + ::DevQueryCaps(hdcScreen, CAPS_COLOR_PLANES, 1L, &lPlanes); + ::DevQueryCaps(hdcScreen, CAPS_COLOR_BITCOUNT, 1L, &lBitsPerPixel); + + nDepth = (int)(lPlanes * lBitsPerPixel); + ::DevCloseDC(hdcScreen); + ::WinReleasePS(hpsScreen); + } return (nDepth); } @@ -748,18 +809,61 @@ void wxDisplaySize( { HPS hpsScreen; HDC hdcScreen; - LONG lWidth; - LONG lHeight; + static LONG lWidth = 0; + static LONG lHeight = 0; + + // The screen size ain't gonna change either so just cache the values + if (!lWidth) { + hpsScreen = ::WinGetScreenPS(HWND_DESKTOP); + hdcScreen = ::GpiQueryDevice(hpsScreen); + ::DevQueryCaps(hdcScreen, CAPS_WIDTH, 1L, &lWidth); + ::DevQueryCaps(hdcScreen, CAPS_HEIGHT, 1L, &lHeight); + ::DevCloseDC(hdcScreen); + ::WinReleasePS(hpsScreen); + } + *pWidth = (int)lWidth; + *pHeight = (int)lHeight; +} + +void wxDisplaySizeMM( + int* pWidth +, int* pHeight +) +{ + HPS hpsScreen; + HDC hdcScreen; hpsScreen = ::WinGetScreenPS(HWND_DESKTOP); hdcScreen = ::GpiQueryDevice(hpsScreen); - ::DevQueryCaps(hdcScreen, CAPS_WIDTH, 1L, &lWidth); - ::DevQueryCaps(hdcScreen, CAPS_HEIGHT, 1L, &lHeight); - DevCloseDC(hdcScreen); - *pWidth = (int)lWidth; - *pHeight = (int)lHeight; + + if (pWidth) + ::DevQueryCaps( hdcScreen + ,CAPS_HORIZONTAL_RESOLUTION + ,1L + ,(PLONG)pWidth + ); + if (pHeight) + ::DevQueryCaps( hdcScreen + ,CAPS_VERTICAL_RESOLUTION + ,1L + ,(PLONG)pHeight + ); + ::DevCloseDC(hdcScreen); + ::WinReleasePS(hpsScreen); } +void wxClientDisplayRect(int *x, int *y, int *width, int *height) +{ + // This is supposed to return desktop dimensions minus any window + // manager panels, menus, taskbars, etc. If there is a way to do that + // for this platform please fix this function, otherwise it defaults + // to the entire desktop. + if (x) *x = 0; + if (y) *y = 0; + wxDisplaySize(width, height); +} + + bool wxDirExists( const wxString& rDir ) @@ -817,3 +921,608 @@ WXWORD WXDLLEXPORT wxGetWindowId( return ::WinQueryWindowUShort((HWND)hWnd, QWS_ID); } +wxString WXDLLEXPORT wxPMErrorToStr( + ERRORID vError +) +{ + wxString sError; + + // + // Remove the high order byte -- it is useless + // + vError &= 0x0000ffff; + switch(vError) + { + case PMERR_INVALID_HWND: + sError = wxT("Invalid window handle specified"); + break; + + case PMERR_INVALID_FLAG: + sError = wxT("Invalid flag bit set"); + break; + + case PMERR_NO_MSG_QUEUE: + sError = wxT("No message queue available"); + break; + + case PMERR_INVALID_PARM: + sError = wxT("Parameter contained invalid data"); + break; + + case PMERR_INVALID_PARAMETERS: + sError = wxT("Parameter value is out of range"); + break; + + case PMERR_PARAMETER_OUT_OF_RANGE: + sError = wxT("Parameter value is out of range"); + break; + + case PMERR_INVALID_INTEGER_ATOM: + sError = wxT("Not a valid atom"); + break; + + case PMERR_INVALID_HATOMTBL: + sError = wxT("Atom table handle is invalid"); + break; + + case PMERR_INVALID_ATOM_NAME: + sError = wxT("Not a valid atom name"); + break; + + case PMERR_ATOM_NAME_NOT_FOUND: + sError = wxT("Valid name format, but cannot find name in atom table"); + break; + + default: + sError = wxT("Unknown error"); + } + return(sError); +} // end of wxPMErrorToStr + +void wxDrawBorder( + HPS hPS +, RECTL& rRect +, WXDWORD dwStyle +) +{ + POINTL vPoint[2]; + + vPoint[0].x = rRect.xLeft; + vPoint[0].y = rRect.yBottom; + ::GpiMove(hPS, &vPoint[0]); + if (dwStyle & wxSIMPLE_BORDER || + dwStyle & wxSTATIC_BORDER) + { + vPoint[1].x = rRect.xRight - 1; + vPoint[1].y = rRect.yTop - 1; + ::GpiBox( hPS + ,DRO_OUTLINE + ,&vPoint[1] + ,0L + ,0L + ); + } + if (dwStyle & wxSUNKEN_BORDER) + { + LINEBUNDLE vLineBundle; + + vLineBundle.lColor = 0x00FFFFFF; // WHITE + vLineBundle.usMixMode = FM_OVERPAINT; + vLineBundle.fxWidth = 2; + vLineBundle.lGeomWidth = 2; + vLineBundle.usType = LINETYPE_SOLID; + vLineBundle.usEnd = 0; + vLineBundle.usJoin = 0; + ::GpiSetAttrs( hPS + ,PRIM_LINE + ,LBB_COLOR | LBB_MIX_MODE | LBB_WIDTH | LBB_GEOM_WIDTH | LBB_TYPE + ,0L + ,&vLineBundle + ); + vPoint[1].x = rRect.xRight - 1; + vPoint[1].y = rRect.yTop - 1; + ::GpiBox( hPS + ,DRO_OUTLINE + ,&vPoint[1] + ,0L + ,0L + ); + vPoint[0].x = rRect.xLeft + 1; + vPoint[0].y = rRect.yBottom + 1; + ::GpiMove(hPS, &vPoint[0]); + vPoint[1].x = rRect.xRight - 2; + vPoint[1].y = rRect.yTop - 2; + ::GpiBox( hPS + ,DRO_OUTLINE + ,&vPoint[1] + ,0L + ,0L + ); + + vLineBundle.lColor = 0x00000000; // BLACK + vLineBundle.usMixMode = FM_OVERPAINT; + vLineBundle.fxWidth = 2; + vLineBundle.lGeomWidth = 2; + vLineBundle.usType = LINETYPE_SOLID; + vLineBundle.usEnd = 0; + vLineBundle.usJoin = 0; + ::GpiSetAttrs( hPS + ,PRIM_LINE + ,LBB_COLOR | LBB_MIX_MODE | LBB_WIDTH | LBB_GEOM_WIDTH | LBB_TYPE + ,0L + ,&vLineBundle + ); + vPoint[0].x = rRect.xLeft + 2; + vPoint[0].y = rRect.yBottom + 2; + ::GpiMove(hPS, &vPoint[0]); + vPoint[1].x = rRect.xLeft + 2; + vPoint[1].y = rRect.yTop - 3; + ::GpiLine(hPS, &vPoint[1]); + vPoint[1].x = rRect.xRight - 3; + vPoint[1].y = rRect.yTop - 3; + ::GpiLine(hPS, &vPoint[1]); + + vPoint[0].x = rRect.xLeft + 3; + vPoint[0].y = rRect.yBottom + 3; + ::GpiMove(hPS, &vPoint[0]); + vPoint[1].x = rRect.xLeft + 3; + vPoint[1].y = rRect.yTop - 4; + ::GpiLine(hPS, &vPoint[1]); + vPoint[1].x = rRect.xRight - 4; + vPoint[1].y = rRect.yTop - 4; + ::GpiLine(hPS, &vPoint[1]); + } + if (dwStyle & wxDOUBLE_BORDER) + { + LINEBUNDLE vLineBundle; + + vLineBundle.lColor = 0x00FFFFFF; // WHITE + vLineBundle.usMixMode = FM_OVERPAINT; + vLineBundle.fxWidth = 2; + vLineBundle.lGeomWidth = 2; + vLineBundle.usType = LINETYPE_SOLID; + vLineBundle.usEnd = 0; + vLineBundle.usJoin = 0; + ::GpiSetAttrs( hPS + ,PRIM_LINE + ,LBB_COLOR | LBB_MIX_MODE | LBB_WIDTH | LBB_GEOM_WIDTH | LBB_TYPE + ,0L + ,&vLineBundle + ); + vPoint[1].x = rRect.xRight - 1; + vPoint[1].y = rRect.yTop - 1; + ::GpiBox( hPS + ,DRO_OUTLINE + ,&vPoint[1] + ,0L + ,0L + ); + vLineBundle.lColor = 0x00000000; // WHITE + vLineBundle.usMixMode = FM_OVERPAINT; + vLineBundle.fxWidth = 2; + vLineBundle.lGeomWidth = 2; + vLineBundle.usType = LINETYPE_SOLID; + vLineBundle.usEnd = 0; + vLineBundle.usJoin = 0; + ::GpiSetAttrs( hPS + ,PRIM_LINE + ,LBB_COLOR | LBB_MIX_MODE | LBB_WIDTH | LBB_GEOM_WIDTH | LBB_TYPE + ,0L + ,&vLineBundle + ); + vPoint[0].x = rRect.xLeft + 2; + vPoint[0].y = rRect.yBottom + 2; + ::GpiMove(hPS, &vPoint[0]); + vPoint[1].x = rRect.xRight - 2; + vPoint[1].y = rRect.yTop - 2; + ::GpiBox( hPS + ,DRO_OUTLINE + ,&vPoint[1] + ,0L + ,0L + ); + vLineBundle.lColor = 0x00FFFFFF; // BLACK + vLineBundle.usMixMode = FM_OVERPAINT; + vLineBundle.fxWidth = 2; + vLineBundle.lGeomWidth = 2; + vLineBundle.usType = LINETYPE_SOLID; + vLineBundle.usEnd = 0; + vLineBundle.usJoin = 0; + ::GpiSetAttrs( hPS + ,PRIM_LINE + ,LBB_COLOR | LBB_MIX_MODE | LBB_WIDTH | LBB_GEOM_WIDTH | LBB_TYPE + ,0L + ,&vLineBundle + ); + vPoint[0].x = rRect.xLeft + 3; + vPoint[0].y = rRect.yBottom + 3; + ::GpiMove(hPS, &vPoint[0]); + vPoint[1].x = rRect.xRight - 3; + vPoint[1].y = rRect.yTop - 3; + ::GpiBox( hPS + ,DRO_OUTLINE + ,&vPoint[1] + ,0L + ,0L + ); + } + if (dwStyle & wxRAISED_BORDER) + { + LINEBUNDLE vLineBundle; + + vLineBundle.lColor = 0x00000000; // BLACK + vLineBundle.usMixMode = FM_OVERPAINT; + vLineBundle.fxWidth = 2; + vLineBundle.lGeomWidth = 2; + vLineBundle.usType = LINETYPE_SOLID; + vLineBundle.usEnd = 0; + vLineBundle.usJoin = 0; + ::GpiSetAttrs( hPS + ,PRIM_LINE + ,LBB_COLOR | LBB_MIX_MODE | LBB_WIDTH | LBB_GEOM_WIDTH | LBB_TYPE + ,0L + ,&vLineBundle + ); + vPoint[1].x = rRect.xRight - 1; + vPoint[1].y = rRect.yTop - 1; + ::GpiBox( hPS + ,DRO_OUTLINE + ,&vPoint[1] + ,0L + ,0L + ); + vPoint[0].x = rRect.xLeft + 1; + vPoint[0].y = rRect.yBottom + 1; + ::GpiMove(hPS, &vPoint[0]); + vPoint[1].x = rRect.xRight - 2; + vPoint[1].y = rRect.yTop - 2; + ::GpiBox( hPS + ,DRO_OUTLINE + ,&vPoint[1] + ,0L + ,0L + ); + + vLineBundle.lColor = 0x00FFFFFF; // WHITE + vLineBundle.usMixMode = FM_OVERPAINT; + vLineBundle.fxWidth = 2; + vLineBundle.lGeomWidth = 2; + vLineBundle.usType = LINETYPE_SOLID; + vLineBundle.usEnd = 0; + vLineBundle.usJoin = 0; + ::GpiSetAttrs( hPS + ,PRIM_LINE + ,LBB_COLOR | LBB_MIX_MODE | LBB_WIDTH | LBB_GEOM_WIDTH | LBB_TYPE + ,0L + ,&vLineBundle + ); + vPoint[0].x = rRect.xLeft + 2; + vPoint[0].y = rRect.yBottom + 2; + ::GpiMove(hPS, &vPoint[0]); + vPoint[1].x = rRect.xLeft + 2; + vPoint[1].y = rRect.yTop - 3; + ::GpiLine(hPS, &vPoint[1]); + vPoint[1].x = rRect.xRight - 3; + vPoint[1].y = rRect.yTop - 3; + ::GpiLine(hPS, &vPoint[1]); + + vPoint[0].x = rRect.xLeft + 3; + vPoint[0].y = rRect.yBottom + 3; + ::GpiMove(hPS, &vPoint[0]); + vPoint[1].x = rRect.xLeft + 3; + vPoint[1].y = rRect.yTop - 4; + ::GpiLine(hPS, &vPoint[1]); + vPoint[1].x = rRect.xRight - 4; + vPoint[1].y = rRect.yTop - 4; + ::GpiLine(hPS, &vPoint[1]); + } +} // end of wxDrawBorder + +void wxOS2SetFont( + HWND hWnd +, const wxFont& rFont +) +{ + char zFont[128]; + char zFacename[30]; + char zWeight[30]; + char zStyle[30]; + + if (hWnd == NULLHANDLE) + return; + + // + // The fonts available for Presentation Params are just a few + // outline fonts, the rest are available to the GPI, so we must + // map the families to one of these three + // + switch(rFont.GetFamily()) + { + case wxSCRIPT: + strcpy(zFacename, "Script"); + break; + + case wxDECORATIVE: + strcpy(zFacename, "WarpSans"); + break; + + case wxROMAN: + strcpy(zFacename,"Times New Roman"); + break; + + case wxTELETYPE: + strcpy(zFacename, "Courier New"); + break; + + case wxMODERN: + strcpy(zFacename, "Courier New"); + break; + + case wxDEFAULT: + default: + case wxSWISS: + strcpy(zFacename, "Helvetica"); + break; + } + + switch(rFont.GetWeight()) + { + default: + case wxNORMAL: + case wxLIGHT: + zWeight[0] = '\0'; + break; + + case wxBOLD: + case wxFONTWEIGHT_MAX: + strcpy(zWeight, "Bold"); + break; + } + + switch(rFont.GetStyle()) + { + case wxITALIC: + case wxSLANT: + strcpy(zStyle, "Italic"); + break; + + default: + zStyle[0] = '\0'; + break; + } + sprintf(zFont, "%d.%s", rFont.GetPointSize(), zFacename); + if (zWeight[0] != '\0') + { + strcat(zFont, " "); + strcat(zFont, zWeight); + } + if (zStyle[0] != '\0') + { + strcat(zFont, " "); + strcat(zFont, zStyle); + } + ::WinSetPresParam(hWnd, PP_FONTNAMESIZE, strlen(zFont) + 1, (PVOID)zFont); +} // end of wxOS2SetFont + +// --------------------------------------------------------------------------- +// Helper for taking a regular bitmap and giving it a disabled look +// --------------------------------------------------------------------------- +wxBitmap wxDisableBitmap( + const wxBitmap& rBmp +, long lColor +) +{ + wxMask* pMask = rBmp.GetMask(); + + if (!pMask) + return(wxNullBitmap); + + DEVOPENSTRUC vDop = {0L, "DISPLAY", NULL, 0L, 0L, 0L, 0L, 0L, 0L}; + SIZEL vSize = {0, 0}; + HDC hDC = ::DevOpenDC(vHabmain, OD_MEMORY, "*", 5L, (PDEVOPENDATA)&vDop, NULLHANDLE); + HPS hPS = ::GpiCreatePS(vHabmain, hDC, &vSize, PU_PELS | GPIA_ASSOC); + BITMAPINFOHEADER2 vHeader; + BITMAPINFO2 vInfo; + ERRORID vError; + wxString sError; + HBITMAP hBitmap = (HBITMAP)rBmp.GetHBITMAP(); + HBITMAP hOldBitmap = NULLHANDLE; + HBITMAP hOldMask = NULLHANDLE; + HBITMAP hMask = (HBITMAP)rBmp.GetMask()->GetMaskBitmap(); + unsigned char* pucBits; // buffer that will contain the bitmap data + unsigned char* pucData; // pointer to use to traverse bitmap data + unsigned char* pucBitsMask; // buffer that will contain the mask data + unsigned char* pucDataMask; // pointer to use to traverse mask data + LONG lScans = 0L; + LONG lScansSet = 0L; + bool bpp16 = (wxDisplayDepth() == 16); + + memset(&vHeader, '\0', 16); + vHeader.cbFix = 16; + + memset(&vInfo, '\0', 16); + vInfo.cbFix = 16; + vInfo.cx = (ULONG)rBmp.GetWidth(); + vInfo.cy = (ULONG)rBmp.GetHeight(); + vInfo.cPlanes = 1; + vInfo.cBitCount = 24; // Set to desired count going in + + // + // Create the buffers for data....all wxBitmaps are 24 bit internally + // + int nBytesPerLine = rBmp.GetWidth() * 3; + int nSizeDWORD = sizeof(DWORD); + int nLineBoundary = nBytesPerLine % nSizeDWORD; + int nPadding = 0; + int i; + int j; + + // + // Bitmap must be ina double-word alligned address so we may + // have some padding to worry about + // + if (nLineBoundary > 0) + { + nPadding = nSizeDWORD - nLineBoundary; + nBytesPerLine += nPadding; + } + pucBits = (unsigned char *)malloc(nBytesPerLine * rBmp.GetHeight()); + memset(pucBits, '\0', (nBytesPerLine * rBmp.GetHeight())); + pucBitsMask = (unsigned char *)malloc(nBytesPerLine * rBmp.GetHeight()); + memset(pucBitsMask, '\0', (nBytesPerLine * rBmp.GetHeight())); + + // + // Extract the bitmap and mask data + // + if ((hOldBitmap = ::GpiSetBitmap(hPS, hBitmap)) == HBM_ERROR) + { + vError = ::WinGetLastError(vHabmain); + sError = wxPMErrorToStr(vError); + } + ::GpiQueryBitmapInfoHeader(hBitmap, &vHeader); + vInfo.cBitCount = 24; + if ((lScans = ::GpiQueryBitmapBits( hPS + ,0L + ,(LONG)rBmp.GetHeight() + ,(PBYTE)pucBits + ,&vInfo + )) == GPI_ALTERROR) + { + vError = ::WinGetLastError(vHabmain); + sError = wxPMErrorToStr(vError); + } + if ((hOldMask = ::GpiSetBitmap(hPS, hMask)) == HBM_ERROR) + { + vError = ::WinGetLastError(vHabmain); + sError = wxPMErrorToStr(vError); + } + ::GpiQueryBitmapInfoHeader(hMask, &vHeader); + vInfo.cBitCount = 24; + if ((lScans = ::GpiQueryBitmapBits( hPS + ,0L + ,(LONG)rBmp.GetHeight() + ,(PBYTE)pucBitsMask + ,&vInfo + )) == GPI_ALTERROR) + { + vError = ::WinGetLastError(vHabmain); + sError = wxPMErrorToStr(vError); + } + if (( hMask = ::GpiSetBitmap(hPS, hOldMask)) == HBM_ERROR) + { + vError = ::WinGetLastError(vHabmain); + sError = wxPMErrorToStr(vError); + } + pucData = pucBits; + pucDataMask = pucBitsMask; + + // + // Get the mask value + // + for (i = 0; i < rBmp.GetHeight(); i++) + { + for (j = 0; j < rBmp.GetWidth(); j++) + { + // Byte 1 + if (bpp16 && *pucDataMask == 0xF8) // 16 bit display gobblygook + { + *pucData = 0x7F; + pucData++; + } + else if (*pucDataMask == 0xFF) // set to grey + { + *pucData = 0x7F; + pucData++; + } + else + { + *pucData = ((unsigned char)(lColor >> 16)); + pucData++; + } + + // Byte 2 + if (bpp16 && *(pucDataMask + 1) == 0xFC) // 16 bit display gobblygook + { + *pucData = 0x7F; + pucData++; + } + else if (*(pucDataMask + 1) == 0xFF) // set to grey + { + *pucData = 0x7F; + pucData++; + } + else + { + *pucData = ((unsigned char)(lColor >> 8)); + pucData++; + } + + // Byte 3 + if (bpp16 && *(pucDataMask + 2) == 0xF8) // 16 bit display gobblygook + { + *pucData = 0x7F; + pucData++; + } + else if (*(pucDataMask + 2) == 0xFF) // set to grey + { + *pucData = 0x7F; + pucData++; + } + else + { + *pucData = ((unsigned char)lColor); + pucData++; + } + pucDataMask += 3; + } + for (j = 0; j < nPadding; j++) + { + pucData++; + pucDataMask++; + } + } + + // + // Create a new bitmap and set the modified bits + // + wxBitmap vNewBmp( rBmp.GetWidth() + ,rBmp.GetHeight() + ,24 + ); + HBITMAP hNewBmp = (HBITMAP)vNewBmp.GetHBITMAP(); + + if ((hOldBitmap = ::GpiSetBitmap(hPS, hNewBmp)) == HBM_ERROR) + { + vError = ::WinGetLastError(vHabmain); + sError = wxPMErrorToStr(vError); + } + if ((lScansSet = ::GpiSetBitmapBits( hPS + ,0L + ,(LONG)rBmp.GetHeight() + ,(PBYTE)pucBits + ,&vInfo + )) == GPI_ALTERROR) + + { + vError = ::WinGetLastError(vHabmain); + sError = wxPMErrorToStr(vError); + } + wxMask* pNewMask; + + pNewMask = new wxMask(pMask->GetMaskBitmap()); + vNewBmp.SetMask(pNewMask); + free(pucBits); + ::GpiSetBitmap(hPS, NULLHANDLE); + ::GpiDestroyPS(hPS); + ::DevCloseDC(hDC); + if (vNewBmp.Ok()) + return(vNewBmp); + return(wxNullBitmap); +} // end of wxDisableBitmap + +COLORREF wxColourToRGB( + const wxColour& rColor +) +{ + return(OS2RGB(rColor.Red(), rColor.Green(), rColor.Blue())); +} // end of wxColourToRGB