While this is not done for all the ports yet, the new API allows returning different PPI values for different monitors, unlike the old (and still existing, but implemented in terms of the new one) global function.
683 lines
19 KiB
C++
683 lines
19 KiB
C++
/////////////////////////////////////////////////////////////////////////////
|
|
// Name: src/motif/utils.cpp
|
|
// Purpose: Various utilities
|
|
// Author: Julian Smart
|
|
// Modified by:
|
|
// Created: 17/09/98
|
|
// Copyright: (c) Julian Smart
|
|
// Licence: wxWindows licence
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
// ============================================================================
|
|
// declarations
|
|
// ============================================================================
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// headers
|
|
// ----------------------------------------------------------------------------
|
|
|
|
// For compilers that support precompilation, includes "wx.h".
|
|
#include "wx/wxprec.h"
|
|
|
|
#include "wx/utils.h"
|
|
|
|
#ifndef WX_PRECOMP
|
|
#include "wx/app.h"
|
|
#include "wx/dcmemory.h"
|
|
#include "wx/bitmap.h"
|
|
#endif
|
|
|
|
#include "wx/apptrait.h"
|
|
#include "wx/evtloop.h"
|
|
#include "wx/private/eventloopsourcesmanager.h"
|
|
#include "wx/motif/private/timer.h"
|
|
|
|
#include <string.h>
|
|
|
|
#if (defined(__SUNCC__) || defined(__CLCC__))
|
|
#include <sysent.h>
|
|
#endif
|
|
|
|
#ifdef __VMS__
|
|
#pragma message disable nosimpint
|
|
#endif
|
|
|
|
#include <Xm/Xm.h>
|
|
#include <Xm/Frame.h>
|
|
|
|
#include "wx/motif/private.h"
|
|
|
|
#include "X11/Xutil.h"
|
|
|
|
#ifdef __VMS__
|
|
#pragma message enable nosimpint
|
|
#endif
|
|
|
|
|
|
// ============================================================================
|
|
// implementation
|
|
// ============================================================================
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// async event processing
|
|
// ----------------------------------------------------------------------------
|
|
|
|
// Consume all events until no more left
|
|
void wxFlushEvents(WXDisplay* wxdisplay)
|
|
{
|
|
Display *display = (Display*)wxdisplay;
|
|
wxEventLoop evtLoop;
|
|
|
|
XSync (display, False);
|
|
|
|
while (evtLoop.Pending())
|
|
{
|
|
XFlush (display);
|
|
evtLoop.Dispatch();
|
|
}
|
|
}
|
|
|
|
#if wxUSE_EVENTLOOP_SOURCE
|
|
|
|
extern "C"
|
|
{
|
|
|
|
static
|
|
void
|
|
wxMotifInputHandler(XtPointer data,
|
|
int* WXUNUSED(fd),
|
|
XtInputId* WXUNUSED(inputId))
|
|
{
|
|
wxEventLoopSourceHandler * const
|
|
handler = static_cast<wxEventLoopSourceHandler *>(data);
|
|
|
|
handler->OnReadWaiting();
|
|
}
|
|
|
|
}
|
|
|
|
// This class exists just to call XtRemoveInput() in its dtor, the real work of
|
|
// dispatching events on the file descriptor to the handler is done by
|
|
// wxMotifInputHandler callback above.
|
|
class wxMotifEventLoopSource : public wxEventLoopSource
|
|
{
|
|
public:
|
|
wxMotifEventLoopSource(XtInputId inputId,
|
|
wxEventLoopSourceHandler *handler,
|
|
int flags)
|
|
: wxEventLoopSource(handler, flags),
|
|
m_inputId(inputId)
|
|
{
|
|
}
|
|
|
|
virtual ~wxMotifEventLoopSource()
|
|
{
|
|
XtRemoveInput(m_inputId);
|
|
}
|
|
|
|
private:
|
|
const XtInputId m_inputId;
|
|
|
|
wxDECLARE_NO_COPY_CLASS(wxMotifEventLoopSource);
|
|
};
|
|
|
|
class wxMotifEventLoopSourcesManager : public wxEventLoopSourcesManagerBase
|
|
{
|
|
public:
|
|
wxEventLoopSource *
|
|
AddSourceForFD(int fd, wxEventLoopSourceHandler* handler, int flags)
|
|
{
|
|
wxCHECK_MSG( wxTheApp, NULL, "Must create wxTheApp first" );
|
|
|
|
// The XtInputXXXMask values cannot be combined (hence "Mask" is a
|
|
// complete misnomer), and supporting those would make the code more
|
|
// complicated and we don't need them for now.
|
|
wxCHECK_MSG( !(flags & (wxEVENT_SOURCE_OUTPUT |
|
|
wxEVENT_SOURCE_EXCEPTION)),
|
|
NULL,
|
|
"Monitoring FDs for output/errors not supported" );
|
|
|
|
wxCHECK_MSG( flags & wxEVENT_SOURCE_INPUT,
|
|
NULL,
|
|
"Should be monitoring for input" );
|
|
|
|
XtInputId inputId = XtAppAddInput
|
|
(
|
|
(XtAppContext) wxTheApp->GetAppContext(),
|
|
fd,
|
|
(XtPointer) XtInputReadMask,
|
|
wxMotifInputHandler,
|
|
handler
|
|
);
|
|
if ( inputId < 0 )
|
|
return 0;
|
|
|
|
return new wxMotifEventLoopSource(inputId, handler, flags);
|
|
}
|
|
};
|
|
|
|
wxEventLoopSourcesManagerBase* wxGUIAppTraits::GetEventLoopSourcesManager()
|
|
{
|
|
static wxMotifEventLoopSourcesManager s_eventLoopSourcesManager;
|
|
|
|
return &s_eventLoopSourcesManager;
|
|
}
|
|
|
|
#endif // wxUSE_EVENTLOOP_SOURCE
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// misc
|
|
// ----------------------------------------------------------------------------
|
|
|
|
// Emit a beeeeeep
|
|
void wxBell()
|
|
{
|
|
// Use current setting for the bell
|
|
XBell (wxGlobalDisplay(), 0);
|
|
}
|
|
|
|
wxPortId wxGUIAppTraits::GetToolkitVersion(int *verMaj,
|
|
int *verMin,
|
|
int *verMicro) const
|
|
{
|
|
// XmVERSION and XmREVISION are defined in Xm/Xm.h
|
|
if ( verMaj )
|
|
*verMaj = XmVERSION;
|
|
if ( verMin )
|
|
*verMin = XmREVISION;
|
|
if ( verMicro )
|
|
*verMicro = 0;
|
|
|
|
return wxPORT_MOTIF;
|
|
}
|
|
|
|
wxEventLoopBase* wxGUIAppTraits::CreateEventLoop()
|
|
{
|
|
return new wxEventLoop;
|
|
}
|
|
|
|
wxTimerImpl* wxGUIAppTraits::CreateTimerImpl(wxTimer* timer)
|
|
{
|
|
return new wxMotifTimerImpl(timer);
|
|
}
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// display info
|
|
// ----------------------------------------------------------------------------
|
|
|
|
void wxGetMousePosition( int* x, int* y )
|
|
{
|
|
#if wxUSE_NANOX
|
|
// TODO
|
|
*x = 0;
|
|
*y = 0;
|
|
#else
|
|
XMotionEvent xev;
|
|
Window root, child;
|
|
XQueryPointer(wxGlobalDisplay(),
|
|
DefaultRootWindow(wxGlobalDisplay()),
|
|
&root, &child,
|
|
&(xev.x_root), &(xev.y_root),
|
|
&(xev.x), &(xev.y),
|
|
&(xev.state));
|
|
*x = xev.x_root;
|
|
*y = xev.y_root;
|
|
#endif
|
|
}
|
|
|
|
// Configurable display in wxX11 and wxMotif
|
|
static WXDisplay *gs_currentDisplay = NULL;
|
|
static wxString gs_displayName;
|
|
|
|
WXDisplay *wxGetDisplay()
|
|
{
|
|
if (gs_currentDisplay)
|
|
return gs_currentDisplay;
|
|
else if (wxTheApp)
|
|
return wxTheApp->GetInitialDisplay();
|
|
return NULL;
|
|
}
|
|
|
|
bool wxSetDisplay(const wxString& display_name)
|
|
{
|
|
gs_displayName = display_name;
|
|
|
|
if ( display_name.empty() )
|
|
{
|
|
gs_currentDisplay = NULL;
|
|
|
|
return true;
|
|
}
|
|
else
|
|
{
|
|
Cardinal argc = 0;
|
|
|
|
Display *display = XtOpenDisplay((XtAppContext) wxTheApp->GetAppContext(),
|
|
display_name.c_str(),
|
|
wxTheApp->GetAppName().c_str(),
|
|
wxTheApp->GetClassName().c_str(),
|
|
NULL,
|
|
#if XtSpecificationRelease < 5
|
|
0, &argc,
|
|
#else
|
|
0, (int *)&argc,
|
|
#endif
|
|
NULL);
|
|
|
|
if (display)
|
|
{
|
|
gs_currentDisplay = (WXDisplay*) display;
|
|
return true;
|
|
}
|
|
else
|
|
return false;
|
|
}
|
|
}
|
|
|
|
wxString wxGetDisplayName()
|
|
{
|
|
return gs_displayName;
|
|
}
|
|
|
|
wxWindow* wxFindWindowAtPoint(const wxPoint& pt)
|
|
{
|
|
return wxGenericFindWindowAtPoint(pt);
|
|
}
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// Some colour manipulation routines
|
|
// ----------------------------------------------------------------------------
|
|
|
|
void wxHSVToXColor(wxHSV *hsv,XColor *rgb)
|
|
{
|
|
int h = hsv->h;
|
|
int s = hsv->s;
|
|
int v = hsv->v;
|
|
int r = 0, g = 0, b = 0;
|
|
int i, f;
|
|
int p, q, t;
|
|
s = (s * wxMAX_RGB) / wxMAX_SV;
|
|
v = (v * wxMAX_RGB) / wxMAX_SV;
|
|
if (h == 360) h = 0;
|
|
if (s == 0) { h = 0; r = g = b = v; }
|
|
i = h / 60;
|
|
f = h % 60;
|
|
p = v * (wxMAX_RGB - s) / wxMAX_RGB;
|
|
q = v * (wxMAX_RGB - s * f / 60) / wxMAX_RGB;
|
|
t = v * (wxMAX_RGB - s * (60 - f) / 60) / wxMAX_RGB;
|
|
switch (i)
|
|
{
|
|
case 0: r = v, g = t, b = p; break;
|
|
case 1: r = q, g = v, b = p; break;
|
|
case 2: r = p, g = v, b = t; break;
|
|
case 3: r = p, g = q, b = v; break;
|
|
case 4: r = t, g = p, b = v; break;
|
|
case 5: r = v, g = p, b = q; break;
|
|
}
|
|
rgb->red = (unsigned short)(r << 8);
|
|
rgb->green = (unsigned short)(g << 8);
|
|
rgb->blue = (unsigned short)(b << 8);
|
|
}
|
|
|
|
void wxXColorToHSV(wxHSV *hsv,XColor *rgb)
|
|
{
|
|
int r = rgb->red >> 8;
|
|
int g = rgb->green >> 8;
|
|
int b = rgb->blue >> 8;
|
|
int maxv = wxMax3(r, g, b);
|
|
int minv = wxMin3(r, g, b);
|
|
int h = 0, s, v;
|
|
v = maxv;
|
|
if (maxv) s = (maxv - minv) * wxMAX_RGB / maxv;
|
|
else s = 0;
|
|
if (s == 0) h = 0;
|
|
else
|
|
{
|
|
int rc, gc, bc, hex = 0;
|
|
rc = (maxv - r) * wxMAX_RGB / (maxv - minv);
|
|
gc = (maxv - g) * wxMAX_RGB / (maxv - minv);
|
|
bc = (maxv - b) * wxMAX_RGB / (maxv - minv);
|
|
if (r == maxv) { h = bc - gc, hex = 0; }
|
|
else if (g == maxv) { h = rc - bc, hex = 2; }
|
|
else if (b == maxv) { h = gc - rc, hex = 4; }
|
|
h = hex * 60 + (h * 60 / wxMAX_RGB);
|
|
if (h < 0) h += 360;
|
|
}
|
|
hsv->h = h;
|
|
hsv->s = (s * wxMAX_SV) / wxMAX_RGB;
|
|
hsv->v = (v * wxMAX_SV) / wxMAX_RGB;
|
|
}
|
|
|
|
void wxAllocNearestColor(Display *d,Colormap cmp,XColor *xc)
|
|
{
|
|
#if !wxUSE_NANOX
|
|
int llp;
|
|
|
|
int screen = DefaultScreen(d);
|
|
int num_colors = DisplayCells(d,screen);
|
|
|
|
XColor *color_defs = new XColor[num_colors];
|
|
for(llp = 0;llp < num_colors;llp++) color_defs[llp].pixel = llp;
|
|
XQueryColors(d,cmp,color_defs,num_colors);
|
|
|
|
wxHSV hsv_defs, hsv;
|
|
wxXColorToHSV(&hsv,xc);
|
|
|
|
int diff, min_diff = 0, pixel = 0;
|
|
|
|
for(llp = 0;llp < num_colors;llp++)
|
|
{
|
|
wxXColorToHSV(&hsv_defs,&color_defs[llp]);
|
|
diff = wxSIGN(wxH_WEIGHT * (hsv.h - hsv_defs.h)) +
|
|
wxSIGN(wxS_WEIGHT * (hsv.s - hsv_defs.s)) +
|
|
wxSIGN(wxV_WEIGHT * (hsv.v - hsv_defs.v));
|
|
if (llp == 0) min_diff = diff;
|
|
if (min_diff > diff) { min_diff = diff; pixel = llp; }
|
|
if (min_diff == 0) break;
|
|
}
|
|
|
|
xc -> red = color_defs[pixel].red;
|
|
xc -> green = color_defs[pixel].green;
|
|
xc -> blue = color_defs[pixel].blue;
|
|
xc -> flags = DoRed | DoGreen | DoBlue;
|
|
|
|
/* FIXME, TODO
|
|
if (!XAllocColor(d,cmp,xc))
|
|
cout << "wxAllocNearestColor : Warning : Cannot find nearest color !\n";
|
|
*/
|
|
|
|
delete[] color_defs;
|
|
#endif
|
|
}
|
|
|
|
void wxAllocColor(Display *d,Colormap cmp,XColor *xc)
|
|
{
|
|
if (!XAllocColor(d,cmp,xc))
|
|
{
|
|
// cout << "wxAllocColor : Warning : cannot allocate color, attempt find nearest !\n";
|
|
wxAllocNearestColor(d,cmp,xc);
|
|
}
|
|
}
|
|
|
|
wxString wxGetXEventName(XEvent& event)
|
|
{
|
|
#if wxUSE_NANOX
|
|
wxString str(wxT("(some event)"));
|
|
return str;
|
|
#else
|
|
int type = event.xany.type;
|
|
static char* event_name[] = {
|
|
wxMOTIF_STR(""), wxMOTIF_STR("unknown(-)"), // 0-1
|
|
wxMOTIF_STR("KeyPress"), wxMOTIF_STR("KeyRelease"), wxMOTIF_STR("ButtonPress"), wxMOTIF_STR("ButtonRelease"), // 2-5
|
|
wxMOTIF_STR("MotionNotify"), wxMOTIF_STR("EnterNotify"), wxMOTIF_STR("LeaveNotify"), wxMOTIF_STR("FocusIn"), // 6-9
|
|
wxMOTIF_STR("FocusOut"), wxMOTIF_STR("KeymapNotify"), wxMOTIF_STR("Expose"), wxMOTIF_STR("GraphicsExpose"), // 10-13
|
|
wxMOTIF_STR("NoExpose"), wxMOTIF_STR("VisibilityNotify"), wxMOTIF_STR("CreateNotify"), // 14-16
|
|
wxMOTIF_STR("DestroyNotify"), wxMOTIF_STR("UnmapNotify"), wxMOTIF_STR("MapNotify"), wxMOTIF_STR("MapRequest"),// 17-20
|
|
wxMOTIF_STR("ReparentNotify"), wxMOTIF_STR("ConfigureNotify"), wxMOTIF_STR("ConfigureRequest"), // 21-23
|
|
wxMOTIF_STR("GravityNotify"), wxMOTIF_STR("ResizeRequest"), wxMOTIF_STR("CirculateNotify"), // 24-26
|
|
wxMOTIF_STR("CirculateRequest"), wxMOTIF_STR("PropertyNotify"), wxMOTIF_STR("SelectionClear"), // 27-29
|
|
wxMOTIF_STR("SelectionRequest"), wxMOTIF_STR("SelectionNotify"), wxMOTIF_STR("ColormapNotify"), // 30-32
|
|
wxMOTIF_STR("ClientMessage"), wxMOTIF_STR("MappingNotify"), // 33-34
|
|
wxMOTIF_STR("unknown(+)")}; // 35
|
|
type = wxMin(35, type); type = wxMax(1, type);
|
|
wxString str(event_name[type]);
|
|
return str;
|
|
#endif
|
|
}
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// accelerators
|
|
// ----------------------------------------------------------------------------
|
|
|
|
// Find the letter corresponding to the mnemonic, for Motif
|
|
char wxFindMnemonic (const char *s)
|
|
{
|
|
char mnem = 0;
|
|
int len = strlen (s);
|
|
int i;
|
|
|
|
for (i = 0; i < len; i++)
|
|
{
|
|
if (s[i] == '&')
|
|
{
|
|
// Carefully handle &&
|
|
if ((i + 1) <= len && s[i + 1] == '&')
|
|
i++;
|
|
else
|
|
{
|
|
mnem = s[i + 1];
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
return mnem;
|
|
}
|
|
|
|
char* wxFindAccelerator( const char *s )
|
|
{
|
|
#if 1
|
|
wxUnusedVar(s);
|
|
// VZ: this function returns incorrect keysym which completely breaks kbd
|
|
// handling
|
|
return NULL;
|
|
#else
|
|
// The accelerator text is after the \t char.
|
|
s = strchr( s, '\t' );
|
|
|
|
if( !s ) return NULL;
|
|
|
|
/*
|
|
Now we need to format it as X standard:
|
|
|
|
input output
|
|
|
|
F7 --> <Key>F7
|
|
Ctrl+N --> Ctrl<Key>N
|
|
Alt+k --> Meta<Key>k
|
|
Ctrl+Shift+A --> Ctrl Shift<Key>A
|
|
|
|
and handle Ctrl-N & similia
|
|
*/
|
|
|
|
static char buf[256];
|
|
|
|
buf[0] = '\0';
|
|
wxString tmp = s + 1; // skip TAB
|
|
size_t index = 0;
|
|
|
|
while( index < tmp.length() )
|
|
{
|
|
size_t plus = tmp.find( '+', index );
|
|
size_t minus = tmp.find( '-', index );
|
|
|
|
// neither '+' nor '-', add <Key>
|
|
if( plus == wxString::npos && minus == wxString::npos )
|
|
{
|
|
strcat( buf, "<Key>" );
|
|
strcat( buf, tmp.c_str() + index );
|
|
|
|
return buf;
|
|
}
|
|
|
|
// OK: npos is big and positive
|
|
size_t sep = wxMin( plus, minus );
|
|
wxString mod = tmp.substr( index, sep - index );
|
|
|
|
// Ctrl -> Ctrl
|
|
// Shift -> Shift
|
|
// Alt -> Meta
|
|
if( mod == "Alt" )
|
|
mod = "Meta";
|
|
|
|
if( buf[0] )
|
|
strcat( buf, " " );
|
|
|
|
strcat( buf, mod.c_str() );
|
|
|
|
index = sep + 1;
|
|
}
|
|
|
|
return NULL;
|
|
#endif
|
|
}
|
|
|
|
XmString wxFindAcceleratorText (const char *s)
|
|
{
|
|
#if 1
|
|
wxUnusedVar(s);
|
|
// VZ: this function returns incorrect keysym which completely breaks kbd
|
|
// handling
|
|
return NULL;
|
|
#else
|
|
// The accelerator text is after the \t char.
|
|
s = strchr( s, '\t' );
|
|
|
|
if( !s ) return NULL;
|
|
|
|
return wxStringToXmString( s + 1 ); // skip TAB!
|
|
#endif
|
|
}
|
|
|
|
// Change a widget's foreground and background colours.
|
|
void wxDoChangeForegroundColour(WXWidget widget, wxColour& foregroundColour)
|
|
{
|
|
if (!foregroundColour.IsOk())
|
|
return;
|
|
|
|
// When should we specify the foreground, if it's calculated
|
|
// by wxComputeColours?
|
|
// Solution: say we start with the default (computed) foreground colour.
|
|
// If we call SetForegroundColour explicitly for a control or window,
|
|
// then the foreground is changed.
|
|
// Therefore SetBackgroundColour computes the foreground colour, and
|
|
// SetForegroundColour changes the foreground colour. The ordering is
|
|
// important.
|
|
|
|
XtVaSetValues ((Widget) widget,
|
|
XmNforeground, foregroundColour.AllocColour(XtDisplay((Widget) widget)),
|
|
NULL);
|
|
}
|
|
|
|
void wxDoChangeBackgroundColour(WXWidget widget, const wxColour& backgroundColour, bool changeArmColour)
|
|
{
|
|
if (!backgroundColour.IsOk())
|
|
return;
|
|
|
|
wxComputeColours (XtDisplay((Widget) widget), & backgroundColour,
|
|
NULL);
|
|
|
|
XtVaSetValues ((Widget) widget,
|
|
XmNbackground, g_itemColors[wxBACK_INDEX].pixel,
|
|
XmNtopShadowColor, g_itemColors[wxTOPS_INDEX].pixel,
|
|
XmNbottomShadowColor, g_itemColors[wxBOTS_INDEX].pixel,
|
|
XmNforeground, g_itemColors[wxFORE_INDEX].pixel,
|
|
NULL);
|
|
|
|
if (changeArmColour)
|
|
XtVaSetValues ((Widget) widget,
|
|
XmNarmColor, g_itemColors[wxSELE_INDEX].pixel,
|
|
NULL);
|
|
}
|
|
|
|
extern void wxDoChangeFont(WXWidget widget, const wxFont& font)
|
|
{
|
|
// Lesstif 0.87 hangs here, but 0.93 does not; MBN: sometimes it does
|
|
#if !wxCHECK_LESSTIF() // || wxCHECK_LESSTIF_VERSION( 0, 93 )
|
|
Widget w = (Widget)widget;
|
|
XtVaSetValues( w,
|
|
wxFont::GetFontTag(), font.GetFontTypeC( XtDisplay(w) ),
|
|
NULL );
|
|
#else
|
|
wxUnusedVar(widget);
|
|
wxUnusedVar(font);
|
|
#endif
|
|
|
|
}
|
|
|
|
wxString wxXmStringToString( const XmString& xmString )
|
|
{
|
|
char *txt;
|
|
if( XmStringGetLtoR( xmString, XmSTRING_DEFAULT_CHARSET, &txt ) )
|
|
{
|
|
wxString str(txt);
|
|
XtFree (txt);
|
|
return str;
|
|
}
|
|
|
|
return wxEmptyString;
|
|
}
|
|
|
|
XmString wxStringToXmString( const char* str )
|
|
{
|
|
return XmStringCreateLtoR((char *)str, XmSTRING_DEFAULT_CHARSET);
|
|
}
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// wxBitmap utility functions
|
|
// ----------------------------------------------------------------------------
|
|
|
|
// Creates a bitmap with transparent areas drawn in
|
|
// the given colour.
|
|
wxBitmap wxCreateMaskedBitmap(const wxBitmap& bitmap, const wxColour& colour)
|
|
{
|
|
wxBitmap newBitmap(bitmap.GetWidth(),
|
|
bitmap.GetHeight(),
|
|
bitmap.GetDepth());
|
|
wxMemoryDC destDC;
|
|
wxMemoryDC srcDC;
|
|
|
|
srcDC.SelectObjectAsSource(bitmap);
|
|
destDC.SelectObject(newBitmap);
|
|
|
|
wxBrush brush(colour, wxSOLID);
|
|
destDC.SetBackground(brush);
|
|
destDC.Clear();
|
|
destDC.Blit(0, 0, bitmap.GetWidth(), bitmap.GetHeight(),
|
|
&srcDC, 0, 0, wxCOPY, true);
|
|
|
|
return newBitmap;
|
|
}
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// Miscellaneous functions
|
|
// ----------------------------------------------------------------------------
|
|
|
|
WXWidget wxCreateBorderWidget( WXWidget parent, long style )
|
|
{
|
|
Widget borderWidget = (Widget)NULL, parentWidget = (Widget)parent;
|
|
|
|
if (style & wxSIMPLE_BORDER)
|
|
{
|
|
borderWidget = XtVaCreateManagedWidget
|
|
(
|
|
"simpleBorder",
|
|
xmFrameWidgetClass, parentWidget,
|
|
XmNshadowType, XmSHADOW_ETCHED_IN,
|
|
XmNshadowThickness, 1,
|
|
NULL
|
|
);
|
|
}
|
|
else if ((style & wxSUNKEN_BORDER) || (style & wxBORDER_THEME))
|
|
{
|
|
borderWidget = XtVaCreateManagedWidget
|
|
(
|
|
"sunkenBorder",
|
|
xmFrameWidgetClass, parentWidget,
|
|
XmNshadowType, XmSHADOW_IN,
|
|
NULL
|
|
);
|
|
}
|
|
else if (style & wxRAISED_BORDER)
|
|
{
|
|
borderWidget = XtVaCreateManagedWidget
|
|
(
|
|
"raisedBorder",
|
|
xmFrameWidgetClass, parentWidget,
|
|
XmNshadowType, XmSHADOW_OUT,
|
|
NULL
|
|
);
|
|
}
|
|
|
|
return borderWidget;
|
|
}
|