From 621793f45e003588e32f7a6ca10cd238f7c96fe6 Mon Sep 17 00:00:00 2001
From: Julian Smart <julian@anthemion.co.uk>
Date: Tue, 24 Nov 1998 21:55:10 +0000
Subject: [PATCH] 2nd attempt at MDI in wxMotif, using wxNotebook this time
 (still some probs).

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@1034 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
---
 docs/latex/wx/notebook.tex  |   8 +-
 include/wx/gdicmn.h         |   5 +-
 include/wx/generic/tabg.h   |   3 +
 include/wx/motif/frame.h    |   1 +
 include/wx/motif/mdi.h      |  62 +++--
 include/wx/motif/menu.h     |   6 +
 include/wx/motif/notebook.h |   9 +-
 include/wx/msw/notebook.h   |   2 +
 include/wx/msw/radiobut.h   |   1 +
 include/wx/stubs/notebook.h |   2 +
 src/generic/tabg.cpp        |  43 ++-
 src/motif/data.cpp          |   1 +
 src/motif/frame.cpp         |  50 ++--
 src/motif/makefile.unx      |  15 +-
 src/motif/mdi.cpp           | 532 +++++++++++++++++-------------------
 src/motif/menu.cpp          |  69 +++++
 src/motif/notebook.cpp      | 197 +++++++------
 src/motif/window.cpp        |  11 +-
 src/msw/notebook.cpp        |  12 +
 src/msw/radiobut.cpp        |  12 +
 src/stubs/notebook.cpp      |  10 +
 21 files changed, 620 insertions(+), 431 deletions(-)

diff --git a/docs/latex/wx/notebook.tex b/docs/latex/wx/notebook.tex
index 1817f10652..726da6a80a 100644
--- a/docs/latex/wx/notebook.tex
+++ b/docs/latex/wx/notebook.tex
@@ -120,7 +120,7 @@ Deletes all pages.
 
 \func{bool}{DeletePage}{\param{int}{ page}}
 
-Deletes the specified page.
+Deletes the specified page, and the associated window.
 
 \membersection{wxNotebook::GetImageList}\label{wxnotebookgetimagelist}
 
@@ -211,6 +211,12 @@ An event handler function, called when the page selection is changed.
 
 \helpref{wxNotebookEvent}{wxnotebookevent}
 
+\membersection{wxNotebook::RemovePage}\label{wxnotebookremovepage}
+
+\func{bool}{RemovePage}{\param{int}{ page}}
+
+Deletes the specified page, without deleting the associated window.
+
 \membersection{wxNotebook::SetImageList}\label{wxnotebooksetimagelist}
 
 \func{void}{SetImageList}{\param{wxImageList*}{ imageList}}
diff --git a/include/wx/gdicmn.h b/include/wx/gdicmn.h
index 2f2570797a..fe995f30a5 100644
--- a/include/wx/gdicmn.h
+++ b/include/wx/gdicmn.h
@@ -331,9 +331,12 @@ extern void WXDLLEXPORT wxSetCursor(const wxCursor& cursor);
 // Load from a resource
 # define wxICON(X) wxIcon("" #X "")
 
-#elif defined(__WXGTK__) || defined(__WXMOTIF__)
+#elif defined(__WXGTK__)
 // Initialize from an included XPM
 # define wxICON(X) wxIcon( (const char**) X##_xpm )
+#elif defined(__WXMOTIF__)
+// Initialize from an included XPM
+# define wxICON(X) wxIcon( X##_xpm )
 #else
 
 // This will usually mean something on any platform
diff --git a/include/wx/generic/tabg.h b/include/wx/generic/tabg.h
index e937b156b1..3b246de2d5 100644
--- a/include/wx/generic/tabg.h
+++ b/include/wx/generic/tabg.h
@@ -114,6 +114,9 @@ public:
   
   // Automatically positions tabs
   wxTabControl *AddTab(int id, const wxString& label, wxTabControl *existingTab = (wxTabControl *) NULL);
+
+  // Remove the tab without deleting the window
+  bool RemoveTab(int id);
   
   void ClearTabs(bool deleteTabs = TRUE);
 
diff --git a/include/wx/motif/frame.h b/include/wx/motif/frame.h
index 8c5da8f12f..0614b627ba 100644
--- a/include/wx/motif/frame.h
+++ b/include/wx/motif/frame.h
@@ -155,6 +155,7 @@ public:
   inline WXWidget GetWorkAreaWidget() const { return m_workArea; }
   inline WXWidget GetClientAreaWidget() const { return m_clientArea; }
   inline WXWidget GetTopWidget() const { return m_frameShell; }
+  inline WXWidget GetMainWindowWidget() const { return m_frameWidget; }
 
   // The widget that can have children on it
   WXWidget GetClientWidget() const;
diff --git a/include/wx/motif/mdi.h b/include/wx/motif/mdi.h
index b843dc4e60..73138a679a 100644
--- a/include/wx/motif/mdi.h
+++ b/include/wx/motif/mdi.h
@@ -16,7 +16,16 @@
 #pragma interface "mdi.h"
 #endif
 
+/*
+New MDI scheme using tabs. We can use a wxNotebook to implement the client
+window. wxMDIChildFrame can be implemented as an XmMainWindow widget
+as before, and is a child of the notebook _and_ of the parent frame...
+but wxMDIChildFrame::GetParent should return the parent frame.
+
+*/
+
 #include "wx/frame.h"
+#include "wx/notebook.h"
 
 WXDLLEXPORT_DATA(extern const char*) wxFrameNameStr;
 WXDLLEXPORT_DATA(extern const char*) wxStatusLineNameStr;
@@ -24,11 +33,6 @@ WXDLLEXPORT_DATA(extern const char*) wxStatusLineNameStr;
 class WXDLLEXPORT wxMDIClientWindow;
 class WXDLLEXPORT wxMDIChildFrame;
 
-#if wxUSE_MDI_WIDGETS
-class XsMDICanvas;
-class wxXsMDIWindow;
-#endif
-
 class WXDLLEXPORT wxMDIParentFrame: public wxFrame
 {
 DECLARE_DYNAMIC_CLASS(wxMDIParentFrame)
@@ -87,12 +91,24 @@ public:
   virtual void ActivatePrevious();
 
 // Implementation
+
+  // Set the active child
   inline void SetActiveChild(wxMDIChildFrame* child) { m_activeChild = child; }
 
+  // Set the child's menubar into the parent frame
+  void SetChildMenuBar(wxMDIChildFrame* frame);
+
+  inline wxMenuBar* GetActiveMenuBar() const { return m_activeMenuBar; }
+
+  // Redirect events to active child first
+  virtual bool ProcessEvent(wxEvent& event);
+
+
 protected:
 
   wxMDIClientWindow*    m_clientWindow;
   wxMDIChildFrame*      m_activeChild;
+  wxMenuBar*            m_activeMenuBar;
 
 DECLARE_EVENT_TABLE()
 };
@@ -136,6 +152,13 @@ public:
   // Set icon
   virtual void SetIcon(const wxIcon& icon);
 
+  // Override wxFrame operations
+  void CaptureMouse();
+  void ReleaseMouse();
+  void Raise();
+  void Lower(void);
+  void SetSizeHints(int minW = -1, int minH = -1, int maxW = -1, int maxH = -1, int incW = -1, int incH = -1);
+
   // MDI operations
   virtual void Maximize();
   inline void Minimize() { Iconize(TRUE); };
@@ -145,16 +168,21 @@ public:
   virtual bool IsIconized() const ;
 
   bool Show(bool show);
-  void BuildClientArea(WXWidget parent);
+
+  inline WXWidget GetMainWidget() const { return m_mainWidget; };
   inline WXWidget GetTopWidget() const { return m_mainWidget; };
-#if wxUSE_MDI_WIDGETS
-  inline wxXsMDIWindow *GetMDIWindow() const { return m_mdiWindow; };
-#endif
+  inline WXWidget GetClientWidget() const { return m_mainWidget; };
+
+/*
   virtual void OnRaise();
   virtual void OnLower();
+*/
+
+  inline void SetMDIParentFrame(wxMDIParentFrame* parentFrame) { m_mdiParentFrame = parentFrame; }
+  inline wxMDIParentFrame* GetMDIParentFrame() const { return m_mdiParentFrame; }
 
 protected:
-  wxXsMDIWindow*    m_mdiWindow ;
+  wxMDIParentFrame* m_mdiParentFrame;
 };
 
 /* The client window is a child of the parent MDI frame, and itself
@@ -164,7 +192,7 @@ protected:
  * of the children. Phew! So the children are sort of 'adopted'...
  */
 
