This allows to get rid of ugly preprocessor checks due to the fact that this function could be defined in one or the other library depending on the port used and also fix a problem with it being defined differently in the base library depending on which GUI port (Carbon or Cocoa) was used under OS X. It also fixes the problem with wxBell() in wxGTK under Windows. Closes #14406. git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@71797 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
879 lines
26 KiB
C++
879 lines
26 KiB
C++
///////////////////////////////////////////////////////////////////////////////
|
|
// Name: src/os2/utilsgui.cpp
|
|
// Purpose: Various utility functions only available in GUI
|
|
// Author: David Webster
|
|
// Modified by:
|
|
// Created: 20.08.2003 (extracted from os2/utils.cpp)
|
|
// RCS-ID: $Id$
|
|
// Copyright: (c) David Webster
|
|
// Licence: wxWindows licence
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
|
|
// ============================================================================
|
|
// declarations
|
|
// ============================================================================
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// headers
|
|
// ----------------------------------------------------------------------------
|
|
|
|
// for compilers that support precompilation, includes "wx.h".
|
|
#include "wx/wxprec.h"
|
|
|
|
#ifdef __BORLANDC__
|
|
#pragma hdrstop
|
|
#endif
|
|
|
|
#ifndef WX_PRECOMP
|
|
#include "wx/utils.h"
|
|
#include "wx/app.h"
|
|
#include "wx/cursor.h"
|
|
#include "wx/font.h"
|
|
#include "wx/timer.h"
|
|
#endif //WX_PRECOMP
|
|
|
|
#include "wx/apptrait.h"
|
|
#include "wx/os2/private/timer.h"
|
|
#include "wx/evtloop.h"
|
|
|
|
#include "wx/os2/private.h" // includes <windows.h>
|
|
|
|
// ============================================================================
|
|
// implementation
|
|
// ============================================================================
|
|
|
|
// Emit a beeeeeep
|
|
void wxBell()
|
|
{
|
|
DosBeep(1000,1000); // 1kHz during 1 sec.
|
|
}
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// functions to work with .INI files
|
|
// ----------------------------------------------------------------------------
|
|
|
|
// Sleep for nSecs seconds. Attempt a Windows implementation using timers.
|
|
static bool inTimer = false;
|
|
|
|
class wxSleepTimer: public wxTimer
|
|
{
|
|
public:
|
|
inline void Notify()
|
|
{
|
|
inTimer = false;
|
|
Stop();
|
|
}
|
|
};
|
|
|
|
// ---------------------------------------------------------------------------
|
|
// helper functions for showing a "busy" cursor
|
|
// ---------------------------------------------------------------------------
|
|
|
|
HCURSOR gs_wxBusyCursor = 0; // new, busy cursor
|
|
HCURSOR gs_wxBusyCursorOld = 0; // old cursor
|
|
static int gs_wxBusyCursorCount = 0;
|
|
|
|
// Set the cursor to the busy cursor for all windows
|
|
void wxBeginBusyCursor(const wxCursor* pCursor)
|
|
{
|
|
if ( gs_wxBusyCursorCount++ == 0 )
|
|
{
|
|
gs_wxBusyCursor = (HCURSOR)pCursor->GetHCURSOR();
|
|
::WinSetPointer(HWND_DESKTOP, (HPOINTER)gs_wxBusyCursor);
|
|
}
|
|
//else: nothing to do, already set
|
|
}
|
|
|
|
// Restore cursor to normal
|
|
void wxEndBusyCursor()
|
|
{
|
|
wxCHECK_RET( gs_wxBusyCursorCount > 0
|
|
,wxT("no matching wxBeginBusyCursor() for wxEndBusyCursor()")
|
|
);
|
|
|
|
if (--gs_wxBusyCursorCount == 0)
|
|
{
|
|
::WinSetPointer(HWND_DESKTOP, (HPOINTER)gs_wxBusyCursorOld);
|
|
gs_wxBusyCursorOld = 0;
|
|
}
|
|
}
|
|
|
|
// true if we're between the above two calls
|
|
bool wxIsBusy()
|
|
{
|
|
return (gs_wxBusyCursorCount > 0);
|
|
}
|
|
|
|
// Check whether this window wants to process messages, e.g. Stop button
|
|
// in long calculations.
|
|
bool wxCheckForInterrupt( wxWindow* pWnd )
|
|
{
|
|
if(pWnd)
|
|
{
|
|
QMSG vMsg;
|
|
HAB hab = 0;
|
|
HWND hwndFilter = NULLHANDLE;
|
|
|
|
while(::WinPeekMsg(hab, &vMsg, hwndFilter, 0, 0, PM_REMOVE))
|
|
{
|
|
::WinDispatchMsg(hab, &vMsg);
|
|
}
|
|
return true;//*** temporary?
|
|
}
|
|
else
|
|
{
|
|
wxFAIL_MSG(wxT("pWnd==NULL !!!"));
|
|
return false;//*** temporary?
|
|
}
|
|
}
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// get display info
|
|
// ----------------------------------------------------------------------------
|
|
|
|
// See also the wxGetMousePosition in window.cpp
|
|
// Deprecated: use wxPoint wxGetMousePosition() instead
|
|
void wxGetMousePosition(
|
|
int* pX
|
|
, int* pY
|
|
)
|
|
{
|
|
POINTL vPt;
|
|
|
|
::WinQueryPointerPos(HWND_DESKTOP, &vPt);
|
|
*pX = vPt.x;
|
|
*pY = vPt.y;
|
|
};
|
|
|
|
// Return true if we have a colour display
|
|
bool wxColourDisplay()
|
|
{
|
|
#if 0
|
|
HPS hpsScreen;
|
|
HDC hdcScreen;
|
|
LONG lColors;
|
|
|
|
hpsScreen = ::WinGetScreenPS(HWND_DESKTOP);
|
|
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
|
|
int wxDisplayDepth()
|
|
{
|
|
HPS hpsScreen;
|
|
HDC hdcScreen;
|
|
LONG lPlanes;
|
|
LONG lBitsPerPixel;
|
|
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);
|
|
}
|
|
|
|
// Get size of display
|
|
void wxDisplaySize(
|
|
int* pWidth
|
|
, int* pHeight
|
|
)
|
|
{
|
|
HPS hpsScreen;
|
|
HDC hdcScreen;
|
|
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);
|
|
}
|
|
if (pWidth)
|
|
*pWidth = (int)lWidth;
|
|
if (pHeight)
|
|
*pHeight = (int)lHeight;
|
|
}
|
|
|
|
void wxDisplaySizeMM(
|
|
int* pWidth
|
|
, int* pHeight
|
|
)
|
|
{
|
|
HPS hpsScreen;
|
|
HDC hdcScreen;
|
|
|
|
hpsScreen = ::WinGetScreenPS(HWND_DESKTOP);
|
|
hdcScreen = ::GpiQueryDevice(hpsScreen);
|
|
|
|
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);
|
|
}
|
|
|
|
void wxGUIAppTraits::InitializeGui(unsigned long &ulHab)
|
|
{
|
|
ulHab = ::WinInitialize(0);
|
|
}
|
|
|
|
void wxGUIAppTraits::TerminateGui(unsigned long ulHab)
|
|
{
|
|
::WinTerminate(ulHab);
|
|
}
|
|
|
|
wxPortId wxGUIAppTraits::GetToolkitVersion(int *verMaj, int *verMin) const
|
|
{
|
|
// How to get version of PM ? I guess, just reusing the OS version is OK.
|
|
(void) wxGetOsVersion(verMaj, verMin);
|
|
return wxPORT_OS2;
|
|
}
|
|
|
|
wxTimerImpl* wxGUIAppTraits::CreateTimerImpl(wxTimer *timer)
|
|
{
|
|
return new wxOS2TimerImpl(timer);
|
|
}
|
|
|
|
wxEventLoopBase* wxGUIAppTraits::CreateEventLoop()
|
|
{
|
|
return new wxEventLoop;
|
|
}
|
|
|
|
// ---------------------------------------------------------------------------
|
|
// window information functions
|
|
// ---------------------------------------------------------------------------
|
|
|
|
wxString WXDLLEXPORT wxGetWindowText( WXHWND hWnd )
|
|
{
|
|
wxString vStr;
|
|
|
|
if ( hWnd )
|
|
{
|
|
long lLen = ::WinQueryWindowTextLength((HWND)hWnd) + 1;
|
|
::WinQueryWindowText((HWND)hWnd, lLen, (PSZ)(wxChar*)wxStringBuffer(vStr, lLen));
|
|
}
|
|
|
|
return vStr;
|
|
}
|
|
|
|
wxString WXDLLEXPORT wxGetWindowClass( WXHWND hWnd )
|
|
{
|
|
wxString vStr;
|
|
if ( hWnd )
|
|
{
|
|
int nLen = 256; // some starting value
|
|
|
|
for ( ;; )
|
|
{
|
|
int nCount = ::WinQueryClassName((HWND)hWnd, nLen, (PSZ)(wxChar*)wxStringBuffer(vStr, nLen));
|
|
|
|
if (nCount == nLen )
|
|
{
|
|
// the class name might have been truncated, retry with larger
|
|
// buffer
|
|
nLen *= 2;
|
|
}
|
|
else
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
return vStr;
|
|
}
|
|
|
|
WXWORD WXDLLEXPORT wxGetWindowId(
|
|
WXHWND hWnd
|
|
)
|
|
{
|
|
return ::WinQueryWindowUShort((HWND)hWnd, QWS_ID);
|
|
}
|
|
|
|
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 in a double-word aligned 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.IsOk())
|
|
return(vNewBmp);
|
|
return(wxNullBitmap);
|
|
} // end of wxDisableBitmap
|
|
|
|
COLORREF wxColourToRGB(
|
|
const wxColour& rColor
|
|
)
|
|
{
|
|
return(OS2RGB(rColor.Red(), rColor.Green(), rColor.Blue()));
|
|
} // end of wxColourToRGB
|