]> git.saurik.com Git - wxWidgets.git/blobdiff - src/x11/toplevel.cpp
fixes to static box borders calculations and significant code cleanup (finalizes...
[wxWidgets.git] / src / x11 / toplevel.cpp
index 14b660afe3491e0795b550137c7ed5e4f7758f6e..7ac9f6937245fd418ed4798859de22e958e44fd1 100644 (file)
@@ -1,13 +1,13 @@
-/////////////////////////////////////////////////////////////////////////////
-// Name:        motif/frame.cpp
-// Purpose:     wxFrame
+///////////////////////////////////////////////////////////////////////////////
+// Name:        x11/toplevel.cpp
+// Purpose:     implements wxTopLevelWindow for X11
 // Author:      Julian Smart
 // Modified by:
-// Created:     17/09/98
+// Created:     24.09.01
 // RCS-ID:      $Id$
-// Copyright:   (c) Julian Smart
-// Licence:     wxWindows licence
-/////////////////////////////////////////////////////////////////////////////
+// Copyright:   (c) 2002 Julian Smart
+// License:     wxWindows licence
+///////////////////////////////////////////////////////////////////////////////
 
 // ============================================================================
 // declarations
 // headers
 // ----------------------------------------------------------------------------
 
-#ifdef __GNUG__
-    #pragma implementation "frame.h"
+#if defined(__GNUG__) && !defined(NO_GCC_PRAGMA)
+    #pragma implementation "toplevel.h"
 #endif
 
+// For compilers that support precompilation, includes "wx.h".
+#include "wx/wxprec.h"
 
-#ifdef __VMS
-#define XtDisplay XTDISPLAY
-#define XtWindow XTWINDOW
-#define XtScreen XTSCREEN
+#ifdef __BORLANDC__
+    #pragma hdrstop
 #endif
 
-# include "wx/frame.h"
-#include "wx/statusbr.h"
-#include "wx/toolbar.h"
-#include "wx/menuitem.h"
-#include "wx/menu.h"
-#include "wx/dcclient.h"
-#include "wx/dialog.h"
-#include "wx/settings.h"
-#include "wx/app.h"
-#include "wx/utils.h"
-#include "wx/log.h"
-
-#ifdef __VMS__
-    #pragma message disable nosimpint
-#endif
-
-#if defined(__ultrix) || defined(__sgi)
-    #include <Xm/Frame.h>
-#endif
-
-#include <Xm/Xm.h>
-#include <X11/Shell.h>
-#if XmVersion >= 1002
-    #include <Xm/XmAll.h>
-#else
-    #include <Xm/Frame.h>
-#endif
-#include <Xm/MwmUtil.h>
-#include <Xm/BulletinB.h>
-#include <Xm/Form.h>
-#include <Xm/MainW.h>
-#include <Xm/RowColumn.h>
-#include <Xm/Label.h>
-#include <Xm/AtomMgr.h>
-#include <Xm/LabelG.h>
-#include <Xm/Frame.h>
-#if   XmVersion > 1000
-    #include <Xm/Protocols.h>
-#endif
+#ifndef WX_PRECOMP
+    #include "wx/app.h"
+    #include "wx/toplevel.h"
+    #include "wx/string.h"
+    #include "wx/log.h"
+    #include "wx/intl.h"
+    #include "wx/frame.h"
+    #include "wx/menu.h"
+    #include "wx/statusbr.h"
+#endif //WX_PRECOMP
 
-#ifdef __VMS__
-    #pragma message enable nosimpint
-#endif
-
-#include "wx/motif/private.h"
-
-// ----------------------------------------------------------------------------
-// private functions
-// ----------------------------------------------------------------------------
-
-static void wxFrameEventHandler(Widget    wid,
-                             XtPointer WXUNUSED(client_data),
-                             XEvent*   event,
-                             Boolean*  continueToDispatch);
-static void wxCloseFrameCallback(Widget, XtPointer, XmAnyCallbackStruct *cbs);
-static void wxFrameFocusProc(Widget workArea, XtPointer clientData,
-                            XmAnyCallbackStruct *cbs);
-static void wxFrameMapProc(Widget frameShell, XtPointer clientData,
-                           XCrossingEvent * event);
-
-// ----------------------------------------------------------------------------
-// globals
-// ----------------------------------------------------------------------------
+#include "wx/settings.h"
+#include "wx/x11/private.h"
+#include "X11/Xutil.h"
 
-extern wxList wxModelessWindows;
-extern wxList wxPendingDelete;
+#include "wx/unix/utilsx11.h"
 
-// TODO: this should be tidied so that any frame can be the
-// top frame
-static bool wxTopLevelUsed = FALSE;
+bool wxMWMIsRunning(Window w);
 
 // ----------------------------------------------------------------------------
-// wxWin macros
+// wxTopLevelWindowX11 creation
 // ----------------------------------------------------------------------------
 
-BEGIN_EVENT_TABLE(wxFrame, wxFrameBase)
-    EVT_ACTIVATE(wxFrame::OnActivate)
-    EVT_SYS_COLOUR_CHANGED(wxFrame::OnSysColourChanged)
-END_EVENT_TABLE()
-
-IMPLEMENT_DYNAMIC_CLASS(wxFrame, wxWindow)
-
-// ============================================================================
-// implementation
-// ============================================================================
+void wxTopLevelWindowX11::Init()
+{
+    m_iconized =
+    m_maximizeOnShow = FALSE;
 
-// ----------------------------------------------------------------------------
-// frame construction
-// ----------------------------------------------------------------------------
+    // unlike (almost?) all other windows, frames are created hidden
+    m_isShown = FALSE;
 
-void wxFrame::Init()
-{
-    m_iconized = FALSE;
-
-    //// Motif-specific
-    m_frameShell = (WXWidget) NULL;
-    m_frameWidget = (WXWidget) NULL;;
-    m_workArea = (WXWidget) NULL;;
-    m_clientArea = (WXWidget) NULL;;
-    m_visibleStatus = TRUE;
+    // Data to save/restore when calling ShowFullScreen
+    m_fsStyle = 0;
+    m_fsIsMaximized = FALSE;
+    m_fsIsShowing = FALSE;
+    
+    m_needResizeInIdle = FALSE;
+    
+    m_x = -1;
+    m_y = -1;
+    m_width = 20;
+    m_height = 20;
 }
 
-bool wxFrame::Create(wxWindow *parent,
-                     wxWindowID id,
-                     const wxString& title,
-                     const wxPoint& pos,
-                     const wxSize& size,
-                     long style,
-                     const wxString& name)
+bool wxTopLevelWindowX11::Create(wxWindow *parent,
+                                 wxWindowID id,
+                                 const wxString& title,
+                                 const wxPoint& pos,
+                                 const wxSize& size,
+                                 long style,
+                                 const wxString& name)
 {
-    if ( parent )
-        parent->AddChild(this);
-    else
-        wxTopLevelWindows.Append(this);
+    // init our fields
+    Init();
 
-    wxModelessWindows.Append(this);
+    m_windowStyle = style;
+    m_parent = parent;
 
     SetName(name);
 
-    m_windowStyle = style;
+    m_windowId = id == -1 ? NewControlId() : id;
 
-    m_backgroundColour = wxSystemSettings::GetColour(wxSYS_COLOUR_APPWORKSPACE);
-    m_foregroundColour = *wxBLACK;
-    m_font = wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT);
+    if (parent)
+        parent->AddChild(this);
 
-    if ( id > -1 )
-        m_windowId = id;
+    wxTopLevelWindows.Append(this);
+    
+    Display *xdisplay = wxGlobalDisplay();
+    int xscreen = DefaultScreen( xdisplay );
+    Visual *xvisual = DefaultVisual( xdisplay, xscreen );
+    Window xparent = RootWindow( xdisplay, xscreen );
+    Colormap cm = DefaultColormap( xdisplay, xscreen );
+    
+    if (GetExtraStyle() & wxTOPLEVEL_EX_DIALOG)
+        m_backgroundColour = wxSystemSettings::GetColour(wxSYS_COLOUR_BTNFACE);
     else
-        m_windowId = (int)NewControlId();
-
-    int x = pos.x, y = pos.y;
-    int width = size.x, height = size.y;
-
-    // Set reasonable values for position and size if defaults have been
-    // requested
-    //
-    // MB TODO: something better than these arbitrary values ?
-    // VZ       should use X resources for this...
-    if ( width == -1 )
-        width = 400;
-    if ( height == -1 )
-        height = 400;
-
-    int displayW, displayH;
-    wxDisplaySize( &displayW, &displayH );
-
-    if ( x == -1 )
-    {
-        x = (displayW - width) / 2;
-        if (x < 10) x = 10;
-    }
-    if ( y == -1 )
+        m_backgroundColour = wxSystemSettings::GetColour(wxSYS_COLOUR_APPWORKSPACE);
+    m_backgroundColour.CalcPixel( (WXColormap) cm );
+    m_hasBgCol = TRUE;
+       
+    m_x = pos.x;
+    if (m_x < -1)
+        m_x = 10;
+        
+    m_y = pos.y;
+    if (m_y < 0)
+        m_y = 10;
+        
+    m_width = size.x;
+    if (m_width < 0)
+        m_width = 500;
+        
+    m_height = size.y;
+    if (m_height < 0)
+        m_height = 380;
+    
+#if !wxUSE_NANOX
+    XSetWindowAttributes xattributes;
+    
+    long xattributes_mask =
+        CWBorderPixel | CWBackPixel;
+
+    xattributes.background_pixel = m_backgroundColour.GetPixel();
+    xattributes.border_pixel = BlackPixel( xdisplay, xscreen );
+
+    if (HasFlag( wxNO_BORDER ))
     {
-        y = (displayH - height) / 2;
-        if (y < 10) y = 10;
+        xattributes_mask |= CWOverrideRedirect;
+        xattributes.override_redirect = True;
     }
-
-    // VZ: what does this do??
-    if (wxTopLevelUsed)
-    {
-        // Change suggested by Matthew Flatt
-        m_frameShell = (WXWidget)XtAppCreateShell
-                                 (
-                                  name,
-                                  wxTheApp->GetClassName(),
-                                  topLevelShellWidgetClass,
-                                  (Display*) wxGetDisplay(),
-                                  NULL,
-                                  0
-                                 );
-    }
-    else
-    {
-        m_frameShell = wxTheApp->GetTopLevelWidget();
-        wxTopLevelUsed = TRUE;
-    }
-
-    XtVaSetValues((Widget) m_frameShell,
-        // Allows menu to resize
-        XmNallowShellResize, True,
-        XmNdeleteResponse, XmDO_NOTHING,
-        XmNmappedWhenManaged, False,
-        XmNiconic, (style & wxICONIZE) ? TRUE : FALSE,
-        NULL);
-
-    if (!title.IsEmpty())
-        XtVaSetValues((Widget) m_frameShell,
-        XmNtitle, title.c_str(),
-        NULL);
-
-    m_frameWidget = (WXWidget) XtVaCreateManagedWidget("main_window",
-        xmMainWindowWidgetClass, (Widget) m_frameShell,
-        XmNresizePolicy, XmRESIZE_NONE,
-        NULL);
-
-    m_workArea = (WXWidget) XtVaCreateWidget("form",
-        xmFormWidgetClass, (Widget) m_frameWidget,
-        XmNresizePolicy, XmRESIZE_NONE,
-        NULL);
-
-    m_clientArea = (WXWidget) XtVaCreateWidget("client",
-        xmBulletinBoardWidgetClass, (Widget) m_workArea,
-        XmNmarginWidth, 0,
-        XmNmarginHeight, 0,
-        XmNrightAttachment, XmATTACH_FORM,
-        XmNleftAttachment, XmATTACH_FORM,
-        XmNtopAttachment, XmATTACH_FORM,
-        XmNbottomAttachment, XmATTACH_FORM,
-        //                    XmNresizePolicy, XmRESIZE_ANY,
-        NULL);
-
-    wxLogTrace(wxTRACE_Messages,
-               "Created frame (0x%08x) with work area 0x%08x and client "
-               "area 0x%08x", m_frameWidget, m_workArea, m_clientArea);
-
-    XtAddEventHandler((Widget) m_clientArea, ExposureMask,FALSE,
-        wxUniversalRepaintProc, (XtPointer) this);
-
-    XtAddEventHandler((Widget) m_clientArea,
-        ButtonPressMask | ButtonReleaseMask | PointerMotionMask | KeyPressMask,
-        FALSE,
-        wxFrameEventHandler,
-        (XtPointer)this);
-
-    XtVaSetValues((Widget) m_frameWidget,
-        XmNworkWindow, (Widget) m_workArea,
-        NULL);
-
-    XtManageChild((Widget) m_clientArea);
-    XtManageChild((Widget) m_workArea);
-
-    wxAddWindowToTable((Widget) m_workArea, this);
-    wxAddWindowToTable((Widget) m_clientArea, this);
-
-    XtTranslations ptr;
-
-    XtOverrideTranslations((Widget) m_workArea,
-        ptr = XtParseTranslationTable("<Configure>: resize()"));
-
-    XtFree((char *)ptr);
-
-    XtAddCallback((Widget) m_workArea, XmNfocusCallback,
-        (XtCallbackProc)wxFrameFocusProc, (XtPointer)this);
-
-    /* Part of show-&-hide fix */
-    XtAddEventHandler((Widget) m_frameShell, StructureNotifyMask,
-        False, (XtEventHandler)wxFrameMapProc,
-        (XtPointer)m_workArea);
-
-    if (x > -1)
-        XtVaSetValues((Widget) m_frameShell, XmNx, x, NULL);
-    if (y > -1)
-        XtVaSetValues((Widget) m_frameShell, XmNy, y, NULL);
-    if (width > -1)
-        XtVaSetValues((Widget) m_frameShell, XmNwidth, width, NULL);
-    if (height > -1)
-        XtVaSetValues((Widget) m_frameShell, XmNheight, height, NULL);
-
-    m_mainWidget = m_frameWidget;
-
-    ChangeFont(FALSE);
-
-    // This patch comes from Torsten Liermann lier@lier1.muc.de
-    if (XmIsMotifWMRunning( (Widget) m_frameShell ))
-    {
-        int decor = 0;
-        if (style & wxRESIZE_BORDER)
-            decor |= MWM_DECOR_RESIZEH;
-        if (style & wxSYSTEM_MENU)
-            decor |= MWM_DECOR_MENU;
-        if ((style & wxCAPTION) ||
-            (style & wxTINY_CAPTION_HORIZ) ||
-            (style & wxTINY_CAPTION_VERT))
-            decor |= MWM_DECOR_TITLE;
-        if (style & wxTHICK_FRAME)
-            decor |= MWM_DECOR_BORDER;
-        if (style & wxTHICK_FRAME)
-            decor |= MWM_DECOR_BORDER;
-        if (style & wxMINIMIZE_BOX)
-            decor |= MWM_DECOR_MINIMIZE;
-        if (style & wxMAXIMIZE_BOX)
-            decor |= MWM_DECOR_MAXIMIZE;
-        XtVaSetValues((Widget) m_frameShell,XmNmwmDecorations,decor,NULL);
-    }
-    // This allows non-Motif window managers to support at least the
-    // no-decorations case.
-    else
+    
+    if (!HasFlag( wxFULL_REPAINT_ON_RESIZE ))
     {
-        if (style == 0)
-            XtVaSetValues((Widget) m_frameShell,XmNoverrideRedirect,TRUE,NULL);
+        xattributes_mask |= CWBitGravity;
+        xattributes.bit_gravity = NorthWestGravity;
     }
-    XtRealizeWidget((Widget) m_frameShell);
-
-    // Intercept CLOSE messages from the window manager
-    Atom WM_DELETE_WINDOW = XmInternAtom(XtDisplay((Widget) m_frameShell), "WM_DELETE_WINDOW", False);
-#if (XmREVISION > 1 || XmVERSION > 1)
-    XmAddWMProtocolCallback((Widget) m_frameShell, WM_DELETE_WINDOW, (XtCallbackProc) wxCloseFrameCallback, (XtPointer)this);
-#else
-#if XmREVISION == 1
-    XmAddWMProtocolCallback((Widget) m_frameShell, WM_DELETE_WINDOW, (XtCallbackProc) wxCloseFrameCallback, (caddr_t)this);
+    
+    xattributes_mask |= CWEventMask;
+    xattributes.event_mask = 
+        ExposureMask | KeyPressMask | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask |
+        ButtonMotionMask | EnterWindowMask | LeaveWindowMask | PointerMotionMask |
+        KeymapStateMask | FocusChangeMask | ColormapChangeMask | StructureNotifyMask |
+        PropertyChangeMask;
+        
+    Window xwindow = XCreateWindow( xdisplay, xparent, m_x, m_y, m_width, m_height,
+                                    0, DefaultDepth(xdisplay,xscreen), InputOutput, xvisual, xattributes_mask, &xattributes );
 #else
-    XmAddWMProtocolCallback((Widget) m_frameShell, WM_DELETE_WINDOW, (void (*)())wxCloseFrameCallback, (caddr_t)this);
+    long backColor, foreColor;
+    backColor = GR_RGB(m_backgroundColour.Red(), m_backgroundColour.Green(), m_backgroundColour.Blue());
+    foreColor = GR_RGB(m_foregroundColour.Red(), m_foregroundColour.Green(), m_foregroundColour.Blue());
+    
+    Window xwindow = XCreateWindowWithColor( xdisplay, xparent, m_x, m_y, m_width, m_height,
+                                    0, 0, InputOutput, xvisual, backColor, foreColor);
 #endif
-#endif
-
-    ChangeBackgroundColour();
 
-    PreResize();
-
-    wxSizeEvent sizeEvent(wxSize(width, height), GetId());
-    sizeEvent.SetEventObject(this);
-
-    GetEventHandler()->ProcessEvent(sizeEvent);
-
-    return TRUE;
-}
-
-wxFrame::~wxFrame()
-{
-    m_isBeingDeleted = TRUE;
-
-    if (m_clientArea)
-    {
-      XtRemoveEventHandler((Widget) m_clientArea, ExposureMask, FALSE,
-          wxUniversalRepaintProc, (XtPointer) this);
-      XtRemoveEventHandler((Widget) m_clientArea, ButtonPressMask | ButtonReleaseMask | PointerMotionMask | KeyPressMask,
-          FALSE,
-          wxFrameEventHandler, (XtPointer) this);
-      wxDeleteWindowFromTable((Widget) m_clientArea);
-    }
-
-    if (GetMainWidget())
-        Show(FALSE);
-
-    if (m_frameMenuBar)
-    {
-        m_frameMenuBar->DestroyMenuBar();
-
-        // Hack to stop core dump on Ultrix, OSF, for some strange reason.
-#if MOTIF_MENUBAR_DELETE_FIX
-        GetMenuBar()->SetMainWidget((WXWidget) NULL);
+    m_mainWindow = (WXWindow) xwindow;
+    m_clientWindow = (WXWindow) xwindow;
+    wxAddWindowToTable( xwindow, (wxWindow*) this );
+
+#if wxUSE_NANOX
+    XSelectInput( xdisplay, xwindow,
+                  GR_EVENT_MASK_CLOSE_REQ |
+                  ExposureMask |
+                  KeyPressMask |
+                  KeyReleaseMask |
+                  ButtonPressMask |
+                  ButtonReleaseMask |
+                  ButtonMotionMask |
+                  EnterWindowMask |
+                  LeaveWindowMask |
+                  PointerMotionMask |
+                  KeymapStateMask |
+                  FocusChangeMask |
+                  ColormapChangeMask |
+                  StructureNotifyMask |
+                  PropertyChangeMask
+                  );
 #endif
-        delete m_frameMenuBar;
-        m_frameMenuBar = NULL;
-    }
 
-    wxTopLevelWindows.DeleteObject(this);
-    wxModelessWindows.DeleteObject(this);
+    // Set background to None which will prevent X11 from clearing the
+    // background completely.
+    XSetWindowBackgroundPixmap( xdisplay, xwindow, None );
 
-    if (m_frameStatusBar)
+#if !wxUSE_NANOX
+    if (HasFlag( wxSTAY_ON_TOP ))
     {
-        delete m_frameStatusBar;
-        m_frameStatusBar = NULL;
+        Window xroot = RootWindow( xdisplay, xscreen );
+        XSetTransientForHint( xdisplay, xwindow, xroot );
     }
-
-    DestroyChildren();
-
-    if (m_workArea)
+    else
     {
-        wxDeleteWindowFromTable((Widget) m_workArea);
-
-        XtDestroyWidget ((Widget) m_workArea);
+       if (GetExtraStyle() & wxTOPLEVEL_EX_DIALOG)
+       {
+            if (GetParent() && GetParent()->GetMainWindow())
+            {
+                Window xparentwindow = (Window) GetParent()->GetMainWindow();
+                XSetTransientForHint( xdisplay, xwindow, xparentwindow );
+            }
+        }
     }
 
-    if (m_frameWidget)
-    {
-        wxDeleteWindowFromTable((Widget) m_frameWidget);
-        XtDestroyWidget ((Widget) m_frameWidget);
+    XSizeHints size_hints;
+    size_hints.flags = PSize | PPosition | PWinGravity;
+    size_hints.x = m_x;
+    size_hints.y = m_y;
+    size_hints.width = m_width;
+    size_hints.height = m_height;
+    size_hints.win_gravity = NorthWestGravity;
+    XSetWMNormalHints( xdisplay, xwindow, &size_hints);
+    
+    XWMHints wm_hints;
+    wm_hints.flags = InputHint | StateHint;
+    if (GetParent())
+    {  
+        wm_hints.flags |= WindowGroupHint;
+        wm_hints.window_group = (Window) GetParent()->GetMainWindow();
     }
+    wm_hints.input = True;
+    wm_hints.initial_state = NormalState;
+    XSetWMHints( xdisplay, xwindow, &wm_hints);
 
-    if (m_frameShell)
-        XtDestroyWidget ((Widget) m_frameShell);
+    Atom wm_protocols[2];
+    wm_protocols[0] = XInternAtom( xdisplay, "WM_DELETE_WINDOW", False );
+    wm_protocols[1] = XInternAtom( xdisplay, "WM_TAKE_FOCUS", False );
+    XSetWMProtocols( xdisplay, xwindow, wm_protocols, 2);
 
-    SetMainWidget((WXWidget) NULL);
+#endif
+    
+    wxSetWMDecorations( xwindow, style);
 
-    /* Check if it's the last top-level window */
+    SetTitle(title);
+    
+    return TRUE;
+}
+
+wxTopLevelWindowX11::~wxTopLevelWindowX11()
+{
+    wxTopLevelWindows.DeleteObject(this);
 
-    if (wxTheApp && (wxTopLevelWindows.Number() == 0))
+    // If this is the last top-level window, exit.
+    if ( wxTheApp && (wxTopLevelWindows.GetCount() == 0) )
     {
         wxTheApp->SetTopWindow(NULL);
 
@@ -417,514 +260,536 @@ wxFrame::~wxFrame()
     }
 }
 
-// Get size *available for subwindows* i.e. excluding menu bar, toolbar etc.
-void wxFrame::DoGetClientSize(int *x, int *y) const
+void wxTopLevelWindowX11::OnInternalIdle()
 {
-    Dimension xx, yy;
-    XtVaGetValues((Widget) m_workArea, XmNwidth, &xx, XmNheight, &yy, NULL);
-
-    if (m_frameStatusBar)
+    wxWindow::OnInternalIdle();
+    
+    // Do this only after the last idle event so that
+    // all windows have been updated before a new
+    // round of size events is sent
+    if (m_needResizeInIdle && !wxTheApp->Pending())
     {
-        int sbw, sbh;
-        m_frameStatusBar->GetSize(& sbw, & sbh);
-        yy -= sbh;
+        wxSizeEvent event( GetClientSize(), GetId() );
+        event.SetEventObject( this );
+        GetEventHandler()->ProcessEvent( event );
+        
+        m_needResizeInIdle = FALSE;
     }
-#if wxUSE_TOOLBAR
-    if (m_frameToolBar)
-    {
-        int tbw, tbh;
-        m_frameToolBar->GetSize(& tbw, & tbh);
-        if (m_frameToolBar->GetWindowStyleFlag() & wxTB_VERTICAL)
-            xx -= tbw;
-        else
-            yy -= tbh;
-    }
-#endif // wxUSE_TOOLBAR
-    /*
-    if (GetMenuBar() != (wxMenuBar*) NULL)
-    {
-    // it seems that if a frame holds a panel, the menu bar size
-    // gets automatically taken care of --- grano@cs.helsinki.fi 4.4.95
-    bool hasSubPanel = FALSE;
-    for(wxNode* node = GetChildren().First(); node; node = node->Next())
-    {
-    wxWindow *win = (wxWindow *)node->Data();
-    hasSubPanel = (win->IsKindOf(CLASSINFO(wxPanel)) && !win->IsKindOf(CLASSINFO(wxDialog)));
-
-      if (hasSubPanel)
-      break;
-      }
-      if (! hasSubPanel) {
-      Dimension ys;
-      XtVaGetValues((Widget) GetMenuBarWidget(), XmNheight, &ys, NULL);
-      yy -= ys;
-      }
-      }
-    */
-
-    *x = xx; *y = yy;
 }
 
-// Set the client size (i.e. leave the calculation of borders etc.
-// to wxWindows)
-void wxFrame::DoSetClientSize(int width, int height)
-{
-    // Calculate how large the new main window should be
-    // by finding the difference between the client area and the
-    // main window area, and adding on to the new client area
-    if (width > -1)
-        XtVaSetValues((Widget) m_workArea, XmNwidth, width, NULL);
+// ----------------------------------------------------------------------------
+// wxTopLevelWindowX11 showing
+// ----------------------------------------------------------------------------
 
-    if (height > -1)
+bool wxTopLevelWindowX11::Show(bool show)
+{
+    if (show)
     {
-        if (m_frameStatusBar)
-        {
-            int sbw, sbh;
-            m_frameStatusBar->GetSize(& sbw, & sbh);
-            height += sbh;
-        }
-#if wxUSE_TOOLBAR
-        if (m_frameToolBar)
-        {
-            int tbw, tbh;
-            m_frameToolBar->GetSize(& tbw, & tbh);
-            if (m_frameToolBar->GetWindowStyleFlag() & wxTB_VERTICAL)
-                width += tbw;
-            else
-                height += tbh;
-        }
-#endif // wxUSE_TOOLBAR
-
-        XtVaSetValues((Widget) m_workArea, XmNheight, height, NULL);
+        wxSizeEvent event(GetSize(), GetId());
+        
+        event.SetEventObject(this);
+        GetEventHandler()->ProcessEvent(event);
+        
+        m_needResizeInIdle = FALSE;
     }
-    PreResize();
-
-    wxSizeEvent sizeEvent(wxSize(width, height), GetId());
-    sizeEvent.SetEventObject(this);
-
-    GetEventHandler()->ProcessEvent(sizeEvent);
 
+    bool ret = wxWindowX11::Show(show);
+    
+    return ret;
 }
 
-void wxFrame::DoGetSize(int *width, int *height) const
-{
-    Dimension xx, yy;
-    XtVaGetValues((Widget) m_frameShell, XmNwidth, &xx, XmNheight, &yy, NULL);
-    *width = xx; *height = yy;
-}
+// ----------------------------------------------------------------------------
+// wxTopLevelWindowX11 maximize/minimize
+// ----------------------------------------------------------------------------
 
-void wxFrame::DoGetPosition(int *x, int *y) const
+void wxTopLevelWindowX11::Maximize(bool maximize)
 {
-    Window parent_window = XtWindow((Widget) m_frameShell),
-        next_parent   = XtWindow((Widget) m_frameShell),
-        root          = RootWindowOfScreen(XtScreen((Widget) m_frameShell));
-
-    // search for the parent that is child of ROOT, because the WM may
-    // reparent twice and notify only the next parent (like FVWM)
-    while (next_parent != root) {
-        Window *theChildren; unsigned int n;
-        parent_window = next_parent;
-        XQueryTree(XtDisplay((Widget) m_frameShell), parent_window, &root,
-            &next_parent, &theChildren, &n);
-        XFree(theChildren); // not needed
-    }
-    int xx, yy; unsigned int dummy;
-    XGetGeometry(XtDisplay((Widget) m_frameShell), parent_window, &root,
-        &xx, &yy, &dummy, &dummy, &dummy, &dummy);
-    if (x) *x = xx;
-    if (y) *y = yy;
+    // TODO
 }
 
-void wxFrame::DoSetSize(int x, int y, int width, int height, int WXUNUSED(sizeFlags))
+bool wxTopLevelWindowX11::IsMaximized() const
 {
-    if (x > -1)
-        XtVaSetValues((Widget) m_frameShell, XmNx, x, NULL);
-    if (y > -1)
-        XtVaSetValues((Widget) m_frameShell, XmNy, y, NULL);
-    if (width > -1)
-        XtVaSetValues((Widget) m_frameWidget, XmNwidth, width, NULL);
-    if (height > -1)
-        XtVaSetValues((Widget) m_frameWidget, XmNheight, height, NULL);
-
-    if (!(height == -1 && width == -1))
-    {
-        PreResize();
-
-        wxSizeEvent sizeEvent(wxSize(width, height), GetId());
-        sizeEvent.SetEventObject(this);
-
-        GetEventHandler()->ProcessEvent(sizeEvent);
-    }
+    // TODO
+    return TRUE;
 }
 
-bool wxFrame::Show(bool show)
+void wxTopLevelWindowX11::Iconize(bool iconize)
 {
-    if (!m_frameShell)
-        return wxWindow::Show(show);
-
-    m_visibleStatus = show; /* show-&-hide fix */
-
-    m_isShown = show;
-    if (show) {
-        XtMapWidget((Widget) m_frameShell);
-        XRaiseWindow(XtDisplay((Widget) m_frameShell), XtWindow((Widget) m_frameShell));
-    } else {
-        XtUnmapWidget((Widget) m_frameShell);
-        //    XmUpdateDisplay(wxTheApp->topLevel); // Experimental: may be responsible for crashes
+    if (!m_iconized && GetMainWindow())
+    {
+        if (XIconifyWindow(wxGlobalDisplay(),
+            (Window) GetMainWindow(), DefaultScreen(wxGlobalDisplay())) != 0)
+            m_iconized = TRUE;
     }
-    return TRUE;
 }
 
-void wxFrame::Iconize(bool iconize)
+bool wxTopLevelWindowX11::IsIconized() const
 {
-    if (!iconize)
-        Show(TRUE);
-
-    if (m_frameShell)
-        XtVaSetValues((Widget) m_frameShell, XmNiconic, (Boolean)iconize, NULL);
+    return m_iconized;
 }
 
-void wxFrame::Restore()
+void wxTopLevelWindowX11::Restore()
 {
-    if ( m_frameShell )
-        XtVaSetValues((Widget) m_frameShell, XmNiconic, FALSE, NULL);
+    // This is the way to deiconify the window, according to the X FAQ
+    if (m_iconized && GetMainWindow())
+    {
+        XMapWindow(wxGlobalDisplay(), (Window) GetMainWindow());
+        m_iconized = FALSE;
+    }
 }
 
-void wxFrame::Maximize(bool maximize)
-{
-    Show(TRUE);
-
-    if ( maximize )
-        Restore();
-}
+// ----------------------------------------------------------------------------
+// wxTopLevelWindowX11 fullscreen
+// ----------------------------------------------------------------------------
 
-bool wxFrame::IsIconized() const
+bool wxTopLevelWindowX11::ShowFullScreen(bool show, long style)
 {
-    if (!m_frameShell)
-        return FALSE;
+    if (show)
+    {
+        if (IsFullScreen())
+            return FALSE;
 
-    Boolean iconic;
-    XtVaGetValues((Widget) m_frameShell, XmNiconic, &iconic, NULL);
-    return iconic;
-}
+        m_fsIsShowing = TRUE;
+        m_fsStyle = style;
 
-// Is it maximized?
-bool wxFrame::IsMaximized() const
-{
-    // No maximizing in Motif (?)
-    return FALSE;
-}
+        // TODO
 
-void wxFrame::SetTitle(const wxString& title)
-{
-    if (title == m_title)
-        return;
+        return TRUE;
+    }
+    else
+    {
+        if (!IsFullScreen())
+            return FALSE;
 
-    m_title = title;
+        m_fsIsShowing = FALSE;
 
-    if (!title.IsNull())
-        XtVaSetValues((Widget) m_frameShell,
-        XmNtitle, title.c_str(),
-        XmNiconName, title.c_str(),
-        NULL);
+        // TODO
+        return TRUE;
+    }
 }
 
-void wxFrame::SetIcon(const wxIcon& icon)
+// ----------------------------------------------------------------------------
+// wxTopLevelWindowX11 misc
+// ----------------------------------------------------------------------------
+
+void wxTopLevelWindowX11::DoSetIcon(const wxIcon& icon)
 {
-    m_icon = icon;
+    if (icon.Ok() && GetMainWindow())
+    {
+#if wxUSE_NANOX
+#else
+        XWMHints *wmHints = XAllocWMHints();
+        wmHints->icon_pixmap = (Pixmap) icon.GetPixmap();
 
-    if (!m_frameShell)
-        return;
+        wmHints->flags = IconPixmapHint;
 
-    if (!icon.Ok() || !icon.GetPixmap())
-        return;
+        if (icon.GetMask())
+        {
+            wmHints->flags |= IconMaskHint;
+            wmHints->icon_mask = (Pixmap) icon.GetMask()->GetBitmap();
+        }
 
-    XtVaSetValues((Widget) m_frameShell, XtNiconPixmap, icon.GetPixmap(), NULL);
+        XSetWMHints(wxGlobalDisplay(), (Window) GetMainWindow(), wmHints);
+        XFree(wmHints);
+#endif
+    }
 }
 
-void wxFrame::PositionStatusBar()
+void wxTopLevelWindowX11::SetIcons(const wxIconBundle& icons )
 {
-    if (!m_frameStatusBar)
-        return;
-
-    int w, h;
-    GetClientSize(&w, &h);
-    int sw, sh;
-    m_frameStatusBar->GetSize(&sw, &sh);
+    // this sets m_icon
+    wxTopLevelWindowBase::SetIcons( icons );
 
-    // Since we wish the status bar to be directly under the client area,
-    // we use the adjusted sizes without using wxSIZE_NO_ADJUSTMENTS.
-    m_frameStatusBar->SetSize(0, h, w, sh);
+    DoSetIcon( icons.GetIcon( -1 ) );
+    wxSetIconsX11( wxGlobalDisplay(), GetMainWindow(), icons );
 }
 
-WXWidget wxFrame::GetMenuBarWidget() const
+bool wxTopLevelWindowX11::SetShape(const wxRegion& region)
 {
-    if (GetMenuBar())
-        return GetMenuBar()->GetMainWidget();
-    else
-        return (WXWidget) NULL;
+    return wxDoSetShape( wxGlobalDisplay(),
+                         (Window)GetMainWindow(),
+                         region );
 }
 
-void wxFrame::SetMenuBar(wxMenuBar *menuBar)
+void wxTopLevelWindowX11::SetTitle(const wxString& title)
 {
-    if (!menuBar)
-    {
-        m_frameMenuBar = NULL;
-        return;
-    }
-
-    // Currently can't set it twice
-    //    wxASSERT_MSG( (m_frameMenuBar == (wxMenuBar*) NULL), "Cannot set the menubar more than once");
-
-    if (m_frameMenuBar)
+    m_title = title;
+    
+    if (GetMainWindow())
     {
-        m_frameMenuBar->DestroyMenuBar();
-        delete m_frameMenuBar;
+#if wxUSE_UNICODE
+        //  I wonder of e.g. Metacity takes UTF-8 here
+        XStoreName(wxGlobalDisplay(), (Window) GetMainWindow(),
+            (const char*) title.ToAscii() );
+        XSetIconName(wxGlobalDisplay(), (Window) GetMainWindow(),
+            (const char*) title.ToAscii() );
+#else
+        XStoreName(wxGlobalDisplay(), (Window) GetMainWindow(),
+            (const char*) title);
+        XSetIconName(wxGlobalDisplay(), (Window) GetMainWindow(),
+            (const char*) title);
+#endif
     }
-
-    m_frameMenuBar = menuBar;
-    m_frameMenuBar->CreateMenuBar(this);
 }
 
-// Responds to colour changes, and passes event on to children.
-void wxFrame::OnSysColourChanged(wxSysColourChangedEvent& event)
+wxString wxTopLevelWindowX11::GetTitle() const
 {
-    SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_APPWORKSPACE));
-    Refresh();
-
-    if ( m_frameStatusBar )
-    {
-        wxSysColourChangedEvent event2;
-        event2.SetEventObject( m_frameStatusBar );
-        m_frameStatusBar->ProcessEvent(event2);
-    }
-
-    // Propagate the event to the non-top-level children
-    wxWindow::OnSysColourChanged(event);
+    return m_title;
 }
 
-// Default activation behaviour - set the focus for the first child
-// subwindow found.
-void wxFrame::OnActivate(wxActivateEvent& event)
+// For implementation purposes - sometimes decorations make the client area
+// smaller
+wxPoint wxTopLevelWindowX11::GetClientAreaOrigin() const
 {
-    if (!event.GetActive())
-        return;
-
-    for(wxNode *node = GetChildren().First(); node; node = node->Next())
-    {
-        // Find a child that's a subwindow, but not a dialog box.
-        wxWindow *child = (wxWindow *)node->Data();
-        if (!child->IsKindOf(CLASSINFO(wxFrame)) &&
-            !child->IsKindOf(CLASSINFO(wxDialog)))
-        {
-            child->SetFocus();
-            return;
-        }
-    }
+    // wxFrame::GetClientAreaOrigin
+    // does the required calculation already.
+    return wxPoint(0, 0);
 }
 
-#if wxUSE_TOOLBAR
+void wxTopLevelWindowX11::DoGetClientSize( int *width, int *height ) const
+{
+    if (width)
+       *width = m_width;
+    if (height)
+       *height = m_height;
+}
 
-wxToolBar* wxFrame::CreateToolBar(long style,
-                                  wxWindowID id,
-                                  const wxString& name)
+void wxTopLevelWindowX11::DoGetSize( int *width, int *height ) const
 {
-    if ( wxFrameBase::CreateToolBar(style, id, name) )
-    {
-        PositionToolBar();
-    }
+    // TODO add non-client size
 
-    return m_frameToolBar;
+    if (width)
+       *width = m_width;
+    if (height)
+       *height = m_height;
 }
 
-void wxFrame::PositionToolBar()
+void wxTopLevelWindowX11::DoSetClientSize(int width, int height)
 {
-    if (GetToolBar())
-    {
-        int cw, ch;
-        GetClientSize(& cw, &ch);
+    int old_width = m_width;
+    int old_height = m_height;
 
-        int tw, th;
-        GetToolBar()->GetSize(& tw, & th);
+    m_width = width;
+    m_height = height;
+    
+    if (m_width == old_width && m_height == old_height)
+        return;
+        
+    // wxLogDebug("DoSetClientSize: %s (%ld) %dx%d", GetClassInfo()->GetClassName(), GetId(), width, height);
+    
+#if !wxUSE_NANOX
+    XSizeHints size_hints;
+    size_hints.flags = PSize;
+    size_hints.width = width;
+    size_hints.height = height;
+    XSetWMNormalHints( wxGlobalDisplay(), (Window) GetMainWindow(), &size_hints );
+#endif
+    
+    wxWindowX11::DoSetClientSize(width, height);
+}
+
+void wxTopLevelWindowX11::DoSetSize(int x, int y, int width, int height, int sizeFlags)
+{
+    int old_x = m_x;
+    int old_y = m_y;
+    int old_width = m_width;
+    int old_height = m_height;
+
+    if (x != -1 || (sizeFlags & wxSIZE_ALLOW_MINUS_ONE))
+        m_x = x;
+        
+    if (y != -1 || (sizeFlags & wxSIZE_ALLOW_MINUS_ONE))
+        m_y = y;
+        
+    if (width != -1 || (sizeFlags & wxSIZE_ALLOW_MINUS_ONE))
+        m_width = width;
+        
+    if (height != -1 || (sizeFlags & wxSIZE_ALLOW_MINUS_ONE))
+        m_height = height;
+        
+    if (m_x == old_x && m_y == old_y && m_width == old_width && m_height == old_height)
+        return;
+    
+    // wxLogDebug("DoSetSize: %s (%ld) %d, %d %dx%d", GetClassInfo()->GetClassName(), GetId(), x, y, width, height);
+
+#if !wxUSE_NANOX    
+    XSizeHints size_hints;
+    size_hints.flags = 0;
+    size_hints.flags |= PPosition;
+    size_hints.flags |= PSize;
+    size_hints.x = m_x;
+    size_hints.y = m_y;
+    size_hints.width = m_width;
+    size_hints.height = m_height;
+    XSetWMNormalHints( wxGlobalDisplay(), (Window) GetMainWindow(), &size_hints);
+#endif
 
-        if (GetToolBar()->GetWindowStyleFlag() & wxTB_VERTICAL)
-        {
-            // Use the 'real' position. wxSIZE_NO_ADJUSTMENTS
-            // means, pretend we don't have toolbar/status bar, so we
-            // have the original client size.
-            GetToolBar()->SetSize(0, 0, tw, ch + th, wxSIZE_NO_ADJUSTMENTS);
-        }
-        else
-        {
-            // Use the 'real' position
-            GetToolBar()->SetSize(0, 0, cw, th, wxSIZE_NO_ADJUSTMENTS);
-        }
-    }
-}
-#endif // wxUSE_TOOLBAR
+    wxWindowX11::DoSetSize(x, y, width, height, sizeFlags);
+    
+#if 0
+    Display *display = wxGlobalDisplay();
+    Window root = RootWindowOfScreen(DefaultScreenOfDisplay(display));
+    Window parent_window = window,
+        next_parent   = window;
 
-void wxFrame::Raise()
-{
-    Window parent_window = XtWindow((Widget) m_frameShell),
-        next_parent   = XtWindow((Widget) m_frameShell),
-        root          = RootWindowOfScreen(XtScreen((Widget) m_frameShell));
     // search for the parent that is child of ROOT, because the WM may
     // reparent twice and notify only the next parent (like FVWM)
     while (next_parent != root) {
-        Window *theChildren; unsigned int n;
+        Window *theChildren;
+#if wxUSE_NANOX
+        GR_COUNT n;
+#else
+        unsigned int n;
+#endif
         parent_window = next_parent;
-        XQueryTree(XtDisplay((Widget) m_frameShell), parent_window, &root,
+        XQueryTree(display, parent_window, &root,
             &next_parent, &theChildren, &n);
         XFree(theChildren); // not needed
     }
-    XRaiseWindow(XtDisplay((Widget) m_frameShell), parent_window);
+
+    XWindowChanges windowChanges;
+    windowChanges.x = x;
+    windowChanges.y = y;
+    windowChanges.width = width;
+    windowChanges.height = height;
+    windowChanges.stack_mode = 0;
+    int valueMask = CWX | CWY | CWWidth | CWHeight;
+
+    if (x != -1 || (sizeFlags & wxSIZE_ALLOW_MINUS_ONE))
+    {
+        valueMask |= CWX;
+    }
+    if (y != -1 || (sizeFlags & wxSIZE_ALLOW_MINUS_ONE))
+    {
+        valueMask |= CWY;
+    }
+    if (width != -1)
+    {
+        windowChanges.width = wxMax(1, width);
+        valueMask |= CWWidth;
+    }
+    if (height != -1)
+    {
+        windowChanges.height = wxMax(1, height);
+        valueMask |= CWHeight;
+    }
+
+    XConfigureWindow( display, parent_window, valueMask, &windowChanges );
+#endif
 }
 
-void wxFrame::Lower()
+void wxTopLevelWindowX11::DoGetPosition(int *x, int *y) const
 {
-    Window parent_window = XtWindow((Widget) m_frameShell),
-        next_parent   = XtWindow((Widget) m_frameShell),
-        root          = RootWindowOfScreen(XtScreen((Widget) m_frameShell));
+    XSync(wxGlobalDisplay(), False);
+    Window window = (Window) m_mainWindow;
+    if (!window)
+        return ;
+
+    Display *display = wxGlobalDisplay();
+    Window root = RootWindowOfScreen(DefaultScreenOfDisplay(display));
+    Window parent_window = window,
+        next_parent   = window;
+
     // search for the parent that is child of ROOT, because the WM may
     // reparent twice and notify only the next parent (like FVWM)
     while (next_parent != root) {
-        Window *theChildren; unsigned int n;
+        Window *theChildren;
+#if wxUSE_NANOX
+        GR_COUNT n;
+#else
+        unsigned int n;
+#endif
         parent_window = next_parent;
-        XQueryTree(XtDisplay((Widget) m_frameShell), parent_window, &root,
+        XQueryTree(display, parent_window, &root,
             &next_parent, &theChildren, &n);
         XFree(theChildren); // not needed
     }
-    XLowerWindow(XtDisplay((Widget) m_frameShell), parent_window);
+#if 0
+    int xx, yy; unsigned int dummy;
+    XGetGeometry(display, parent_window, &root,
+                 &xx, &yy, &dummy, &dummy, &dummy, &dummy);
+    if (x) *x = xx;
+    if (y) *y = yy;
+#else
+    XWindowAttributes attr;
+    Status status = XGetWindowAttributes( wxGlobalDisplay(), parent_window, & attr);
+    if (status)
+    {
+        if (x) *x = attr.x;
+        if (y) *y = attr.y;
+    }
+    else
+    {
+        if (x) *x = 0;
+        if (y) *y = 0;
+    }
+#endif
 }
 
-void wxFrameFocusProc(Widget WXUNUSED(workArea), XtPointer WXUNUSED(clientData),
-                      XmAnyCallbackStruct *WXUNUSED(cbs))
-{
-    // wxDebugMsg("focus proc from frame %ld\n",(long)frame);
-    // TODO
-    // wxFrame *frame = (wxFrame *)clientData;
-    // frame->GetEventHandler()->OnSetFocus();
-}
 
-/* MATTEW: Used to insure that hide-&-show within an event cycle works */
-static void wxFrameMapProc(Widget frameShell, XtPointer clientData,
-                           XCrossingEvent * event)
-{
-    wxFrame *frame = (wxFrame *)wxGetWindowFromTable((Widget)clientData);
+#ifndef MWM_DECOR_BORDER
 
-    if (frame) {
-        XEvent *e = (XEvent *)event;
+#define MWM_HINTS_FUNCTIONS     (1L << 0)
+#define MWM_HINTS_DECORATIONS   (1L << 1)
+#define MWM_HINTS_INPUT_MODE    (1L << 2)
+#define MWM_HINTS_STATUS        (1L << 3)
 
-        if (e->xany.type == MapNotify)
-        {
-            // Iconize fix
-            XtVaSetValues(frameShell, XmNiconic, (Boolean)False, NULL);
-            if (!frame->GetVisibleStatus())
-            {
-                /* We really wanted this to be hidden! */
-                XtUnmapWidget((Widget) frame->GetShellWidget());
-            }
-        }
-        else if (e->xany.type == UnmapNotify)
-            // Iconize fix
-            XtVaSetValues(frameShell, XmNiconic, (Boolean)True, NULL);
-    }
-}
+#define MWM_DECOR_ALL           (1L << 0)
+#define MWM_DECOR_BORDER        (1L << 1)
+#define MWM_DECOR_RESIZEH       (1L << 2)
+#define MWM_DECOR_TITLE         (1L << 3)
+#define MWM_DECOR_MENU          (1L << 4)
+#define MWM_DECOR_MINIMIZE      (1L << 5)
+#define MWM_DECOR_MAXIMIZE      (1L << 6)
 
-//// Motif-specific
-bool wxFrame::PreResize()
-{
-#if wxUSE_TOOLBAR
-    PositionToolBar();
-#endif // wxUSE_TOOLBAR
+#define MWM_FUNC_ALL            (1L << 0)
+#define MWM_FUNC_RESIZE         (1L << 1)
+#define MWM_FUNC_MOVE           (1L << 2)
+#define MWM_FUNC_MINIMIZE       (1L << 3)
+#define MWM_FUNC_MAXIMIZE       (1L << 4)
+#define MWM_FUNC_CLOSE          (1L << 5)
 
-#if wxUSE_STATUSBAR
-    PositionStatusBar();
-#endif // wxUSE_STATUSBAR
+#define MWM_INPUT_MODELESS 0
+#define MWM_INPUT_PRIMARY_APPLICATION_MODAL 1
+#define MWM_INPUT_SYSTEM_MODAL 2
+#define MWM_INPUT_FULL_APPLICATION_MODAL 3
+#define MWM_INPUT_APPLICATION_MODAL MWM_INPUT_PRIMARY_APPLICATION_MODAL
 
-    return TRUE;
-}
+#define MWM_TEAROFF_WINDOW     (1L<<0)
 
-WXWidget wxFrame::GetClientWidget() const
-{
-    return m_clientArea;
-}
+#endif
 
-void wxFrame::ChangeFont(bool WXUNUSED(keepOriginalSize))
-{
-    // TODO
-}
+struct MwmHints {
+    long flags;
+    long functions;
+    long decorations;
+    long input_mode;
+};
 
-void wxFrame::ChangeBackgroundColour()
-{
-    if (GetClientWidget())
-        DoChangeBackgroundColour(GetClientWidget(), m_backgroundColour);
-}
+#define PROP_MOTIF_WM_HINTS_ELEMENTS 5
 
-void wxFrame::ChangeForegroundColour()
+// Set the window manager decorations according to the
+// given wxWidgets style
+bool wxSetWMDecorations(Window w, long style)
 {
-    if (GetClientWidget())
-        DoChangeForegroundColour(GetClientWidget(), m_foregroundColour);
-}
+#if wxUSE_NANOX
+    GR_WM_PROPERTIES wmProp;
 
-void wxCloseFrameCallback(Widget WXUNUSED(widget), XtPointer client_data, XmAnyCallbackStruct *WXUNUSED(cbs))
-{
-    wxFrame *frame = (wxFrame *)client_data;
+    wmProp.flags = 0;
+    wmProp.props = 0;
 
-    wxCloseEvent closeEvent(wxEVT_CLOSE_WINDOW, frame->GetId());
-    closeEvent.SetEventObject(frame);
+    if (style & wxRESIZE_BORDER)
+    {
+        wmProp.props |= GR_WM_PROPS_APPFRAME ;
+        wmProp.flags |= GR_WM_FLAGS_PROPS ;
+    }
 
-    // May delete the frame (with delayed deletion)
-    frame->GetEventHandler()->ProcessEvent(closeEvent);
-}
+    if (style & wxCLOSE_BOX)
+    {
+        wmProp.props |= GR_WM_PROPS_CLOSEBOX ;
+        wmProp.flags |= GR_WM_FLAGS_PROPS ;
+    }
 
-static void wxFrameEventHandler(Widget    wid,
-                             XtPointer WXUNUSED(client_data),
-                             XEvent*   event,
-                             Boolean*  continueToDispatch)
-{
-    wxFrame *frame = (wxFrame *)wxGetWindowFromTable(wid);
-    if (frame)
+    if ((style & wxCAPTION) ||
+        (style & wxTINY_CAPTION_HORIZ) ||
+        (style & wxTINY_CAPTION_VERT))
     {
-        wxMouseEvent wxevent(wxEVT_NULL);
-        if (wxTranslateMouseEvent(wxevent, frame, wid, event))
+        wmProp.props |= GR_WM_PROPS_CAPTION ;
+        wmProp.flags |= GR_WM_FLAGS_PROPS ;
+
+        // The default dialog style doesn't include any kind
+        // of border, which is a bit odd. Anyway, inclusion
+        // of a caption surely implies a border.
+        style |= wxTHICK_FRAME;
+    }
+
+    if (style & wxTHICK_FRAME)
+    {
+        wmProp.props |= GR_WM_PROPS_APPFRAME ;
+        wmProp.flags |= GR_WM_FLAGS_PROPS ;
+    }
+
+    if (style & wxSIMPLE_BORDER)
+    {
+        wmProp.props |= GR_WM_PROPS_BORDER ;
+        wmProp.flags |= GR_WM_FLAGS_PROPS ;
+    }
+
+    if (style & wxMINIMIZE_BOX)
+    {
+    }
+
+    if (style & wxMAXIMIZE_BOX)
+    {
+        wmProp.props |= GR_WM_PROPS_MAXIMIZE ;
+        wmProp.flags |= GR_WM_FLAGS_PROPS ;
+    }
+
+    if (((style & wxBORDER) != wxBORDER) && ((style & wxTHICK_FRAME) != wxTHICK_FRAME)
+        && ((style & wxRESIZE_BORDER) != wxRESIZE_BORDER))
+    {
+        wmProp.props |= GR_WM_PROPS_NODECORATE ;
+        wmProp.flags |= GR_WM_FLAGS_PROPS ;
+    }
+
+    GrSetWMProperties(w, & wmProp);
+    
+#else
+
+    Atom mwm_wm_hints = XInternAtom(wxGlobalDisplay(),"_MOTIF_WM_HINTS", False);
+    if (mwm_wm_hints == 0)
+       return FALSE;
+    
+    MwmHints hints;
+    hints.flags = MWM_HINTS_DECORATIONS | MWM_HINTS_FUNCTIONS;
+    hints.decorations = 0;
+    hints.functions = 0;
+    
+    if ((style & wxSIMPLE_BORDER) || (style & wxNO_BORDER))
+    {
+        // leave zeros
+    }
+    else
+    {
+        hints.decorations = MWM_DECOR_BORDER;
+        hints.functions = MWM_FUNC_MOVE;
+
+        if ((style & wxCAPTION) != 0)
+            hints.decorations |= MWM_DECOR_TITLE;
+            
+        if ((style & wxSYSTEM_MENU) != 0)
+            hints.decorations |= MWM_DECOR_MENU;
+        
+        if ((style & wxCLOSE_BOX) != 0)
+            hints.functions |= MWM_FUNC_CLOSE;
+        
+        if ((style & wxMINIMIZE_BOX) != 0)
         {
-            wxevent.SetEventObject(frame);
-            wxevent.SetId(frame->GetId());
-            frame->GetEventHandler()->ProcessEvent(wxevent);
+            hints.functions |= MWM_FUNC_MINIMIZE;
+            hints.decorations |= MWM_DECOR_MINIMIZE;
         }
-        else
+        
+        if ((style & wxMAXIMIZE_BOX) != 0)
         {
-            // An attempt to implement OnCharHook by calling OnCharHook first;
-            // if this returns TRUE, set continueToDispatch to False
-            // (don't continue processing).
-            // Otherwise set it to True and call OnChar.
-            wxKeyEvent keyEvent(wxEVT_CHAR);
-            if (wxTranslateKeyEvent(keyEvent, frame, wid, event))
-            {
-                keyEvent.SetEventObject(frame);
-                keyEvent.SetId(frame->GetId());
-                keyEvent.SetEventType(wxEVT_CHAR_HOOK);
-                if (frame->GetEventHandler()->ProcessEvent(keyEvent))
-                {
-                    *continueToDispatch = False;
-                    return;
-                }
-                else
-                {
-                    // For simplicity, OnKeyDown is the same as OnChar
-                    // TODO: filter modifier key presses from OnChar
-                    keyEvent.SetEventType(wxEVT_KEY_DOWN);
-
-                    // Only process OnChar if OnKeyDown didn't swallow it
-                    if (!frame->GetEventHandler()->ProcessEvent (keyEvent))
-                    {
-                        keyEvent.SetEventType(wxEVT_CHAR);
-                        frame->GetEventHandler()->ProcessEvent(keyEvent);
-                    }
-                }
-            }
+            hints.functions |= MWM_FUNC_MAXIMIZE;
+            hints.decorations |= MWM_DECOR_MAXIMIZE;
+        }
+        
+        if ((style & wxRESIZE_BORDER) != 0)
+        {
+            hints.functions |= MWM_FUNC_RESIZE;
+            hints.decorations |= MWM_DECOR_RESIZEH;
         }
     }
-    *continueToDispatch = True;
+
+    XChangeProperty(wxGlobalDisplay(),
+                   w,
+                   mwm_wm_hints, mwm_wm_hints,
+                   32, PropModeReplace,
+                   (unsigned char *) &hints, PROP_MOTIF_WM_HINTS_ELEMENTS);
+
+#endif
+    return TRUE;
 }
+
+