]> git.saurik.com Git - wxWidgets.git/blame - src/motif/utils.cpp
Fix build with wxUSE_FFILE=0.
[wxWidgets.git] / src / motif / utils.cpp
CommitLineData
4bb6408c 1/////////////////////////////////////////////////////////////////////////////
355b4d3d 2// Name: src/motif/utils.cpp
4bb6408c
JS
3// Purpose: Various utilities
4// Author: Julian Smart
5// Modified by:
6// Created: 17/09/98
7// RCS-ID: $Id$
8// Copyright: (c) Julian Smart
65571936 9// Licence: wxWindows licence
4bb6408c
JS
10/////////////////////////////////////////////////////////////////////////////
11
518b5d2f
VZ
12// ============================================================================
13// declarations
14// ============================================================================
15
16// ----------------------------------------------------------------------------
17// headers
18// ----------------------------------------------------------------------------
4bb6408c 19
1248b41f
MB
20// For compilers that support precompilation, includes "wx.h".
21#include "wx/wxprec.h"
22
2b5f62a0 23#include "wx/utils.h"
670f9935
WS
24
25#ifndef WX_PRECOMP
26 #include "wx/app.h"
f38924e8 27 #include "wx/dcmemory.h"
0bca0373 28 #include "wx/bitmap.h"
670f9935
WS
29#endif
30
d48568a5 31#include "wx/apptrait.h"
eb6fa4b4 32#include "wx/evtloop.h"
38534f59 33#include "wx/private/eventloopsourcesmanager.h"
c2ca375c 34#include "wx/motif/private/timer.h"
2b5f62a0 35
2b5f62a0 36#include <string.h>
2b5f62a0
VZ
37
38#if (defined(__SUNCC__) || defined(__CLCC__))
39 #include <sysent.h>
40#endif
41
42#ifdef __VMS__
43#pragma message disable nosimpint
44#endif
45
2b5f62a0 46#include <Xm/Xm.h>
6769d0cb
MB
47#include <Xm/Frame.h>
48
2b5f62a0 49#include "wx/motif/private.h"
2b5f62a0 50
2b5f62a0
VZ
51#include "X11/Xutil.h"
52
53#ifdef __VMS__
54#pragma message enable nosimpint
55#endif
56
2b5f62a0
VZ
57
58// ============================================================================
59// implementation
60// ============================================================================
61
62// ----------------------------------------------------------------------------
63// async event processing
64// ----------------------------------------------------------------------------
65
66// Consume all events until no more left
eb6fa4b4 67void wxFlushEvents(WXDisplay* wxdisplay)
2b5f62a0 68{
eb6fa4b4
MB
69 Display *display = (Display*)wxdisplay;
70 wxEventLoop evtLoop;
2b5f62a0 71
96be256b 72 XSync (display, False);
2b5f62a0 73
eb6fa4b4 74 while (evtLoop.Pending())
2b5f62a0 75 {
eb6fa4b4
MB
76 XFlush (display);
77 evtLoop.Dispatch();
2b5f62a0 78 }
2b5f62a0
VZ
79}
80
38534f59
VZ
81#if wxUSE_EVENTLOOP_SOURCE
82
83extern "C"
84{
85
86static
87void
88wxMotifInputHandler(XtPointer data,
89 int* WXUNUSED(fd),
90 XtInputId* WXUNUSED(inputId))
91{
92 wxEventLoopSourceHandler * const
93 handler = static_cast<wxEventLoopSourceHandler *>(data);
94
95 handler->OnReadWaiting();
96}
97
98}
99
100// This class exists just to call XtRemoveInput() in its dtor, the real work of
101// dispatching events on the file descriptor to the handler is done by
102// wxMotifInputHandler callback above.
103class wxMotifEventLoopSource : public wxEventLoopSource
104{
105public:
106 wxMotifEventLoopSource(XtInputId inputId,
107 wxEventLoopSourceHandler *handler,
108 int flags)
109 : wxEventLoopSource(handler, flags),
110 m_inputId(inputId)
111 {
112 }
113
114 virtual ~wxMotifEventLoopSource()
115 {
116 XtRemoveInput(m_inputId);
117 }
118
119private:
120 const XtInputId m_inputId;
121
122 wxDECLARE_NO_COPY_CLASS(wxMotifEventLoopSource);
123};
124
125class wxMotifEventLoopSourcesManager : public wxEventLoopSourcesManagerBase
126{
127public:
128 wxEventLoopSource *
129 AddSourceForFD(int fd, wxEventLoopSourceHandler* handler, int flags)
130 {
131 wxCHECK_MSG( wxTheApp, NULL, "Must create wxTheApp first" );
132
133 // The XtInputXXXMask values cannot be combined (hence "Mask" is a
134 // complete misnomer), and supporting those would make the code more
135 // complicated and we don't need them for now.
136 wxCHECK_MSG( !(flags & (wxEVENT_SOURCE_OUTPUT |
137 wxEVENT_SOURCE_EXCEPTION)),
138 NULL,
139 "Monitoring FDs for output/errors not supported" );
140
141 wxCHECK_MSG( flags & wxEVENT_SOURCE_INPUT,
142 NULL,
143 "Should be monitoring for input" );
144
145 XtInputId inputId = XtAppAddInput
146 (
147 (XtAppContext) wxTheApp->GetAppContext(),
148 fd,
149 (XtPointer) XtInputReadMask,
150 wxMotifInputHandler,
151 handler
152 );
153 if ( inputId < 0 )
154 return 0;
155
156 return new wxMotifEventLoopSource(inputId, handler, flags);
157 }
158};
159
160wxEventLoopSourcesManagerBase* wxGUIAppTraits::GetEventLoopSourcesManager()
161{
162 static wxMotifEventLoopSourcesManager s_eventLoopSourcesManager;
163
164 return &s_eventLoopSourcesManager;
165}
166
167#endif // wxUSE_EVENTLOOP_SOURCE
168
2b5f62a0
VZ
169// ----------------------------------------------------------------------------
170// misc
171// ----------------------------------------------------------------------------
172
173// Emit a beeeeeep
174void wxBell()
175{
176 // Use current setting for the bell
eb6fa4b4 177 XBell (wxGlobalDisplay(), 0);
2b5f62a0
VZ
178}
179
8bb6b2c0 180wxPortId wxGUIAppTraits::GetToolkitVersion(int *verMaj, int *verMin) const
2b5f62a0 181{
8bb6b2c0
VZ
182 // XmVERSION and XmREVISION are defined in Xm/Xm.h
183 if ( verMaj )
184 *verMaj = XmVERSION;
185 if ( verMin )
186 *verMin = XmREVISION;
f9788a11 187
8bb6b2c0 188 return wxPORT_MOTIF;
2b5f62a0
VZ
189}
190
2ddff00c 191wxEventLoopBase* wxGUIAppTraits::CreateEventLoop()
b46b1d59
VZ
192{
193 return new wxEventLoop;
194}
195
c2ca375c
VZ
196wxTimerImpl* wxGUIAppTraits::CreateTimerImpl(wxTimer* timer)
197{
198 return new wxMotifTimerImpl(timer);
199}
200
2b5f62a0
VZ
201// ----------------------------------------------------------------------------
202// display info
203// ----------------------------------------------------------------------------
204
205void wxGetMousePosition( int* x, int* y )
206{
207#if wxUSE_NANOX
208 // TODO
209 *x = 0;
210 *y = 0;
211#else
212 XMotionEvent xev;
213 Window root, child;
eb6fa4b4
MB
214 XQueryPointer(wxGlobalDisplay(),
215 DefaultRootWindow(wxGlobalDisplay()),
2b5f62a0
VZ
216 &root, &child,
217 &(xev.x_root), &(xev.y_root),
218 &(xev.x), &(xev.y),
219 &(xev.state));
220 *x = xev.x_root;
221 *y = xev.y_root;
222#endif
e933b5bc 223}
2b5f62a0 224
ea76a6a5 225// Return true if we have a colour display
2b5f62a0
VZ
226bool wxColourDisplay()
227{
228 return wxDisplayDepth() > 1;
229}
230
231// Returns depth of screen
232int wxDisplayDepth()
233{
eb6fa4b4 234 Display *dpy = wxGlobalDisplay();
2b5f62a0
VZ
235
236 return DefaultDepth (dpy, DefaultScreen (dpy));
237}
238
239// Get size of display
240void wxDisplaySize(int *width, int *height)
241{
eb6fa4b4 242 Display *dpy = wxGlobalDisplay();
2b5f62a0
VZ
243
244 if ( width )
245 *width = DisplayWidth (dpy, DefaultScreen (dpy));
246 if ( height )
247 *height = DisplayHeight (dpy, DefaultScreen (dpy));
248}
249
250void wxDisplaySizeMM(int *width, int *height)
251{
eb6fa4b4 252 Display *dpy = wxGlobalDisplay();
2b5f62a0
VZ
253
254 if ( width )
255 *width = DisplayWidthMM(dpy, DefaultScreen (dpy));
256 if ( height )
257 *height = DisplayHeightMM(dpy, DefaultScreen (dpy));
258}
259
2b5f62a0
VZ
260// Configurable display in wxX11 and wxMotif
261static WXDisplay *gs_currentDisplay = NULL;
262static wxString gs_displayName;
263
264WXDisplay *wxGetDisplay()
265{
266 if (gs_currentDisplay)
267 return gs_currentDisplay;
2b5f62a0
VZ
268 else if (wxTheApp)
269 return wxTheApp->GetInitialDisplay();
270 return NULL;
2b5f62a0
VZ
271}
272
273bool wxSetDisplay(const wxString& display_name)
274{
275 gs_displayName = display_name;
276
ea76a6a5 277 if ( display_name.empty() )
2b5f62a0
VZ
278 {
279 gs_currentDisplay = NULL;
280
ea76a6a5 281 return true;
2b5f62a0
VZ
282 }
283 else
284 {
2b5f62a0
VZ
285 Cardinal argc = 0;
286
287 Display *display = XtOpenDisplay((XtAppContext) wxTheApp->GetAppContext(),
3e2d47e1
MB
288 display_name.c_str(),
289 wxTheApp->GetAppName().c_str(),
290 wxTheApp->GetClassName().c_str(),
2b5f62a0
VZ
291 NULL,
292#if XtSpecificationRelease < 5
293 0, &argc,
294#else
295 0, (int *)&argc,
296#endif
297 NULL);
298
299 if (display)
300 {
301 gs_currentDisplay = (WXDisplay*) display;
ea76a6a5 302 return true;
2b5f62a0
VZ
303 }
304 else
96be256b 305 return false;
2b5f62a0
VZ
306 }
307}
308
309wxString wxGetDisplayName()
310{
311 return gs_displayName;
312}
313
314wxWindow* wxFindWindowAtPoint(const wxPoint& pt)
315{
316 return wxGenericFindWindowAtPoint(pt);
317}
318
2b5f62a0
VZ
319// ----------------------------------------------------------------------------
320// Some colour manipulation routines
321// ----------------------------------------------------------------------------
322
323void wxHSVToXColor(wxHSV *hsv,XColor *rgb)
324{
325 int h = hsv->h;
326 int s = hsv->s;
327 int v = hsv->v;
328 int r = 0, g = 0, b = 0;
329 int i, f;
330 int p, q, t;
331 s = (s * wxMAX_RGB) / wxMAX_SV;
332 v = (v * wxMAX_RGB) / wxMAX_SV;
333 if (h == 360) h = 0;
334 if (s == 0) { h = 0; r = g = b = v; }
335 i = h / 60;
336 f = h % 60;
337 p = v * (wxMAX_RGB - s) / wxMAX_RGB;
338 q = v * (wxMAX_RGB - s * f / 60) / wxMAX_RGB;
339 t = v * (wxMAX_RGB - s * (60 - f) / 60) / wxMAX_RGB;
340 switch (i)
341 {
342 case 0: r = v, g = t, b = p; break;
343 case 1: r = q, g = v, b = p; break;
344 case 2: r = p, g = v, b = t; break;
345 case 3: r = p, g = q, b = v; break;
346 case 4: r = t, g = p, b = v; break;
347 case 5: r = v, g = p, b = q; break;
348 }
355b4d3d
WS
349 rgb->red = (unsigned short)(r << 8);
350 rgb->green = (unsigned short)(g << 8);
351 rgb->blue = (unsigned short)(b << 8);
2b5f62a0
VZ
352}
353
354void wxXColorToHSV(wxHSV *hsv,XColor *rgb)
355{
356 int r = rgb->red >> 8;
357 int g = rgb->green >> 8;
358 int b = rgb->blue >> 8;
359 int maxv = wxMax3(r, g, b);
360 int minv = wxMin3(r, g, b);
361 int h = 0, s, v;
362 v = maxv;
363 if (maxv) s = (maxv - minv) * wxMAX_RGB / maxv;
364 else s = 0;
365 if (s == 0) h = 0;
366 else
367 {
368 int rc, gc, bc, hex = 0;
369 rc = (maxv - r) * wxMAX_RGB / (maxv - minv);
370 gc = (maxv - g) * wxMAX_RGB / (maxv - minv);
371 bc = (maxv - b) * wxMAX_RGB / (maxv - minv);
372 if (r == maxv) { h = bc - gc, hex = 0; }
373 else if (g == maxv) { h = rc - bc, hex = 2; }
374 else if (b == maxv) { h = gc - rc, hex = 4; }
375 h = hex * 60 + (h * 60 / wxMAX_RGB);
376 if (h < 0) h += 360;
377 }
378 hsv->h = h;
379 hsv->s = (s * wxMAX_SV) / wxMAX_RGB;
380 hsv->v = (v * wxMAX_SV) / wxMAX_RGB;
381}
382
383void wxAllocNearestColor(Display *d,Colormap cmp,XColor *xc)
384{
385#if !wxUSE_NANOX
386 int llp;
387
388 int screen = DefaultScreen(d);
389 int num_colors = DisplayCells(d,screen);
390
391 XColor *color_defs = new XColor[num_colors];
392 for(llp = 0;llp < num_colors;llp++) color_defs[llp].pixel = llp;
393 XQueryColors(d,cmp,color_defs,num_colors);
394
395 wxHSV hsv_defs, hsv;
396 wxXColorToHSV(&hsv,xc);
397
398 int diff, min_diff = 0, pixel = 0;
399
400 for(llp = 0;llp < num_colors;llp++)
401 {
402 wxXColorToHSV(&hsv_defs,&color_defs[llp]);
403 diff = wxSIGN(wxH_WEIGHT * (hsv.h - hsv_defs.h)) +
404 wxSIGN(wxS_WEIGHT * (hsv.s - hsv_defs.s)) +
405 wxSIGN(wxV_WEIGHT * (hsv.v - hsv_defs.v));
406 if (llp == 0) min_diff = diff;
407 if (min_diff > diff) { min_diff = diff; pixel = llp; }
408 if (min_diff == 0) break;
409 }
410
411 xc -> red = color_defs[pixel].red;
412 xc -> green = color_defs[pixel].green;
413 xc -> blue = color_defs[pixel].blue;
414 xc -> flags = DoRed | DoGreen | DoBlue;
415
416/* FIXME, TODO
417 if (!XAllocColor(d,cmp,xc))
418 cout << "wxAllocNearestColor : Warning : Cannot find nearest color !\n";
419*/
420
421 delete[] color_defs;
422#endif
423}
424
425void wxAllocColor(Display *d,Colormap cmp,XColor *xc)
426{
427 if (!XAllocColor(d,cmp,xc))
428 {
4c51a665 429 // cout << "wxAllocColor : Warning : cannot allocate color, attempt find nearest !\n";
2b5f62a0
VZ
430 wxAllocNearestColor(d,cmp,xc);
431 }
432}
433
2b5f62a0
VZ
434wxString wxGetXEventName(XEvent& event)
435{
436#if wxUSE_NANOX
437 wxString str(wxT("(some event)"));
438 return str;
439#else
440 int type = event.xany.type;
ea76a6a5 441 static char* event_name[] = {
f1db433a
VZ
442 wxMOTIF_STR(""), wxMOTIF_STR("unknown(-)"), // 0-1
443 wxMOTIF_STR("KeyPress"), wxMOTIF_STR("KeyRelease"), wxMOTIF_STR("ButtonPress"), wxMOTIF_STR("ButtonRelease"), // 2-5
444 wxMOTIF_STR("MotionNotify"), wxMOTIF_STR("EnterNotify"), wxMOTIF_STR("LeaveNotify"), wxMOTIF_STR("FocusIn"), // 6-9
445 wxMOTIF_STR("FocusOut"), wxMOTIF_STR("KeymapNotify"), wxMOTIF_STR("Expose"), wxMOTIF_STR("GraphicsExpose"), // 10-13
446 wxMOTIF_STR("NoExpose"), wxMOTIF_STR("VisibilityNotify"), wxMOTIF_STR("CreateNotify"), // 14-16
447 wxMOTIF_STR("DestroyNotify"), wxMOTIF_STR("UnmapNotify"), wxMOTIF_STR("MapNotify"), wxMOTIF_STR("MapRequest"),// 17-20
448 wxMOTIF_STR("ReparentNotify"), wxMOTIF_STR("ConfigureNotify"), wxMOTIF_STR("ConfigureRequest"), // 21-23
449 wxMOTIF_STR("GravityNotify"), wxMOTIF_STR("ResizeRequest"), wxMOTIF_STR("CirculateNotify"), // 24-26
450 wxMOTIF_STR("CirculateRequest"), wxMOTIF_STR("PropertyNotify"), wxMOTIF_STR("SelectionClear"), // 27-29
451 wxMOTIF_STR("SelectionRequest"), wxMOTIF_STR("SelectionNotify"), wxMOTIF_STR("ColormapNotify"), // 30-32
452 wxMOTIF_STR("ClientMessage"), wxMOTIF_STR("MappingNotify"), // 33-34
453 wxMOTIF_STR("unknown(+)")}; // 35
ea76a6a5
WS
454 type = wxMin(35, type); type = wxMax(1, type);
455 wxString str(event_name[type]);
456 return str;
2b5f62a0
VZ
457#endif
458}
2b5f62a0 459
2b5f62a0
VZ
460// ----------------------------------------------------------------------------
461// accelerators
462// ----------------------------------------------------------------------------
463
464// Find the letter corresponding to the mnemonic, for Motif
465char wxFindMnemonic (const char *s)
466{
467 char mnem = 0;
468 int len = strlen (s);
469 int i;
eb6fa4b4 470
2b5f62a0
VZ
471 for (i = 0; i < len; i++)
472 {
473 if (s[i] == '&')
474 {
475 // Carefully handle &&
476 if ((i + 1) <= len && s[i + 1] == '&')
477 i++;
478 else
479 {
480 mnem = s[i + 1];
481 break;
482 }
483 }
484 }
485 return mnem;
486}
487
eb6fa4b4 488char* wxFindAccelerator( const char *s )
2b5f62a0 489{
eb6fa4b4 490#if 1
355b4d3d 491 wxUnusedVar(s);
2b5f62a0
VZ
492 // VZ: this function returns incorrect keysym which completely breaks kbd
493 // handling
494 return NULL;
eb6fa4b4
MB
495#else
496 // The accelerator text is after the \t char.
497 s = strchr( s, '\t' );
498
499 if( !s ) return NULL;
2b5f62a0 500
2b5f62a0
VZ
501 /*
502 Now we need to format it as X standard:
503
504 input output
505
506 F7 --> <Key>F7
507 Ctrl+N --> Ctrl<Key>N
508 Alt+k --> Meta<Key>k
509 Ctrl+Shift+A --> Ctrl Shift<Key>A
510
eb6fa4b4 511 and handle Ctrl-N & similia
2b5f62a0
VZ
512 */
513
514 static char buf[256];
eb6fa4b4 515
2b5f62a0 516 buf[0] = '\0';
eb6fa4b4
MB
517 wxString tmp = s + 1; // skip TAB
518 size_t index = 0;
2b5f62a0 519
eb6fa4b4 520 while( index < tmp.length() )
2b5f62a0 521 {
eb6fa4b4
MB
522 size_t plus = tmp.find( '+', index );
523 size_t minus = tmp.find( '-', index );
524
525 // neither '+' nor '-', add <Key>
526 if( plus == wxString::npos && minus == wxString::npos )
2b5f62a0 527 {
eb6fa4b4
MB
528 strcat( buf, "<Key>" );
529 strcat( buf, tmp.c_str() + index );
530
531 return buf;
2b5f62a0 532 }
eb6fa4b4
MB
533
534 // OK: npos is big and positive
535 size_t sep = wxMin( plus, minus );
536 wxString mod = tmp.substr( index, sep - index );
537
538 // Ctrl -> Ctrl
539 // Shift -> Shift
540 // Alt -> Meta
541 if( mod == "Alt" )
542 mod = "Meta";
543
544 if( buf[0] )
545 strcat( buf, " " );
546
547 strcat( buf, mod.c_str() );
548
549 index = sep + 1;
2b5f62a0 550 }
eb6fa4b4
MB
551
552 return NULL;
2b5f62a0
VZ
553#endif
554}
555
556XmString wxFindAcceleratorText (const char *s)
557{
eb6fa4b4 558#if 1
355b4d3d 559 wxUnusedVar(s);
2b5f62a0
VZ
560 // VZ: this function returns incorrect keysym which completely breaks kbd
561 // handling
562 return NULL;
eb6fa4b4
MB
563#else
564 // The accelerator text is after the \t char.
565 s = strchr( s, '\t' );
2b5f62a0 566
eb6fa4b4
MB
567 if( !s ) return NULL;
568
569 return wxStringToXmString( s + 1 ); // skip TAB!
2b5f62a0
VZ
570#endif
571}
572
2b5f62a0 573// Change a widget's foreground and background colours.
2b5f62a0
VZ
574void wxDoChangeForegroundColour(WXWidget widget, wxColour& foregroundColour)
575{
a1b806b9 576 if (!foregroundColour.IsOk())
105fbe1f
MB
577 return;
578
2b5f62a0
VZ
579 // When should we specify the foreground, if it's calculated
580 // by wxComputeColours?
581 // Solution: say we start with the default (computed) foreground colour.
582 // If we call SetForegroundColour explicitly for a control or window,
583 // then the foreground is changed.
584 // Therefore SetBackgroundColour computes the foreground colour, and
585 // SetForegroundColour changes the foreground colour. The ordering is
586 // important.
587
588 XtVaSetValues ((Widget) widget,
589 XmNforeground, foregroundColour.AllocColour(XtDisplay((Widget) widget)),
590 NULL);
591}
592
f516d986 593void wxDoChangeBackgroundColour(WXWidget widget, const wxColour& backgroundColour, bool changeArmColour)
2b5f62a0 594{
a1b806b9 595 if (!backgroundColour.IsOk())
105fbe1f
MB
596 return;
597
2b5f62a0 598 wxComputeColours (XtDisplay((Widget) widget), & backgroundColour,
d3b9f782 599 NULL);
2b5f62a0
VZ
600
601 XtVaSetValues ((Widget) widget,
602 XmNbackground, g_itemColors[wxBACK_INDEX].pixel,
603 XmNtopShadowColor, g_itemColors[wxTOPS_INDEX].pixel,
604 XmNbottomShadowColor, g_itemColors[wxBOTS_INDEX].pixel,
605 XmNforeground, g_itemColors[wxFORE_INDEX].pixel,
606 NULL);
607
608 if (changeArmColour)
609 XtVaSetValues ((Widget) widget,
610 XmNarmColor, g_itemColors[wxSELE_INDEX].pixel,
611 NULL);
612}
613
fbfb8bcc 614extern void wxDoChangeFont(WXWidget widget, const wxFont& font)
e1aae528 615{
101b4778
MB
616 // Lesstif 0.87 hangs here, but 0.93 does not; MBN: sometimes it does
617#if !wxCHECK_LESSTIF() // || wxCHECK_LESSTIF_VERSION( 0, 93 )
e1aae528 618 Widget w = (Widget)widget;
e1aae528 619 XtVaSetValues( w,
73608949 620 wxFont::GetFontTag(), font.GetFontTypeC( XtDisplay(w) ),
e1aae528 621 NULL );
355b4d3d
WS
622#else
623 wxUnusedVar(widget);
624 wxUnusedVar(font);
e1aae528
MB
625#endif
626
627}
628
e1aae528
MB
629wxString wxXmStringToString( const XmString& xmString )
630{
631 char *txt;
632 if( XmStringGetLtoR( xmString, XmSTRING_DEFAULT_CHARSET, &txt ) )
633 {
634 wxString str(txt);
635 XtFree (txt);
636 return str;
637 }
638
639 return wxEmptyString;
640}
641
3e2d47e1
MB
642XmString wxStringToXmString( const char* str )
643{
644 return XmStringCreateLtoR((char *)str, XmSTRING_DEFAULT_CHARSET);
645}
aae0472b
MB
646
647// ----------------------------------------------------------------------------
648// wxBitmap utility functions
649// ----------------------------------------------------------------------------
650
651// Creates a bitmap with transparent areas drawn in
652// the given colour.
fbfb8bcc 653wxBitmap wxCreateMaskedBitmap(const wxBitmap& bitmap, const wxColour& colour)
aae0472b
MB
654{
655 wxBitmap newBitmap(bitmap.GetWidth(),
656 bitmap.GetHeight(),
657 bitmap.GetDepth());
658 wxMemoryDC destDC;
659 wxMemoryDC srcDC;
660
f536319d 661 srcDC.SelectObjectAsSource(bitmap);
aae0472b
MB
662 destDC.SelectObject(newBitmap);
663
664 wxBrush brush(colour, wxSOLID);
aae0472b
MB
665 destDC.SetBackground(brush);
666 destDC.Clear();
667 destDC.Blit(0, 0, bitmap.GetWidth(), bitmap.GetHeight(),
ea76a6a5 668 &srcDC, 0, 0, wxCOPY, true);
aae0472b
MB
669
670 return newBitmap;
671}
6769d0cb
MB
672
673// ----------------------------------------------------------------------------
674// Miscellaneous functions
675// ----------------------------------------------------------------------------
676
677WXWidget wxCreateBorderWidget( WXWidget parent, long style )
678{
679 Widget borderWidget = (Widget)NULL, parentWidget = (Widget)parent;
680
681 if (style & wxSIMPLE_BORDER)
682 {
683 borderWidget = XtVaCreateManagedWidget
684 (
685 "simpleBorder",
686 xmFrameWidgetClass, parentWidget,
687 XmNshadowType, XmSHADOW_ETCHED_IN,
688 XmNshadowThickness, 1,
689 NULL
690 );
691 }
cce69fec 692 else if ((style & wxSUNKEN_BORDER) || (style & wxBORDER_THEME))
6769d0cb
MB
693 {
694 borderWidget = XtVaCreateManagedWidget
695 (
696 "sunkenBorder",
697 xmFrameWidgetClass, parentWidget,
698 XmNshadowType, XmSHADOW_IN,
699 NULL
700 );
701 }
702 else if (style & wxRAISED_BORDER)
703 {
704 borderWidget = XtVaCreateManagedWidget
705 (
706 "raisedBorder",
707 xmFrameWidgetClass, parentWidget,
708 XmNshadowType, XmSHADOW_OUT,
709 NULL
710 );
711 }
712
713 return borderWidget;
714}