-class WXDLLEXPORT wxMDIClientWindow: public wxWindow
+class WXDLLEXPORT wxMDIClientWindow: public wxNotebook
 {
   DECLARE_DYNAMIC_CLASS(wxMDIClientWindow)
  public:
@@ -184,25 +212,17 @@ class WXDLLEXPORT wxMDIClientWindow: public wxWindow
    void GetSize(int *width, int *height) const ;
    void GetPosition(int *x, int *y) const ;
 
-
   // Note: this is virtual, to allow overridden behaviour.
   virtual bool CreateClient(wxMDIParentFrame *parent, long style = wxVSCROLL | wxHSCROLL);
 
   // Explicitly call default scroll behaviour
   void OnScroll(wxScrollEvent& event);
 
-#if wxUSE_MDI_WIDGETS
-  inline XsMDICanvas* GetMDICanvas() const { return m_mdiCanvas; }
-  WXWidget GetTopWidget() const { return m_topWidget; }
-#endif
+  // Implementation
+  void OnPageChanged(wxNotebookEvent& event);
 
 protected:
 
-#if wxUSE_MDI_WIDGETS
-  XsMDICanvas*   m_mdiCanvas;
-  WXWidget       m_topWidget;
-#endif
-
 DECLARE_EVENT_TABLE()
 };
 
diff --git a/include/wx/motif/menu.h b/include/wx/motif/menu.h
index e0b40fc05b..f9ebc22090 100644
--- a/include/wx/motif/menu.h
+++ b/include/wx/motif/menu.h
@@ -188,6 +188,12 @@ class WXDLLEXPORT wxMenuBar: public wxEvtHandler
   inline WXWidget GetMainWidget() const { return m_mainWidget; }
   inline void SetMainWidget(WXWidget widget) { m_mainWidget = widget; }
 
+  // Create menubar
+  bool CreateMenuBar(wxFrame* frame);
+
+  // Destroy menubar, but keep data structures intact so we can recreate it.
+  bool DestroyMenuBar();
+
  public:
   wxEvtHandler *            m_eventHandler;
   int                       m_menuCount;
diff --git a/include/wx/motif/notebook.h b/include/wx/motif/notebook.h
index 734d17fc05..0615edef40 100644
--- a/include/wx/motif/notebook.h
+++ b/include/wx/motif/notebook.h
@@ -109,6 +109,9 @@ public:
     // get number of pages in the dialog
   int GetPageCount() const;
 
+  // Find the position of the wxNotebookPage, -1 if not found.
+  int FindPagePosition(wxNotebookPage* page) const;
+
     // set the currently selected page, return the index of the previously
     // selected one (or -1 on error)
     // NB: this function will _not_ generate wxEVT_NOTEBOOK_PAGE_xxx events
@@ -148,8 +151,12 @@ public:
 
   // operations
   // ----------
-    // remove one page from the notebook
+    // remove one page from the notebook, and delete the page.
   bool DeletePage(int nPage);
+  bool DeletePage(wxNotebookPage* page);
+    // remove one page from the notebook, without deleting the page.
+  bool RemovePage(int nPage);
+  bool RemovePage(wxNotebookPage* page);
     // remove all pages
   bool DeleteAllPages();
     // adds a new page to the notebook (it will be deleted ny the notebook,
diff --git a/include/wx/msw/notebook.h b/include/wx/msw/notebook.h
index bebae78055..b75bc7f228 100644
--- a/include/wx/msw/notebook.h
+++ b/include/wx/msw/notebook.h
@@ -143,6 +143,8 @@ public:
   // ----------
     // remove one page from the notebook
   bool DeletePage(int nPage);
+    // remove one page from the notebook, without deleting
+  bool RemovePage(int nPage);
     // remove all pages
   bool DeleteAllPages();
     // adds a new page to the notebook (it will be deleted ny the notebook,
diff --git a/include/wx/msw/radiobut.h b/include/wx/msw/radiobut.h
index a2514e7574..1a546cee83 100644
--- a/include/wx/msw/radiobut.h
+++ b/include/wx/msw/radiobut.h
@@ -47,6 +47,7 @@ class WXDLLEXPORT wxRadioButton: public wxControl
   virtual void SetValue(bool val);
   virtual bool GetValue(void) const ;
 
+  bool MSWCommand(WXUINT param, WXWORD id);
   void Command(wxCommandEvent& event);
   virtual WXHBRUSH OnCtlColor(WXHDC pDC, WXHWND pWnd, WXUINT nCtlColor,
 			WXUINT message, WXWPARAM wParam, WXLPARAM lParam);
diff --git a/include/wx/stubs/notebook.h b/include/wx/stubs/notebook.h
index 9b0794f359..83f8c1ce4e 100644
--- a/include/wx/stubs/notebook.h
+++ b/include/wx/stubs/notebook.h
@@ -132,6 +132,8 @@ public:
   // ----------
     // remove one page from the notebook
   bool DeletePage(int nPage);
+    // remove one page from the notebook, without deleting
+  bool RemovePage(int nPage);
     // remove all pages
   bool DeleteAllPages();
     // adds a new page to the notebook (it will be deleted ny the notebook,
diff --git a/src/generic/tabg.cpp b/src/generic/tabg.cpp
index fe7590fd50..cc6a601bc5 100644
--- a/src/generic/tabg.cpp
+++ b/src/generic/tabg.cpp
@@ -597,6 +597,35 @@ wxTabControl *wxTabView::AddTab(int id, const wxString& label, wxTabControl *exi
   
   return tabControl;
 }
+
+// Remove the tab without deleting the window
+bool wxTabView::RemoveTab(int id)
+{
+  wxNode *layerNode = m_layers.First();
+  while (layerNode)
+  {
+    wxTabLayer *layer = (wxTabLayer *)layerNode->Data();
+    wxNode *tabNode = layer->First();
+    while (tabNode)
+    {
+      wxTabControl *tab = (wxTabControl *)tabNode->Data();
+      if (tab->GetId() == id)
+      {
+        if (id == m_tabSelection)
+          m_tabSelection = -1;
+        delete tab;
+        delete tabNode;
+
+        // The layout has changed
+        Layout();
+        return TRUE;
+      }
+      tabNode = tabNode->Next();
+    }
+    layerNode = layerNode->Next();
+  }
+  return FALSE;
+}
   
 // Returns the total height of the tabs component -- this may be several
 // times the height of a tab, if there are several tab layers (rows).
@@ -968,20 +997,26 @@ void wxTabView::SetTabSelection(int sel, bool activateTool)
 {
   int oldSel = m_tabSelection;
   wxTabControl *control = FindTabControlForId(sel);
+  wxTabControl *oldControl = FindTabControlForId(m_tabSelection);
 
   if (!OnTabPreActivate(sel, oldSel))
     return;
     
   if (control)
-    control->SetSelected((sel != 0)); // TODO ??
-  else
+    control->SetSelected((sel != -1)); // TODO ??
+  else if (sel != -1)
   {
-    wxMessageBox(_("Could not find tab for id"), _("Error"), wxOK);
+    wxFAIL_MSG(_("Could not find tab for id"));
     return;
   }
+
+  if (oldControl)
+    oldControl->SetSelected(FALSE);
     
   m_tabSelection = sel;
-  MoveSelectionTab(control);
+
+  if (control)
+    MoveSelectionTab(control);
   
   if (activateTool)
     OnTabActivate(sel, oldSel);
diff --git a/src/motif/data.cpp b/src/motif/data.cpp
index e65f345b87..94cbc7eaf9 100644
--- a/src/motif/data.cpp
+++ b/src/motif/data.cpp
@@ -14,6 +14,7 @@
 #endif
 
 #include "wx/wx.h"
+#include "wx/postscrp.h"
 
 #define _MAXPATHLEN 500
 
diff --git a/src/motif/frame.cpp b/src/motif/frame.cpp
index d7fe6aefac..f0b7089297 100644
--- a/src/motif/frame.cpp
+++ b/src/motif/frame.cpp
@@ -287,6 +287,8 @@ wxFrame::~wxFrame()
 
   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);
@@ -486,6 +488,9 @@ void wxFrame::SetSize(int x, int y, int width, int height, int sizeFlags)
 
 bool wxFrame::Show(bool show)
 {
+  if (!m_frameShell)
+    return wxWindow::Show(show);
+
   m_visibleStatus = show; /* show-&-hide fix */
 
   m_isShown = show;
@@ -504,7 +509,8 @@ void wxFrame::Iconize(bool iconize)
   if (!iconize)
     Show(TRUE);
 
-  XtVaSetValues((Widget) m_frameShell, XmNiconic, (Boolean)iconize, NULL);
+  if (m_frameShell)
+    XtVaSetValues((Widget) m_frameShell, XmNiconic, (Boolean)iconize, NULL);
 }
 
 // Equivalent to maximize/restore in Windows
