1 /////////////////////////////////////////////////////////////////////////////
2 // Name:        src/motif/utils.cpp
3 // Purpose:     Various utilities
4 // Author:      Julian Smart
5 // Modified by:
6 // Created:     17/09/98
7 // Copyright:   (c) Julian Smart
8 // Licence:     wxWindows licence
9 /////////////////////////////////////////////////////////////////////////////
10 
11 // ============================================================================
12 // declarations
13 // ============================================================================
14 
15 // ----------------------------------------------------------------------------
16 // headers
17 // ----------------------------------------------------------------------------
18 
19 // For compilers that support precompilation, includes "wx.h".
20 #include "wx/wxprec.h"
21 
22 #include "wx/utils.h"
23 
24 #ifndef WX_PRECOMP
25     #include "wx/app.h"
26     #include "wx/dcmemory.h"
27     #include "wx/bitmap.h"
28 #endif
29 
30 #include "wx/apptrait.h"
31 #include "wx/evtloop.h"
32 #include "wx/private/eventloopsourcesmanager.h"
33 #include "wx/motif/private/timer.h"
34 
35 #include <string.h>
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 
45 #include <Xm/Xm.h>
46 #include <Xm/Frame.h>
47 
48 #include "wx/motif/private.h"
49 
50 #include "X11/Xutil.h"
51 
52 #ifdef __VMS__
53 #pragma message enable nosimpint
54 #endif
55 
56 
57 // ============================================================================
58 // implementation
59 // ============================================================================
60 
61 // ----------------------------------------------------------------------------
62 // async event processing
63 // ----------------------------------------------------------------------------
64 
65 // Consume all events until no more left
wxFlushEvents(WXDisplay * wxdisplay)66 void wxFlushEvents(WXDisplay* wxdisplay)
67 {
68     Display *display = (Display*)wxdisplay;
69     wxEventLoop evtLoop;
70 
71     XSync (display, False);
72 
73     while (evtLoop.Pending())
74     {
75         XFlush (display);
76         evtLoop.Dispatch();
77     }
78 }
79 
80 #if wxUSE_EVENTLOOP_SOURCE
81 
82 extern "C"
83 {
84 
85 static
86 void
wxMotifInputHandler(XtPointer data,int * WXUNUSED (fd),XtInputId * WXUNUSED (inputId))87 wxMotifInputHandler(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.
102 class wxMotifEventLoopSource : public wxEventLoopSource
103 {
104 public:
wxMotifEventLoopSource(XtInputId inputId,wxEventLoopSourceHandler * handler,int flags)105     wxMotifEventLoopSource(XtInputId inputId,
106                            wxEventLoopSourceHandler *handler,
107                            int flags)
108         : wxEventLoopSource(handler, flags),
109           m_inputId(inputId)
110     {
111     }
112 
~wxMotifEventLoopSource()113     virtual ~wxMotifEventLoopSource()
114     {
115         XtRemoveInput(m_inputId);
116     }
117 
118 private:
119     const XtInputId m_inputId;
120 
121     wxDECLARE_NO_COPY_CLASS(wxMotifEventLoopSource);
122 };
123 
124 class wxMotifEventLoopSourcesManager : public wxEventLoopSourcesManagerBase
125 {
126 public:
127     wxEventLoopSource *
AddSourceForFD(int fd,wxEventLoopSourceHandler * handler,int flags)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 
GetEventLoopSourcesManager()159 wxEventLoopSourcesManagerBase* wxGUIAppTraits::GetEventLoopSourcesManager()
160 {
161     static wxMotifEventLoopSourcesManager s_eventLoopSourcesManager;
162 
163     return &s_eventLoopSourcesManager;
164 }
165 
166 #endif // wxUSE_EVENTLOOP_SOURCE
167 
168 // ----------------------------------------------------------------------------
169 // misc
170 // ----------------------------------------------------------------------------
171 
172 // Emit a beeeeeep
wxBell()173 void wxBell()
174 {
175     // Use current setting for the bell
176     XBell (wxGlobalDisplay(), 0);
177 }
178 
GetToolkitVersion(int * verMaj,int * verMin) const179 wxPortId wxGUIAppTraits::GetToolkitVersion(int *verMaj, int *verMin) const
180 {
181     // XmVERSION and XmREVISION are defined in Xm/Xm.h
182     if ( verMaj )
183         *verMaj = XmVERSION;
184     if ( verMin )
185         *verMin = XmREVISION;
186 
187     return wxPORT_MOTIF;
188 }
189 
CreateEventLoop()190 wxEventLoopBase* wxGUIAppTraits::CreateEventLoop()
191 {
192     return new wxEventLoop;
193 }
194 
CreateTimerImpl(wxTimer * timer)195 wxTimerImpl* wxGUIAppTraits::CreateTimerImpl(wxTimer* timer)
196 {
197     return new wxMotifTimerImpl(timer);
198 }
199 
200 // ----------------------------------------------------------------------------
201 // display info
202 // ----------------------------------------------------------------------------
203 
wxGetMousePosition(int * x,int * y)204 void 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;
213     XQueryPointer(wxGlobalDisplay(),
214                   DefaultRootWindow(wxGlobalDisplay()),
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
222 }
223 
224 // Return true if we have a colour display
wxColourDisplay()225 bool wxColourDisplay()
226 {
227     return wxDisplayDepth() > 1;
228 }
229 
230 // Returns depth of screen
wxDisplayDepth()231 int wxDisplayDepth()
232 {
233     Display *dpy = wxGlobalDisplay();
234 
235     return DefaultDepth (dpy, DefaultScreen (dpy));
236 }
237 
238 // Get size of display
wxDisplaySize(int * width,int * height)239 void wxDisplaySize(int *width, int *height)
240 {
241     Display *dpy = wxGlobalDisplay();
242 
243     if ( width )
244         *width = DisplayWidth (dpy, DefaultScreen (dpy));
245     if ( height )
246         *height = DisplayHeight (dpy, DefaultScreen (dpy));
247 }
248 
wxDisplaySizeMM(int * width,int * height)249 void wxDisplaySizeMM(int *width, int *height)
250 {
251     Display *dpy = wxGlobalDisplay();
252 
253     if ( width )
254         *width = DisplayWidthMM(dpy, DefaultScreen (dpy));
255     if ( height )
256         *height = DisplayHeightMM(dpy, DefaultScreen (dpy));
257 }
258 
259 // Configurable display in wxX11 and wxMotif
260 static WXDisplay *gs_currentDisplay = NULL;
261 static wxString gs_displayName;
262 
wxGetDisplay()263 WXDisplay *wxGetDisplay()
264 {
265     if (gs_currentDisplay)
266         return gs_currentDisplay;
267     else if (wxTheApp)
268         return wxTheApp->GetInitialDisplay();
269     return NULL;
270 }
271 
wxSetDisplay(const wxString & display_name)272 bool wxSetDisplay(const wxString& display_name)
273 {
274     gs_displayName = display_name;
275 
276     if ( display_name.empty() )
277     {
278         gs_currentDisplay = NULL;
279 
280         return true;
281     }
282     else
283     {
284         Cardinal argc = 0;
285 
286         Display *display = XtOpenDisplay((XtAppContext) wxTheApp->GetAppContext(),
287             display_name.c_str(),
288             wxTheApp->GetAppName().c_str(),
289             wxTheApp->GetClassName().c_str(),
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;
301             return true;
302         }
303         else
304             return false;
305     }
306 }
307 
wxGetDisplayName()308 wxString wxGetDisplayName()
309 {
310     return gs_displayName;
311 }
312 
wxFindWindowAtPoint(const wxPoint & pt)313 wxWindow* wxFindWindowAtPoint(const wxPoint& pt)
314 {
315     return wxGenericFindWindowAtPoint(pt);
316 }
317 
318 // ----------------------------------------------------------------------------
319 // Some colour manipulation routines
320 // ----------------------------------------------------------------------------
321 
wxHSVToXColor(wxHSV * hsv,XColor * rgb)322 void 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     }
348     rgb->red = (unsigned short)(r << 8);
349     rgb->green = (unsigned short)(g << 8);
350     rgb->blue = (unsigned short)(b << 8);
351 }
352 
wxXColorToHSV(wxHSV * hsv,XColor * rgb)353 void 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 
wxAllocNearestColor(Display * d,Colormap cmp,XColor * xc)382 void 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 
wxAllocColor(Display * d,Colormap cmp,XColor * xc)424 void wxAllocColor(Display *d,Colormap cmp,XColor *xc)
425 {
426     if (!XAllocColor(d,cmp,xc))
427     {
428         //          cout << "wxAllocColor : Warning : cannot allocate color, attempt find nearest !\n";
429         wxAllocNearestColor(d,cmp,xc);
430     }
431 }
432 
wxGetXEventName(XEvent & event)433 wxString 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;
440     static char* event_name[] = {
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
453     type = wxMin(35, type); type = wxMax(1, type);
454     wxString str(event_name[type]);
455     return str;
456 #endif
457 }
458 
459 // ----------------------------------------------------------------------------
460 // accelerators
461 // ----------------------------------------------------------------------------
462 
463 // Find the letter corresponding to the mnemonic, for Motif
wxFindMnemonic(const char * s)464 char wxFindMnemonic (const char *s)
465 {
466     char mnem = 0;
467     int len = strlen (s);
468     int i;
469 
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 
wxFindAccelerator(const char * s)487 char* wxFindAccelerator( const char *s )
488 {
489 #if 1
490     wxUnusedVar(s);
491     // VZ: this function returns incorrect keysym which completely breaks kbd
492     //     handling
493     return NULL;
494 #else
495     // The accelerator text is after the \t char.
496     s = strchr( s, '\t' );
497 
498     if( !s ) return NULL;
499 
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 
510         and handle Ctrl-N & similia
511     */
512 
513     static char buf[256];
514 
515     buf[0] = '\0';
516     wxString tmp = s + 1; // skip TAB
517     size_t index = 0;
518 
519     while( index < tmp.length() )
520     {
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 )
526         {
527             strcat( buf, "<Key>" );
528             strcat( buf, tmp.c_str() + index );
529 
530             return buf;
531         }
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;
549     }
550 
551     return NULL;
552 #endif
553 }
554 
wxFindAcceleratorText(const char * s)555 XmString wxFindAcceleratorText (const char *s)
556 {
557 #if 1
558     wxUnusedVar(s);
559     // VZ: this function returns incorrect keysym which completely breaks kbd
560     //     handling
561     return NULL;
562 #else
563     // The accelerator text is after the \t char.
564     s = strchr( s, '\t' );
565 
566     if( !s ) return NULL;
567 
568     return wxStringToXmString( s + 1 ); // skip TAB!
569 #endif
570 }
571 
572 // Change a widget's foreground and background colours.
wxDoChangeForegroundColour(WXWidget widget,wxColour & foregroundColour)573 void wxDoChangeForegroundColour(WXWidget widget, wxColour& foregroundColour)
574 {
575     if (!foregroundColour.IsOk())
576         return;
577 
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 
wxDoChangeBackgroundColour(WXWidget widget,const wxColour & backgroundColour,bool changeArmColour)592 void wxDoChangeBackgroundColour(WXWidget widget, const wxColour& backgroundColour, bool changeArmColour)
593 {
594     if (!backgroundColour.IsOk())
595         return;
596 
597     wxComputeColours (XtDisplay((Widget) widget), & backgroundColour,
598         NULL);
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 
wxDoChangeFont(WXWidget widget,const wxFont & font)613 extern void wxDoChangeFont(WXWidget widget, const wxFont& font)
614 {
615     // Lesstif 0.87 hangs here, but 0.93 does not; MBN: sometimes it does
616 #if !wxCHECK_LESSTIF() // || wxCHECK_LESSTIF_VERSION( 0, 93 )
617     Widget w = (Widget)widget;
618     XtVaSetValues( w,
619                    wxFont::GetFontTag(), font.GetFontTypeC( XtDisplay(w) ),
620                    NULL );
621 #else
622     wxUnusedVar(widget);
623     wxUnusedVar(font);
624 #endif
625 
626 }
627 
wxXmStringToString(const XmString & xmString)628 wxString 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 
wxStringToXmString(const char * str)641 XmString wxStringToXmString( const char* str )
642 {
643     return XmStringCreateLtoR((char *)str, XmSTRING_DEFAULT_CHARSET);
644 }
645 
646 // ----------------------------------------------------------------------------
647 // wxBitmap utility functions
648 // ----------------------------------------------------------------------------
649 
650 // Creates a bitmap with transparent areas drawn in
651 // the given colour.
wxCreateMaskedBitmap(const wxBitmap & bitmap,const wxColour & colour)652 wxBitmap wxCreateMaskedBitmap(const wxBitmap& bitmap, const wxColour& colour)
653 {
654     wxBitmap newBitmap(bitmap.GetWidth(),
655                        bitmap.GetHeight(),
656                        bitmap.GetDepth());
657     wxMemoryDC destDC;
658     wxMemoryDC srcDC;
659 
660     srcDC.SelectObjectAsSource(bitmap);
661     destDC.SelectObject(newBitmap);
662 
663     wxBrush brush(colour, wxSOLID);
664     destDC.SetBackground(brush);
665     destDC.Clear();
666     destDC.Blit(0, 0, bitmap.GetWidth(), bitmap.GetHeight(),
667                 &srcDC, 0, 0, wxCOPY, true);
668 
669     return newBitmap;
670 }
671 
672 // ----------------------------------------------------------------------------
673 // Miscellaneous functions
674 // ----------------------------------------------------------------------------
675 
wxCreateBorderWidget(WXWidget parent,long style)676 WXWidget 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     }
691     else if ((style & wxSUNKEN_BORDER) || (style & wxBORDER_THEME))
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 }
714