1 ///////////////////////////////////////////////////////////////////////////////
2 // Name:        src/x11/toplevel.cpp
3 // Purpose:     implements wxTopLevelWindow for X11
4 // Author:      Julian Smart
5 // Modified by:
6 // Created:     24.09.01
7 // Copyright:   (c) 2002 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 #ifdef __BORLANDC__
23     #pragma hdrstop
24 #endif
25 
26 #include "wx/toplevel.h"
27 
28 #ifndef WX_PRECOMP
29     #include "wx/app.h"
30     #include "wx/string.h"
31     #include "wx/log.h"
32     #include "wx/intl.h"
33     #include "wx/frame.h"
34     #include "wx/menu.h"
35     #include "wx/statusbr.h"
36     #include "wx/settings.h"
37 #endif //WX_PRECOMP
38 
39 #include "wx/x11/private.h"
40 #include "X11/Xutil.h"
41 
42 #include "wx/unix/utilsx11.h"
43 
44 bool wxMWMIsRunning(Window w);
45 
46 // ----------------------------------------------------------------------------
47 // wxTopLevelWindowX11 creation
48 // ----------------------------------------------------------------------------
49 
Init()50 void wxTopLevelWindowX11::Init()
51 {
52     m_iconized =
53     m_maximizeOnShow = false;
54 
55     // unlike (almost?) all other windows, frames are created hidden
56     m_isShown = false;
57 
58     // Data to save/restore when calling ShowFullScreen
59     m_fsStyle = 0;
60     m_fsIsMaximized = false;
61     m_fsIsShowing = false;
62 
63     m_needResizeInIdle = false;
64 
65     m_x = wxDefaultCoord;
66     m_y = wxDefaultCoord;
67     m_width = 20;
68     m_height = 20;
69 }
70 
Create(wxWindow * parent,wxWindowID id,const wxString & title,const wxPoint & pos,const wxSize & size,long style,const wxString & name)71 bool wxTopLevelWindowX11::Create(wxWindow *parent,
72                                  wxWindowID id,
73                                  const wxString& title,
74                                  const wxPoint& pos,
75                                  const wxSize& size,
76                                  long style,
77                                  const wxString& name)
78 {
79     // init our fields
80     Init();
81 
82     m_windowStyle = style;
83     m_parent = parent;
84 
85     SetName(name);
86 
87     m_windowId = id == wxID_ANY ? NewControlId() : id;
88 
89     if (parent)
90         parent->AddChild(this);
91 
92     wxTopLevelWindows.Append(this);
93 
94     Display *xdisplay = wxGlobalDisplay();
95     int xscreen = DefaultScreen( xdisplay );
96     Visual *xvisual = DefaultVisual( xdisplay, xscreen );
97     Window xparent = RootWindow( xdisplay, xscreen );
98     Colormap cm = DefaultColormap( xdisplay, xscreen );
99 
100     if (GetExtraStyle() & wxTOPLEVEL_EX_DIALOG)
101         m_backgroundColour = wxSystemSettings::GetColour(wxSYS_COLOUR_BTNFACE);
102     else
103         m_backgroundColour = wxSystemSettings::GetColour(wxSYS_COLOUR_APPWORKSPACE);
104     m_backgroundColour.CalcPixel( (WXColormap) cm );
105     m_hasBgCol = true;
106 
107     m_x = pos.x;
108     if (m_x < -1)
109         m_x = 10;
110 
111     m_y = pos.y;
112     if (m_y < 0)
113         m_y = 10;
114 
115     m_width = size.x;
116     if (m_width < 0)
117         m_width = 500;
118 
119     m_height = size.y;
120     if (m_height < 0)
121         m_height = 380;
122 
123 #if !wxUSE_NANOX
124     XSetWindowAttributes xattributes;
125 
126     long xattributes_mask =
127         CWBorderPixel | CWBackPixel;
128 
129     xattributes.background_pixel = m_backgroundColour.GetPixel();
130     xattributes.border_pixel = BlackPixel( xdisplay, xscreen );
131 
132     if (HasFlag( wxNO_BORDER ))
133     {
134         xattributes_mask |= CWOverrideRedirect;
135         xattributes.override_redirect = True;
136     }
137 
138     if (!HasFlag( wxFULL_REPAINT_ON_RESIZE ))
139     {
140         xattributes_mask |= CWBitGravity;
141         xattributes.bit_gravity = NorthWestGravity;
142     }
143 
144     xattributes_mask |= CWEventMask;
145     xattributes.event_mask =
146         ExposureMask | KeyPressMask | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask |
147         ButtonMotionMask | EnterWindowMask | LeaveWindowMask | PointerMotionMask |
148         KeymapStateMask | FocusChangeMask | ColormapChangeMask | StructureNotifyMask |
149         PropertyChangeMask;
150 
151     Window xwindow = XCreateWindow( xdisplay, xparent, m_x, m_y, m_width, m_height,
152                                     0, DefaultDepth(xdisplay,xscreen), InputOutput, xvisual, xattributes_mask, &xattributes );
153 #else
154     long backColor, foreColor;
155     backColor = GR_RGB(m_backgroundColour.Red(), m_backgroundColour.Green(), m_backgroundColour.Blue());
156     foreColor = GR_RGB(m_foregroundColour.Red(), m_foregroundColour.Green(), m_foregroundColour.Blue());
157 
158     Window xwindow = XCreateWindowWithColor( xdisplay, xparent, m_x, m_y, m_width, m_height,
159                                     0, 0, InputOutput, xvisual, backColor, foreColor);
160 #endif
161 
162     m_mainWindow = (WXWindow) xwindow;
163     m_clientWindow = (WXWindow) xwindow;
164     wxAddWindowToTable( xwindow, (wxWindow*) this );
165 
166 #if wxUSE_NANOX
167     XSelectInput( xdisplay, xwindow,
168                   GR_EVENT_MASK_CLOSE_REQ |
169                   ExposureMask |
170                   KeyPressMask |
171                   KeyReleaseMask |
172                   ButtonPressMask |
173                   ButtonReleaseMask |
174                   ButtonMotionMask |
175                   EnterWindowMask |
176                   LeaveWindowMask |
177                   PointerMotionMask |
178                   KeymapStateMask |
179                   FocusChangeMask |
180                   ColormapChangeMask |
181                   StructureNotifyMask |
182                   PropertyChangeMask
183                   );
184 #endif
185 
186     // Set background to None which will prevent X11 from clearing the
187     // background completely.
188     XSetWindowBackgroundPixmap( xdisplay, xwindow, None );
189 
190 #if !wxUSE_NANOX
191     if (HasFlag( wxSTAY_ON_TOP ))
192     {
193         Window xroot = RootWindow( xdisplay, xscreen );
194         XSetTransientForHint( xdisplay, xwindow, xroot );
195     }
196     else
197     {
198        if (GetExtraStyle() & wxTOPLEVEL_EX_DIALOG)
199        {
200             if (GetParent() && GetParent()->X11GetMainWindow())
201             {
202                 Window xparentwindow = (Window) GetParent()->X11GetMainWindow();
203                 XSetTransientForHint( xdisplay, xwindow, xparentwindow );
204             }
205         }
206     }
207 
208     XSizeHints size_hints;
209     size_hints.flags = PSize | PPosition | PWinGravity;
210     size_hints.x = m_x;
211     size_hints.y = m_y;
212     size_hints.width = m_width;
213     size_hints.height = m_height;
214     size_hints.win_gravity = NorthWestGravity;
215     XSetWMNormalHints( xdisplay, xwindow, &size_hints);
216 
217     XWMHints wm_hints;
218     wm_hints.flags = InputHint | StateHint;
219     if (GetParent())
220     {
221         wm_hints.flags |= WindowGroupHint;
222         wm_hints.window_group = (Window) GetParent()->X11GetMainWindow();
223     }
224     wm_hints.input = True;
225     wm_hints.initial_state = NormalState;
226     XSetWMHints( xdisplay, xwindow, &wm_hints);
227 
228     Atom wm_protocols[2];
229     wm_protocols[0] = XInternAtom( xdisplay, "WM_DELETE_WINDOW", False );
230     wm_protocols[1] = XInternAtom( xdisplay, "WM_TAKE_FOCUS", False );
231     XSetWMProtocols( xdisplay, xwindow, wm_protocols, 2);
232 
233 #endif
234 
235     wxSetWMDecorations( xwindow, style);
236 
237     SetTitle(title);
238 
239     return true;
240 }
241 
~wxTopLevelWindowX11()242 wxTopLevelWindowX11::~wxTopLevelWindowX11()
243 {
244     wxTopLevelWindows.DeleteObject(this);
245 
246     // If this is the last top-level window, exit.
247     if ( wxTheApp && (wxTopLevelWindows.GetCount() == 0) )
248     {
249         wxTheApp->SetTopWindow(NULL);
250 
251         if (wxTheApp->GetExitOnFrameDelete())
252         {
253             // Signal to the app that we're going to close
254             wxTheApp->ExitMainLoop();
255         }
256     }
257 }
258 
OnInternalIdle()259 void wxTopLevelWindowX11::OnInternalIdle()
260 {
261     wxWindow::OnInternalIdle();
262 
263     // Do this only after the last idle event so that
264     // all windows have been updated before a new
265     // round of size events is sent
266     if (m_needResizeInIdle && !wxTheApp->Pending())
267     {
268         wxSizeEvent event( GetClientSize(), GetId() );
269         event.SetEventObject( this );
270         HandleWindowEvent( event );
271 
272         m_needResizeInIdle = false;
273     }
274 }
275 
276 // ----------------------------------------------------------------------------
277 // wxTopLevelWindowX11 showing
278 // ----------------------------------------------------------------------------
279 
Show(bool show)280 bool wxTopLevelWindowX11::Show(bool show)
281 {
282     if (show)
283     {
284         wxSizeEvent event(GetSize(), GetId());
285 
286         event.SetEventObject(this);
287         HandleWindowEvent(event);
288 
289         m_needResizeInIdle = false;
290     }
291 
292     bool ret = wxWindowX11::Show(show);
293 
294     return ret;
295 }
296 
297 // ----------------------------------------------------------------------------
298 // wxTopLevelWindowX11 maximize/minimize
299 // ----------------------------------------------------------------------------
300 
Maximize(bool WXUNUSED (maximize))301 void wxTopLevelWindowX11::Maximize(bool WXUNUSED(maximize))
302 {
303     // TODO
304 }
305 
IsMaximized() const306 bool wxTopLevelWindowX11::IsMaximized() const
307 {
308     // TODO
309     return true;
310 }
311 
Iconize(bool iconize)312 void wxTopLevelWindowX11::Iconize(bool iconize)
313 {
314     if ( !iconize )
315     {
316         Restore();
317         return;
318     }
319 
320     if (!m_iconized && X11GetMainWindow())
321     {
322         if (XIconifyWindow(wxGlobalDisplay(),
323             (Window) X11GetMainWindow(), DefaultScreen(wxGlobalDisplay())) != 0)
324             m_iconized = true;
325     }
326 }
327 
IsIconized() const328 bool wxTopLevelWindowX11::IsIconized() const
329 {
330     return m_iconized;
331 }
332 
Restore()333 void wxTopLevelWindowX11::Restore()
334 {
335     // This is the way to deiconify the window, according to the X FAQ
336     if (m_iconized && X11GetMainWindow())
337     {
338         XMapWindow(wxGlobalDisplay(), (Window) X11GetMainWindow());
339         m_iconized = false;
340     }
341 }
342 
343 // ----------------------------------------------------------------------------
344 // wxTopLevelWindowX11 fullscreen
345 // ----------------------------------------------------------------------------
346 
ShowFullScreen(bool show,long style)347 bool wxTopLevelWindowX11::ShowFullScreen(bool show, long style)
348 {
349     if (show)
350     {
351         if (IsFullScreen())
352             return false;
353 
354         m_fsIsShowing = true;
355         m_fsStyle = style;
356 
357         // TODO
358 
359         return true;
360     }
361     else
362     {
363         if (!IsFullScreen())
364             return false;
365 
366         m_fsIsShowing = false;
367 
368         // TODO
369         return true;
370     }
371 }
372 
373 // ----------------------------------------------------------------------------
374 // wxTopLevelWindowX11 misc
375 // ----------------------------------------------------------------------------
376 
DoSetIcon(const wxIcon & icon)377 void wxTopLevelWindowX11::DoSetIcon(const wxIcon& icon)
378 {
379     if (icon.IsOk() && X11GetMainWindow())
380     {
381 #if !wxUSE_NANOX
382         XWMHints *wmHints = XAllocWMHints();
383         wmHints->icon_pixmap = (Pixmap) icon.GetPixmap();
384 
385         wmHints->flags = IconPixmapHint;
386 
387         if (icon.GetMask())
388         {
389             wmHints->flags |= IconMaskHint;
390             wmHints->icon_mask = (Pixmap) icon.GetMask()->GetBitmap();
391         }
392 
393         XSetWMHints(wxGlobalDisplay(), (Window) X11GetMainWindow(), wmHints);
394         XFree(wmHints);
395 #endif
396     }
397 }
398 
SetIcons(const wxIconBundle & icons)399 void wxTopLevelWindowX11::SetIcons(const wxIconBundle& icons )
400 {
401     // this sets m_icon
402     wxTopLevelWindowBase::SetIcons( icons );
403 
404     DoSetIcon( icons.GetIcon( -1 ) );
405     wxSetIconsX11( wxGlobalDisplay(), X11GetMainWindow(), icons );
406 }
407 
SetShape(const wxRegion & region)408 bool wxTopLevelWindowX11::SetShape(const wxRegion& region)
409 {
410     return wxDoSetShape( wxGlobalDisplay(),
411                          (Window)X11GetMainWindow(),
412                          region );
413 }
414 
SetTitle(const wxString & title)415 void wxTopLevelWindowX11::SetTitle(const wxString& title)
416 {
417     m_title = title;
418 
419     if (X11GetMainWindow())
420     {
421 #if wxUSE_UNICODE
422         //  I wonder of e.g. Metacity takes UTF-8 here
423         XStoreName(wxGlobalDisplay(), (Window) X11GetMainWindow(),
424             (const char*) title.ToAscii() );
425         XSetIconName(wxGlobalDisplay(), (Window) X11GetMainWindow(),
426             (const char*) title.ToAscii() );
427 #else
428         XStoreName(wxGlobalDisplay(), (Window) X11GetMainWindow(),
429             (const char*) title);
430         XSetIconName(wxGlobalDisplay(), (Window) X11GetMainWindow(),
431             (const char*) title);
432 #endif
433     }
434 }
435 
GetTitle() const436 wxString wxTopLevelWindowX11::GetTitle() const
437 {
438     return m_title;
439 }
440 
441 // For implementation purposes - sometimes decorations make the client area
442 // smaller
GetClientAreaOrigin() const443 wxPoint wxTopLevelWindowX11::GetClientAreaOrigin() const
444 {
445     // wxFrame::GetClientAreaOrigin
446     // does the required calculation already.
447     return wxPoint(0, 0);
448 }
449 
DoGetClientSize(int * width,int * height) const450 void wxTopLevelWindowX11::DoGetClientSize( int *width, int *height ) const
451 {
452     if (width)
453        *width = m_width;
454     if (height)
455        *height = m_height;
456 }
457 
DoGetSize(int * width,int * height) const458 void wxTopLevelWindowX11::DoGetSize( int *width, int *height ) const
459 {
460     // TODO add non-client size
461 
462     if (width)
463        *width = m_width;
464     if (height)
465        *height = m_height;
466 }
467 
DoSetClientSize(int width,int height)468 void wxTopLevelWindowX11::DoSetClientSize(int width, int height)
469 {
470     int old_width = m_width;
471     int old_height = m_height;
472 
473     m_width = width;
474     m_height = height;
475 
476     if (m_width == old_width && m_height == old_height)
477         return;
478 
479     // wxLogDebug("DoSetClientSize: %s (%ld) %dx%d", GetClassInfo()->GetClassName(), GetId(), width, height);
480 
481 #if !wxUSE_NANOX
482     XSizeHints size_hints;
483     size_hints.flags = PSize;
484     size_hints.width = width;
485     size_hints.height = height;
486     XSetWMNormalHints( wxGlobalDisplay(), (Window) X11GetMainWindow(), &size_hints );
487 #endif
488 
489     wxWindowX11::DoSetClientSize(width, height);
490 }
491 
DoSetSize(int x,int y,int width,int height,int sizeFlags)492 void wxTopLevelWindowX11::DoSetSize(int x, int y, int width, int height, int sizeFlags)
493 {
494     int old_x = m_x;
495     int old_y = m_y;
496     int old_width = m_width;
497     int old_height = m_height;
498 
499     if (x != wxDefaultCoord || (sizeFlags & wxSIZE_ALLOW_MINUS_ONE))
500         m_x = x;
501 
502     if (y != wxDefaultCoord || (sizeFlags & wxSIZE_ALLOW_MINUS_ONE))
503         m_y = y;
504 
505     if (width != wxDefaultCoord || (sizeFlags & wxSIZE_ALLOW_MINUS_ONE))
506         m_width = width;
507 
508     if (height != wxDefaultCoord || (sizeFlags & wxSIZE_ALLOW_MINUS_ONE))
509         m_height = height;
510 
511     if (m_x == old_x && m_y == old_y && m_width == old_width && m_height == old_height)
512         return;
513 
514     // wxLogDebug("DoSetSize: %s (%ld) %d, %d %dx%d", GetClassInfo()->GetClassName(), GetId(), x, y, width, height);
515 
516 #if !wxUSE_NANOX
517     XSizeHints size_hints;
518     size_hints.flags = 0;
519     size_hints.flags |= PPosition;
520     size_hints.flags |= PSize;
521     size_hints.x = m_x;
522     size_hints.y = m_y;
523     size_hints.width = m_width;
524     size_hints.height = m_height;
525     XSetWMNormalHints( wxGlobalDisplay(), (Window) X11GetMainWindow(), &size_hints);
526 #endif
527 
528     wxWindowX11::DoSetSize(x, y, width, height, sizeFlags);
529 
530 #if 0
531     Display *display = wxGlobalDisplay();
532     Window root = RootWindowOfScreen(DefaultScreenOfDisplay(display));
533     Window parent_window = window,
534         next_parent   = window;
535 
536     // search for the parent that is child of ROOT, because the WM may
537     // reparent twice and notify only the next parent (like FVWM)
538     while (next_parent != root) {
539         Window *theChildren;
540 #if wxUSE_NANOX
541         GR_COUNT n;
542 #else
543         unsigned int n;
544 #endif
545         parent_window = next_parent;
546         XQueryTree(display, parent_window, &root,
547             &next_parent, &theChildren, &n);
548         XFree(theChildren); // not needed
549     }
550 
551     XWindowChanges windowChanges;
552     windowChanges.x = x;
553     windowChanges.y = y;
554     windowChanges.width = width;
555     windowChanges.height = height;
556     windowChanges.stack_mode = 0;
557     int valueMask = CWX | CWY | CWWidth | CWHeight;
558 
559     if (x != wxDefaultCoord || (sizeFlags & wxSIZE_ALLOW_MINUS_ONE))
560     {
561         valueMask |= CWX;
562     }
563     if (y != wxDefaultCoord || (sizeFlags & wxSIZE_ALLOW_MINUS_ONE))
564     {
565         valueMask |= CWY;
566     }
567     if (width != wxDefaultCoord)
568     {
569         windowChanges.width = wxMax(1, width);
570         valueMask |= CWWidth;
571     }
572     if (height != wxDefaultCoord)
573     {
574         windowChanges.height = wxMax(1, height);
575         valueMask |= CWHeight;
576     }
577 
578     XConfigureWindow( display, parent_window, valueMask, &windowChanges );
579 #endif
580 }
581 
DoGetPosition(int * x,int * y) const582 void wxTopLevelWindowX11::DoGetPosition(int *x, int *y) const
583 {
584     XSync(wxGlobalDisplay(), False);
585     Window window = (Window) m_mainWindow;
586     if (!window)
587         return ;
588 
589     Display *display = wxGlobalDisplay();
590     Window root = RootWindowOfScreen(DefaultScreenOfDisplay(display));
591     Window parent_window = window,
592         next_parent   = window;
593 
594     // search for the parent that is child of ROOT, because the WM may
595     // reparent twice and notify only the next parent (like FVWM)
596     while (next_parent != root) {
597         Window *theChildren;
598 #if wxUSE_NANOX
599         GR_COUNT n;
600 #else
601         unsigned int n;
602 #endif
603         parent_window = next_parent;
604         XQueryTree(display, parent_window, &root,
605             &next_parent, &theChildren, &n);
606         XFree(theChildren); // not needed
607     }
608 #if 0
609     int xx, yy; unsigned int dummy;
610     XGetGeometry(display, parent_window, &root,
611                  &xx, &yy, &dummy, &dummy, &dummy, &dummy);
612     if (x) *x = xx;
613     if (y) *y = yy;
614 #else
615     XWindowAttributes attr;
616     Status status = XGetWindowAttributes( wxGlobalDisplay(), parent_window, & attr);
617     if (status)
618     {
619         if (x) *x = attr.x;
620         if (y) *y = attr.y;
621     }
622     else
623     {
624         if (x) *x = 0;
625         if (y) *y = 0;
626     }
627 #endif
628 }
629 
630 
631 #ifndef MWM_DECOR_BORDER
632 
633 #define MWM_HINTS_FUNCTIONS     (1L << 0)
634 #define MWM_HINTS_DECORATIONS   (1L << 1)
635 #define MWM_HINTS_INPUT_MODE    (1L << 2)
636 #define MWM_HINTS_STATUS        (1L << 3)
637 
638 #define MWM_DECOR_ALL           (1L << 0)
639 #define MWM_DECOR_BORDER        (1L << 1)
640 #define MWM_DECOR_RESIZEH       (1L << 2)
641 #define MWM_DECOR_TITLE         (1L << 3)
642 #define MWM_DECOR_MENU          (1L << 4)
643 #define MWM_DECOR_MINIMIZE      (1L << 5)
644 #define MWM_DECOR_MAXIMIZE      (1L << 6)
645 
646 #define MWM_FUNC_ALL            (1L << 0)
647 #define MWM_FUNC_RESIZE         (1L << 1)
648 #define MWM_FUNC_MOVE           (1L << 2)
649 #define MWM_FUNC_MINIMIZE       (1L << 3)
650 #define MWM_FUNC_MAXIMIZE       (1L << 4)
651 #define MWM_FUNC_CLOSE          (1L << 5)
652 
653 #define MWM_INPUT_MODELESS 0
654 #define MWM_INPUT_PRIMARY_APPLICATION_MODAL 1
655 #define MWM_INPUT_SYSTEM_MODAL 2
656 #define MWM_INPUT_FULL_APPLICATION_MODAL 3
657 #define MWM_INPUT_APPLICATION_MODAL MWM_INPUT_PRIMARY_APPLICATION_MODAL
658 
659 #define MWM_TEAROFF_WINDOW (1L<<0)
660 
661 #endif
662 
663 struct MwmHints {
664     long flags;
665     long functions;
666     long decorations;
667     long input_mode;
668 };
669 
670 #define PROP_MOTIF_WM_HINTS_ELEMENTS 5
671 
672 // Set the window manager decorations according to the
673 // given wxWidgets style
wxSetWMDecorations(Window w,long style)674 bool wxSetWMDecorations(Window w, long style)
675 {
676 #if wxUSE_NANOX
677     GR_WM_PROPERTIES wmProp;
678 
679     wmProp.flags = 0;
680     wmProp.props = 0;
681 
682     if (style & wxRESIZE_BORDER)
683     {
684         wmProp.props |= GR_WM_PROPS_APPFRAME ;
685         wmProp.flags |= GR_WM_FLAGS_PROPS ;
686     }
687 
688     if (style & wxCLOSE_BOX)
689     {
690         wmProp.props |= GR_WM_PROPS_CLOSEBOX ;
691         wmProp.flags |= GR_WM_FLAGS_PROPS ;
692     }
693 
694     if ((style & wxCAPTION) ||
695         (style & wxTINY_CAPTION))
696     {
697         wmProp.props |= GR_WM_PROPS_CAPTION ;
698         wmProp.flags |= GR_WM_FLAGS_PROPS ;
699 
700         // The default dialog style doesn't include any kind
701         // of border, which is a bit odd. Anyway, inclusion
702         // of a caption surely implies a border.
703         style |= wxRESIZE_BORDER;
704     }
705 
706     if (style & wxRESIZE_BORDER)
707     {
708         wmProp.props |= GR_WM_PROPS_APPFRAME ;
709         wmProp.flags |= GR_WM_FLAGS_PROPS ;
710     }
711 
712     if (style & wxSIMPLE_BORDER)
713     {
714         wmProp.props |= GR_WM_PROPS_BORDER ;
715         wmProp.flags |= GR_WM_FLAGS_PROPS ;
716     }
717 
718     if (style & wxMINIMIZE_BOX)
719     {
720     }
721 
722     if (style & wxMAXIMIZE_BOX)
723     {
724         wmProp.props |= GR_WM_PROPS_MAXIMIZE ;
725         wmProp.flags |= GR_WM_FLAGS_PROPS ;
726     }
727 
728     if ( !(style & wxBORDER) && !(style & wxRESIZE_BORDER) )
729     {
730         wmProp.props |= GR_WM_PROPS_NODECORATE ;
731         wmProp.flags |= GR_WM_FLAGS_PROPS ;
732     }
733 
734     GrSetWMProperties(w, & wmProp);
735 
736 #else
737 
738     Atom mwm_wm_hints = XInternAtom(wxGlobalDisplay(),"_MOTIF_WM_HINTS", False);
739     if (mwm_wm_hints == 0)
740        return false;
741 
742     MwmHints hints;
743     hints.flags = MWM_HINTS_DECORATIONS | MWM_HINTS_FUNCTIONS;
744     hints.decorations = 0;
745     hints.functions = 0;
746 
747     if ((style & wxSIMPLE_BORDER) || (style & wxNO_BORDER))
748     {
749         // leave zeros
750     }
751     else
752     {
753         hints.decorations = MWM_DECOR_BORDER;
754         hints.functions = MWM_FUNC_MOVE;
755 
756         if ((style & wxCAPTION) != 0)
757             hints.decorations |= MWM_DECOR_TITLE;
758 
759         if ((style & wxSYSTEM_MENU) != 0)
760             hints.decorations |= MWM_DECOR_MENU;
761 
762         if ((style & wxCLOSE_BOX) != 0)
763             hints.functions |= MWM_FUNC_CLOSE;
764 
765         if ((style & wxMINIMIZE_BOX) != 0)
766         {
767             hints.functions |= MWM_FUNC_MINIMIZE;
768             hints.decorations |= MWM_DECOR_MINIMIZE;
769         }
770 
771         if ((style & wxMAXIMIZE_BOX) != 0)
772         {
773             hints.functions |= MWM_FUNC_MAXIMIZE;
774             hints.decorations |= MWM_DECOR_MAXIMIZE;
775         }
776 
777         if ((style & wxRESIZE_BORDER) != 0)
778         {
779             hints.functions |= MWM_FUNC_RESIZE;
780             hints.decorations |= MWM_DECOR_RESIZEH;
781         }
782     }
783 
784     XChangeProperty(wxGlobalDisplay(),
785                     w,
786                     mwm_wm_hints, mwm_wm_hints,
787                     32, PropModeReplace,
788                     (unsigned char *) &hints, PROP_MOTIF_WM_HINTS_ELEMENTS);
789 
790 #endif
791     return true;
792 }
793