@@ -512,12 +518,15 @@ void wxFrame::Maximize(bool maximize)
 {
   Show(TRUE);
 
-  if (maximize)
+  if (maximize && m_frameShell)
     XtVaSetValues((Widget) m_frameShell, XmNiconic, FALSE, NULL);
 }
 
 bool wxFrame::IsIconized() const
 {
+  if (!m_frameShell)
+    return FALSE;
+
   Boolean iconic;
   XtVaGetValues((Widget) m_frameShell, XmNiconic, &iconic, NULL);
   return iconic;
@@ -541,6 +550,9 @@ void wxFrame::SetIcon(const wxIcon& icon)
 {
   m_icon = icon;
 
+  if (!m_frameShell)
+    return;
+
   // TODO
   /*
   if (!icon.Ok() || !icon.GetPixmap())
@@ -638,32 +650,16 @@ void wxFrame::SetMenuBar(wxMenuBar *menuBar)
     }
 
     // Currently can't set it twice
-    wxASSERT_MSG( (m_frameMenuBar == (wxMenuBar*) NULL), "Cannot set the menubar more than once");
-  
-    m_frameMenuBar = menuBar;
+//    wxASSERT_MSG( (m_frameMenuBar == (wxMenuBar*) NULL), "Cannot set the menubar more than once");
 
-  Widget menuBarW = XmCreateMenuBar ((Widget) m_frameWidget, "MenuBar", NULL, 0);
-  m_frameMenuBar->SetMainWidget( (WXWidget) menuBarW);
-
-  int i;
-  for (i = 0; i < menuBar->GetMenuCount(); i++)
+    if (m_frameMenuBar)
     {
-      wxMenu *menu = menuBar->GetMenu(i);
-      wxString title(menuBar->m_titles[i]);
-      menu->SetButtonWidget(menu->CreateMenu (menuBar, menuBarW, menu, title, TRUE));
-
-      /*
-       * COMMENT THIS OUT IF YOU DON'T LIKE A RIGHT-JUSTIFIED HELP MENU
-       */
-      wxStripMenuCodes ((char*) (const char*) title, wxBuffer);
-
-      if (strcmp (wxBuffer, "Help") == 0)
-	XtVaSetValues ((Widget) menuBarW, XmNmenuHelpWidget, (Widget) menu->GetButtonWidget(), NULL);
+        m_frameMenuBar->DestroyMenuBar();
+        delete m_frameMenuBar;
     }
 
-  XtRealizeWidget ((Widget) menuBarW);
-  XtManageChild ((Widget) menuBarW);
-  menuBar->SetMenuBarFrame(this);
+    m_frameMenuBar = menuBar;
+    m_frameMenuBar->CreateMenuBar(this);
 }
 
 void wxFrame::Fit()
@@ -1071,12 +1067,14 @@ void wxFrame::ChangeFont(bool keepOriginalSize)
 
 void wxFrame::ChangeBackgroundColour()
 {
-    // TODO
+    if (GetClientWidget())
+        DoChangeBackgroundColour(GetClientWidget(), m_backgroundColour);
 }
 
 void wxFrame::ChangeForegroundColour()
 {
-    // TODO
+    if (GetClientWidget())
+        DoChangeForegroundColour(GetClientWidget(), m_foregroundColour);
 }
 
 void wxCloseFrameCallback(Widget widget, XtPointer client_data, XmAnyCallbackStruct *cbs)
diff --git a/src/motif/makefile.unx b/src/motif/makefile.unx
index a05e8a1282..fcaa095e9e 100644
--- a/src/motif/makefile.unx
+++ b/src/motif/makefile.unx
@@ -179,13 +179,14 @@ EXTRA_C_SRC=\
   xmcombo/xmcombo.c # $(ZLIB_SRC)
 
 EXTRA_CPP_SRC=\
-  mdi/lib/XsComponent.C\
-  mdi/lib/XsMDICanvas.C\
-  mdi/lib/XsMDIWindow.C\
-  mdi/lib/XsMotifWindow.C\
-  mdi/lib/XsMoveOutline.C\
-  mdi/lib/XsOutline.C\
-  mdi/lib/XsResizeOutline.C
+
+#  mdi/lib/XsComponent.C\
+#  mdi/lib/XsMDICanvas.C\
+#  mdi/lib/XsMDIWindow.C\
+#  mdi/lib/XsMotifWindow.C\
+#  mdi/lib/XsMoveOutline.C\
+#  mdi/lib/XsOutline.C\
+#  mdi/lib/XsResizeOutline.C
 
 all:    $(WXLIB)
 
diff --git a/src/motif/mdi.cpp b/src/motif/mdi.cpp
index 75a528cedb..902714acc2 100644
--- a/src/motif/mdi.cpp
+++ b/src/motif/mdi.cpp
@@ -28,9 +28,6 @@
 #include <Xm/AtomMgr.h>
 #include <Xm/Protocols.h>
 
-#include "mdi/lib/XsMDICanvas.h"
-#include "mdi/lib/XsMotifWindow.h"
-
 #include "wx/motif/private.h"
 
 extern wxList wxModelessWindows;
@@ -39,10 +36,12 @@ extern wxList wxModelessWindows;
 extern void wxFrameFocusProc(Widget workArea, XtPointer clientData, 
                       XmAnyCallbackStruct *cbs);
 
+#define wxID_NOTEBOOK_CLIENT_AREA wxID_HIGHEST + 100
+
 #if !USE_SHARED_LIBRARY
 IMPLEMENT_DYNAMIC_CLASS(wxMDIParentFrame, wxFrame)
 IMPLEMENT_DYNAMIC_CLASS(wxMDIChildFrame, wxFrame)
-IMPLEMENT_DYNAMIC_CLASS(wxMDIClientWindow, wxWindow)
+IMPLEMENT_DYNAMIC_CLASS(wxMDIClientWindow, wxNotebook)
 
 BEGIN_EVENT_TABLE(wxMDIParentFrame, wxFrame)
   EVT_SIZE(wxMDIParentFrame::OnSize)
@@ -50,172 +49,20 @@ BEGIN_EVENT_TABLE(wxMDIParentFrame, wxFrame)
   EVT_SYS_COLOUR_CHANGED(wxMDIParentFrame::OnSysColourChanged)
 END_EVENT_TABLE()
 
-BEGIN_EVENT_TABLE(wxMDIClientWindow, wxWindow)
+BEGIN_EVENT_TABLE(wxMDIClientWindow, wxNotebook)
   EVT_SCROLL(wxMDIClientWindow::OnScroll)
+  EVT_NOTEBOOK_PAGE_CHANGED(wxID_NOTEBOOK_CLIENT_AREA, wxMDIClientWindow::OnPageChanged)
 END_EVENT_TABLE()
 
 #endif
 
