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