-  /*
-static void _doNothingCallback (Widget, XtPointer, XtPointer)
-{
-}
-*/
-
-// wxXsMDIWindow represents the MDI child frame, as far as the MDI
-// package is concerned.
-// TODO: override raise, so we can tell which is the 'active'
-// (raised) window. We can also use it to send wxActivateEvents,
-// and switching menubars when we make the child frame menubar
-// appear on the parent frame.
-
-// Note: see XsMotifWindow.C, _XsMotifMenu::_processItem for
-// where user menu selections are processed.
-// When Close is selected, _win->close() is called.
-
-class wxXsMDIWindow: public XsMotifWindow
-{
-public:
-  wxMDIChildFrame* m_childFrame;
-
-  wxXsMDIWindow(const char* name, wxMDIChildFrame* frame): XsMotifWindow(name)
-  {
-    m_childFrame = frame;
-  }
-  virtual void setSize(Dimension w, Dimension h)
-  {
-      XsMotifWindow::setSize(w, h);
-
-      // Generate wxSizeEvent here, I think. Maybe also restore, maximize
-      // Probably don't need to generate size event here since work area
-      // is used (???)
-      wxSizeEvent event(wxSize(w, h), m_childFrame->GetId());
-      event.SetEventObject(m_childFrame);
-      m_childFrame->ProcessEvent(event);
-  }
-  virtual void close()
-  {
-      XsMotifWindow::close();
-      m_childFrame->Close();
-  }
-  virtual void raise()
-  {
-      XsMotifWindow::raise();
-      m_childFrame->OnRaise();
-  }
-  virtual void lower()
-  {
-      XsMotifWindow::lower();
-      m_childFrame->OnLower();
-  }
-  virtual void _buildClientArea(Widget parent)
-  {
-      m_childFrame->BuildClientArea((WXWidget) parent);
-
-    // Code from MDI sample
-#if 0
-   assert (parent != 0);
-   
-   Widget   pulldown;
-   Widget   cascade;
-   Widget   button;
-   
-// Create a main window with some dummy menus
-
-   Widget mainW = XtVaCreateWidget ("mainWin", xmMainWindowWidgetClass, parent,
-      XmNtopAttachment, XmATTACH_FORM, XmNbottomAttachment, XmATTACH_FORM,
-      XmNleftAttachment, XmATTACH_FORM, XmNrightAttachment, XmATTACH_FORM,
-      NULL);
-      
-// Create a menubar
-
-   Widget menuBar = XmCreateMenuBar (mainW, "menuBar", NULL, 0);
-
-// Create the "file" menu
-
-   pulldown = XmCreatePulldownMenu (menuBar, "pulldown", NULL, 0);
-   cascade = XtVaCreateManagedWidget ("fileMenu", xmCascadeButtonGadgetClass,
-      menuBar, XmNsubMenuId, pulldown, NULL);
-   
-   button = XtVaCreateManagedWidget ("openMenuItem", xmPushButtonGadgetClass,
-      pulldown, NULL);
-   XtAddCallback (button, XmNactivateCallback, _doNothingCallback, (XtPointer)this);
-      
-   button = XtVaCreateManagedWidget ("newMenuItem", xmPushButtonGadgetClass,
-      pulldown, NULL);
-   //   XtAddCallback (button, XmNactivateCallback, _newWindowCallback, (XtPointer)this);
-
-// Create the "edit" menu
-
-   pulldown = XmCreatePulldownMenu (menuBar, "pulldown", NULL, 0);
-   cascade = XtVaCreateManagedWidget ("editMenu", xmCascadeButtonGadgetClass,
-      menuBar, XmNsubMenuId, pulldown, NULL);
-   
-   button = XtVaCreateManagedWidget ("cutMenuItem", xmPushButtonGadgetClass,
-      pulldown, NULL);
-   XtAddCallback (button, XmNactivateCallback, _doNothingCallback, (XtPointer)this);
-      
-   button = XtVaCreateManagedWidget ("copyMenuItem", xmPushButtonGadgetClass,
-      pulldown, NULL);
-   XtAddCallback (button, XmNactivateCallback, _doNothingCallback, (XtPointer)this);
-
-   button = XtVaCreateManagedWidget ("pasteMenuItem", xmPushButtonGadgetClass,
-      pulldown, NULL);
-   XtAddCallback (button, XmNactivateCallback, _doNothingCallback, (XtPointer)this);
-
-// Create the help menu
-
-   pulldown = XmCreatePulldownMenu (menuBar, "pulldown", NULL, 0);
-   cascade = XtVaCreateManagedWidget ("helpMenu", xmCascadeButtonGadgetClass,
-      menuBar, XmNsubMenuId, pulldown, NULL);
-   
-   button = XtVaCreateManagedWidget ("aboutMenuItem", xmPushButtonGadgetClass,
-      pulldown, NULL);
-   XtAddCallback (button, XmNactivateCallback, _doNothingCallback, (XtPointer)this);
-      
-   XtVaSetValues (menuBar, XmNmenuHelpWidget, cascade, NULL);
-
-// Manage the menubar
-
-   XtManageChild (menuBar);
-   
-// Create the work area
-
-   const int nargs = 8;
-   Arg   args[nargs];
-   int n;
-	    
-   n = 0;
-   XtSetArg (args[n], XmNscrollingPolicy, XmAUTOMATIC); n++;
-   XtSetArg (args[n], XmNhighlightThickness, (Dimension)0);    n++;
-   XtSetArg (args[n], XmNeditMode, XmMULTI_LINE_EDIT); n++;
-   XtSetArg (args[n], XmNeditable, True); n++;
-   XtSetArg (args[n], XmNwordWrap, False); n++;
-   XtSetArg (args[n], XmNcursorPositionVisible, True);   n++;
-   XtSetArg (args[n], XmNverifyBell, True); n++;
-			      
-   assert (n <= nargs);
-				 
-   Widget scrolledText = XmCreateScrolledText (mainW, "scrolledText", args, n);
-   XtManageChild (scrolledText);
-   
-// Set the main window area
-
-   XtVaSetValues (mainW, XmNmenuBar, menuBar, XmNworkWindow,
-      XtParent (scrolledText), NULL);
-   
-   XtManageChild (mainW);
-#endif
-  }
-  void Show() { show(); }
-};
-
 // Parent frame
 
 wxMDIParentFrame::wxMDIParentFrame()
 {
     m_clientWindow = (wxMDIClientWindow*) NULL;
     m_activeChild = (wxMDIChildFrame*) NULL;
+    m_activeMenuBar = (wxMenuBar*) NULL;
 }
 
 bool wxMDIParentFrame::Create(wxWindow *parent,
@@ -228,6 +75,7 @@ bool wxMDIParentFrame::Create(wxWindow *parent,
 {
     m_clientWindow = (wxMDIClientWindow*) NULL;
     m_activeChild = (wxMDIChildFrame*) NULL;
+    m_activeMenuBar = (wxMenuBar*) NULL;
 
     bool success = wxFrame::Create(parent, id, title, pos, size, style, name);
     if (success)
@@ -237,8 +85,13 @@ bool wxMDIParentFrame::Create(wxWindow *parent,
         // (we're in the constructor). How to resolve?
 
         m_clientWindow = OnCreateClient();
-	// Uses own style for client style
-	m_clientWindow->CreateClient(this, GetWindowStyleFlag());
+
+        // Uses own style for client style
+        m_clientWindow->CreateClient(this, GetWindowStyleFlag());
+
+        int w, h;
+        GetClientSize(& w, & h);
+        m_clientWindow->SetSize(0, 0, w, h);
         return TRUE;
     }
     else
@@ -247,8 +100,13 @@ bool wxMDIParentFrame::Create(wxWindow *parent,
 
 wxMDIParentFrame::~wxMDIParentFrame()
 {
+    // Make sure we delete the client window last of all
+    RemoveChild(m_clientWindow);
+
     DestroyChildren();
+
     delete m_clientWindow;
+    m_clientWindow = NULL;
 }
 
 // Get size *available for subwindows* i.e. excluding menu bar.
@@ -259,7 +117,9 @@ void wxMDIParentFrame::GetClientSize(int *x, int *y) const
 
 void wxMDIParentFrame::SetMenuBar(wxMenuBar *menu_bar)
 {
-    wxFrame::SetMenuBar(menu_bar);
+    m_frameMenuBar = menu_bar;
+
+    SetChildMenuBar((wxMDIChildFrame*) NULL);
 }
 
 void wxMDIParentFrame::OnSize(wxSizeEvent& event)
@@ -295,6 +155,88 @@ wxMDIClientWindow *wxMDIParentFrame::OnCreateClient()
 	return new wxMDIClientWindow ;
 }
 
+// Set the child's menu into the parent frame
+void wxMDIParentFrame::SetChildMenuBar(wxMDIChildFrame* child)
+{
+    wxMenuBar* oldMenuBar = m_activeMenuBar;
+
+    if (child == (wxMDIChildFrame*) NULL)  // No child: use parent frame
+    {
+        if (GetMenuBar() && (GetMenuBar() != m_activeMenuBar))
+        {
+	  //            if (m_activeMenuBar)
+	  //                m_activeMenuBar->DestroyMenuBar();
+
+            m_activeMenuBar = GetMenuBar();
+            m_activeMenuBar->CreateMenuBar(this);
+	    /*
+            if (oldMenuBar && XtIsManaged((Widget) oldMenuBar->GetMainWidget()))
+              XtUnmanageChild((Widget) oldMenuBar->GetMainWidget());
+	      */
+            if (oldMenuBar && oldMenuBar->GetMainWidget())
+              XtUnmapWidget((Widget) oldMenuBar->GetMainWidget());
+
+        }
+    }
+    else if (child->GetMenuBar() == (wxMenuBar*) NULL) // No child menu bar: use parent frame
+    {
+        if (GetMenuBar() && (GetMenuBar() != m_activeMenuBar))
+        {
+	  //            if (m_activeMenuBar)
+	  //                m_activeMenuBar->DestroyMenuBar();
+            m_activeMenuBar = GetMenuBar();
+            m_activeMenuBar->CreateMenuBar(this);
+	    /*
+            if (oldMenuBar && XtIsManaged((Widget) oldMenuBar->GetMainWidget()))
+              XtUnmanageChild((Widget) oldMenuBar->GetMainWidget());
+	      */
+            if (oldMenuBar && oldMenuBar->GetMainWidget())
+              XtUnmapWidget((Widget) oldMenuBar->GetMainWidget());
+        }
+    }
+    else // The child has a menubar
+    {
+        if (child->GetMenuBar() != m_activeMenuBar)
+        {
+	  //            if (m_activeMenuBar)
+	  //                m_activeMenuBar->DestroyMenuBar();
+
+            m_activeMenuBar = child->GetMenuBar();
+            m_activeMenuBar->CreateMenuBar(this);
+	    /*
+            if (oldMenuBar && XtIsManaged((Widget) oldMenuBar->GetMainWidget()))
+              XtUnmanageChild((Widget) oldMenuBar->GetMainWidget());
+	      */
+            if (oldMenuBar && oldMenuBar->GetMainWidget())
+              XtUnmapWidget((Widget) oldMenuBar->GetMainWidget());
+        }
+    }
+}
+
+// Redirect events to active child first
+bool wxMDIParentFrame::ProcessEvent(wxEvent& event)
+{
+    // Stops the same event being processed repeatedly
+    static wxEventType inEvent = wxEVT_NULL;
+    if (inEvent == event.GetEventType())
+        return FALSE;
+
+    inEvent = event.GetEventType();
+    
+    bool res = FALSE;
+    if (m_activeChild && event.IsKindOf(CLASSINFO(wxCommandEvent)))
+    {
+      res = m_activeChild->GetEventHandler()->ProcessEvent(event);
+    }
+
+    if (!res)
+      res = GetEventHandler()->wxEvtHandler::ProcessEvent(event);
+
+    inEvent = wxEVT_NULL;
+
+    return res;
+}
+
 // Responds to colour changes, and passes event on to children.
 void wxMDIParentFrame::OnSysColourChanged(wxSysColourChangedEvent& event)
 {
@@ -334,6 +276,7 @@ void wxMDIParentFrame::ActivatePrevious()
 
 wxMDIChildFrame::wxMDIChildFrame()
 {
+    m_mdiParentFrame = (wxMDIParentFrame*) NULL;
 }
 
 bool wxMDIChildFrame::Create(wxMDIParentFrame *parent,
@@ -346,12 +289,22 @@ bool wxMDIChildFrame::Create(wxMDIParentFrame *parent,
 {
     SetName(name);
 
+    m_backgroundColour = wxSystemSettings::GetSystemColour(wxSYS_COLOUR_APPWORKSPACE);
+    m_foregroundColour = *wxBLACK;
+    m_windowFont = wxSystemSettings::GetSystemFont(wxSYS_DEFAULT_GUI_FONT);
+
     if ( id > -1 )
         m_windowId = id;
     else
         m_windowId = (int)NewControlId();
 
-    if (parent) parent->AddChild(this);
+    wxMDIClientWindow* clientWindow = parent->GetClientWindow();
+
+    wxASSERT_MSG( (clientWindow != (wxWindow*) NULL), "Missing MDI client window.");
+
+    if (clientWindow) clientWindow->AddChild(this);
+
+    SetMDIParentFrame(parent);
 
     int x = pos.x; int y = pos.y;
     int width = size.x; int height = size.y;
@@ -360,10 +313,6 @@ bool wxMDIChildFrame::Create(wxMDIParentFrame *parent,
     if (height == -1)
         height = 200; // TODO: give reasonable default
 
-    wxMDIClientWindow* clientWindow = parent->GetClientWindow();
-    if (!clientWindow)
-        return FALSE;
-
     // We're deactivating the old child
     wxMDIChildFrame* oldActiveChild = parent->GetActiveChild();
     if (oldActiveChild)
@@ -373,92 +322,43 @@ bool wxMDIChildFrame::Create(wxMDIParentFrame *parent,
         oldActiveChild->GetEventHandler()->ProcessEvent(event);
     }
 
-    m_mdiWindow = new wxXsMDIWindow("mdiChildWindow", this);
-    clientWindow->GetMDICanvas()->add(m_mdiWindow);
-
     // This is the currently active child
     parent->SetActiveChild((wxMDIChildFrame*) this);
 
-    m_mdiWindow->Show();
-
-#if 0
-    m_mainWidget = (WXWidget) (Widget) (*m_mdiWindow);
-
-    m_frameWidget = (WXWidget) XtVaCreateManagedWidget("main_window",
-                    xmMainWindowWidgetClass, (Widget) m_mainWidget,
-                    XmNresizePolicy, XmRESIZE_NONE,
-                    NULL);
+    // This time we'll try a bog-standard bulletin board for
+    // the 'frame'. A main window doesn't seem to work.
 
-    m_workArea = (WXWidget) XtVaCreateWidget("form",
-                    xmFormWidgetClass, (Widget) m_frameWidget,
-                    XmNresizePolicy, XmRESIZE_NONE,
-                    NULL);
-
-    m_clientArea = (WXWidget) XtVaCreateWidget("client",
-                    xmBulletinBoardWidgetClass, (Widget) m_workArea,
+    m_mainWidget = (WXWidget) XtVaCreateWidget("client",
+                    xmBulletinBoardWidgetClass, (Widget) clientWindow->GetTopWidget(),
                     XmNmarginWidth, 0,
                     XmNmarginHeight, 0,
+       /*
                     XmNrightAttachment, XmATTACH_FORM,
                     XmNleftAttachment, XmATTACH_FORM,
                     XmNtopAttachment, XmATTACH_FORM,
                     XmNbottomAttachment, XmATTACH_FORM,
-//                    XmNresizePolicy, XmRESIZE_ANY,
+    */
+	            XmNresizePolicy, XmRESIZE_NONE,
                     NULL);
+    
+    SetCanAddEventHandler(TRUE);
+    AttachWidget (parent, m_mainWidget, (WXWidget) NULL, pos.x, pos.y, size.x, size.y);
 
-    XtVaSetValues((Widget) m_frameWidget,
-      XmNworkWindow, (Widget) m_workArea,
-      NULL);
-
-    XtManageChild((Widget) m_clientArea);
-    XtManageChild((Widget) m_workArea);
-
-    wxASSERT_MSG ((wxWidgetHashTable->Get((long)m_workArea) == (wxObject*) NULL), "Widget table clash in frame.cpp") ;
-
-    wxAddWindowToTable((Widget) m_workArea, this);
-
-    XtTranslations ptr ;
-
-    XtOverrideTranslations((Widget) m_workArea,
-                ptr = XtParseTranslationTable("<Configure>: resize()"));
-
-    XtFree((char *)ptr);
-
-    XtAddCallback((Widget) m_workArea, XmNfocusCallback, 
-                (XtCallbackProc)wxFrameFocusProc, (XtPointer)this);
-
-    if (x > -1)
-      XtVaSetValues((Widget) m_mainWidget, XmNx, x, NULL);
-    if (y > -1)
-      XtVaSetValues((Widget) m_mainWidget, XmNy, y, NULL);
-    if (width > -1)
-      XtVaSetValues((Widget) m_mainWidget, XmNwidth, width, NULL);
-    if (height > -1)
-      XtVaSetValues((Widget) m_mainWidget, XmNheight, height, NULL);
-#endif
+    ChangeBackgroundColour();
 
-    SetTitle(title);
-
-    PreResize();
-
-    m_mdiWindow->setSize(width, height);
-
-    wxModelessWindows.Append(this);
-    return TRUE;
-}
-
-void wxMDIChildFrame::BuildClientArea(WXWidget parent)
-{
-    m_mainWidget = parent;
+    // Old stuff
+#if 0
 
     m_frameWidget = (WXWidget) XtVaCreateManagedWidget("main_window",
-                    xmMainWindowWidgetClass, (Widget) m_mainWidget,
+                    xmMainWindowWidgetClass, (Widget) clientWindow->GetTopWidget(),
                     XmNresizePolicy, XmRESIZE_NONE,
-                    XmNtopAttachment, XmATTACH_FORM,
-                    XmNbottomAttachment, XmATTACH_FORM,
-                    XmNleftAttachment, XmATTACH_FORM,
-                    XmNrightAttachment, XmATTACH_FORM,
                     NULL);
 
+    // TODO: make sure this doesn't cause problems.
+    // I think ~wxFrame will do the right thing since it deletes m_frameWidget,
+    // then sets the main widget to NULL.
+    m_mainWidget = m_frameWidget;
+
     m_workArea = (WXWidget) XtVaCreateWidget("form",
                     xmFormWidgetClass, (Widget) m_frameWidget,
                     XmNresizePolicy, XmRESIZE_NONE,
@@ -496,9 +396,7 @@ void wxMDIChildFrame::BuildClientArea(WXWidget parent)
     XtAddCallback((Widget) m_workArea, XmNfocusCallback, 
                 (XtCallbackProc)wxFrameFocusProc, (XtPointer)this);
 
-    /*
-    int x = pos.x; int y = pos.y;
-    int width = size.x; int height = size.y;
+    XtManageChild((Widget) m_mainWidget);
 
     if (x > -1)
       XtVaSetValues((Widget) m_mainWidget, XmNx, x, NULL);
@@ -508,23 +406,54 @@ void wxMDIChildFrame::BuildClientArea(WXWidget parent)
       XtVaSetValues((Widget) m_mainWidget, XmNwidth, width, NULL);
     if (height > -1)
       XtVaSetValues((Widget) m_mainWidget, XmNheight, height, NULL);
-      */
 
-    XtManageChild((Widget) m_frameWidget);
+#endif
+
+    XtManageChild((Widget) m_mainWidget);
+
+    SetTitle(title);
+
+    clientWindow->AddPage(this, title, TRUE);
+    clientWindow->Refresh();
+
+    // Positions the toolbar and status bar -- but we don't have any.
+    //    PreResize();
+
+    wxModelessWindows.Append(this);
+    return TRUE;
 }
 
 
 wxMDIChildFrame::~wxMDIChildFrame()
 {
-    wxMDIParentFrame* parentFrame = (wxMDIParentFrame*) GetParent() ;
-    if (parentFrame->GetActiveChild() == this)
-        parentFrame->SetActiveChild((wxMDIChildFrame*) NULL);
-
-    wxMDIClientWindow* clientWindow = parentFrame->GetClientWindow();
-    clientWindow->GetMDICanvas()->remove(m_mdiWindow);
-    m_mainWidget = (WXWidget) 0;
+    if (GetMDIParentFrame())
+    {
+        wxMDIParentFrame* parentFrame = GetMDIParentFrame();
+
+        if (parentFrame->GetActiveChild() == this)
+            parentFrame->SetActiveChild((wxMDIChildFrame*) NULL);
+        wxMDIClientWindow* clientWindow = parentFrame->GetClientWindow();
+
+        // Remove page if still there
+        if (clientWindow->RemovePage(this))
+          clientWindow->Refresh();
+
+        // Set the selection to the first remaining page
+        if (clientWindow->GetPageCount() > 0)
+        {
+            wxMDIChildFrame* child = (wxMDIChildFrame*)  clientWindow->GetPage(0);
+            parentFrame->SetActiveChild(child);
+            parentFrame->SetChildMenuBar(child);
+        }
+        else
+        {
+            parentFrame->SetActiveChild((wxMDIChildFrame*) NULL);
+            parentFrame->SetChildMenuBar((wxMDIChildFrame*) NULL);
+        }
+    }
 }
 
+#if 0
 // Implementation: intercept and act upon raise and lower commands.
 void wxMDIChildFrame::OnRaise()
 {
@@ -559,22 +488,23 @@ void wxMDIChildFrame::OnLower()
     // so make the active child NULL.
     parentFrame->SetActiveChild((wxMDIChildFrame*) NULL);
 }
+#endif
 
 // Set the client size (i.e. leave the calculation of borders etc.
 // to wxWindows)
 void wxMDIChildFrame::SetClientSize(int width, int height)
 {
-    wxFrame::SetClientSize(width, height);
+  wxWindow::SetClientSize(width, height);
 }
 
 void wxMDIChildFrame::GetClientSize(int* width, int* height) const
 {
-    wxFrame::GetClientSize(width, height);
+    wxWindow::GetSize(width, height);
 }
 
 void wxMDIChildFrame::SetSize(int x, int y, int width, int height, int sizeFlags)
 {
-    wxWindow::SetSize(x, y, width, height, sizeFlags);
+  wxWindow::SetSize(x, y, width, height, sizeFlags);
 }
 
 void wxMDIChildFrame::GetSize(int* width, int* height) const
@@ -590,16 +520,18 @@ void wxMDIChildFrame::GetPosition(int *x, int *y) const
 bool wxMDIChildFrame::Show(bool show)
 {
     m_visibleStatus = show; /* show-&-hide fix */
-    return TRUE;
+    return wxWindow::Show(show);
 }
 
-void wxMDIChildFrame::SetMenuBar(wxMenuBar *menu_bar)
+void wxMDIChildFrame::SetMenuBar(wxMenuBar *menuBar)
 {
-    // TODO
-    // Currently, the menu appears on the child frame. 
-    // It should eventually be recreated on the main frame
-    // whenever the child is activated.
-    wxFrame::SetMenuBar(menu_bar);
+    // Don't create the underlying menubar yet; need to recreate
+    // it every time the child is activated.
+    m_frameMenuBar = menuBar;
+
+    // We make the assumption that if you're setting the menubar,
+    // this is the currently active child.
+    GetMDIParentFrame()->SetChildMenuBar(this);
 }
 
 // Set icon
@@ -618,68 +550,80 @@ void wxMDIChildFrame::SetIcon(const wxIcon& icon)
 void wxMDIChildFrame::SetTitle(const wxString& title)
 {
     m_title = title;
-    m_mdiWindow->setTitle(title);
-    m_mdiWindow->setIconName(title);
+    // TODO: set parent frame title
 }
 
 // MDI operations
 void wxMDIChildFrame::Maximize()
 {
-   m_mdiWindow->maximize();
+    // TODO
 }
 
 void wxMDIChildFrame::Iconize(bool iconize)
 {
-   if (iconize)
-      m_mdiWindow->minimize();
-   else
-      m_mdiWindow->restore();
+  // TODO
 }
 
 bool wxMDIChildFrame::IsIconized() const
 {
-    return m_mdiWindow->minimized();
+    return FALSE;
 }
 
 void wxMDIChildFrame::Restore()
 {
-    m_mdiWindow->restore();
+    // TODO
 }
 
 void wxMDIChildFrame::Activate()
 {
-    m_mdiWindow->raise();
+    // TODO
+}
+
+void wxMDIChildFrame::CaptureMouse()
+{
+  wxWindow::CaptureMouse();
+}
+
+void wxMDIChildFrame::ReleaseMouse()
+{
+  wxWindow::ReleaseMouse();
+}
+
+void wxMDIChildFrame::Raise()
+{
+  wxWindow::Raise();
+}
+
+void wxMDIChildFrame::Lower(void)
+{
+  wxWindow::Raise();
+}
+
+void wxMDIChildFrame::SetSizeHints(int WXUNUSED(minW), int WXUNUSED(minH), int WXUNUSED(maxW), int WXUNUSED(maxH), int WXUNUSED(incW), int WXUNUSED(incH))
+{
 }
 
 // Client window
 
 wxMDIClientWindow::wxMDIClientWindow()
 {
-    m_mdiCanvas = NULL;
-    m_topWidget = (WXWidget) 0;
 }
 
 wxMDIClientWindow::~wxMDIClientWindow()
 {
+    // By the time this destructor is called, the child frames will have been
+   // deleted and removed from the notebook/client window.
     DestroyChildren();
-    delete m_mdiCanvas;
 
     m_mainWidget = (WXWidget) 0;
-    m_topWidget = (WXWidget) 0;
 }
 
 bool wxMDIClientWindow::CreateClient(wxMDIParentFrame *parent, long style)
 {
-    m_windowParent = parent;
-    m_backgroundColour = wxSystemSettings::GetSystemColour(wxSYS_COLOUR_APPWORKSPACE);
-    m_mdiCanvas = new XsMDICanvas("mdiClientWindow", (Widget) parent->GetClientWidget());
-    m_mainWidget = (WXWidget) m_mdiCanvas->GetDrawingArea();
-    //    m_topWidget = (WXWidget) m_mdiCanvas->GetBase();
-    m_topWidget = (WXWidget) (Widget) (*m_mdiCanvas);
-
-    m_mdiCanvas->show();
+  //    m_windowParent = parent;
+    //    m_backgroundColour = wxSystemSettings::GetSystemColour(wxSYS_COLOUR_APPWORKSPACE);
 
-    return TRUE;
+    return wxNotebook::Create(parent, wxID_NOTEBOOK_CLIENT_AREA, wxPoint(0, 0), wxSize(100, 100), 0);
 }
 
 void wxMDIClientWindow::SetSize(int x, int y, int width, int height, int sizeFlags)
@@ -713,3 +657,31 @@ void wxMDIClientWindow::OnScroll(wxScrollEvent& event)
     Default(); // Default processing
 }
 
+void wxMDIClientWindow::OnPageChanged(wxNotebookEvent& event)
+{
+    // Notify child that it has been activated
+    if (event.GetOldSelection() != -1)
+    {
+        wxMDIChildFrame* oldChild = (wxMDIChildFrame*) GetPage(event.GetOldSelection());
+        if (oldChild)
+        {
+            wxActivateEvent event(wxEVT_ACTIVATE, FALSE, oldChild->GetId());
+            event.SetEventObject( oldChild );
+            oldChild->GetEventHandler()->ProcessEvent(event);
+        }
+    }
+    wxMDIChildFrame* activeChild = (wxMDIChildFrame*) GetPage(event.GetSelection());
+    if (activeChild)
+    {
+        wxActivateEvent event(wxEVT_ACTIVATE, TRUE, activeChild->GetId());
+        event.SetEventObject( activeChild );
+        activeChild->GetEventHandler()->ProcessEvent(event);
+
+        if (activeChild->GetMDIParentFrame())
+        {
+            activeChild->GetMDIParentFrame()->SetActiveChild(activeChild);
+            activeChild->GetMDIParentFrame()->SetChildMenuBar(activeChild);
+        }
+    }
+    event.Skip();
+}
diff --git a/src/motif/menu.cpp b/src/motif/menu.cpp
index d10b977174..91df050e49 100644
--- a/src/motif/menu.cpp
+++ b/src/motif/menu.cpp
@@ -455,6 +455,7 @@ wxMenuBar::wxMenuBar()
     m_menus = NULL;
     m_titles = NULL;
     m_menuBarFrame = NULL;
+    m_mainWidget = (WXWidget) NULL;
 }
 
 wxMenuBar::wxMenuBar(int n, wxMenu *menus[], const wxString titles[])
@@ -747,6 +748,74 @@ wxString wxMenuBar::GetHelpString (int id) const
     return wxString("");
 }
 
+// Create menubar
+bool wxMenuBar::CreateMenuBar(wxFrame* parent)
+{
+  if (m_mainWidget)
+  {
+    XtVaSetValues((Widget) parent->GetMainWindowWidget(), XmNmenuBar, (Widget) m_mainWidget, NULL);
+    /*
+    if (!XtIsManaged((Widget) m_mainWidget))
+      XtManageChild((Widget) m_mainWidget);
+      */
+    XtMapWidget((Widget) m_mainWidget);
+    return TRUE;
+  }
+
+  Widget menuBarW = XmCreateMenuBar ((Widget) parent->GetMainWindowWidget(), "MenuBar", NULL, 0);
+  m_mainWidget = (WXWidget) menuBarW;
+
+  int i;
+  for (i = 0; i < GetMenuCount(); i++)
+    {
+      wxMenu *menu = GetMenu(i);
+      wxString title(m_titles[i]);
+      menu->SetButtonWidget(menu->CreateMenu (this, menuBarW, menu, title, TRUE));
+
+      /*
+       * COMMENT THIS OUT IF YOU DON'T LIKE A RIGHT-JUSTIFIED HELP MENU
+       */
+      wxStripMenuCodes ((char*) (const char*) title, wxBuffer);
+
+      if (strcmp (wxBuffer, "Help") == 0)
+        XtVaSetValues ((Widget) menuBarW, XmNmenuHelpWidget, (Widget) menu->GetButtonWidget(), NULL);
+    }
+
+  XtVaSetValues((Widget) parent->GetMainWindowWidget(), XmNmenuBar, (Widget) m_mainWidget, NULL);
+  XtRealizeWidget ((Widget) menuBarW);
+  XtManageChild ((Widget) menuBarW);
+  SetMenuBarFrame(parent);
+
+  return TRUE;
+}
+
+// Destroy menubar, but keep data structures intact so we can recreate it.
+bool wxMenuBar::DestroyMenuBar()
+{
+  if (!m_mainWidget)
+  {
+      SetMenuBarFrame((wxFrame*) NULL);
+      return FALSE;
+  }
+
+  XtUnmanageChild ((Widget) m_mainWidget);
+  XtUnrealizeWidget ((Widget) m_mainWidget);
+
+  int i;
+  for (i = 0; i < GetMenuCount(); i++)
+    {
+      wxMenu *menu = GetMenu(i);
+      menu->DestroyMenu(TRUE);
+
+    }
+  XtDestroyWidget((Widget) m_mainWidget);
+  m_mainWidget = (WXWidget) 0;
+
+  SetMenuBarFrame((wxFrame*) NULL);
+
+  return TRUE;
+}
+
 //// Motif-specific
 
 extern wxApp *wxTheApp;
diff --git a/src/motif/notebook.cpp b/src/motif/notebook.cpp
index ba296eb4d0..fd0e099d65 100644
--- a/src/motif/notebook.cpp
+++ b/src/motif/notebook.cpp
@@ -138,7 +138,10 @@ int wxNotebook::SetSelection(int nPage)
 
     wxASSERT( IS_VALID_PAGE(nPage) );
 
-    ChangePage(m_nSelection, nPage);
+    wxNotebookPage* pPage = GetPage(nPage);
+
+    m_tabView->SetTabSelection((int) (long) pPage);
+    //    ChangePage(m_nSelection, nPage);
 
     // TODO
     return 0;
@@ -196,22 +199,96 @@ void wxNotebook::SetImageList(wxImageList* imageList)
 // wxNotebook operations
 // ----------------------------------------------------------------------------
 
-// remove one page from the notebook
+// remove one page from the notebook and delete it
 bool wxNotebook::DeletePage(int nPage)
 {
-    wxFAIL_MSG("Sorry, DeletePage not implemented for Motif wxNotebook because wxTabView doesn't support it.");
-    return FALSE;
-
-/*
     wxCHECK( IS_VALID_PAGE(nPage), FALSE );
 
-    // TODO: delete native widget page
+    if (m_nSelection != -1)
+    {
+        m_aPages[m_nSelection]->Show(FALSE);
+        m_aPages[m_nSelection]->Lower();
+    }
+
+    wxNotebookPage* pPage = GetPage(nPage);
+    m_tabView->RemoveTab((int) (long) pPage);
 
     delete m_aPages[nPage];
     m_aPages.Remove(nPage);
 
+    if (m_aPages.GetCount() == 0)
+    {
+      m_nSelection = -1;
+      m_tabView->SetTabSelection(-1, FALSE);
+    }
+    else if (m_nSelection > 0)
+    {
+      m_nSelection = -1;
+      m_tabView->SetTabSelection((int) (long) GetPage(0), FALSE);
+      ChangePage(-1, 0);
+    }
+
     return TRUE;
-*/
+}
+
+bool wxNotebook::DeletePage(wxNotebookPage* page)
+{
+    int pagePos = FindPagePosition(page);
+    if (pagePos > -1)
+        return DeletePage(pagePos);
+    else
+        return FALSE;
+}
+
+// remove one page from the notebook
+bool wxNotebook::RemovePage(int nPage)
+{
+    wxCHECK( IS_VALID_PAGE(nPage), FALSE );
+
+    if (m_nSelection != -1)
+    {
+        m_aPages[m_nSelection]->Show(FALSE);
+        m_aPages[m_nSelection]->Lower();
+    }
+
+    wxNotebookPage* pPage = GetPage(nPage);
+    m_tabView->RemoveTab((int) (long) pPage);
+
+    m_aPages.Remove(nPage);
+
+    if (m_aPages.GetCount() == 0)
+    {
+      m_nSelection = -1;
+      m_tabView->SetTabSelection(-1, FALSE);
+    }
+    else if (m_nSelection > 0)
+    {
+      m_nSelection = -1;
+      m_tabView->SetTabSelection((int) (long) GetPage(0), FALSE);
+      ChangePage(-1, 0);
+    }
+
+    return TRUE;
+}
+
+bool wxNotebook::RemovePage(wxNotebookPage* page)
+{
+    int pagePos = FindPagePosition(page);
+    if (pagePos > -1)
+        return RemovePage(pagePos);
+    else
+        return FALSE;
+}
+
+// Find the position of the wxNotebookPage, -1 if not found.
+int wxNotebook::FindPagePosition(wxNotebookPage* page) const
+{
+    int nPageCount = GetPageCount();
+    int nPage;
+    for ( nPage = 0; nPage < nPageCount; nPage++ )
+        if (m_aPages[nPage] == page)
+            return nPage;
+    return -1;
 }
 
 // remove all pages
@@ -248,23 +325,23 @@ bool wxNotebook::InsertPage(int nPage,
     wxASSERT( pPage != NULL );
     wxCHECK( IS_VALID_PAGE(nPage) || nPage == GetPageCount(), FALSE );
 
-    m_tabView->AddTab(nPage, strText);
-    pPage->Show(FALSE);
-
-/*
-    if (bSelect)
-        m_tabView->SetTabSelection(nPage, TRUE);
-*/
+    m_tabView->AddTab((int) (long) pPage, strText);
+    if (!bSelect)
+      pPage->Show(FALSE);
 
     // save the pointer to the page
     m_aPages.Insert(pPage, nPage);
 
-    // some page must be selected: either this one or the first one if there is 
+    if (bSelect)
+    {
+        // This will cause ChangePage to be called, via OnSelPage
+        m_tabView->SetTabSelection((int) (long) pPage, TRUE);
+    }
+
+    // some page must be selected: either this one or the first one if there is
     // still no selection
-    if ( bSelect )
-        m_nSelection = nPage;
-    else if ( m_nSelection == -1 )
-        m_nSelection = 0;
+    if ( m_nSelection == -1 )
+      ChangePage(-1, 0);
 
     return TRUE;
 }
@@ -311,12 +388,13 @@ void wxNotebook::OnSize(wxSizeEvent& event)
         m_tabView->SetViewRect(rect);
 
         m_tabView->Layout();
-
+	/*
         // emulate page change (it's esp. important to do it first time because
         // otherwise our page would stay invisible)
         int nSel = m_nSelection;
         m_nSelection = -1;
         SetSelection(nSel);
+	*/
 
         // fit the notebook page to the tab control's display area
 
@@ -493,76 +571,19 @@ void wxNotebookTabView::OnTabActivate(int activateId, int deactivateId)
     return;
 
   wxNotebookEvent event(wxEVT_COMMAND_NOTEBOOK_PAGE_CHANGED, m_notebook->GetId());
-  event.SetEventObject(m_notebook);
-  event.SetSelection(activateId);
-  event.SetOldSelection(deactivateId);
-  m_notebook->GetEventHandler()->ProcessEvent(event);
-  
-  /*    
-  wxWindow *oldWindow = ((deactivateId == -1) ? 0 : m_notebook->GetPage(deactivateId));
-  wxWindow *newWindow = m_notebook->GetPage(activateId);
-
-  if (oldWindow)
-  {
-    oldWindow->Show(FALSE);
-    oldWindow->Lower();
-  }
-  if (newWindow)
-  {
-    newWindow->Show(TRUE);
-    newWindow->Raise();
 
-    int cw, ch;
-    m_notebook->GetClientSize(& cw, & ch);
-
-    int tabHeight = GetTotalTabHeight();
-    wxRect rect;
-    rect.x = 4;
-    rect.y = tabHeight + 4;
-    rect.width = cw - 8;
-    rect.height = ch - 4 - rect.y ;
-  
-    newWindow->SetSize(rect.x + 2, rect.y + 2, rect.width - 2, rect.height - 2);
-    newWindow->Refresh();
-  }
+  // Translate from wxTabView's ids (which aren't position-dependent)
+  // to wxNotebook's (which are).
+  wxNotebookPage* pActive = (wxNotebookPage*) activateId;
+  wxNotebookPage* pDeactive = (wxNotebookPage*) deactivateId;
 
-  // TODO: only refresh the tab area.    
-  m_notebook->Refresh();
-*/
-}
+  int activatePos = m_notebook->FindPagePosition(pActive);
+  int deactivatePos = m_notebook->FindPagePosition(pDeactive);
 
-#if 0
-void wxNotebookTabView::AddTabWindow(int id, wxWindow *window)
-{
-  m_tabWindows.Append((long)id, window);
-  window->Show(FALSE);
-}
-
-wxWindow *wxNotebookTabView::GetTabWindow(int id) const
-{
-  wxNode *node = m_tabWindows.Find((long)id);
-  if (!node)
-    return (wxWindow *) NULL;
-  return (wxWindow *)node->Data();    
-}
-
-void wxNotebookTabView::ClearWindows(bool deleteWindows)
-{
-  if (deleteWindows)
-    m_tabWindows.DeleteContents(TRUE);
-  m_tabWindows.Clear();
-  m_tabWindows.DeleteContents(FALSE);
+  event.SetEventObject(m_notebook);
+  event.SetSelection(activatePos);
+  event.SetOldSelection(deactivatePos);
+  m_notebook->GetEventHandler()->ProcessEvent(event);
 }
 
-void wxNotebookTabView::ShowWindowForTab(int id)
-{
-  wxWindow *newWindow = GetTabWindow(id);
-  if (newWindow == m_currentWindow)
-    return;
-  if (m_currentWindow)
-    m_currentWindow->Show(FALSE);
-  newWindow->Show(TRUE);
-  newWindow->Refresh();
-}
-#endif
 
diff --git a/src/motif/window.cpp b/src/motif/window.cpp
index 618603b721..568974519d 100644
--- a/src/motif/window.cpp
+++ b/src/motif/window.cpp
@@ -746,7 +746,11 @@ bool wxWindow::Show(bool show)
        }
        else
        {
-           XtMapWidget((Widget) GetTopWidget());
+           WXWidget topWidget = GetTopWidget();
+           if (GetTopWidget())
+             XtMapWidget((Widget) GetTopWidget());
+           else if (GetMainWidget())
+             XtMapWidget((Widget) GetMainWidget());
        }
     }
     else
@@ -759,7 +763,10 @@ bool wxWindow::Show(bool show)
        }
        else
        {
-           XtUnmapWidget((Widget) GetTopWidget());
+           if (GetTopWidget())
+             XtUnmapWidget((Widget) GetTopWidget());
+           else if (GetMainWidget())
+             XtUnmapWidget((Widget) GetMainWidget());
        }
     }
 
diff --git a/src/msw/notebook.cpp b/src/msw/notebook.cpp
index 788da296c5..e58af84b52 100644
--- a/src/msw/notebook.cpp
+++ b/src/msw/notebook.cpp
@@ -278,6 +278,18 @@ bool wxNotebook::DeletePage(int nPage)
   return TRUE;
 }
 
+// remove one page from the notebook, without deleting
+bool wxNotebook::RemovePage(int nPage)
+{
+  wxCHECK_MSG( IS_VALID_PAGE(nPage), FALSE, "notebook page out of range" );
+
+  TabCtrl_DeleteItem(m_hwnd, nPage);
+
+  m_aPages.Remove(nPage);
+
+  return TRUE;
+}
+
 // remove all pages
 bool wxNotebook::DeleteAllPages()
 {
diff --git a/src/msw/radiobut.cpp b/src/msw/radiobut.cpp
index 32cf7fe87e..8a222716d2 100644
--- a/src/msw/radiobut.cpp
+++ b/src/msw/radiobut.cpp
@@ -33,6 +33,18 @@ IMPLEMENT_DYNAMIC_CLASS(wxRadioButton, wxControl)
 // IMPLEMENT_DYNAMIC_CLASS(wxBitmapRadioButton, wxRadioButton)
 #endif
 
+bool wxRadioButton::MSWCommand(WXUINT param, WXWORD id)
+{
+  if (param == BN_CLICKED)
+  {
+    wxCommandEvent event(wxEVT_COMMAND_RADIOBUTTON_SELECTED, m_windowId);
+    event.SetEventObject( this );
+    ProcessCommand(event);
+    return TRUE;
+  }
+  else return FALSE;
+}
+
 bool wxRadioButton::Create(wxWindow *parent, wxWindowID id,
        const wxString& label,
            const wxPoint& pos,
diff --git a/src/stubs/notebook.cpp b/src/stubs/notebook.cpp
index 233bc5639b..312dd0f3d3 100644
--- a/src/stubs/notebook.cpp
+++ b/src/stubs/notebook.cpp
@@ -202,6 +202,16 @@ bool wxNotebook::DeletePage(int nPage)
     return TRUE;
 }
 
+// remove one page from the notebook, without deleting the window
+bool wxNotebook::RemovePage(int nPage)
+{
+    wxCHECK( IS_VALID_PAGE(nPage), FALSE );
+
+    m_aPages.Remove(nPage);
+
+    return TRUE;
+}
+
 // remove all pages
 bool wxNotebook::DeleteAllPages()
 {
-- 
2.45.2

