]> git.saurik.com Git - wxWidgets.git/commitdiff
More Motif additions: mdi and sashtest samples now just about work!
authorJulian Smart <julian@anthemion.co.uk>
Mon, 19 Oct 1998 21:51:15 +0000 (21:51 +0000)
committerJulian Smart <julian@anthemion.co.uk>
Mon, 19 Oct 1998 21:51:15 +0000 (21:51 +0000)
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@873 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775

45 files changed:
distrib/msw/motif.rsp
include/wx/motif/mdi.h
samples/mdi/mdi.cpp
src/make.env
src/makeg95.env
src/motif/combobox.cpp
src/motif/frame.cpp
src/motif/makefile.unx
src/motif/mdi.cpp
src/motif/mdi/COPYRIGHT [new file with mode: 0644]
src/motif/mdi/Imakefile [new file with mode: 0644]
src/motif/mdi/config/C++.rules [new file with mode: 0644]
src/motif/mdi/config/MDI.tmpl [new file with mode: 0644]
src/motif/mdi/doc/canvas.html [new file with mode: 0644]
src/motif/mdi/doc/mdi.html [new file with mode: 0644]
src/motif/mdi/doc/mwindow.html [new file with mode: 0644]
src/motif/mdi/doc/pics/classes.gif [new file with mode: 0644]
src/motif/mdi/doc/pics/mdi.gif [new file with mode: 0644]
src/motif/mdi/doc/pics/winclass.gif [new file with mode: 0644]
src/motif/mdi/lib/Imakefile [new file with mode: 0644]
src/motif/mdi/lib/XsComponent.C [new file with mode: 0644]
src/motif/mdi/lib/XsComponent.h [new file with mode: 0644]
src/motif/mdi/lib/XsMDICanvas.C [new file with mode: 0644]
src/motif/mdi/lib/XsMDICanvas.h [new file with mode: 0644]
src/motif/mdi/lib/XsMDIWindow.C [new file with mode: 0644]
src/motif/mdi/lib/XsMDIWindow.h [new file with mode: 0644]
src/motif/mdi/lib/XsMotifWindow.C [new file with mode: 0644]
src/motif/mdi/lib/XsMotifWindow.h [new file with mode: 0644]
src/motif/mdi/lib/XsMoveOutline.C [new file with mode: 0644]
src/motif/mdi/lib/XsMoveOutline.h [new file with mode: 0644]
src/motif/mdi/lib/XsOutline.C [new file with mode: 0644]
src/motif/mdi/lib/XsOutline.h [new file with mode: 0644]
src/motif/mdi/lib/XsResizeOutline.C [new file with mode: 0644]
src/motif/mdi/lib/XsResizeOutline.h [new file with mode: 0644]
src/motif/mdi/lib/xs_motif_icon.xbm [new file with mode: 0644]
src/motif/mdi/test/Imakefile [new file with mode: 0644]
src/motif/mdi/test/MDItest.C [new file with mode: 0644]
src/motif/xmcombo/combobox.doc [new file with mode: 0644]
src/motif/xmcombo/combobox.man [new file with mode: 0644]
src/motif/xmcombo/combop.h [new file with mode: 0644]
src/motif/xmcombo/copying.txt [new file with mode: 0644]
src/motif/xmcombo/demo.c [new file with mode: 0644]
src/motif/xmcombo/xmcombo.c [new file with mode: 0644]
src/motif/xmcombo/xmcombo.h [new file with mode: 0644]
src/msw/makefile.g95

index 5b311108a5bc8afdd86a2911683b23252dc5c2ab..dea0cf7529389425dd284ea9c056005c0f2c004a 100644 (file)
@@ -4,11 +4,26 @@ src/motif/*.h
 src/motif/makefile*
 src/motif/*.inc
 src/motif/*.xbm
 src/motif/makefile*
 src/motif/*.inc
 src/motif/*.xbm
-src/motif/combobox/*.c
-src/motif/combobox/*.h
-src/motif/combobox/*.doc
-src/motif/combobox/*.man
-src/motif/combobox/*.txt
+src/motif/xmcombo/*.c
+src/motif/xmcombo/*.h
+src/motif/xmcombo/*.doc
+src/motif/xmcombo/*.man
+src/motif/xmcombo/*.txt
+src/motif/mdi/COPYRIGHT
+src/motif/mdi/Imakefile
+src/motif/mdi/Readme
+src/motif/mdi/config/C++.rules
+src/motif/mdi/config/MDI.tmpl
+src/motif/mdi/doc/*.html
+src/motif/mdi/doc/pics/*.gif
+src/motif/mdi/lib/*.C
+src/motif/mdi/lib/*.h
+src/motif/mdi/lib/*.xbm
+src/motif/mdi/lib/Imakefile
+src/motif/mdi/test/*.C
+src/motif/mdi/test/Imakefile
+
+
 
 src/make.env
 src/makeprog.env
 
 src/make.env
 src/makeprog.env
index fa1db5314c4bb0dbba76b5818dbfd72a4b6495ed..d3ee46079da7087cc5185df530c91530d636d62b 100644 (file)
@@ -26,6 +26,9 @@ WXDLLEXPORT_DATA(extern const char*) wxStatusLineNameStr;
 class WXDLLEXPORT wxMDIClientWindow;
 class WXDLLEXPORT wxMDIChildFrame;
 
 class WXDLLEXPORT wxMDIClientWindow;
 class WXDLLEXPORT wxMDIChildFrame;
 
+class XsMDICanvas;
+class wxXsMDIWindow;
+
 class WXDLLEXPORT wxMDIParentFrame: public wxFrame
 {
 DECLARE_DYNAMIC_CLASS(wxMDIParentFrame)
 class WXDLLEXPORT wxMDIParentFrame: public wxFrame
 {
 DECLARE_DYNAMIC_CLASS(wxMDIParentFrame)
@@ -85,7 +88,6 @@ public:
 
 protected:
 
 
 protected:
 
-  // TODO maybe have this member
   wxMDIClientWindow     *m_clientWindow;
 
 DECLARE_EVENT_TABLE()
   wxMDIClientWindow     *m_clientWindow;
 
 DECLARE_EVENT_TABLE()
@@ -120,13 +122,31 @@ public:
 
   // Set menu bar
   void SetMenuBar(wxMenuBar *menu_bar);
 
   // Set menu bar
   void SetMenuBar(wxMenuBar *menu_bar);
+  void SetTitle(const wxString& title);
   void SetClientSize(int width, int height);
   void SetClientSize(int width, int height);
+  void GetClientSize(int *width, int *height) const;
+  void SetSize(int x, int y, int width, int height, int sizeFlags = wxSIZE_AUTO);
+  void GetSize(int *width, int *height) const;
   void GetPosition(int *x, int *y) const ;
 
   void GetPosition(int *x, int *y) const ;
 
+  // Set icon
+  virtual void SetIcon(const wxIcon& icon);
+
   // MDI operations
   virtual void Maximize();
   // MDI operations
   virtual void Maximize();
+  inline void Minimize() { Iconize(TRUE); };
+  virtual void Iconize(bool iconize);
   virtual void Restore();
   virtual void Activate();
   virtual void Restore();
   virtual void Activate();
+  virtual bool IsIconized() const ;
+
+  bool Show(bool show);
+  void BuildClientArea(WXWidget parent);
+  inline WXWidget GetTopWidget() const { return m_mainWidget; };
+  inline wxXsMDIWindow *GetMDIWindow() const { return m_mdiWindow; };
+
+protected:
+  wxXsMDIWindow*    m_mdiWindow ;
 };
 
 /* The client window is a child of the parent MDI frame, and itself
 };
 
 /* The client window is a child of the parent MDI frame, and itself
@@ -149,14 +169,29 @@ class WXDLLEXPORT wxMDIClientWindow: public wxWindow
 
   ~wxMDIClientWindow();
 
 
   ~wxMDIClientWindow();
 
+   void SetSize(int x, int y, int width, int height, int sizeFlags = wxSIZE_AUTO);
+   void SetClientSize(int width, int height);
+   void GetClientSize(int *width, int *height) const;
+
+   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);
 
   // 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);
 
+  inline XsMDICanvas* GetMDICanvas() const { return m_mdiCanvas; }
+
+  WXWidget GetTopWidget() const { return m_topWidget; }
+
 protected:
 
 protected:
 
+  XsMDICanvas*   m_mdiCanvas;
+  WXWidget       m_topWidget;
+
 DECLARE_EVENT_TABLE()
 };
 
 DECLARE_EVENT_TABLE()
 };
 
index f94ac448f814275cf2ea4cb70c8bfe910d803e90..e52b33de8e4ff7247827ee3729ba8f013b83c620 100644 (file)
@@ -23,7 +23,7 @@
 
 #include <wx/toolbar.h>
 
 
 #include <wx/toolbar.h>
 
-#ifdef __WXGTK__
+#if defined(__WXGTK__) || defined(__WXMOTIF__)
 #include "mondrian.xpm"
 #include "bitmaps/new.xpm"
 #include "bitmaps/open.xpm"
 #include "mondrian.xpm"
 #include "bitmaps/new.xpm"
 #include "bitmaps/open.xpm"
@@ -142,6 +142,8 @@ void MyFrame::OnNewWindow(wxCommandEvent& WXUNUSED(event) )
       // Give it an icon
 #ifdef __WXMSW__
       subframe->SetIcon(wxIcon("chrt_icn"));
       // Give it an icon
 #ifdef __WXMSW__
       subframe->SetIcon(wxIcon("chrt_icn"));
+#else
+      subframe->SetIcon(wxIcon( mondrian_xpm ));
 #endif
 
       // Make a menubar
 #endif
 
       // Make a menubar
@@ -186,7 +188,7 @@ END_EVENT_TABLE()
 
 // Define a constructor for my canvas
 MyCanvas::MyCanvas(wxWindow *parent, const wxPoint& pos, const wxSize& size):
 
 // Define a constructor for my canvas
 MyCanvas::MyCanvas(wxWindow *parent, const wxPoint& pos, const wxSize& size):
- wxScrolledWindow(parent, -1, pos, size, wxSUNKEN_BORDER)
+ wxScrolledWindow(parent, -1, pos, size, wxSUNKEN_BORDER|wxVSCROLL|wxHSCROLL)
 {
 }
 
 {
 }
 
index 55a9efe36d5bcd12e32b8c8552531412b05087da..14d45519e3d92d15ee2d67493aad4c42c0a6ce71 100644 (file)
@@ -88,6 +88,9 @@ LDLIBS      = $(EXTRALDLIBS) $(GUILDLIBS)
 .cpp.o :
        $(CC) -c $(CPPFLAGS) -o $@ $<
 
 .cpp.o :
        $(CC) -c $(CPPFLAGS) -o $@ $<
 
+.C.o :
+       $(CC) -c $(CPPFLAGS) -o $@ $<
+
 ####################### Targets to allow multiple GUIs ####################
 
 dummy:
 ####################### Targets to allow multiple GUIs ####################
 
 dummy:
index 9f63cdba4c2c4bb2487f4214212f63dbfd764eb9..374bdf15da8e7e6bf55cf5b0ca434e77f9030d71 100644 (file)
@@ -31,8 +31,7 @@ CC = gcc
 CCC = $(CC)
 
 # Compiler used for LEX generated C
 CCC = $(CC)
 
 # Compiler used for LEX generated C
-# AIX: use $(CCC)
-CCLEX=$(CC)
+CCLEX=gcc
 
 MAKE=make
 
 
 MAKE=make
 
index 1ebd7a76ea72a2e5c06fa745794a1323dab93df0..305a39a2b9df7d6642f8bee41931537c67602e33 100644 (file)
@@ -18,7 +18,7 @@
 #if wxUSE_COMBOBOX
 
 #include <Xm/Xm.h>
 #if wxUSE_COMBOBOX
 
 #include <Xm/Xm.h>
-#include "combobox/combobox.h"
+#include "xmcombo/xmcombo.h"
 
 void  wxComboBoxCallback (Widget w, XtPointer clientData,
                   XmComboBoxSelectionCallbackStruct * cbs);
 
 void  wxComboBoxCallback (Widget w, XtPointer clientData,
                   XmComboBoxSelectionCallbackStruct * cbs);
index 16be1d39c36c792d41e62e197ca0fbdf642a44c3..c0a24a49ef6ff7145bfba19ac62bea2e93d4839d 100644 (file)
@@ -51,7 +51,7 @@
 #include "wx/motif/private.h"
 
 void wxCloseFrameCallback(Widget, XtPointer, XmAnyCallbackStruct *cbs);
 #include "wx/motif/private.h"
 
 void wxCloseFrameCallback(Widget, XtPointer, XmAnyCallbackStruct *cbs);
-static void wxFrameFocusProc(Widget workArea, XtPointer clientData, 
+void wxFrameFocusProc(Widget workArea, XtPointer clientData, 
                       XmAnyCallbackStruct *cbs);
 static void wxFrameMapProc(Widget frameShell, XtPointer clientData, 
                           XCrossingEvent * event);
                       XmAnyCallbackStruct *cbs);
 static void wxFrameMapProc(Widget frameShell, XtPointer clientData, 
                           XCrossingEvent * event);
@@ -310,14 +310,21 @@ wxFrame::~wxFrame()
     XtDestroyWidget (statusLineWidget);
  */
 
     XtDestroyWidget (statusLineWidget);
  */
 
-  wxDeleteWindowFromTable((Widget) m_workArea);
+  if (m_workArea)
+  {
+      wxDeleteWindowFromTable((Widget) m_workArea);
 
 
-  XtDestroyWidget ((Widget) m_workArea);
-  XtDestroyWidget ((Widget) m_frameWidget);
+      XtDestroyWidget ((Widget) m_workArea);
+  }
 
 
-  wxDeleteWindowFromTable((Widget) m_frameWidget);
+  if (m_frameWidget)
+  {
+      wxDeleteWindowFromTable((Widget) m_frameWidget);
+      XtDestroyWidget ((Widget) m_frameWidget);
+  }
 
 
-  XtDestroyWidget ((Widget) m_frameShell);
+  if (m_frameShell)
+      XtDestroyWidget ((Widget) m_frameShell);
 
   SetMainWidget((WXWidget) NULL);
 
 
   SetMainWidget((WXWidget) NULL);
 
@@ -982,7 +989,7 @@ void wxFrame::SetToolBar(wxToolBar *toolbar)
 wxToolBar *wxFrame::GetToolBar() const
 { return m_frameToolBar; }
 
 wxToolBar *wxFrame::GetToolBar() const
 { return m_frameToolBar; }
 
-static void wxFrameFocusProc(Widget workArea, XtPointer clientData, 
+void wxFrameFocusProc(Widget workArea, XtPointer clientData, 
                       XmAnyCallbackStruct *cbs)
 {
   wxFrame *frame = (wxFrame *)clientData;
                       XmAnyCallbackStruct *cbs)
 {
   wxFrame *frame = (wxFrame *)clientData;
index 89c66ecb6baefe222b3f3e0e40a73e953f6f3092..cc4119e127ceef5e8267cca9f5c3bfce8aa9d023 100644 (file)
@@ -165,13 +165,22 @@ LIB_C_SRC=\
  ../common/extended.c
 
 EXTRA_C_SRC=\
  ../common/extended.c
 
 EXTRA_C_SRC=\
-  combobox/combobox.c
+  xmcombo/xmcombo.c
+
+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
 
 all:    $(WXLIB)
 
 # Define library objects
 OBJECTS=\
 
 all:    $(WXLIB)
 
 # Define library objects
 OBJECTS=\
- $(LIB_CPP_SRC:.cpp=.o) $(LIB_C_SRC:.c=.o) $(EXTRA_C_SRC:.c=.o)
+ $(LIB_CPP_SRC:.cpp=.o) $(LIB_C_SRC:.c=.o) $(EXTRA_C_SRC:.c=.o) $(EXTRA_CPP_SRC:.C=.o)
 
 $(WXLIB) : $(OBJECTS)
        ar $(AROPTIONS) $@ $(OBJECTS)
 
 $(WXLIB) : $(OBJECTS)
        ar $(AROPTIONS) $@ $(OBJECTS)
index 113f78c50ab6ad6fbcd082b150dc6d0b5335fded..0ecb45e87ba080dc3ad8dd5268d8d592abc52890 100644 (file)
 #include "wx/menu.h"
 #include "wx/settings.h"
 
 #include "wx/menu.h"
 #include "wx/settings.h"
 
+#include <Xm/Xm.h>
+#include <Xm/BulletinB.h>
+#include <Xm/Form.h>
+#include <Xm/MainW.h>
+#include <Xm/RowColumn.h>
+#include <Xm/CascadeBG.h>
+#include <Xm/Text.h>
+#include <Xm/PushBG.h>
+#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;
 
 extern wxList wxModelessWindows;
 
+// Implemented in frame.cpp
+extern void wxFrameFocusProc(Widget workArea, XtPointer clientData, 
+                      XmAnyCallbackStruct *cbs);
+
 #if !USE_SHARED_LIBRARY
 IMPLEMENT_DYNAMIC_CLASS(wxMDIParentFrame, wxFrame)
 IMPLEMENT_DYNAMIC_CLASS(wxMDIChildFrame, wxFrame)
 #if !USE_SHARED_LIBRARY
 IMPLEMENT_DYNAMIC_CLASS(wxMDIParentFrame, wxFrame)
 IMPLEMENT_DYNAMIC_CLASS(wxMDIChildFrame, wxFrame)
@@ -36,10 +56,155 @@ END_EVENT_TABLE()
 
 #endif
 
 
 #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 _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()
 {
 // Parent frame
 
 wxMDIParentFrame::wxMDIParentFrame()
 {
+    m_clientWindow = NULL;
 }
 
 bool wxMDIParentFrame::Create(wxWindow *parent,
 }
 
 bool wxMDIParentFrame::Create(wxWindow *parent,
@@ -50,49 +215,39 @@ bool wxMDIParentFrame::Create(wxWindow *parent,
            long style,
            const wxString& name)
 {
            long style,
            const wxString& name)
 {
-    if (!parent)
-        wxTopLevelWindows.Append(this);
-
-    SetName(name);
-    m_windowStyle = style;
-
-    if (parent) parent->AddChild(this);
+    m_clientWindow = NULL;
 
 
-    if ( id > -1 )
-        m_windowId = id;
+    bool success = wxFrame::Create(parent, id, title, pos, size, style, name);
+    if (success)
+    {
+        // TODO: app cannot override OnCreateClient since
+        // wxMDIParentFrame::OnCreateClient will still be called
+        // (we're in the constructor). How to resolve?
+
+        m_clientWindow = OnCreateClient();
+       // Uses own style for client style
+       m_clientWindow->CreateClient(this, GetWindowStyleFlag());
+        return TRUE;
+    }
     else
     else
-        m_windowId = (int)NewControlId();
-
-    // TODO: create MDI parent frame
-
-    wxModelessWindows.Append(this);
-
-    return TRUE;
+        return FALSE;
 }
 
 wxMDIParentFrame::~wxMDIParentFrame()
 {
 }
 
 wxMDIParentFrame::~wxMDIParentFrame()
 {
+    DestroyChildren();
+    delete m_clientWindow;
 }
 
 // Get size *available for subwindows* i.e. excluding menu bar.
 void wxMDIParentFrame::GetClientSize(int *x, int *y) const
 {
 }
 
 // Get size *available for subwindows* i.e. excluding menu bar.
 void wxMDIParentFrame::GetClientSize(int *x, int *y) const
 {
-    // TODO
+    wxFrame::GetClientSize(x, y);
 }
 
 void wxMDIParentFrame::SetMenuBar(wxMenuBar *menu_bar)
 {
 }
 
 void wxMDIParentFrame::SetMenuBar(wxMenuBar *menu_bar)
 {
-    // TODO
-    if (!menu_bar)
-    {
-        m_frameMenuBar = NULL;
-        return;
-    }
-  
-    if (menu_bar->m_menuBarFrame)
-           return;
-
-    m_frameMenuBar = menu_bar;
+    wxFrame::SetMenuBar(menu_bar);
 }
 
 void wxMDIParentFrame::OnSize(wxSizeEvent& event)
 }
 
 void wxMDIParentFrame::OnSize(wxSizeEvent& event)
@@ -187,74 +342,304 @@ bool wxMDIChildFrame::Create(wxMDIParentFrame *parent,
 
     if (parent) parent->AddChild(this);
 
 
     if (parent) parent->AddChild(this);
 
-    // TODO: create child frame
+    int x = pos.x; int y = pos.y;
+    int width = size.x; int height = size.y;
+
+    wxMDIClientWindow* clientWindow = parent->GetClientWindow();
+    if (!clientWindow)
+        return FALSE;
+
+    m_mdiWindow = new wxXsMDIWindow("mdiChildWindow", this);
+    clientWindow->GetMDICanvas()->add(m_mdiWindow);
+    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);
+
+    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);
+
+    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
+
+    SetTitle(title);
+
+    PreResize();
+
+    wxSizeEvent sizeEvent(wxSize(width, height), GetId());
+    sizeEvent.SetEventObject(this);
+
+    GetEventHandler()->ProcessEvent(sizeEvent);
 
     wxModelessWindows.Append(this);
 
     wxModelessWindows.Append(this);
-    return FALSE;
+    return TRUE;
+}
+
+void wxMDIChildFrame::BuildClientArea(WXWidget parent)
+{
+    m_mainWidget = parent;
+
+    m_frameWidget = (WXWidget) XtVaCreateManagedWidget("main_window",
+                    xmMainWindowWidgetClass, (Widget) m_mainWidget,
+                    XmNresizePolicy, XmRESIZE_NONE,
+                    XmNtopAttachment, XmATTACH_FORM,
+                    XmNbottomAttachment, XmATTACH_FORM,
+                    XmNleftAttachment, XmATTACH_FORM,
+                    XmNrightAttachment, XmATTACH_FORM,
+                    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);
+
+    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);
+
+    /*
+    int x = pos.x; int y = pos.y;
+    int width = size.x; int height = size.y;
+
+    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);
+      */
+
+    XtManageChild((Widget) m_frameWidget);
 }
 
 }
 
+
 wxMDIChildFrame::~wxMDIChildFrame()
 {
 wxMDIChildFrame::~wxMDIChildFrame()
 {
+    wxMDIClientWindow* clientWindow = ((wxMDIParentFrame*)GetParent())->GetClientWindow();
+    clientWindow->GetMDICanvas()->remove(m_mdiWindow);
+    m_mainWidget = (WXWidget) 0;
 }
 
 // Set the client size (i.e. leave the calculation of borders etc.
 // to wxWindows)
 void wxMDIChildFrame::SetClientSize(int width, int height)
 {
 }
 
 // Set the client size (i.e. leave the calculation of borders etc.
 // to wxWindows)
 void wxMDIChildFrame::SetClientSize(int width, int height)
 {
-    // TODO
+    wxFrame::SetClientSize(width, height);
+}
+
+void wxMDIChildFrame::GetClientSize(int* width, int* height) const
+{
+    wxFrame::GetClientSize(width, height);
+}
+
+void wxMDIChildFrame::SetSize(int x, int y, int width, int height, int sizeFlags)
+{
+    wxWindow::SetSize(x, y, width, height, sizeFlags);
+}
+
+void wxMDIChildFrame::GetSize(int* width, int* height) const
+{
+    wxWindow::GetSize(width, height);
 }
 
 void wxMDIChildFrame::GetPosition(int *x, int *y) const
 {
 }
 
 void wxMDIChildFrame::GetPosition(int *x, int *y) const
 {
-    // TODO
+    wxWindow::GetPosition(x, y);
+}
+
+bool wxMDIChildFrame::Show(bool show)
+{
+    m_visibleStatus = show; /* show-&-hide fix */
+    return TRUE;
 }
 
 void wxMDIChildFrame::SetMenuBar(wxMenuBar *menu_bar)
 {
     // TODO
 }
 
 void wxMDIChildFrame::SetMenuBar(wxMenuBar *menu_bar)
 {
     // TODO
-    if (!menu_bar)
+    // 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);
+}
+
+// Set icon
+void wxMDIChildFrame::SetIcon(const wxIcon& icon)
+{
+    m_icon = icon;
+    if (m_icon.Ok())
     {
     {
-        m_frameMenuBar = NULL;
-        return;
+      /* TODO: doesn't work yet (crashes in XCopyArea)
+        Pixmap pixmap = (Pixmap) m_icon.GetPixmap();
+        m_mdiWindow->setPixmap(pixmap);
+       */
     }
     }
-  
-    if (menu_bar->m_menuBarFrame)
-           return;
-    m_frameMenuBar = menu_bar;
+}
+
+void wxMDIChildFrame::SetTitle(const wxString& title)
+{
+    m_title = title;
+    m_mdiWindow->setTitle(title);
+    m_mdiWindow->setIconName(title);
 }
 
 // MDI operations
 void wxMDIChildFrame::Maximize()
 {
 }
 
 // MDI operations
 void wxMDIChildFrame::Maximize()
 {
-    // TODO
+   m_mdiWindow->maximize();
+}
+
+void wxMDIChildFrame::Iconize(bool iconize)
+{
+   if (iconize)
+      m_mdiWindow->minimize();
+   else
+      m_mdiWindow->restore();
+}
+
+bool wxMDIChildFrame::IsIconized() const
+{
+    return m_mdiWindow->minimized();
 }
 
 void wxMDIChildFrame::Restore()
 {
 }
 
 void wxMDIChildFrame::Restore()
 {
-    // TODO
+    m_mdiWindow->restore();
 }
 
 void wxMDIChildFrame::Activate()
 {
 }
 
 void wxMDIChildFrame::Activate()
 {
-    // TODO
+    m_mdiWindow->raise();
 }
 
 // Client window
 
 wxMDIClientWindow::wxMDIClientWindow()
 {
 }
 
 // Client window
 
 wxMDIClientWindow::wxMDIClientWindow()
 {
+    m_mdiCanvas = NULL;
+    m_topWidget = (WXWidget) 0;
 }
 
 wxMDIClientWindow::~wxMDIClientWindow()
 {
 }
 
 wxMDIClientWindow::~wxMDIClientWindow()
 {
+    DestroyChildren();
+    delete m_mdiCanvas;
+
+    m_mainWidget = (WXWidget) 0;
+    m_topWidget = (WXWidget) 0;
 }
 
 bool wxMDIClientWindow::CreateClient(wxMDIParentFrame *parent, long style)
 {
 }
 
 bool wxMDIClientWindow::CreateClient(wxMDIParentFrame *parent, long style)
 {
-    // TODO create client window
+    m_windowParent = parent;
     m_backgroundColour = wxSystemSettings::GetSystemColour(wxSYS_COLOUR_APPWORKSPACE);
     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();
+
+    return TRUE;
+}
+
+void wxMDIClientWindow::SetSize(int x, int y, int width, int height, int sizeFlags)
+{
+    wxWindow::SetSize(x, y, width, height, sizeFlags);
+}
 
 
-    return FALSE;
+void wxMDIClientWindow::SetClientSize(int width, int height)
+{
+    wxWindow::SetClientSize(width, height);
+}
+
+void wxMDIClientWindow::GetClientSize(int *width, int *height) const
+{
+    wxWindow::GetClientSize(width, height);
+}
+
+void wxMDIClientWindow::GetSize(int *width, int *height) const
+{
+    wxWindow::GetSize(width, height);
+}
+
+void wxMDIClientWindow::GetPosition(int *x, int *y) const
+{
+    wxWindow::GetPosition(x, y);
 }
 
 // Explicitly call default scroll behaviour
 }
 
 // Explicitly call default scroll behaviour
diff --git a/src/motif/mdi/COPYRIGHT b/src/motif/mdi/COPYRIGHT
new file mode 100644 (file)
index 0000000..90071d4
--- /dev/null
@@ -0,0 +1,29 @@
+Copyright (c) 1996  Scott W. Sadler
+All rights reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to use,
+copy, modify, and distribute, copies of the Software, and to permit persons to
+whom the Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+SCOTT W. SADLER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of Scott W. Sadler shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization.
+
+Scott W. Sadler
+Software Engineer
+International TechneGroup Incorporated   
+5303 DuPont Circle
+Milford, OH  45150
+sws@iti-oh.com
+http://www.iti-oh.com/~sws
diff --git a/src/motif/mdi/Imakefile b/src/motif/mdi/Imakefile
new file mode 100644 (file)
index 0000000..a2c6b73
--- /dev/null
@@ -0,0 +1,9 @@
+#include "config/MDI.tmpl"
+
+#define IHaveSubdirs
+#define PassCDebugFlags 'CDEBUGFLAGS=$(CDEBUGFLAGS)'
+
+SUBDIRS = lib test
+
+MakeSubdirs($(SUBDIRS))
+DependSubdirs($(SUBDIRS))
diff --git a/src/motif/mdi/config/C++.rules b/src/motif/mdi/config/C++.rules
new file mode 100644 (file)
index 0000000..3cb56a6
--- /dev/null
@@ -0,0 +1,9 @@
+#define CxxRules()                                     @@\
+                                                       @@\
+CxxSuffixRules()               
+
+#define CxxSuffixRules()                               @@\
+.SUFFIX: .C .o                                         @@\
+.C.o:                                                  @@\
+       $(CXX) $(CFLAGS) $(EXTRA_FLAGS) -c $<
+
diff --git a/src/motif/mdi/config/MDI.tmpl b/src/motif/mdi/config/MDI.tmpl
new file mode 100644 (file)
index 0000000..dafc038
--- /dev/null
@@ -0,0 +1,45 @@
+#undef FOUND_COMPILER
+
+#ifdef SGIArchitecture
+CXX = CC
+CC = $(CXX)
+#define FOUND_COMPILER
+#endif
+
+#ifdef SparcArchitecture
+CXX = CC
+CC = $(CXX)
+#define FOUND_COMPILER
+#endif
+
+#ifdef HPArchitecture
+CXX = CC
+CC = $(CXX)
+#define FOUND_COMPILER
+#endif
+
+#ifdef AIXArchitecture
+CXX = xlC
+CC = $(CXX)
+EXTRA_FLAGS =  -U__STR__ -D_POSIX_SOURCE
+#define FOUND_COMPILER
+#endif
+
+#ifdef OSF1Architecture
+CXX = cxx
+CC = $(CXX)
+#define FOUND_COMPILER
+#endif
+
+#ifdef LinuxArchitecture
+CXX = gcc
+CC = $(CXX)
+#define FOUND_COMPILER
+#endif
+
+#ifndef FOUND_COMPILER
+CXX = gcc
+CC = $(CXX)
+#endif
+
+#include "C++.rules"
diff --git a/src/motif/mdi/doc/canvas.html b/src/motif/mdi/doc/canvas.html
new file mode 100644 (file)
index 0000000..1ddbf3c
--- /dev/null
@@ -0,0 +1,140 @@
+<HTML>
+
+<HEAD>
+<TITLE>XsMDICanvas Class</TITLE>
+<LINK REV="made" HREF="mailto:sws@iti-oh.com">
+</HEAD>
+
+<H2>
+The XsMDICanvas Class
+</H2>
+
+<P>
+This section describes how to build and manipulate an MDI using the
+<I>XsMDICanvas</I> class.  Minimally, you must perform the following actions
+to build and display an MDI canvas:
+
+<OL>
+<LI>Create the <I>XsMDICanvas</I> object.</LI>
+<LI>Create the documents as instances of subclasses of <I>XsMDIWindow</I>.</LI>
+<LI>Add the documents to the canvas</LI>
+<LI>Show the canvas</LI>
+</OL>
+
+<P>
+<B>Constructor and Destructor:</B>
+
+<P>
+The <I>XsMDICanvas</I> accepts two arguments:
+
+<DL>
+<DD>XsMDICanvas (const char *name, Widget parent)</DD>
+</DL>
+
+<P>
+The <I>name</I> parameter specifies the name of the canvas and is used
+as the widget name for the underlying implementation.  The <I>parent</I>
+parameter specifies the widget that is to be used as the parent of the
+canvas.
+
+<P>
+The <I>XsMDICanvas</I> destructor destroys the canvas, but it <B>does not</B>
+destroy any of the underlying documents.  It is up to the application to
+destroy these.
+
+<P>
+<B>Adding and removing documents:</B>
+
+<P>
+After the documents are created, they must be added to the canvas.  The
+<I>XsMDICanvas::add()</I> member-function adds documents to the canvas:
+
+<DL>
+<DD>virtual void add (XsMDIWindow *window)</DD>
+</DL>
+
+<P>
+The behavior of adding the same document to the canvas more than once
+is undefined.  Documents can be removed from the canvas by using:
+
+<DL>
+<DD>virtual void remove (XsMDIWindow *window)</DD>
+</DL>
+
+<P>
+Additionally, all documents can be removed from the canvas with:
+
+<DL>
+<DD>void removeAll ( )</DD>
+</DL>
+
+<P>
+The number of documents currently installed in the canvas can be
+retrieved with:
+
+<DL>
+<DD>int numWindows ( ) const</DD>
+</DL>
+
+<P>
+<B>Showing the canvas:</B>
+
+<P>
+In order to show (manage) the canvas call the <I>show</I> member function:
+
+<DL>
+<DD>virtual void show ( )</DD>
+</DL>
+
+This member-function is responsible for cycling all of the installed documents
+and calling their respective <I>XsMDIWindow::_buildClientArea()</I>
+member-functions.  After each document has been created, <I>show</I> will then
+manage each document and, finally, itself.
+
+<P>
+<B>Window Placement:</B>
+
+<P>
+The current implementation of <I>XsMDICanvas</I> uses a very simple algorithm
+to place the documents on the canvas.  In order to implement a more specific
+placement algorithm, derive a class from <I>XsMDICanvas</I> and override
+the member-function:
+
+<DL>
+<DD>virtual  void _placeWindow (XsMDIWindow *win)</DD>
+</DL>
+
+<P>
+This member-function is called for each document in the canvas to compute
+the location of the document.  Please refer to the code (<I>XsMDICanvas.C</I>)
+for more details.
+
+<P>
+<B>Canvas Behavior:</B>
+
+<P>
+The <I>XsMDICanvas</I> is implemented as an <I>XmScrolledWindow</I> with an
+<I>XmDrawingArea</I> work-window.  The instance name for the work-window
+is <I>canvas</I>.  Internal callbacks in the canvas class force the work-window
+to be at-least the size of the clip-window.  This prevents documents from
+being clipped as they are moved around.  
+
+<P>
+By default, the <I>XmDrawingArea</I> work-window has its <I>XmNresizePolicy</I>
+set to <I>XmRESIZE_GROW</I>.  This will allow the work-area to grow to
+whatever size necessary, but it will not automatically shrink as windows
+are manipulated.  If different behavior is desired, the <I>XmNresizePolicy</I>
+resource on the work-area can be set to <I>XmRESIZE_ANY</I>.  This will
+force the work-window to recompute its size as windows are manipulated, and
+it will grow and shrink as necessary.  However, the <I>XsMDICanvas</I> will
+still force the work-area to be at-least the size of the clip-window.
+
+<P>To change the default behavior, add the following resource:
+
+<DL>
+<DD>&ltXsMDICanvas name&gt*canvas.resizePolicy:   XmRESIZE_ANY</DD>
+</DL>
+
+</BODY>
+</HTML>
+
diff --git a/src/motif/mdi/doc/mdi.html b/src/motif/mdi/doc/mdi.html
new file mode 100644 (file)
index 0000000..1ee8252
--- /dev/null
@@ -0,0 +1,182 @@
+<HTML>
+
+<HEAD>
+<TITLE>Motif Multi-Document Interface (MDI)</TITLE>
+<LINK REV="made" HREF="mailto:sws@iti-oh.com">
+</HEAD>
+
+<CENTER>
+<IMG SRC="pics/mdi.gif" ALT="[Class Structure]">
+<P><H2>
+<B>
+The Motif Multi-Document Interface
+</B>
+</H2>
+</CENTER>
+
+<P>
+The Motif Multi-Document Interface (MDI) is a collection of C++ classes
+that emulates the behavior of the Multi-Document Interface in Microsoft
+Windows.  The MDI framework allows a user to view multiple documents (windows)
+constrained to a single parent window.
+
+<P>
+<HR SIZE = 4>
+
+<P>
+<B>
+C<FONT SIZE=-1>LASS</FONT>
+S<FONT SIZE=-1>TRUCTURE:</FONT>
+</B>
+
+<P>
+<IMG SRC="pics/classes.gif" ALT="[Class Structure]">
+
+<BR>
+Figure 1.  Inheritance Graph for MDI classes
+
+<P>
+The <I>XsMDICanvas</I> is a self-contained component used to display and manage
+any number of child document windows.  All documents windows are derived from
+the abstract base-class <I>XsMDIWindow</I>.  To get the Motif-like functionality,
+document windows should be derived from the <I>XsMotifWindow</I> class.
+
+<P>
+<HR SIZE = 4>
+
+<P>
+<B>
+E<FONT SIZE=-1>XAMPLE:</FONT> 
+</B>
+
+<P>
+The process of building and displaying a Multi-Document Interface using MDI
+consists of the following steps:
+
+<OL>
+<LI>Creating the application document(s)</LI>
+<LI>Creating the MDI canvas</LI>
+<LI>Adding the document(s) to the canvas</LI>
+</OL>
+
+<PRE>
+
+#include "XsMDICanvas.h"
+#include "XsMotifWindow.h"
+
+// Application document (derived from XsMotifWindow)
+
+class MyDocument : public XsMotifWindow {
+   public:
+      MyDocument (const char *name);
+      virtual ~MyDocument ( );
+   protected:
+      virtual void _buildClientArea (Widget parent);
+};
+      
+void createCanvas (Widget parent) {
+
+// Create documents
+
+   MyDocument *doc1 = new MyDocument ("doc1");
+   MyDocument *doc2 = new MyDocument ("doc2");
+   
+// Create the canvas
+
+   XsMDICanvas *canvas = new XsMDICanvas ("canvas", parent);
+   
+// Add documents to canvas
+
+   canvas->add (doc1);
+   canvas->add (doc2);
+
+// Show the canvas
+
+   canvas->show ( );
+}
+   
+</PRE>
+
+<P>
+In this example, the application document <I>MyDocument</I> is derived
+from <I>XsMotifWindow</I>.  This provides a Motif-like window suitable for
+use with the <I>XsMDICanvas</I>.
+
+<P>
+Next, two <I>MyDocument</I> objects are created along with the <I>XsMDICanvas</I>.
+The two documents are then added to the canvas using the <I>add</I>
+member-function of the canvas.  Lastly, the canvas is shown (managed)
+using the <I>show</I> member-function.
+
+<P>
+Creating the document <I>MyDocument</I> does not automatically create any
+widgets.  Rather, it only initializes internal variables.  The widgets are
+not created until the document is added to the canvas.  The <I>XsMDICanvas</I>
+is responsible for calling <I>XsMotifWindow::_buildClientArea()</I> at an
+appropriate time.  In this member-function, the application can create the
+actual contents of the document.
+
+<P>
+The member-function <I>_buildClientArea</I> is passed a widget to be used as
+the parent of the document contents.  This parent widget is an unmanaged
+<I>XmForm</I> widget.  The application is free to create whatever contents
+it needs as a child of the <I>XmForm</I> parent.
+
+<P>
+<HR SIZE = 4>
+
+<P>
+<B>
+C<FONT SIZE=-1>LASS</FONT>
+R<FONT SIZE=-1>EFERENCES:</FONT>
+</B>
+
+<P>
+Of the classes in the MDI package, only the following should be of
+interest to MDI library users:
+
+<UL>
+<LI> <A HREF="canvas.html"> XsMDICanvas </A> </LI>
+<LI> <A HREF="mwindow.html"> XsMotifWindow </A> </LI>
+</UL>
+
+<P>
+<HR SIZE = 4>
+
+<P>
+<B>
+E<FONT SIZE=-1>XPLORING</FONT>
+R<FONT SIZE=-1>ESOURCES:</FONT>
+</B>
+
+<P>
+The MDI classes support a number of different X-resources (please refer
+the the class manual pages for complete details).  In order to get a feel
+for the customization capabilities of the MDI library, try running the
+test program (<I>MDItest</I>) with the following command-line options:
+
+<DL>
+<DD>MDItest -xrm "*showBorder:false"</DD>
+<DD>MDItest -xrm "*showTitle:false" -xrm "*showResize:false"</DD>
+<DD>MDItest -xrm "*showMenu:false" -xrm "*showMaximize:false"</DD>
+<DD>MDItest -xrm "*borderSize:4" -xrm "*buttonSize:14"</DD>
+<DD>MDItest -xrm "*lowerOnIconify:true" -xrm "*title:Hello World"</DD>
+</DL>
+
+<P>
+<HR SIZE = 4>
+
+<P>
+<B>
+A<FONT SIZE=-1>DDITIONAL</FONT>
+I<FONT SIZE=-1>INFORMATION:</FONT>
+</B>
+
+<P>
+The test program <I>MDItest.C</I> gives a complete example of an MDI
+application.  It should serve as a good reference/example of the MDI library.
+
+</BODY>
+</HTML>
+
+
diff --git a/src/motif/mdi/doc/mwindow.html b/src/motif/mdi/doc/mwindow.html
new file mode 100644 (file)
index 0000000..effbdcd
--- /dev/null
@@ -0,0 +1,277 @@
+<HTML>
+
+<HEAD>
+<TITLE>XsMotifWindow Class</TITLE>
+<LINK REV="made" HREF="mailto:sws@iti-oh.com">
+</HEAD>
+
+<H2>
+The XsMotifWindow Class
+</H2>
+
+<P>
+The <I>XsMDICanvas</I> requires that all documents be a subclass of 
+<I>XsMDIWindow</I> or a subclass of a class derived from it.  By itself
+<I>XsMDIWindow</I> does not define any appearance or behavior for the
+documents.  However, <I>XsMotifWindow</I>, derived from <I>XsMDIWindow</I>,
+defines a MWM-like look-and-feel to a document.
+
+<P>
+Documents in your application should be derived from <I>XsMotifWindow</I>.  
+This class provides the look-and-feel of Motif window and supports the 
+interaction with the <I>XsMDICanvas</I>.  It is up to the application to 
+define the contents of each document.
+
+<P>
+<B>Constructor and Destructor:</B>
+
+<P>
+The <I>XsMotifWindow</I> constructor accepts one argument:
+
+<DL>
+<DD>XsMotifWindow (const char *name)</DD>
+</DL>
+
+<P>
+The <I>name</I> parameter specifies the name of the document and is used
+as the widget name for the underlying implementation.  The name parameter
+is also used as the default title and icon-name for the document.  
+
+<P>
+<B>Note:</B>  The <I>XsMotifWindow</I> constructor does not create any
+widgets.  Rather it only initializes internal variables.  The widgets are
+not created until the document is added to the canvas.  The <I>XsMDICanvas</I>
+calls the member-function <I>XsMotifWindow::_buildClientArea()</I> when it needs
+to create the document widgets.
+
+<P>
+The <I>XsMotifWindow</I> destructor destroys the document widgets (if they have
+been created) and frees its internal storage.  It is up to the application
+to free all documents.  The <I>XsMDICanvas</I> will <B>not</B> destroy the
+documents for you.
+
+<P>
+<B>Document Utilities:</B>
+
+<P>
+Although rarely called from the application, the <I>XsMotifWindow</I> supports
+a number of utility functions to manipulate the document.
+
+<DL>
+<DD>virtual void raise ( )</DD>
+<DD>virtual void lower ( )</DD>
+<DD>virtual void minimize ( )</DD>
+<DD>virtual void maximize ( )</DD>
+<DD>virtual void restore ( )</DD>
+<DD>virtual void close ( )</DD>
+</DL>
+
+<P>
+The <I>close</I> member-function does not destroy the document, it simply
+hides it from view.  You can restore a closed document with
+<I>XsMotifWindow::show()</I>.
+
+<P>
+The following member-functions are used to change/query the appearance of
+the document:
+
+<DL>
+<DD>void  setTitle (const char *name)</DD>
+<DD>const char *title ( ) const</DD>
+<DD>void  setIconName (const char *name)</DD>
+<DD>const char *iconName ( ) const</DD>
+<DD>void  setPixmap (Pixmap pixmap)</DD>
+<DD>Pixmap pixmap ( ) const</DD>
+<DD>Widget icon ( ) const</DD>
+<DD>Boolean minimized ( ) const</DD>
+<DD>Boolean  maximized ( ) const</DD>
+<DD>virtual void setPosition (Position x, Position y)</DD>
+<DD>virtual void setSize (Dimension width, Dimension height)</DD>
+</DL>
+
+<P>
+The <I>setPixmap</I> member-function accepts a pixmap which the document then
+uses as the decoration on the icon.  Because the document does not make a copy 
+of the pixmap, it is important that the application not free the pixmap until 
+all documents that reference it are deleted.  The document does, however, make 
+a local copy of the title or icon-name string passed to it, so the application
+is free to do whatever it wants to the passed-in string.  The <I>icon</I>
+member-function returns the widget that is used to implement the icon.
+
+
+<P>
+<B>Creating Window Subclasses:</B>
+
+<P>
+The application must derive its documents from <I>XsMotifWindow</I> in order to
+define the contents of the document.  The <I>XsMDICanvas</I> calls the
+protected member-function <I>_buildClientArea</I> when it creates the 
+document. Each class derived from <I>XsMotifWindow</I> <B>must</B> override
+this pure-virtual member-function.
+
+<P>
+The member-function <I>_buildClientArea</I> is called with a single argument:
+
+<DL>
+<DD>virtual void _buildClientArea (Widget parent)</DD>
+</DL>
+
+The <I>parent</I> argument should be used as the parent of the contents of
+the document.  This widget is an unmanaged <I>XmForm</I> widget, and all of 
+the standard resources and constrains apply to it.  The <I>XsMDICanvas</I>
+is responsible for managing the parent widget at the appropriate time.
+
+<P>
+As an example, consider the following:
+
+<PRE>
+// _buildClientArea (called to create document contents)
+
+void MyDocument::_buildClientArea (Widget parent)
+{
+   assert (parent != 0);
+   
+// 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);
+   ...
+   
+   XtManageChild (mainW);
+}
+</PRE>
+
+<P>
+In this case, an <I>XmMainWindow</I> is created as the child of the parent
+widget.  The <I>XmMainWindow</I> is then attached to the 4 sides of the parent
+form.  Note also that the main window is managed before returning from the
+function.
+
+<P>
+<B>Resources:</B>
+
+<P>
+The <I>XsMotifWindow</I> supports the following resources:
+
+<PRE>
+   Name              Class             Type           Default
+------------------------------------------------------------------------------
+   borderSize        BorderSize        Dimension      6
+   buttonSize        ButtonSize        Dimension      23
+   title             Title             String         dynamic
+   titleFont         TitleFont         String         -*-helvetica-bold-o-normal-*-14-*-*-*-*-*-iso8859-1
+   iconSize          IconSize          Dimension      70
+   iconName          IconName          String         dynamic
+   iconFont          IconFont          String         *-helvetica-bold-r-normal-*-12-*-*-*-*-*-iso8859-1
+   XmNiconX          XmCIconX          Position       dynamic
+   XmNiconY          XmCIconY          Position       dynamic
+   saveUnder         SaveUnder         Boolean        True
+   restoreString     RestoreString     String         "Restore"
+   moveString        MoveString        String         "Move"
+   sizeString        SizeString        String         "Size"
+   minimizeString    MinimizeString    String         "Minimize"
+   maximizeString    MaximizeString    String         "Maximize"
+   raiseString       RaiseString       String         "Raise"
+   lowerString       LowerString       String         "Lower"
+   closeString       CloseString       String         "Close"
+   menuFont          MenuFont          String         -*-helvetica-bold-o-normal-*-14-*-*-*-*-*-iso8859-1
+   showBorder        ShowBorder        Boolean        True
+   showResize        ShowResize        Boolean        True
+   showTitle         ShowTitle         Boolean        True
+   showMenu          ShowMenu          Boolean        True
+   showMinimize      ShowMinimize      Boolean        True   
+   showMaximize      ShowMaximize      Boolean        True
+   lowerOnIconify    LowerOnIconify    Boolean        False
+   XmNminWidth       XmCMinWidth       Dimension      dynamic
+   XmNmaxWidth       XmCMaxWidth       Dimension      dynamic
+   XmNminHeight      XmCMinHeight      Dimension      dynamic
+   XmNmaxHeight      XmCMaxHeight      Dimension      dynamic
+</PRE>
+
+<DL>
+<DD>
+<DL>
+<DT>borderSize</DT>
+<DD>Size of the window border.</DD>
+<DT>buttonSize</DT>
+<DD>Size of the window buttons.</DD>
+<DT>title</DT>
+<DD>Title of the window.  The default is the name of the window instance.</DD>
+<DT>titleFont</DT>
+<DD>Font used to draw the window title.</DD>
+<DT>iconSize</DT>
+<DD>Size of the icon representation.</DD>
+<DT>iconName</DT>
+<DD>String used on the title.  If unspecified, the window title is used.</DD>
+<DT>iconFont</DT>
+<DD>Font used to draw the icon-name.</DD>
+<DT>XmNiconX</DT>
+<DD>X-position of the icon.  The default location is the top-left
+corner of the window when it is iconified.</DD>
+<DT>XmNiconY</DT>
+<DD>Y-position of the icon.  The default location is the top-left
+corner of the window when it is iconified.</DD>
+<DT>saveUnder</DT>
+<DD>Enables/Disables save-unders for the menu.</DD>
+<DT>restoreString</DT>
+<DD>String used as the "restore" menu item.</DD>
+<DT>moveString</DT>
+<DD>String used as the "move" menu item.</DD>
+<DT>sizeString</DT>
+<DD>String used as the "size" menu item.</DD>
+<DT>minimizeString</DT>
+<DD>String used as the "minimize" menu item.</DD>
+<DT>maximizeString</DT>
+<DD>String used as the "maximize" menu item.</DD>
+<DT>raiseString</DT>
+<DD>String used as the "raise" menu item.</DD>
+<DT>lowerString</DT>
+<DD>String used as the the "lower" menu item.</DD>
+<DT>closeString</DT>
+<DD>String used as the "close" menu item.</DD>
+<DT>menuFont</DT>
+<DD>Font used to draw the menu strings.</DD>
+<DT>showBorder</DT>
+<DD>Enables/Disables the window border.  If the border is disabled,
+the resize-handles are automatically disabled.</DD>
+<DT>showResize</DT>
+<DD>Enables/Disables the window resize handles.</DD>
+<DT>showTitle</DT>
+<DD>Enables/Disables the window title.  If the title is disabled,
+all of the window buttons are automatically disabled.</DD>
+<DT>showMenu</DT>
+<DD>Enables/Disables the window menu button.</DD>
+<DT>showMinimize</DT>
+<DD>Enables/Disables the window minimize button.</DD>
+<DT>showMaximize</DT>
+<DD>Enables/Disables the window maximize button.</DD>
+<DT>lowerOnIconify</DT>
+<DD>Automatically lower windows when iconified.</DD>
+<DT>XmNminWidth</DT>
+<DD>Minimium window width.  The default is about four times the size of
+the window button.</DD>
+<DT>XmNmaxWidth</DT>
+<DD>Maximum window width.  The default is not to constrain the maximum size.</DD>
+<DT>XmNminHeight</DT>
+<DD>Minimum window height.  The default is about four times the size of
+the window button.</DD>
+<DT>XmNmaxHeight</DT>
+<DD>Maximum window height.  The default is not to constrain the maximum size.</DD>
+</DL>
+</DD>
+</DL>
+
+<P>
+<B>XsMotifWindow Implementation:</B>
+
+<P>
+As a convenience to those who wish to modify the <I>XsMotifWindow</I> code,
+here is a diagram of the internal class structure:
+
+<P>
+<IMG SRC="pics/winclass.gif" ALT="[Class Structure]">
+
+</BODY>
+</HTML>
diff --git a/src/motif/mdi/doc/pics/classes.gif b/src/motif/mdi/doc/pics/classes.gif
new file mode 100644 (file)
index 0000000..9f5deb2
Binary files /dev/null and b/src/motif/mdi/doc/pics/classes.gif differ
diff --git a/src/motif/mdi/doc/pics/mdi.gif b/src/motif/mdi/doc/pics/mdi.gif
new file mode 100644 (file)
index 0000000..c43414b
Binary files /dev/null and b/src/motif/mdi/doc/pics/mdi.gif differ
diff --git a/src/motif/mdi/doc/pics/winclass.gif b/src/motif/mdi/doc/pics/winclass.gif
new file mode 100644 (file)
index 0000000..ef9896e
Binary files /dev/null and b/src/motif/mdi/doc/pics/winclass.gif differ
diff --git a/src/motif/mdi/lib/Imakefile b/src/motif/mdi/lib/Imakefile
new file mode 100644 (file)
index 0000000..2dd6402
--- /dev/null
@@ -0,0 +1,21 @@
+#include "../config/MDI.tmpl"
+
+SRCS =      XsComponent.C XsMDICanvas.C XsMDIWindow.C XsMotifWindow.C \
+            XsMoveOutline.C XsOutline.C XsResizeOutline.C
+
+HEADERS =   XsComponent.h XsMDICanvas.h XsMDIWindow.h XsMotifWindow.h \
+            sMoveOutline.h XsOutline.h XsResizeOutline.h
+
+OBJS =      XsComponent.o XsMDICanvas.o XsMDIWindow.o XsMotifWindow.o \
+            XsMoveOutline.o XsOutline.o XsResizeOutline.o
+
+STD_INCLUDES = -I/usr/include
+
+INCLUDES =  -I.
+
+LIBXSW =    Xsw
+
+NormalLibraryObjectRule()
+NormalLibraryTarget($(LIBXSW),$(OBJS))
+DependTarget()
+CxxRules()
diff --git a/src/motif/mdi/lib/XsComponent.C b/src/motif/mdi/lib/XsComponent.C
new file mode 100644 (file)
index 0000000..a09ed87
--- /dev/null
@@ -0,0 +1,201 @@
+/*
+   Copyright (C) 1996 Scott W. Sadler
+   All rights reserved.
+*/
+
+/*
+   XsComponent.C
+
+   History
+      03-Mar-96 1.0; Scott W. Sadler (sws@iti-oh.com)
+                     Created         
+*/
+
+// Includes
+
+#ifndef NDEBUG
+#include <iostream.h>
+#endif
+
+#include <assert.h>
+#include <stdio.h>
+#include <string.h>
+#include <Xm/Xm.h>
+#include "XsComponent.h"
+
+// Constructor
+
+XsComponent::XsComponent (const char *name)
+{
+   assert (name != 0);
+   
+// Initialize
+
+   _base = 0;
+   
+// Copy component name
+
+   int len = strlen (name);
+   _name = new char [len + 1];
+   strcpy (_name, name);
+}
+
+// Destructor  
+
+XsComponent::~XsComponent ( )
+{
+
+// Destroy the widget
+
+   if (_base != 0)
+   {
+      _removeDestroyHandler ( );
+      XtDestroyWidget (_base);
+   }
+      
+   delete [] _name;
+}
+   
+// show
+
+void XsComponent::show ( )
+{
+
+#ifndef NDEBUG
+   if (XtIsManaged (_base))
+      cout << "Re-managing a widget:" << _name << endl;
+#endif
+
+// Make sure the _destroyHandler was installed
+
+   assert (XtHasCallbacks (_base, XmNdestroyCallback) == XtCallbackHasSome);
+
+   assert (_base != 0);
+   XtManageChild (_base);
+}
+
+// hide
+
+void XsComponent::hide ( )
+{
+
+#ifndef NDEBUG
+   if (!XtIsManaged (_base)) 
+      cout << "Re-unmanaging a widget:" << _name << endl;
+#endif
+
+   assert (_base != 0);
+   XtUnmanageChild (_base);
+}
+
+// Conversion operator
+
+XsComponent::operator Widget ( ) const
+{
+   assert (_base != 0);
+   return (_base);
+}
+
+// operator ==
+   
+Boolean XsComponent::operator == (const XsComponent& rval)
+{
+   return (_base == rval._base);
+}
+   
+// className
+
+const char* XsComponent::className ( ) const
+{
+   return ("XsComponent");
+}
+
+// _installDestroyHandler
+
+void XsComponent::_installDestroyHandler ( )
+{
+   assert (_base != 0);
+   
+// Install the destroy handler
+
+   XtAddCallback (_base, XmNdestroyCallback, _componentDestroyedCallback, (XtPointer)this);
+}
+
+// _removeDestroyHandler
+
+void XsComponent::_removeDestroyHandler ( )
+{
+   assert (_base != 0);
+
+// Remove the destroy handler
+
+   XtRemoveCallback (_base, XmNdestroyCallback, _componentDestroyedCallback, (XtPointer)this);
+}
+
+// _componentDestroyed
+
+void XsComponent::_componentDestroyed ( )
+{
+   _base = 0;
+}
+
+// _componentDestroyedCallback
+
+void XsComponent::_componentDestroyedCallback (Widget, XtPointer clientData, XtPointer)
+{
+   XsComponent *obj = (XsComponent*)clientData;
+   obj->_componentDestroyed ( );
+}
+
+// _setResources
+
+void XsComponent::_setResources (Widget w, const String *resources)
+{
+   assert (w != 0);
+   
+   XrmDatabase rdb = 0;
+   const int bufSize = 200;
+   char  buffer[bufSize];
+   int   loop;
+
+// Create an empty resource database
+
+   rdb = XrmGetStringDatabase ("");
+
+// Add the component resources
+
+   loop = 0;
+   while (resources[loop] != 0)
+   {
+      sprintf (buffer, "*%s%s\n", _name, resources[loop++]);
+      assert (strlen (buffer) < bufSize);
+      XrmPutLineResource (&rdb, buffer);
+   }
+   
+// Merge these resources into the database
+
+   if (rdb != 0)
+   {
+      XrmDatabase db = XtDatabase (XtDisplay (w));
+      XrmCombineDatabase (rdb, &db, FALSE);
+   }
+}
+
+// _getResources
+
+void XsComponent::_getResources (const XtResourceList resources, int num)
+{
+   assert (_base != 0);
+   assert (resources != 0);
+         
+// Validate input
+
+   if (num <= 0)
+      return;
+      
+// Get the subresources
+
+   XtGetSubresources (XtParent (_base), (XtPointer)this, _name,
+      className ( ), resources, num, 0, 0);
+}   
+
diff --git a/src/motif/mdi/lib/XsComponent.h b/src/motif/mdi/lib/XsComponent.h
new file mode 100644 (file)
index 0000000..d2d71f0
--- /dev/null
@@ -0,0 +1,98 @@
+/*
+   Copyright (C) 1996 Scott W. Sadler
+   All rights reserved.
+*/
+
+/*
+   XsComponent.h
+
+   History
+      03-Mar-96 1.0; Scott W. Sadler (sws@iti-oh.com)
+                     Created         
+*/
+
+#ifndef XSCOMPONENT_H
+#define XSCOMPONENT_H
+
+// Includes
+
+#include <X11/Intrinsic.h>
+
+// XsComponent class
+
+class XsComponent {
+
+   public:
+
+// Destructor
+
+      virtual  ~XsComponent ( );
+
+// Component manipulation
+
+      virtual  void show ( );             // Show the component
+      virtual  void hide ( );             // Hide the component
+      
+// Added JACS 19/10/98
+     inline Widget GetBase() const { return _base; }
+      
+// Component name
+
+      const char *name ( ) const;
+
+// Utilities
+
+      Widget   base ( ) const;
+      virtual  operator Widget ( ) const;
+
+// Operators
+
+      Boolean operator == (const XsComponent&);
+
+// Class name
+
+      virtual const char *className ( ) const;
+
+   protected:
+
+// Protected constructor
+
+      XsComponent (const char *name);
+      
+// Component life-cycle
+
+      virtual void _componentDestroyed ( );
+      void  _installDestroyHandler ( );
+      void  _removeDestroyHandler ( );
+                 
+// Resource manager
+
+      void  _setResources (Widget w, const String *);
+      void  _getResources (const XtResourceList, int);
+
+// Implementation
+
+      char    *_name;            // Component name
+      Widget   _base;            // Base widget
+
+   private:
+
+// Callbacks
+
+      static void _componentDestroyedCallback (Widget, XtPointer, XtPointer);
+};
+   
+// Inline member functions
+
+inline Widget XsComponent::base ( ) const
+{
+   return (_base);
+}
+
+inline const char* XsComponent::name ( ) const
+{
+   return (_name);
+}
+
+#endif
+
diff --git a/src/motif/mdi/lib/XsMDICanvas.C b/src/motif/mdi/lib/XsMDICanvas.C
new file mode 100644 (file)
index 0000000..6d84aab
--- /dev/null
@@ -0,0 +1,298 @@
+/*
+   Copyright (C) 1996 Scott W. Sadler
+   All rights reserved.
+*/
+
+/*
+   XsMDICanvas.C
+
+   History
+      03-Mar-96 1.0; Scott W. Sadler (sws@iti-oh.com)
+                     Created         
+*/
+
+// Includes
+
+#include <assert.h>
+#include <Xm/ScrolledW.h>
+#include <Xm/DrawingA.h>
+#include "XsMDICanvas.h"
+#include "XsMDIWindow.h"
+
+// Static definitions
+
+String XsMDICanvas::_resources[] = {
+   "*canvas.resizePolicy:     XmRESIZE_GROW",
+   NULL
+};
+
+// Constructor
+
+XsMDICanvas::XsMDICanvas (const char *name, Widget parent) : XsComponent (name)
+{
+   assert (parent != 0);
+
+// Initialize
+
+   _list = 0;
+   _num = 0;
+   _max = 0;
+   _place = 0;
+   
+// Install resources
+
+   _setResources (parent, _resources);
+   
+// Create the scrolled window
+
+   const int nargs = 10;
+   Arg   args[nargs];
+   int   n = 0;
+   
+   XtSetArg (args[n], XmNscrollingPolicy, XmAUTOMATIC);   n++;
+   XtSetArg (args[n], XmNscrolledWindowMarginHeight, (Dimension)0);  n++;
+   XtSetArg (args[n], XmNscrolledWindowMarginWidth, (Dimension)0);   n++;
+   XtSetArg (args[n], XmNmarginHeight, (Dimension)5);    n++;
+   XtSetArg (args[n], XmNmarginWidth, (Dimension)5);     n++;
+
+   assert (n <= nargs);
+                          
+   _base = XmCreateScrolledWindow (parent, _name, args, n);
+   
+// Install the destroy handler
+            
+   _installDestroyHandler ( );
+               
+// Create the drawing area (canvas)
+
+   _drawArea = XtVaCreateWidget ("canvas", xmDrawingAreaWidgetClass,
+      _base, XmNmarginHeight, (Dimension)0, XmNmarginWidth, (Dimension)0,
+      NULL);
+
+// Set resize callback on drawing area
+
+   XtAddCallback (_drawArea, XmNresizeCallback, _canvasResizeCallback, (XtPointer)this);
+
+// Set resize callback on clip window
+
+   XtVaGetValues (_base, XmNclipWindow, &_clipWin, NULL);
+   XtAddCallback (_clipWin, XmNresizeCallback, _clipResizeCallback, (XtPointer)this);
+}
+
+// Destructor
+
+XsMDICanvas::~XsMDICanvas ( )
+{
+
+/*
+   Remove callbacks to prevent calls to destroyed class-part of XsMDICanvas
+   while children are being destroyed.
+*/
+
+   if (_drawArea)
+      XtRemoveCallback (_drawArea, XmNresizeCallback, _canvasResizeCallback, (XtPointer)this);
+
+   if (_clipWin)
+      XtRemoveCallback (_clipWin, XmNresizeCallback, _clipResizeCallback, (XtPointer)this);
+
+// Remove all windows
+
+   removeAll ( ); 
+}
+   
+// add
+
+void XsMDICanvas::add (XsMDIWindow *win)
+{
+   assert (win != 0);
+
+   const int increment = 10;
+
+// Check if we need to allocate more space
+
+   if (_num >= _max)
+   {
+      XsMDIWindow **newList = new XsMDIWindow*[_max + increment];
+
+      for (int loop = 0; loop < _num; loop++)
+         newList[loop] = _list[loop];
+      _max += increment;
+
+      delete [] _list;
+      _list = newList;
+   }
+
+// Add the new window
+
+   _list[_num++] = win;
+
+// Install the parent canvas 
+
+   win->_setWindowParent (_drawArea);
+
+// If the canvas is shown, place the window
+
+   if (XtIsManaged (_base))
+      _placeWindow (win);
+}
+
+// remove
+
+void XsMDICanvas::remove (XsMDIWindow *win)
+{
+   assert (win != 0);
+
+// Remove the window
+
+   int   i, j;
+
+   for (i = 0; i < _num; i++)
+   {
+      if (_list[i] == win)
+      {
+         win->hide ( );
+         win->_setWindowParent (0);
+         
+         for (j = i; j < _num - 1; j++)
+            _list[j] = _list[j + 1];
+         _num--;
+
+         return;
+      }
+   }
+
+   assert (0);    // Couldn't find window
+}
+
+// removeAll
+
+void XsMDICanvas::removeAll ( )
+{
+
+// Delete and reset the list
+
+   delete [] _list;
+
+   _list = 0;
+   _num = 0;
+   _max = 0;
+}
+                        
+// show
+
+void XsMDICanvas::show ( )
+{
+   assert (_drawArea != 0);
+
+// Place all of the child windows
+
+   for (int loop = 0; loop < _num; loop++)
+      _placeWindow (_list[loop]);
+      
+// Manage the drawing area and canvas
+
+   XtManageChild (_drawArea);
+
+// Call base class
+
+   XsComponent::show ( );
+}
+
+// className
+
+const char* XsMDICanvas::className ( ) const
+{
+   return ("XsMDICanvas");
+}
+
+// _componentDestroyed
+
+void XsMDICanvas::_componentDestroyed ( )
+{
+
+// Remove the callbacks
+
+   XtRemoveCallback (_drawArea, XmNresizeCallback, _canvasResizeCallback, (XtPointer)this);
+   XtRemoveCallback (_clipWin, XmNresizeCallback, _clipResizeCallback, (XtPointer)this);
+   
+   _drawArea = 0;
+   _clipWin = 0;
+}
+   
+// _placeWindow
+
+void XsMDICanvas::_placeWindow (XsMDIWindow *win)
+{
+   assert (win != 0);
+   
+// Compute window placement
+
+   Position x, y;
+   
+   const int maxWin = 10;
+   const Position offset = 20;
+   const Position minOffset = 10;
+   
+   x = (_place * offset) + minOffset;
+   y = (_place * offset) + minOffset;
+   
+   if (++_place == maxWin)
+      _place = 0;
+      
+// Set the window placement
+
+   win->setPosition (x, y);
+   
+// Show the window
+
+   win->show ( );
+}
+
+// _resize
+
+void XsMDICanvas::_resize (XtPointer)
+{
+   Dimension   clipHeight;
+   Dimension   clipWidth;
+   Dimension   canvasHeight;
+   Dimension   canvasWidth;
+           
+// Check if clip window and canvas are managed
+
+   if (!XtIsManaged (_clipWin) || !XtIsManaged (_drawArea))
+      return;
+   
+// Get the clip window size
+
+   XtVaGetValues (_clipWin, XmNwidth, &clipWidth, XmNheight, &clipHeight, NULL);
+   
+// Get the canvas size
+
+   XtVaGetValues (_drawArea, XmNwidth, &canvasWidth, XmNheight, &canvasHeight, NULL);
+
+// Force the canvas to be at least as big as the clip window
+
+   if (canvasWidth < clipWidth)
+      canvasWidth = clipWidth;
+   if (canvasHeight < clipHeight)
+      canvasHeight = clipHeight;
+                          
+   XtVaSetValues (_drawArea, XmNwidth, canvasWidth, XmNheight, canvasHeight, NULL);
+}
+
+// _clipResizeCallback
+
+void XsMDICanvas::_clipResizeCallback (Widget, XtPointer clientData, XtPointer callData)
+{
+   XsMDICanvas *obj = (XsMDICanvas*)clientData;
+   obj->_resize (callData);
+}
+
+// _canvasResizeCallback
+
+void XsMDICanvas::_canvasResizeCallback (Widget, XtPointer clientData, XtPointer callData)
+{
+   XsMDICanvas *obj = (XsMDICanvas*)clientData;
+   obj->_resize (callData);
+}
+
diff --git a/src/motif/mdi/lib/XsMDICanvas.h b/src/motif/mdi/lib/XsMDICanvas.h
new file mode 100644 (file)
index 0000000..0e676b7
--- /dev/null
@@ -0,0 +1,100 @@
+/*
+   Copyright (C) 1996 Scott W. Sadler
+   All rights reserved.
+*/
+
+/*
+   XsMDICanvas.h
+
+   History
+      03-Mar-96 1.0; Scott W. Sadler (sws@iti-oh.com)
+                     Created         
+*/
+
+#ifndef XSMDICANVAS_H
+#define XSMDICANVAS_H
+
+// Includes
+
+#include "XsComponent.h"
+
+// Forward declarations
+
+class XsMDIWindow;
+
+// XsMDICanvas class
+
+class XsMDICanvas : public XsComponent {
+
+   public:
+   
+// Constructor/Destructor
+
+      XsMDICanvas (const char *name, Widget parent);
+      virtual ~XsMDICanvas ( );
+      
+// MDI Window manipulation
+
+      virtual void add (XsMDIWindow *win);      // Add an MDI window
+      virtual void remove (XsMDIWindow *win);   // Remove an MDI window
+      void removeAll ( );                       // Remove all MDI windows
+
+// Added JACS 19/10/98
+     inline Widget GetDrawingArea() const { return _drawArea; }
+      
+// Utilities
+
+      int   numWindows ( ) const;            // Number of MDI windows
+
+// Component methods
+
+      virtual void show ( );
+      
+// Class name
+
+      virtual const char *className ( ) const;
+
+   protected:
+
+// Component life-cycle
+
+      virtual void _componentDestroyed ( );
+
+// Geometry management
+
+      virtual  void _placeWindow (XsMDIWindow *win);
+
+// Canvas resize handler
+
+      virtual void   _resize (XtPointer);
+
+// Implementation
+
+      Widget         _clipWin;
+      Widget         _drawArea;
+
+      XsMDIWindow  **_list;
+      int            _num;
+      int            _max;
+      int            _place;
+      
+   private:
+   
+// Callbacks
+
+      static void _clipResizeCallback (Widget, XtPointer, XtPointer);
+      static void _canvasResizeCallback (Widget, XtPointer, XtPointer);
+      
+// Resources
+
+      static String  _resources[];
+};
+
+// Inline member functions
+
+inline XsMDICanvas::numWindows ( ) const
+{
+   return (_num);
+}
+
+#endif
diff --git a/src/motif/mdi/lib/XsMDIWindow.C b/src/motif/mdi/lib/XsMDIWindow.C
new file mode 100644 (file)
index 0000000..6d112a2
--- /dev/null
@@ -0,0 +1,156 @@
+/*
+   Copyright (C) 1996 Scott W. Sadler
+   All rights reserved.
+*/
+
+/*
+   XsMDIWindow.C
+
+   History
+      03-Mar-96 1.0; Scott W. Sadler (sws@iti-oh.com)
+                     Created         
+*/
+
+// Includes
+
+#include <assert.h>
+#include <Xm/Xm.h>
+#include "XsMDIWindow.h"
+
+// Constructor
+
+XsMDIWindow::XsMDIWindow (const char *name) : XsComponent (name)
+{
+
+// Initialize
+   
+   _clientArea = 0;
+   _parent = 0;
+
+// Initial size and placement
+
+   _initX = (Position)-1;
+   _initY = (Position)-1;
+   _initH = (Dimension)-1;
+   _initW = (Dimension)-1;
+   _placed = False;
+}
+
+// Destructor
+
+XsMDIWindow::~XsMDIWindow ( )
+{
+   // Empty
+}
+
+// raise
+
+void XsMDIWindow::raise ( )
+{
+   assert (_base != 0);
+   XRaiseWindow (XtDisplay (_base), XtWindow (_base));
+}
+
+// lower
+
+void XsMDIWindow::lower ( )
+{
+   assert (_base != 0);
+   XLowerWindow (XtDisplay (_base), XtWindow (_base));
+}
+
+// show
+
+void XsMDIWindow::show ( )
+{
+
+// Create the window (if necessary)
+
+   if (_base == 0)
+   {
+      assert (_parent != 0);
+      _createWindow (_parent);
+   }
+   
+// Manage the client area
+
+   XtManageChild (_clientArea);
+   
+// Configure the window position and size
+
+   if (_placed == False)
+   {
+      const int nargs = 4;
+      Arg   args[nargs];
+      int   n = 0;
+      
+      if (_initX != (Position)-1)
+      {
+         XtSetArg (args[n], XmNx, _initX);   n++;
+      }
+      if (_initY != (Position)-1)
+      {
+         XtSetArg (args[n], XmNy, _initY);   n++;
+      }
+      if (_initW != (Dimension)-1)
+      {
+         XtSetArg (args[n], XmNwidth, _initW);  n++;
+      }
+      if (_initH != (Dimension)-1)
+      {
+         XtSetArg (args[n], XmNheight, _initH); n++;
+      }
+         
+      assert (n <= nargs);
+      XtSetValues (_base, args, n);
+
+      _placed = True;
+   }
+   
+// Call the base class
+
+   XsComponent::show ( );
+}
+
+// setPosition
+
+void XsMDIWindow::setPosition (Position x, Position y)
+{
+   if (_base != 0)
+      XtVaSetValues (_base, XmNx, x, XmNy, y, NULL);
+   else
+   {
+      _initX = x;
+      _initY = y;
+   }      
+}
+
+// setSize
+
+void XsMDIWindow::setSize (Dimension w, Dimension h)
+{
+   if (_base != 0)
+      XtVaSetValues (_base, XmNwidth, w, XmNheight, h, NULL);
+   else
+   {
+      _initW = w;
+      _initH = h;
+   }
+}
+
+// className
+
+const char* XsMDIWindow::className ( ) const
+{
+   return ("XsMDIWindow");
+}
+
+// _setWindowParent
+
+void XsMDIWindow::_setWindowParent (Widget p)
+{
+   
+// This is called by the canvas to tell us who our parent is
+
+   _parent = p;
+}
diff --git a/src/motif/mdi/lib/XsMDIWindow.h b/src/motif/mdi/lib/XsMDIWindow.h
new file mode 100644 (file)
index 0000000..ef12b3c
--- /dev/null
@@ -0,0 +1,89 @@
+/*
+   Copyright (C) 1996 Scott W. Sadler
+   All rights reserved.
+*/
+
+/*
+   XsMDIWindow.h
+
+   History
+      03-Mar-96 1.0; Scott W. Sadler (sws@iti-oh.com)
+                     Created         
+*/
+
+#ifndef XSMDIWINDOW_H
+#define XSMDIWINDOW_H
+
+// Includes
+
+#include "XsComponent.h"
+
+// XsMDIWindow class
+
+class XsMDIWindow : public XsComponent {
+
+   friend class XsMDICanvas;
+   
+   public:
+
+// Constructor/Destructor
+
+      XsMDIWindow (const char *name);
+      virtual ~XsMDIWindow ( );
+      
+// Window manipulation
+
+      virtual void raise ( );
+      virtual void lower ( );
+
+// Utilities
+
+      Widget   clientArea ( ) const;
+      
+// Position and size
+
+      virtual void setPosition (Position x, Position y);
+      virtual void setSize (Dimension w, Dimension h);
+
+// Class name
+
+      virtual const char *className ( ) const;
+
+   protected:
+
+// Only the friendly canvas can show a window
+
+      virtual void show ( );
+
+// Window creation functions
+
+      virtual void _buildClientArea (Widget parent) = 0;
+      virtual void _createWindow (Widget parent) = 0;
+      
+// Implementation
+
+      Widget      _clientArea;         // Client work area
+      
+// Initial window size and placement
+
+      Position    _initX, _initY;
+      Dimension   _initW, _initH;
+      Boolean     _placed;
+         
+   private:
+   
+// Window parent installation 
+
+      void     _setWindowParent (Widget);
+      Widget   _parent;
+};
+
+// Inline member functions
+
+inline Widget XsMDIWindow::clientArea ( ) const
+{
+   return (_clientArea);
+}
+
+#endif
+
diff --git a/src/motif/mdi/lib/XsMotifWindow.C b/src/motif/mdi/lib/XsMotifWindow.C
new file mode 100644 (file)
index 0000000..f1a2a4d
--- /dev/null
@@ -0,0 +1,3368 @@
+/*
+   Copyright (C) 1996 Scott W. Sadler
+   All rights reserved.
+*/
+
+/*
+   XsMotifWindow.C
+
+   History
+      03-Mar-96 1.0; Scott W. Sadler (sws@iti-oh.com)
+                     Created         
+*/
+
+// Includes
+
+#include <assert.h>
+#include <Xm/Form.h>
+#include <Xm/RowColumn.h>
+#include <Xm/SeparatoG.h>
+#include <Xm/PushBG.h>
+#include <X11/Shell.h>
+#include <X11/cursorfont.h>
+#include "XsMotifWindow.h"
+#include "XsResizeOutline.h"
+#include "XsMoveOutline.h"
+#include "xs_motif_icon.xbm"
+
+// Constants
+
+const int BorderSize_   = 6;
+const int ButtonSize_   = 23;
+const int IconSize_     = 70;
+
+/*
+   ----------------------------------------------------------------------------
+   _XsMotifBase
+*/
+   
+// Constructor
+
+_XsMotifBase::_XsMotifBase (const char *name, XsMotifWindow *win) :
+   XsComponent (name)
+{
+   assert (win != 0);
+   
+// Initialize
+
+   _win = win;
+   _topShadowGC = 0;
+   _bottomShadowGC = 0;
+}
+   
+// Destructor
+
+_XsMotifBase::~_XsMotifBase ( )
+{
+   if (_topShadowGC)
+      XtReleaseGC (_base, _topShadowGC);
+
+   if (_bottomShadowGC)
+      XtReleaseGC (_base, _bottomShadowGC);
+}
+
+// show
+
+void _XsMotifBase::show ( )
+{
+   assert (_base != 0);
+   
+// Install event handler
+
+   XtAddEventHandler (_base, StructureNotifyMask, False, _mapEventHandler, (XtPointer)this);
+
+// Call the base-class
+
+   XsComponent::show ( );
+}
+   
+// className
+
+const char* _XsMotifBase::className ( ) const
+{
+   return ("_XsMotifBase");
+}
+
+// _componentDestroyed ( )
+
+void _XsMotifBase::_componentDestroyed ( )
+{
+
+// Clean up the GCs
+
+   if (_topShadowGC)
+      XtReleaseGC (_base, _topShadowGC);
+
+   if (_bottomShadowGC)
+      XtReleaseGC (_base, _bottomShadowGC);
+
+   _topShadowGC = 0;
+   _bottomShadowGC = 0;
+   
+// Call the base-class
+
+   XsComponent::_componentDestroyed ( );
+}
+
+// _drawShadows
+
+void _XsMotifBase::_drawShadows (Position x, Position y, Dimension width,
+   Dimension height, Dimension thick, Boolean reverse)
+{
+   assert (_base != 0);
+   assert (thick > 0);
+   
+   const int nsegs = 2;
+   XSegment segs[nsegs];
+   GC    topShadowGC;
+   GC    bottomShadowGC;
+   
+// Work out the graphics contexts
+
+   topShadowGC = (reverse == False) ? _topShadowGC : _bottomShadowGC;
+   bottomShadowGC = (reverse == False) ? _bottomShadowGC : _topShadowGC;
+   
+   for (int loop = 0; loop < thick; loop++)
+   {
+
+/*
+   TOP SHADOW DRAWING
+*/
+
+// Across the top
+
+      segs[0].x1 = x + loop;
+      segs[0].y1 = y + loop;
+      segs[0].x2 = x + width - loop - 2; 
+      segs[0].y2 = y + loop;
+      
+// Down the left side
+
+      segs[1].x1 = x + loop;
+      segs[1].y1 = y + loop + 1;
+      segs[1].x2 = x + loop;
+      segs[1].y2 = y + height - loop - 2;
+      
+      XDrawSegments (XtDisplay (_base), XtWindow (_base), topShadowGC, segs, nsegs);
+
+/*
+   BOTTOM SHADOW DRAWING
+*/
+      
+// Across the bottom
+
+      segs[0].x1 = x + loop;
+      segs[0].y1 = y + height - loop - 1;
+      segs[0].x2 = x + width - loop - 1;
+      segs[0].y2 = y + height - loop - 1;
+      
+// Down the right side
+
+      segs[1].x1 = x + width - loop - 1;
+      segs[1].y1 = y + loop;
+      segs[1].x2 = x + width - loop - 1;
+      segs[1].y2 = y + height - loop - 1;
+
+      XDrawSegments (XtDisplay (_base), XtWindow (_base), bottomShadowGC, segs, nsegs);
+   }   
+}
+
+// _drawLine
+
+void _XsMotifBase::_drawLine (Position x1, Position y1, Position x2, Position y2, GC &gc)
+{
+   assert (_base != 0);
+   XDrawLine (XtDisplay (_base), XtWindow (_base), gc, x1, y1, x2, y2);
+}
+   
+// _map
+
+void _XsMotifBase::_map ( )
+{
+
+// Create the graphics contexts
+
+   unsigned long valuemask;
+   XGCValues   values;
+   Pixel topShadow;
+   Pixel bottomShadow;
+
+   XtVaGetValues (_win->base ( ), XmNtopShadowColor, &topShadow, XmNbottomShadowColor, 
+      &bottomShadow, NULL);
+
+// Create the graphics contexts
+
+   valuemask = GCForeground | GCLineWidth | GCGraphicsExposures;
+   values.line_width = 0;
+   values.graphics_exposures = False;
+   
+   values.foreground = topShadow;
+   _topShadowGC = XtGetGC (_base, valuemask, &values);
+
+   values.foreground = bottomShadow;
+   _bottomShadowGC = XtGetGC (_base, valuemask, &values);
+}
+
+// _mapEventHandler
+
+void _XsMotifBase::_mapEventHandler (Widget, XtPointer clientData, XEvent *event, Boolean*)
+{
+   if (event->type == MapNotify)
+   {
+      _XsMotifBase *obj = (_XsMotifBase*)clientData;
+      obj->_map ( );
+
+// Remove the event handler
+
+      XtRemoveEventHandler (obj->_base, StructureNotifyMask, False, obj->_mapEventHandler, clientData);
+   }
+}
+
+/*
+   ----------------------------------------------------------------------------
+   _XsMotifComponent
+*/
+   
+Cursor _XsMotifComponent::_cursors[_XsMotifComponent::NumCursors];
+
+int _XsMotifComponent::_mutex = 0;
+
+XtResource _XsMotifComponent::_resourceList[] = {
+   {
+      "borderSize",
+      "BorderSize",
+      XmRDimension,
+      sizeof (Dimension),
+      XtOffset (_XsMotifComponent*, _borderSize),
+      XmRImmediate,
+      (XtPointer)BorderSize_
+   },
+   {
+      "buttonSize",
+      "ButtonSize",
+      XmRDimension,
+      sizeof (Dimension),
+      XtOffset (_XsMotifComponent*, _buttonSize),
+      XmRImmediate,
+      (XtPointer)ButtonSize_
+   }
+};
+
+// Constructor
+
+_XsMotifComponent::_XsMotifComponent (const char *name, XsMotifWindow *win,
+   Widget parent) : _XsMotifBase (name, win)
+{
+   
+// Create cursors (if necessary)
+
+   if (_mutex == 0)
+   {
+
+      Display *dpy = XtDisplay (win->base ( ));
+
+      _cursors[TopCursor] = XCreateFontCursor (dpy, XC_top_side);
+      _cursors[BottomCursor] = XCreateFontCursor (dpy, XC_bottom_side);
+      _cursors[LeftCursor] = XCreateFontCursor (dpy, XC_left_side);
+      _cursors[RightCursor] = XCreateFontCursor (dpy, XC_right_side);
+      _cursors[TopLeftCursor] = XCreateFontCursor (dpy, XC_top_left_corner);
+      _cursors[TopRightCursor] = XCreateFontCursor (dpy, XC_top_right_corner);
+      _cursors[BottomLeftCursor] = XCreateFontCursor (dpy, XC_bottom_left_corner);
+      _cursors[BottomRightCursor] = XCreateFontCursor (dpy, XC_bottom_right_corner);
+
+      _mutex = 1;
+   }
+
+// Create the component
+
+   _base = XtVaCreateWidget (name, widgetClass, (parent != 0) ? parent : _win->base ( ), NULL);
+
+// Install destroy handler
+
+   _installDestroyHandler ( );
+   
+// Get resources
+   
+   _getResources (_resourceList, XtNumber (_resourceList));
+
+// Compute the corner size
+
+   _cornerSize = _buttonSize + _borderSize;
+
+// Install event handlers
+
+   XtAddEventHandler (_base, ExposureMask, False, _exposeEventHandler, (XtPointer)this);
+   XtAddEventHandler (_base, ButtonPressMask | ButtonReleaseMask | Button1MotionMask | Button2MotionMask, False, _inputEventHandler, (XtPointer)this);
+}
+
+// Destructor
+
+_XsMotifComponent::~_XsMotifComponent ( )
+{
+   // Empty
+}
+
+// className
+
+const char* _XsMotifComponent::className ( ) const
+{
+   return ("_XsMotifComponent");
+}
+
+// _input
+
+void _XsMotifComponent::_input (XEvent*)
+{
+   // Empty
+}
+
+// _exposeEventHandler
+
+void _XsMotifComponent::_exposeEventHandler (Widget, XtPointer clientData, XEvent *event, Boolean*)
+{
+   _XsMotifComponent *obj = (_XsMotifComponent*)clientData;
+
+   if (event->xexpose.count == 0)
+      obj->_expose (event);
+}
+
+// _inputEventHandler
+
+void _XsMotifComponent::_inputEventHandler (Widget, XtPointer clientData, XEvent *event, Boolean*)
+{
+   _XsMotifComponent *obj = (_XsMotifComponent*)clientData;
+   obj->_input (event);
+}
+
+/*
+   ----------------------------------------------------------------------------
+   _XsMotifCorner
+*/
+
+// Constructor
+
+_XsMotifCorner::_XsMotifCorner (const char *name, XsMotifWindow *win, Corner corner)
+   : _XsMotifComponent (name, win)
+{
+   
+// Initialize
+
+   _corner = corner;
+
+// Configure component
+
+   XtVaSetValues (_base, XmNwidth, _cornerSize, XmNheight, _cornerSize,
+      XmNborderWidth, (Dimension)0, NULL);
+}
+
+// Destructor
+
+_XsMotifCorner::~_XsMotifCorner ( )
+{
+   // Empty
+}
+
+// className
+
+const char *_XsMotifCorner::className ( ) const
+{
+   return ("_XsMotifCorner");
+}
+
+// _expose
+
+void _XsMotifCorner::_expose (XEvent*)
+{
+   Dimension   w, h;
+
+// Get the size of the corner
+
+   XtVaGetValues (_base, XmNwidth, &w, XmNheight, &h, NULL);
+   
+// Draw the shadow
+
+   _drawShadows (0, 0, w, h, 1);
+
+// Draw the extra lines and relief
+
+   switch (_corner)
+   {
+      case TopLeft:
+      {
+         _drawLine (1, 1, w - 2, 1, _topShadowGC);
+         _drawLine (1, 1, 1, h - 2, _topShadowGC);
+
+// Relief
+
+         _drawLine (_borderSize - 1, _borderSize - 1, _borderSize +
+            _buttonSize - 2, _borderSize - 1, _bottomShadowGC);
+
+         _drawLine (_borderSize - 1, _borderSize - 1, _borderSize - 1,
+            _borderSize + _buttonSize - 2, _bottomShadowGC);
+         
+         break;
+      }
+      case TopRight:
+      {
+         _drawLine (1, 1, w - 2, 1, _topShadowGC);
+         _drawLine (w - 2, 1, w - 2, h - 2, _bottomShadowGC);
+
+// Relief
+
+         _drawLine (0, _borderSize - 1, _buttonSize - 1, _borderSize - 1,
+            _bottomShadowGC);
+
+         _drawLine (w - _borderSize, _borderSize - 1, w - _borderSize,
+            _borderSize + _buttonSize - 2, _topShadowGC);            
+
+         break;
+      }
+      case BottomLeft:
+      {
+         _drawLine (1, 1, 1, h - 2, _topShadowGC);
+         _drawLine (1, h - 2, w - 2, h - 2, _bottomShadowGC);
+
+// Relief
+
+         _drawLine (_borderSize - 1, h - _borderSize, _borderSize +
+            _buttonSize - 2, h - _borderSize, _topShadowGC);
+
+         _drawLine (_borderSize - 1, 1, _borderSize - 1,
+            _buttonSize - 1, _bottomShadowGC);
+
+         break;
+      }
+      case BottomRight:
+      {
+         _drawLine (1, h - 2, w - 2, h - 2, _bottomShadowGC);
+         _drawLine (w - 2, 1, w - 2, h - 2, _bottomShadowGC);
+
+// Relief
+
+         _drawLine (1, h - _borderSize, _buttonSize, h - _borderSize,
+            _topShadowGC);
+
+         _drawLine (w - _borderSize, 1, w - _borderSize,
+            _buttonSize - 1, _topShadowGC);
+
+         break;
+      }
+      default:
+         assert (0);
+   }         
+}
+
+// _input
+
+void _XsMotifCorner::_input (XEvent *event)
+{
+   switch (event->type)
+   {
+      case ButtonPress:
+      {
+         if (event->xbutton.button == 2)
+         {
+            XsMoveOutline move (_win->base ( ));
+
+// Start the move
+
+            if (move.go ( ) != False)
+            {
+
+// Relocate the window      
+   
+               _win->setPosition (move.x ( ), move.y ( ));
+            }
+         }
+         else if (event->xbutton.button == 3)
+            _win->popupMenu ( );
+
+         break;
+      }
+      case ButtonRelease:
+      {
+         switch (event->xbutton.button)
+         {
+            case 1:
+            case 2:
+            {
+               _win->raise ( );     // Raise the window
+               break;
+            }
+         }
+         break;
+      }
+      case MotionNotify:
+      {
+
+// Figure kind of resize we are doing
+
+         int   dir;
+            
+         if (_corner == TopLeft)
+            dir = XsResizeOutline::Up | XsResizeOutline::Left;
+         else if (_corner == TopRight)
+            dir = XsResizeOutline::Up | XsResizeOutline::Right;
+         else if (_corner == BottomLeft)
+            dir = XsResizeOutline::Down | XsResizeOutline::Left;
+         else if (_corner == BottomRight)
+            dir = XsResizeOutline::Down | XsResizeOutline::Right;
+         else
+            assert (0);
+
+         XsResizeOutline resize (_win->base ( ), dir);
+         resize.setMinSize (_win->minWidth ( ), _win->minHeight ( ));
+         
+// Start the resize
+
+         if (resize.go ( ) != False)
+         {
+
+// Relocate the window      
+   
+            _win->setPosition (resize.x ( ), resize.y ( ));
+            _win->setSize (resize.width ( ), resize.height ( ));
+         }
+         break;
+      }
+   }
+}
+
+// _map
+
+void _XsMotifCorner::_map ( )
+{
+
+// Call the base-class
+
+   _XsMotifComponent::_map ( );
+
+// Install the cursor
+
+   if (_corner == TopLeft)
+      XDefineCursor (XtDisplay (_base), XtWindow (_base), _cursors[TopLeftCursor]);
+   else if (_corner == TopRight)
+      XDefineCursor (XtDisplay (_base), XtWindow (_base), _cursors[TopRightCursor]);
+   else if (_corner == BottomLeft)
+      XDefineCursor (XtDisplay (_base), XtWindow (_base), _cursors[BottomLeftCursor]);
+   else if (_corner == BottomRight)
+      XDefineCursor (XtDisplay (_base), XtWindow (_base), _cursors[BottomRightCursor]);
+   else
+      assert (0);
+}
+
+/*
+   ----------------------------------------------------------------------------
+   _XsMotifSide
+*/
+
+// Constructor
+
+_XsMotifSide::_XsMotifSide (const char *name, XsMotifWindow *win, Side side) :
+   _XsMotifComponent (name, win)
+{
+   
+// Initialize
+
+   _side = side;
+   _lastW = _lastH = -1;
+
+// Configure component
+
+   switch (_side)
+   {
+      case Top:
+      case Bottom:
+      {
+         XtVaSetValues (_base, XmNheight, _borderSize, XmNborderWidth,
+            (Dimension)0, NULL);
+         break;
+      }
+      case Left:
+      case Right:
+      {
+         XtVaSetValues (_base, XmNwidth, _borderSize, XmNborderWidth,
+            (Dimension)0, NULL);
+         break;
+      }
+      default:
+         assert (0);      
+   }
+
+// Install event handler
+
+   XtAddEventHandler (_base, StructureNotifyMask, False, _configureEventHandler, (XtPointer)this);
+}
+
+// Destructor
+
+_XsMotifSide::~_XsMotifSide ( )
+{
+   // Empty
+}
+
+// className
+
+const char *_XsMotifSide::className ( ) const
+{
+   return ("_XsMotifSide");
+}
+
+// _expose
+
+void _XsMotifSide::_expose (XEvent *event)
+{
+
+// Clear out the window first
+
+   if (event != 0)
+      XClearWindow (XtDisplay (_base), XtWindow (_base));
+   
+   Dimension   w, h;
+
+// Get the size of the side
+
+   XtVaGetValues (_base, XmNwidth, &w, XmNheight, &h, NULL);
+   
+// Draw the shadow
+
+   _drawShadows (0, 0, w, h, 1);
+
+// Draw the extra lines
+
+   switch (_side)
+   {
+      case Top:
+      {
+         _drawLine (1, 1, w - 2, 1, _topShadowGC);
+         break;
+      }
+      case Bottom:
+      {
+         _drawLine (1, h - 2, w - 2, h - 2, _bottomShadowGC);
+         break;
+      }
+      case Left:
+      {
+         _drawLine (1, 1, 1, h - 2, _topShadowGC);
+         break;
+      }
+      case Right:
+      {
+         _drawLine (w - 2, 1, w - 2, h - 2, _bottomShadowGC);
+         break;
+      }
+      default:
+         assert (0);
+   }
+}
+         
+// _input
+
+void _XsMotifSide::_input (XEvent *event)
+{
+   switch (event->type)
+   {
+      case ButtonPress:
+      {
+         if (event->xbutton.button == 2)
+         {
+            XsMoveOutline move (_win->base ( ));
+
+// Start the move
+
+            if (move.go ( ) != False)
+            {
+
+// Relocate the window      
+   
+               _win->setPosition (move.x ( ), move.y ( ));
+            }
+         }
+         else if (event->xbutton.button == 3)
+            _win->popupMenu ( );
+
+         break;
+      }
+      case ButtonRelease:
+      {
+         switch (event->xbutton.button)
+         {
+            case 1:
+            case 2:
+            {
+               _win->raise ( );     // Raise the window
+               break;
+            }
+         }
+         break;
+      }
+      case MotionNotify:
+      {
+
+// Figure kind of resize we are doing
+
+         int   dir;
+         
+         if (_side == Top)
+            dir = XsResizeOutline::Up;
+         else if (_side == Bottom)
+            dir = XsResizeOutline::Down;
+         else if (_side == Left)
+            dir = XsResizeOutline::Left;
+         else if (_side == Right)
+            dir = XsResizeOutline::Right;
+         else
+            assert (0);
+
+         XsResizeOutline resize (_win->base ( ), dir);
+         resize.setMinSize (_win->minWidth ( ), _win->minHeight ( ));
+
+// Start the resize
+
+         if (resize.go ( ) != False)
+         {
+
+// Relocate the window      
+   
+            _win->setPosition (resize.x ( ), resize.y ( ));
+            _win->setSize (resize.width ( ), resize.height ( ));
+         }
+         break;
+      }
+   }
+}
+
+// _map
+
+void _XsMotifSide::_map ( )
+{
+
+// Call the base-class
+
+   _XsMotifComponent::_map ( );
+
+// Install the cursor
+
+   if (_side == Top)
+      XDefineCursor (XtDisplay (_base), XtWindow (_base), _cursors[TopCursor]);
+   else if (_side == Bottom)
+      XDefineCursor (XtDisplay (_base), XtWindow (_base), _cursors[BottomCursor]);
+   else if (_side == Left)
+      XDefineCursor (XtDisplay (_base), XtWindow (_base), _cursors[LeftCursor]);
+   else if (_side == Right)
+      XDefineCursor (XtDisplay (_base), XtWindow (_base), _cursors[RightCursor]);
+   else
+      assert (0);
+}
+
+// _configure
+
+void _XsMotifSide::_configure (XEvent *event)
+{
+   XConfigureEvent *ce = (XConfigureEvent*)event;
+   
+/*
+   Check if window has been resized.  If so, generate an expose event
+   to redraw its contents.
+*/
+
+   if ((_lastW != ce->width) || (_lastH != ce->height))
+   {
+      if ((_base != 0) && XtIsManaged (_base))
+         XClearArea (XtDisplay (_base), XtWindow (_base), 0, 0, 0, 0, True);
+
+      _lastW = ce->width;
+      _lastH = ce->height;
+   }
+}
+
+// _configureEventHandler
+
+void _XsMotifSide::_configureEventHandler (Widget, XtPointer clientData, XEvent *event, Boolean*)
+{
+   if (event->type == ConfigureNotify)
+   {
+      _XsMotifSide *obj = (_XsMotifSide*)clientData;
+      obj->_configure (event);
+   }
+}
+
+/*
+   ----------------------------------------------------------------------------
+   _XsMotifButton
+*/
+
+// Constructor
+
+_XsMotifButton::_XsMotifButton (const char *name, XsMotifWindow *win, Button button) :
+   _XsMotifComponent (name, win)
+{
+   
+// Initialize
+
+   _pressed = False;
+   _button = button;
+
+// Configure the component
+
+   XtVaSetValues (_base, XmNheight, _buttonSize, XmNwidth, _buttonSize,
+      XmNborderWidth, (Dimension)0, NULL);
+}
+
+// Destructor
+
+_XsMotifButton::~_XsMotifButton ( )
+{
+   // Empty
+}
+
+// redraw
+
+void _XsMotifButton::redraw ( )
+{
+
+// Make sure component is viewable
+
+   if (!XtIsRealized (_base))
+      return;
+      
+// Check if window is viewable
+
+   XWindowAttributes attrs;
+   XGetWindowAttributes (XtDisplay (_base), XtWindow (_base), &attrs);
+   
+   if (attrs.map_state == IsViewable)
+      _expose (0);      // Just pretend we got an expose event
+}
+   
+// className
+
+const char *_XsMotifButton::className ( ) const
+{
+   return ("_XsMotifButton");
+}
+
+// _expose
+
+void _XsMotifButton::_expose (XEvent *event)
+{
+   Dimension   w, h;
+
+// Get the size of the button
+
+   XtVaGetValues (_base, XmNwidth, &w, XmNheight, &h, NULL);
+   
+// Draw the shadow
+
+   _drawShadows (0, 0, w, h, 1, _pressed);
+
+// Draw the extra line
+
+   _drawLine (1, h - 2, w - 2, h - 2, (_pressed) ? _topShadowGC : _bottomShadowGC);
+
+// Check if we need to draw the decal
+
+   if ((_button != Maximize) && (event == 0))
+      return;
+      
+// Compute the decal size
+
+   Dimension dw, dh;
+   Boolean  reverse = False;
+   
+   switch (_button)
+   {
+      case Menu:
+      {
+         dw = _buttonSize - 6;
+        dh = 4;
+         break;            
+      }
+      case Minimize:
+      {
+         dw = dh = 4;
+         break;
+      }
+      case Maximize:
+      {
+         dw = _buttonSize - 6;
+         dh = dw - 1;
+
+         if (_win->maximized ( ))
+            reverse = True;
+            
+         break;
+      }
+      default:
+         assert (0);
+   }
+
+// Draw the decal
+
+   _drawShadows ((w / 2) - (dw / 2), (h / 2) - (dh / 2), dw, dh, 1, reverse);
+}
+
+// _input
+
+void _XsMotifButton::_input (XEvent *event)
+{
+   static Time lastTime = (Time)0;
+   
+   switch (event->type)
+   {
+      case ButtonPress:
+      {
+         if (event->xbutton.button == 1)
+         {
+            _pressed = True;
+         
+            if (_button == Menu)
+            {
+
+// Get double-click time
+
+               int multiClick = XtGetMultiClickTime (XtDisplay (_base));
+
+// Check for double-click
+
+               if ((event->xbutton.time - lastTime) <= multiClick)
+               {
+                  _win->close ( );
+                  return;
+               }                  
+               else
+                  lastTime = event->xbutton.time;                  
+
+// Redraw the button (pushed-in)
+
+               redraw ( );
+
+// Popup the menu
+
+               _win->popupMenu (False);
+
+// The menu will consume the ButtonRelease, so fake one
+
+               _pressed = False;
+               redraw ( );
+
+            }
+            else if ((_button == Minimize) || (_button == Maximize))
+            {
+               redraw ( );
+            }
+         }
+         else if (event->xbutton.button == 2)            
+         {
+            XsMoveOutline move (_win->base ( ));
+
+// Start the move
+
+            if (move.go ( ) != False)
+            {
+
+// Relocate the window      
+   
+               _win->setPosition (move.x ( ), move.y ( ));
+            }
+         }
+         else if (event->xbutton.button == 3)
+            _win->popupMenu ( );
+
+         break;
+      }
+      case ButtonRelease:
+      {
+         if (event->xbutton.button == 1)
+         {
+            _pressed = False;
+
+// Check if pointer is really in the window
+
+            XButtonEvent *b = &event->xbutton;
+            Dimension width, height;
+            Boolean  inWindow = False;
+
+            XtVaGetValues (_base, XmNwidth, &width, XmNheight, &height, NULL);
+            if ((b->x >= 0) && (b->y >= 0) && (b->x < width) && (b->y < height))
+               inWindow = True;
+
+            if (_button == Minimize)
+            {
+               if (inWindow)
+               {
+                  if (_win->minimized ( ))
+                     _win->restore ( );
+                  else
+                     _win->minimize ( );
+               }
+               else
+                  redraw ( );
+            }
+            else if (_button == Maximize)
+            {
+               if (inWindow)
+               {
+                  if (_win->maximized ( ))
+                     _win->restore ( );
+                  else
+                     _win->maximize ( );
+               }
+               else                  
+                  redraw ( );
+            }
+         }
+         break;
+      }
+   }
+}
+
+// _map
+
+void _XsMotifButton::_map ( )
+{
+   
+// Call the base-class
+      
+   _XsMotifComponent::_map ( );
+        
+// Raise ourself
+
+   XRaiseWindow (XtDisplay (_base), XtWindow (_base));
+}
+   
+/*
+   ----------------------------------------------------------------------------
+   _XsMotifTitle
+*/
+
+XtResource _XsMotifTitle::_resourceList[] = {
+   {
+      "title",
+      "Title",
+      XmRString,
+      sizeof (String),
+      XtOffset (_XsMotifTitle*, _titleString),
+      XmRImmediate,
+      NULL
+   },
+   {
+      "titleFont",
+      "TitleFont",
+      XmRFontStruct,
+      sizeof (XFontStruct*),
+      XtOffset (_XsMotifTitle*, _titleFont),
+      XmRString,
+      "-*-helvetica-bold-o-normal-*-14-*-*-*-*-*-iso8859-1"
+   }
+};
+
+// Constructor
+
+_XsMotifTitle::_XsMotifTitle (const char *name, XsMotifWindow *win) :
+   _XsMotifComponent (name, win)
+{
+   
+// Initialize
+
+   _pressed = False;
+   _titleString = 0;
+   _titleFont = 0;
+   _fontGC = 0;
+   _lastW = _lastH = -1;
+   
+// Get resources
+   
+   _getResources (_resourceList, XtNumber (_resourceList));
+
+// Copy title string to local memory
+
+   if (_titleString != 0)
+   {
+      char *tmp = new char[strlen (_titleString) + 1];
+      strcpy (tmp, _titleString);
+      _titleString = tmp;
+   }
+         
+// Configure the title
+
+   XtVaSetValues (_base,  XmNheight, _buttonSize, XmNborderWidth,
+      (Dimension)0, NULL);
+
+// Install event handler
+
+   XtAddEventHandler (_base, StructureNotifyMask, False, _configureEventHandler, (XtPointer)this);
+}
+
+// Destructor
+
+_XsMotifTitle::~_XsMotifTitle ( )
+{
+   if (_fontGC)
+      XtReleaseGC (_base, _fontGC);
+
+   delete [] _titleString;
+}
+
+// setTitle
+
+void _XsMotifTitle::setTitle (const char *title)
+{
+   assert (title != 0);
+      
+   delete [] _titleString;
+   
+   _titleString = new char[strlen (title) + 1];
+   strcpy (_titleString, title);
+}   
+
+// className
+
+const char *_XsMotifTitle::className ( ) const
+{
+   return ("_XsMotifTitle");
+}
+
+// _componentDestroyed
+
+void _XsMotifTitle::_componentDestroyed ( )
+{
+   
+// Clean up the GCs
+
+   if (_fontGC)
+      XtReleaseGC (_base, _fontGC);
+
+   _fontGC = 0;
+   
+// Call base-class
+
+   _XsMotifComponent::_componentDestroyed ( );
+}
+   
+// _redraw
+
+void _XsMotifTitle::_redraw ( )
+{
+   _expose (0);      // Just pretend we got an expose event
+}
+
+// _expose
+
+void _XsMotifTitle::_expose (XEvent *event)
+{
+
+// Clear out the window first
+
+   if (event != 0)
+      XClearWindow (XtDisplay (_base), XtWindow (_base));
+   
+   Dimension   w, h;
+
+// Get the size of the button
+
+   XtVaGetValues (_base, XmNwidth, &w, XmNheight, &h, NULL);
+   
+// Draw the shadow
+
+   _drawShadows (0, 0, w, h, 1, _pressed);
+
+// Draw the extra line
+
+   _drawLine (1, h - 2, w - 2, h - 2, (_pressed) ? _topShadowGC : _bottomShadowGC);
+
+// If this is an artificial event, no need continuing
+
+   if (event == 0)
+      return;
+      
+// Draw the text string
+
+   const int LeftOffset = 5;
+   const int TopOffset = 2;
+
+// Figure out the title
+
+   const char *title = (_titleString != 0) ? _titleString : _win->name ( );
+         
+   if ((title != 0) && (title[0] != '\0'))
+   {
+      int len = strlen (title);
+
+      XDrawString (XtDisplay (_base), XtWindow (_base), _fontGC,
+         LeftOffset, TopOffset + _titleFont->ascent, title, len);
+   }
+}
+
+// _input
+
+void _XsMotifTitle::_input (XEvent *event)
+{
+   switch (event->type)
+   {
+      case ButtonPress:
+      {
+         switch (event->xbutton.button)
+         {
+            case 1:
+            {
+               _pressed = True;
+               _redraw ( );
+               break;
+            }
+            case 2:
+            {
+               XsMoveOutline move (_win->base ( ));
+
+// Start the move
+
+               if (move.go ( ) != False)
+               {
+
+// Relocate the window      
+   
+                  _win->setPosition (move.x ( ), move.y ( ));
+               }
+               break;
+            }
+            case 3:
+            {
+               _win->popupMenu ( );
+               break;
+            }
+         }
+         break;
+      }         
+      case ButtonRelease:
+      {
+         switch (event->xbutton.button)
+         {
+            case 1:
+            case 2:
+            {
+               _pressed = False;
+               _redraw ( );
+
+               _win->raise ( );
+               break;
+            }
+         }
+         break;
+      }
+      case MotionNotify:
+      {
+         XsMoveOutline move (_win->base ( ));
+
+// Start the move
+
+         if (move.go ( ) != False)
+         {
+
+// Relocate the window      
+   
+            _win->setPosition (move.x ( ), move.y ( ));
+
+// Redraw the title bar
+
+            _pressed = False;
+            _redraw ( );
+         }
+         break;
+      }
+   }
+}
+
+// _map
+
+void _XsMotifTitle::_map ( )
+{
+   
+// Call the base-class
+
+   _XsMotifComponent::_map ( );
+
+// Raise ourself
+   
+   XRaiseWindow (XtDisplay (_base), XtWindow (_base));
+   
+   unsigned long valuemask;
+   XGCValues   values;
+   Pixel foreground;
+   Pixel background;
+
+// Get the pixels
+
+   XtVaGetValues (_win->base ( ), XmNforeground, &foreground, XmNbackground, &background, NULL);
+
+// Create the font graphics context
+
+   valuemask = GCForeground | GCBackground | GCGraphicsExposures | GCFont;
+
+   values.foreground = foreground;
+   values.background = background;
+   values.font = _titleFont->fid;
+   values.graphics_exposures = False;
+
+   _fontGC = XtGetGC (_base, valuemask, &values);
+}
+
+// _configure
+
+void _XsMotifTitle::_configure (XEvent *event)
+{
+   XConfigureEvent *ce = (XConfigureEvent*)event;
+   
+/*
+   Check if window has been resized.  If so, generate an expose event
+   to redraw its contents.
+*/
+
+   if ((_lastW != ce->width) || (_lastH != ce->height))
+   {
+      if ((_base != 0) && XtIsManaged (_base))
+         XClearArea (XtDisplay (_base), XtWindow (_base), 0, 0, 0, 0, True);
+
+      _lastW = ce->width;
+      _lastH = ce->height;
+   }
+}
+
+// _configureEventHandler
+
+void _XsMotifTitle::_configureEventHandler (Widget, XtPointer clientData, XEvent *event, Boolean*)
+{
+   if (event->type == ConfigureNotify)
+   {
+      _XsMotifTitle *obj = (_XsMotifTitle*)clientData;
+      obj->_configure (event);
+   }
+}
+
+/*
+   ----------------------------------------------------------------------------
+   _XsMotifIcon
+*/
+
+XtResource _XsMotifIcon::_resourceList[] = {
+   {
+      "iconSize",
+      "IconSize",
+      XmRDimension,
+      sizeof (Dimension),
+      XtOffset (_XsMotifIcon*, _iconSize),
+      XmRImmediate,
+      (XtPointer)IconSize_
+   },
+   {
+      "iconName",
+      "IconName",
+      XmRString,
+      sizeof (String),
+      XtOffset (_XsMotifIcon*, _iconName),
+      XmRImmediate,
+      NULL
+   },
+   {
+      "iconFont",
+      "IconFont",
+      XmRFontStruct,
+      sizeof (XFontStruct*),
+      XtOffset (_XsMotifIcon*, _iconFont),
+      XmRString,
+      "-*-helvetica-bold-r-normal-*-12-*-*-*-*-*-iso8859-1"
+   },
+   {
+      XmNiconX,
+      XmCIconX,
+      XmRPosition,
+      sizeof (Position),
+      XtOffset (_XsMotifIcon*, _iconX),
+      XmRImmediate,
+      (XtPointer)-1
+   },      
+   {
+      XmNiconY,
+      XmCIconY,
+      XmRPosition,
+      sizeof (Position),
+      XtOffset (_XsMotifIcon*, _iconY),
+      XmRImmediate,
+      (XtPointer)-1
+   }
+};
+
+// Constructor
+
+_XsMotifIcon::_XsMotifIcon (const char *name, XsMotifWindow *win, Widget parent) :
+   _XsMotifComponent (name, win, parent)
+{
+   
+// Initialize
+
+   _pixmapGC = 0;
+   _fontGC = 0;
+
+   _iconName = 0;
+   _pixmap = 0;
+   _freePixmap = False;
+   
+   _width = _height = 0;
+   _placed = 0;
+   
+// Get resources
+   
+   _getResources (_resourceList, XtNumber (_resourceList));
+
+// Copy icon name to local memory
+
+   if (_iconName != 0)
+   {
+      char *tmp = new char[strlen (_iconName) + 1];
+      strcpy (tmp, _iconName);
+      _iconName = tmp;
+   }
+
+// Configure the icon
+
+   XtVaSetValues (_base, XmNwidth, _iconSize, XmNheight, _iconSize, NULL);
+}
+
+// Destructor
+
+_XsMotifIcon::~_XsMotifIcon ( )
+{
+   if (_fontGC)
+      XtReleaseGC (_base, _fontGC);
+      
+   if (_pixmapGC)
+      XtReleaseGC (_base, _pixmapGC);
+      
+   if (_freePixmap)
+      XFreePixmap (XtDisplay (_base), _pixmap);
+
+   delete [] _iconName;
+}
+
+// show
+
+void _XsMotifIcon::show ( )
+{
+
+/*
+   Configure the icon position.  Either use the position specified
+   in the resource, or place the icon at the top-left corner of the
+   window.
+*/
+
+   if (_placed == False)
+   {
+      Position x, y;
+   
+      if (_iconX == -1)
+      {
+         XtVaGetValues (_win->base ( ), XmNx, &x, NULL);
+         if (x < 0)  x = 0;
+         _iconX = x;
+      }
+      else
+         x = _iconX;
+      
+      if (_iconY == -1)
+      {
+         XtVaGetValues (_win->base ( ), XmNy, &y, NULL);
+         if (y < 0)  y = 0;
+         _iconY = y;
+      }
+      else
+         y = _iconY;
+      
+      XtVaSetValues (_base, XmNx, x, XmNy, y, NULL);
+
+      _placed = True;
+   }
+   
+// Call the base class
+
+   _XsMotifComponent::show ( );
+}
+
+// setIconName
+
+void _XsMotifIcon::setIconName (const char *iconName)
+{
+   assert (iconName != 0);
+
+   delete [] _iconName;
+   
+   _iconName = new char[strlen (iconName) + 1];
+   strcpy (_iconName, iconName);
+}
+
+// setPixmap
+
+void _XsMotifIcon::setPixmap (Pixmap pixmap)
+{
+   assert (pixmap != 0);
+   
+// Free the existing pixmap (if necessary)
+
+   if (_freePixmap)
+   {
+      XFreePixmap (XtDisplay (_base), _pixmap);
+      _freePixmap = False;
+   }
+   
+// Save the new pixmap
+
+   _pixmap = pixmap;
+
+// Get the pixmap width and height
+
+   Window   dummy;
+   int      xd, yd;
+   unsigned int   uw, uh, ub, ud;
+   
+   XGetGeometry (XtDisplay (_base), _pixmap, &dummy, &xd, &yd, &uw, &uh, &ub, &ud);
+
+   _width = uw;
+   _height = uh;
+}
+   
+// className
+
+const char *_XsMotifIcon::className ( ) const
+{
+   return ("_XsMotifIcon");
+}
+
+// _componentDestroyed
+
+void _XsMotifIcon::_componentDestroyed ( )
+{
+   
+// Clear up the GCs
+
+   if (_fontGC)
+      XtReleaseGC (_base, _fontGC);
+
+   if (_pixmapGC)
+      XtReleaseGC (_base, _pixmapGC);
+
+   if (_freePixmap)
+      XFreePixmap (XtDisplay (_base), _pixmap);
+
+   _fontGC = 0;
+   _pixmapGC = 0;
+   _freePixmap = 0;
+   
+// Call the base-class
+
+   _XsMotifComponent::_componentDestroyed ( );
+}
+   
+// _input
+
+void _XsMotifIcon::_input (XEvent *event)
+{
+   static Time lastTime = (Time)0;
+   
+   switch (event->type)
+   {
+      case ButtonPress:
+      {
+         switch (event->xbutton.button)
+         {
+            case 1:
+               break;
+
+            case 2:
+            {
+               XsMoveOutline move (_base);
+
+// Start the move
+
+               if (move.go ( ) != False)
+               {
+
+// Relocate the window      
+   
+                  _win->setPosition (move.x ( ), move.y ( ));
+               }
+               break;
+            }
+            case 3:
+            {
+               _win->popupMenu ( );
+               break;
+            }               
+         }
+         break;
+      }         
+      case ButtonRelease:
+      {
+         switch (event->xbutton.button)
+         {
+            case 1:
+            {
+
+// Get double-click time
+
+               int multiClick = XtGetMultiClickTime (XtDisplay (_base));
+
+// Check for double-click
+
+               if ((event->xbutton.time - lastTime) <= multiClick)
+                  _win->restore ( );
+               else
+               {
+                  lastTime = event->xbutton.time;
+                  _win->raise ( );
+               }
+               break;
+            }
+         }
+         break;
+      }
+      case MotionNotify:
+      {
+         XsMoveOutline  move (_base);
+
+// Start the move
+
+         if (move.go ( ) != False)
+         {
+
+// Relocate the icon
+   
+            _win->setPosition (move.x ( ), move.y ( ));
+         }
+         break;
+      }
+   }
+}
+
+// _expose
+
+void _XsMotifIcon::_expose (XEvent *)
+{
+   Dimension   iconHeight;
+   Dimension   iconWidth;
+
+// Compute icon size
+
+   XtVaGetValues (_base, XmNwidth, &iconWidth, XmNheight, &iconHeight, NULL);
+         
+// Draw the shadow
+
+   _drawShadows (0, 0, iconWidth, iconHeight, 2);
+
+// Figure out the icon string
+
+   const char *iconName = (_iconName != 0) ? _iconName : (_win->title ( ) != 0) ?
+      _win->title ( ) : _win->name ( );
+         
+   const int fontX = 3;
+   const int fontY = 3;
+   
+   if ((iconName != 0) && (iconName[0] != '\0'))
+   {
+      int   textWidth;
+      int   len = strlen (iconName);
+         
+// Compute the text size
+
+      textWidth = XTextWidth (_iconFont, iconName, len);
+
+// Center the text in the bottom of the icon (or left-justify it)
+      
+      int   x, y;
+
+      if (textWidth <= (iconWidth - (fontX * 2)))
+         x = (iconWidth - (int)textWidth) / 2;
+      else
+         x = fontX;
+           
+      y = (int)iconHeight - _iconFont->descent - fontY;
+
+// Draw the string
+
+      XDrawString (XtDisplay (_base), XtWindow (_base), _fontGC,
+         x, y, iconName, len);
+   }
+
+// Compute label size
+
+   int labelHeight = _iconFont->descent + _iconFont->ascent + (fontY * 2);
+   
+   if (labelHeight >= (iconHeight - 6))
+      return;
+      
+// Draw the separator
+
+   int sepY = (iconHeight) - labelHeight;
+
+   _drawLine (1, sepY, iconWidth - 2, sepY, _bottomShadowGC);
+   _drawLine (1, sepY + 1, iconWidth - 2, sepY + 1, _topShadowGC);
+
+// Draw the pixmap frame
+
+   const int frameX = 4;
+   const int frameY = 4;
+   
+   if ((frameX + 6) >= sepY)
+      return;
+      
+   int   frameWidth = iconWidth - (frameX * 2);
+   int   frameHeight = sepY - frameY - 2;
+   
+   _drawShadows (frameX, frameY, frameWidth, frameHeight, 1, True);
+
+   frameWidth -= 2;
+   frameHeight -= 2;
+   
+   _drawShadows (frameX + 1, frameY + 1, frameWidth, frameHeight, 1);
+   
+   frameWidth -= 2;
+   frameHeight -= 2;
+
+// Blit the pixmap
+
+   if (_pixmap != 0)
+   {
+      if ((frameWidth > 0) && (frameHeight > 0))
+      {
+         int   origX, origY;
+         int   drawW, drawH;
+         
+// Center the pixmap or top-left orient it
+
+         if (frameWidth > _width)
+         {
+            origX = (frameWidth - _width) / 2;
+            origX += frameX + 2;
+            drawW = _width;
+         }
+         else
+         {
+            origX = frameX + 2;
+            drawW = frameWidth;
+         }
+            
+         if (frameHeight > _height)
+         {
+            origY = (frameHeight - _height) / 2;
+            origY += frameY + 2;
+            drawH = _height;
+         }
+         else
+         {
+            origY = frameY + 2;
+            drawH = frameHeight;
+         }
+      
+         XCopyArea (XtDisplay (_base), _pixmap, XtWindow (_base), _pixmapGC,
+            0, 0, drawW, drawH, origX, origY);
+      }
+   }
+}
+   
+// _map
+
+void _XsMotifIcon::_map ( )
+{
+   unsigned long valuemask;
+   XGCValues   values;
+   Pixel fg;
+   Pixel bg;
+   int   depth;
+   
+// Call the base-class
+      
+   _XsMotifComponent::_map ( );
+        
+// Get the icon pixels
+
+   XtVaGetValues (_win->base ( ), XmNdepth, &depth, XmNbackground, &bg,
+      XmNforeground, &fg, NULL);
+      
+// Create the default icon pixmap
+
+   if (_pixmap == 0)
+   {
+      _pixmap = XCreatePixmapFromBitmapData (XtDisplay (_base), XtWindow (_base),
+         xs_motif_icon_bits, xs_motif_icon_width, xs_motif_icon_height,
+         fg, bg, depth);
+
+// Set this pixmap
+
+      setPixmap (_pixmap);
+      
+      _freePixmap = True;
+      
+// Create the icon pixmap graphics context
+
+      valuemask = GCGraphicsExposures | GCForeground | GCBackground;
+      
+      values.graphics_exposures = False;
+      values.foreground = fg;
+      values.background = bg;
+
+      _pixmapGC = XtGetGC (_base, valuemask, &values);
+   }
+
+// Create the font graphics context
+
+   valuemask = GCForeground | GCBackground | GCGraphicsExposures | GCFont;
+
+   values.foreground = fg;
+   values.background = bg;
+   values.font = _iconFont->fid;
+   values.graphics_exposures = False;
+
+   _fontGC = XtGetGC (_base, valuemask, &values);
+}
+   
+/*
+   ----------------------------------------------------------------------------
+   _XsMotifMenu
+*/
+
+// Static definitions
+
+int _XsMotifMenu::_count = 0;
+Cursor _XsMotifMenu::_cursor = None;
+Pixmap _XsMotifMenu::_stipple = None;
+Display *_XsMotifMenu::_dpy = 0;
+
+// Resources
+
+XtResource _XsMotifMenu::_resourceList[] = {
+   {
+      "saveUnder",
+      "SaveUnder",
+      XmRBoolean,
+      sizeof (Boolean),
+      XtOffset (_XsMotifMenu*, _saveUnder),
+      XmRImmediate,
+      (XtPointer)True
+   },
+   {
+      "restoreString",
+      "RestoreString",
+      XmRString,
+      sizeof (String),
+      XtOffset (_XsMotifMenu*, _strings[Restore]),
+      XmRString,
+      "Restore"
+   },
+   {
+      "moveString",
+      "MoveString",
+      XmRString,
+      sizeof (String),
+      XtOffset (_XsMotifMenu*, _strings[Move]),
+      XmRString,
+      "Move"
+   },
+   {
+      "sizeString",
+      "SizeString",
+      XmRString,
+      sizeof (String),
+      XtOffset (_XsMotifMenu*, _strings[Size]),
+      XmRString,
+      "Size"
+   },
+   {
+      "minimizeString",
+      "MinimizeString",
+      XmRString,
+      sizeof (String),
+      XtOffset (_XsMotifMenu*, _strings[Minimize]),
+      XmRString,
+      "Minimize"
+   },
+   {
+      "maximizeString",
+      "MaximizeString",
+      XmRString,
+      sizeof (String),
+      XtOffset (_XsMotifMenu*, _strings[Maximize]),
+      XmRString,
+      "Maximize"
+   },
+   {
+      "raiseString",
+      "RaiseString",
+      XmRString,
+      sizeof (String),
+      XtOffset (_XsMotifMenu*, _strings[Raise]),
+      XmRString,
+      "Raise"
+   },
+   {
+      "lowerString",
+      "LowerString",
+      XmRString,
+      sizeof (String),
+      XtOffset (_XsMotifMenu*, _strings[Lower]),
+      XmRString,
+      "Lower"
+   },
+   {
+      "closeString",
+      "CloseString",
+      XmRString,
+      sizeof (String),
+      XtOffset (_XsMotifMenu*, _strings[Close]),
+      XmRString,
+      "Close"
+   },
+   {
+      "menuFont",
+      "menuFont",
+      XmRFontStruct,
+      sizeof (XFontStruct*),
+      XtOffset (_XsMotifMenu*, _menuFont),
+      XmRString,
+      "-*-helvetica-bold-o-normal-*-14-*-*-*-*-*-iso8859-1"
+   }
+};
+
+// Constructor
+
+_XsMotifMenu::_XsMotifMenu (const char *name, XsMotifWindow *win) :
+   _XsMotifBase (name, win)
+{
+
+// Create the cursor (if necessary)
+
+   if (_count++ == 0)
+   {
+
+// Create the menu cursor
+
+      _cursor = XCreateFontCursor (XtDisplay (win->base ( )), XC_arrow);
+
+// Create a stippled pixmap
+
+      Widget   parent = _win->base ( );
+      Pixel    foreground;
+      Pixel    background;
+      int      depth;
+      
+      XtVaGetValues (parent, XmNforeground, &foreground, XmNbackground,
+         &background, XmNdepth, &depth, NULL);
+      
+      const int pixmapWidth = 2;
+      const int pixmapHeight = 2;
+      static unsigned char pixmapBits[] = { 0x02, 0x01 };
+
+      _dpy = XtDisplay (parent);
+      _stipple = XCreatePixmapFromBitmapData (_dpy, DefaultRootWindow (_dpy),
+         (char*)pixmapBits, pixmapWidth, pixmapHeight, foreground, background,
+         depth);
+   }      
+
+// Initialize
+
+   _fontGC = 0;
+   _grayGC = 0;
+   _backgroundGC = 0;
+   
+// Create the component (why doesn't overrideShell work?)
+
+   _base = XtVaCreatePopupShell (_name, topLevelShellWidgetClass,
+      XtParent (_win->base ( )), XmNoverrideRedirect, True,
+      XmNborderWidth, 1, NULL);
+
+// Install destroy handler
+
+   _installDestroyHandler ( );
+   
+// Install event handler ('cause we never call _XsMotifBase::show)
+
+   XtAddEventHandler (_base, StructureNotifyMask, False, _mapEventHandler, (XtPointer)this);
+
+// Get resources
+   
+   _getResources (_resourceList, XtNumber (_resourceList));
+
+// Get the background color
+
+   Pixel bg;
+
+   XtVaGetValues (_win->base ( ), XmNbackground, &bg, NULL);
+      
+// Compute the size of the (largest) menu item
+
+   int   textHeight = _menuFont->ascent + _menuFont->descent;
+   int   textWidth = 0;
+   int   tmp;
+   
+   for (int loop = 0; loop < Num; loop++)
+   {
+      tmp = XTextWidth (_menuFont, _strings[loop], strlen (_strings[loop]));
+
+      if (tmp > textWidth)
+         textWidth = tmp;
+   }
+      
+// Put a border around the buttons
+
+   textWidth += (2 * HorizTextOffset);
+   textHeight += (2 * VertTextOffset);
+   
+/*
+   The menu height is the menu-shadow (1 pixel on top and bottom) + the
+   items themselves.
+*/
+
+   int   menuHeight = (2 * ShadowThickness) +   // Top and bottom shadow
+                      (textHeight * Num);       // The menu items
+   
+/*
+   The menu width is the menu-shadow (1 pixel on the left and right) +
+   the largest menu text (calculated above)
+*/
+
+   int   menuWidth = (2 * ShadowThickness) +    // Left and right shadow   
+                     textWidth;                 // Largest text item
+
+// Configure the popup
+      
+   XtVaSetValues (_base, XmNsaveUnder, _saveUnder, XmNwidth, menuWidth,
+      XmNheight, menuHeight, NULL);
+}
+
+// Destructor
+
+_XsMotifMenu::~_XsMotifMenu ( )
+{
+   if (_fontGC)
+      XtReleaseGC (_base, _fontGC);
+
+   if (_grayGC)
+      XtReleaseGC (_base, _grayGC);
+      
+   if (_backgroundGC)
+      XtReleaseGC (_base, _backgroundGC);
+
+// Free the pixmap (if necessary)
+
+   if (--_count == 0)
+      XFreePixmap (_dpy, _stipple);
+}
+
+// popup
+
+void _XsMotifMenu::popup (Boolean atPointer)
+{
+   assert (_base != 0);
+   
+   Position x, y;
+
+// Compute the location of the menu.
+
+   if (atPointer)
+   {
+      unsigned int mask;
+      Window   win;
+      int      winX, winY;
+      int      rootX, rootY;
+            
+// Menu at pointer location
+
+      XQueryPointer (XtDisplay (_base), XtWindow (XtParent (_base)),
+         &win, &win, &rootX, &rootY, &winX, &winY, &mask);
+         
+      x = (Position)rootX;
+      y = (Position)rootY;
+   }
+   else
+   {
+      
+// Menu at top-left corner of client area
+
+      XtTranslateCoords (_win->clientArea ( ), 0, 0, &x, &y);
+   }      
+
+// Move the menu
+
+   XtVaSetValues (_base, XmNx, x, XmNy, y, NULL);
+   
+// Initialize the item
+
+   _curItem = NoItem;
+   
+// Pop it up
+
+   XtPopup (_base, XtGrabNone);
+   
+// Grab the pointer
+
+   if (_grabPointer ( ) == FALSE)
+      return;
+   
+// Update the menu
+
+   _processEvents ( );
+   
+// Pop the menu down
+
+   XtPopdown (_base);
+
+// Ungrab the pointer
+
+   _ungrabPointer ( );
+
+   if (_curItem != NoItem)
+   {
+      
+/*
+   Post a work-proc to process this item.  This will allow everything
+   to get caught up before we process the menu item
+*/
+
+      XtAppContext appContext = XtWidgetToApplicationContext (_base);
+      XtAppAddWorkProc (appContext, _workProc, (XtPointer)this);
+   }
+}   
+
+// className
+
+const char *_XsMotifMenu::className ( ) const
+{
+   return ("_XsMotifMenu");
+}
+
+// _componentDestroyed
+
+void _XsMotifMenu::_componentDestroyed ( )
+{
+
+// Clean up the GCs
+
+   if (_fontGC)
+      XtReleaseGC (_base, _fontGC);
+
+   if (_grayGC)
+      XtReleaseGC (_base, _grayGC);
+      
+   if (_backgroundGC)
+      XtReleaseGC (_base, _backgroundGC);
+
+   _fontGC = 0;
+   _grayGC = 0;
+   _backgroundGC = 0;
+   
+// Call the base-class
+
+   _XsMotifBase::_componentDestroyed ( );
+}
+   
+// _processEvents
+
+void _XsMotifMenu::_processEvents ( )
+{
+   assert (_base != 0);
+   
+   XtAppContext appContext = XtWidgetToApplicationContext (_base);
+   XEvent event;
+   Display *dpy = XtDisplay (_base);
+   int   done = 0;
+      
+   while (!done)
+   {
+      XtAppNextEvent (appContext, &event);
+
+// Process this event
+
+      switch (event.type)
+      {
+         case ButtonRelease:
+         {
+            done = 1;
+            break;
+         }
+         case Expose:
+         {
+            _redrawMenu ( );
+            break;
+         }
+         case MotionNotify:
+         {
+            XEvent next;
+
+// Process only the last motion event
+
+            while (XPending (dpy) > 0)
+            {
+               XPeekEvent (dpy, &next);
+               if (next.type != MotionNotify)
+                  break;
+               XtAppNextEvent (appContext, &event);
+            }
+
+// Track the mouse and toggle the menu items
+
+            Item item = _trackPointer ((XMotionEvent*)&event);
+
+// Unselect the current item (if the item is different)
+               
+            if (item != _curItem)
+            {
+               _toggleItem (_curItem, False);
+               
+// Select the new item
+   
+               _toggleItem ((_curItem = item), True);
+            }
+                        
+            break;
+         }
+         default:
+         {
+            XtDispatchEvent (&event);
+            break;
+         }
+      }
+   }
+}
+
+// _processItem
+
+void _XsMotifMenu::_processItem (Item item)
+{
+   if (item == NoItem)
+      return;
+
+   switch (item)
+   {
+      case Restore:
+      {
+         _win->restore ( );
+         break;
+      }         
+      case Move:
+      {
+         Widget base = (_win->minimized ( )) ? _win->icon ( ) : _win->base ( );
+
+// Warp the pointer to the center of the window
+
+         Dimension width, height;
+         XtVaGetValues (base, XmNwidth, &width, XmNheight, &height, NULL);
+         
+         XWarpPointer (XtDisplay (_base), None, XtWindow (base), 0, 0, 0, 0,
+            (width / 2), (height / 2));
+            
+// Move the window
+
+         XsMoveOutline move (base);
+
+// Start the move
+
+         if (move.go (True) != False)
+         {
+
+// Relocate the window      
+   
+            _win->setPosition (move.x ( ), move.y ( ));
+         }
+         break;
+      }         
+      case Size:
+      {
+         Widget base = (_win->minimized ( )) ? _win->icon ( ) : _win->base ( );
+
+// Warp the pointer to the center of the window
+
+         Dimension width, height;
+         XtVaGetValues (base, XmNwidth, &width, XmNheight, &height, NULL);
+         
+         XWarpPointer (XtDisplay (_base), None, XtWindow (base), 0, 0, 0, 0,
+            (width / 2), (height / 2));
+            
+// Resize the window
+
+         XsResizeOutline resize (_win->base ( ), XsResizeOutline::Undetermined);
+         resize.setMinSize (_win->minWidth ( ), _win->minHeight ( ));
+
+// Start the resize
+
+         if (resize.go (True) != False)
+         {
+
+// Relocate the window      
+   
+            _win->setPosition (resize.x ( ), resize.y ( ));
+            _win->setSize (resize.width ( ), resize.height ( ));
+         }
+         break;
+      }
+      case Minimize:
+      {
+         _win->minimize ( );
+         break;
+      }
+      case Maximize:
+      {
+         _win->maximize ( );
+         break;
+      }         
+      case Raise:
+      {
+         _win->raise ( );
+         break;
+      }
+      case Lower:
+      {
+         _win->lower ( );
+         break;
+      }
+      case Close:
+      {
+         _win->close ( );
+         break;
+      }
+      default:
+         assert (0);
+   }
+}
+
+// _redrawMenu
+
+void _XsMotifMenu::_redrawMenu ( )
+{
+   Dimension   w, h;
+   
+// Get the size of the menu
+
+   XtVaGetValues (_base, XmNwidth, &w, XmNheight, &h, NULL);
+   
+// Draw a shadow around the menu
+
+   _drawShadows (0, 0, w, h, ShadowThickness);
+
+// Cycle and draw all of the elements
+
+   for (int loop = 0; loop < Num; loop++)
+      _redrawItem ((Item)loop);
+}
+
+// _redrawItem
+
+void _XsMotifMenu::_redrawItem (Item item)
+{
+   if (item == NoItem)
+      return;
+   
+   int   x = ShadowThickness + HorizTextOffset;
+   int   y;
+      
+/*
+   Compute the y-position of the element.  This will be the size of the
+   top-shadow + the items before it + the offset of the item itself
+*/
+
+   y = ShadowThickness +                           // Top shadow
+       (item * ((VertTextOffset * 2) + (_menuFont->descent + _menuFont->ascent))) +
+       (VertTextOffset + _menuFont->ascent);       // The item iteself
+
+// Figure out the graphics-context
+
+   GC gc;
+   
+   if (_win->minimized ( ))
+      gc = ((item == Size) || (item == Minimize)) ? _grayGC : _fontGC;
+   else if (_win->maximized ( ))
+      gc = (item == Maximize) ? _grayGC : _fontGC;
+   else
+      gc = (item == Restore) ? _grayGC : _fontGC;      
+   
+// Draw the string
+
+   XDrawString (XtDisplay (_base), XtWindow (_base), gc, x, y,
+      _strings[item], strlen (_strings[item]));
+}
+
+// _toggleItem
+
+void _XsMotifMenu::_toggleItem (Item item, Boolean active)
+{
+   if (item == NoItem)
+      return;
+   
+/*
+   Either draw the background of the specified item in the active color
+   or the standard background color
+*/
+
+   GC gc = (active) ? _topShadowGC : _backgroundGC;
+   
+// Get the width of the menu
+
+   Dimension menuWidth;
+   XtVaGetValues (_base, XmNwidth, &menuWidth, NULL);
+
+// Compute the location and size of the rectangle
+
+   int   x, y;
+   unsigned int width, height;
+
+   x = ShadowThickness;
+   height = ((VertTextOffset * 2) + (_menuFont->descent + _menuFont->ascent));
+   y = ShadowThickness + (item * height);
+   width = menuWidth - (2 * ShadowThickness);
+   
+// Draw the filled rectangle
+
+   XFillRectangle (XtDisplay (_base), XtWindow (_base), gc, x, y, width, height);
+
+// Redraw the text
+
+   _redrawItem (item);
+}
+   
+// _trackPointer
+
+_XsMotifMenu::Item _XsMotifMenu::_trackPointer (XMotionEvent *event)
+{
+   assert (_base != 0);
+   
+   Dimension   menuWidth;
+   Dimension   menuHeight;
+   Position    x, y;   
+
+// Get the menu size and position
+
+   XtVaGetValues (_base, XmNwidth, &menuWidth, XmNheight, &menuHeight,
+      XmNx, &x, XmNy, &y, NULL);
+   
+// Make sure the pointer is in the menu
+
+   if ((event->x_root < x) || (event->x_root > (x + menuWidth)))
+      return (NoItem);
+      
+   if ((event->y_root < y) || (event->y_root > (y + menuHeight)))
+      return (NoItem);
+      
+// Make sure the pointer is on the confines of the shadow
+
+   if ((event->x < ShadowThickness) || (event->x > (menuWidth - (2 * ShadowThickness))))
+      return (NoItem);
+      
+   if ((event->y < ShadowThickness) || (event->y > (menuHeight - (2 * ShadowThickness))))
+      return (NoItem);
+      
+/*
+   Now we are just concerned with the y-position.  Subtract off the
+   shadow thickness to normalize the location
+*/
+
+   int   yPos = event->y - ShadowThickness;
+   
+// Compute which item the mouse is in
+
+   int itemHeight = (VertTextOffset * 2) + (_menuFont->descent + _menuFont->ascent);
+
+   Item item = (Item)(yPos / itemHeight);
+   
+// Validate that the item is not grayed-out
+
+   if (_win->minimized ( ))
+   {
+      if ((item == Size) || (item == Minimize))
+         item = NoItem;
+   }
+   else if (_win->maximized ( ))
+   {
+      if (item == Maximize)
+         item = NoItem;
+   }
+   else if (item == Restore)
+      item = NoItem;
+
+   return (item);
+}
+
+// _grabPointer 
+
+Boolean _XsMotifMenu::_grabPointer ( )
+{
+   
+// Sync everything up before being grabby
+
+   XSync (XtDisplay (_base), False);
+
+// Grab the pointer
+
+   if (XGrabPointer (XtDisplay (_base), XtWindow (_base), False,
+      (unsigned int)(ButtonPressMask | ButtonReleaseMask | PointerMotionMask |
+      EnterWindowMask | LeaveWindowMask), GrabModeAsync,
+      GrabModeAsync, None, _cursor, CurrentTime) != GrabSuccess)
+   {
+      XBell (XtDisplay (_base), 100);
+      return (False);
+   }
+      
+   return (True);
+}
+
+// _ungrabPointer
+
+void _XsMotifMenu::_ungrabPointer ( )
+{
+
+// Ungrab the pointer
+
+   XUngrabPointer (XtDisplay (_base), CurrentTime);
+
+// Sync everything back up
+
+   XSync (XtDisplay (_base), False);
+}
+
+// _map
+
+void _XsMotifMenu::_map ( )
+{
+   
+// Call the base-class
+
+   _XsMotifBase::_map ( );
+
+   unsigned long valuemask;
+   XGCValues   values;
+   Pixel foreground;
+   Pixel background;
+   
+// Get the pixels
+
+   XtVaGetValues (XtParent (_base), XmNforeground, &foreground, NULL);
+   XtVaGetValues (_base, XmNbackground, &background, NULL);
+
+// Create the font graphics context
+
+   valuemask = GCForeground | GCBackground | GCGraphicsExposures | GCFont;
+
+   values.foreground = foreground;
+   values.background = background;
+   values.font = _menuFont->fid;
+   values.graphics_exposures = False;
+
+   _fontGC = XtGetGC (_base, valuemask, &values);
+
+// Create the insensitive font graphics context
+
+   valuemask |= (GCFillStyle | GCTile);
+
+   values.fill_style = FillTiled;
+   values.tile = _stipple;
+
+   _grayGC = XtGetGC (_base, valuemask, &values);
+
+// Create the background contexts
+
+   valuemask = GCForeground | GCLineWidth | GCGraphicsExposures;
+   values.line_width = 0;
+   values.graphics_exposures = False;
+   values.foreground = background;
+
+   _backgroundGC = XtGetGC (_base, valuemask, &values);
+}
+
+// _workProc
+
+Boolean _XsMotifMenu::_workProc (XtPointer clientData)
+{
+   _XsMotifMenu *obj = (_XsMotifMenu*)clientData;
+   if (obj->_curItem != NoItem)
+      obj->_processItem (obj->_curItem);
+
+   return (True);
+}
+
+/*
+   ----------------------------------------------------------------------------
+   XsMotifWindow
+*/
+
+// Static definitions
+
+XtResource XsMotifWindow::_resourceList[] = {
+   {
+      "showBorder",
+      "ShowBorder",
+      XmRBoolean,
+      sizeof (Boolean),
+      XtOffset (XsMotifWindow*, _showBorder),
+      XmRImmediate,
+      (XtPointer)True
+   },
+   {
+      "showResize",
+      "ShowResize",
+      XmRBoolean,
+      sizeof (Boolean),
+      XtOffset (XsMotifWindow*, _showResize),
+      XmRImmediate,
+      (XtPointer)True
+   },
+   {
+      "showTitle",
+      "ShowTitle",
+      XmRBoolean,
+      sizeof (Boolean),
+      XtOffset (XsMotifWindow*, _showTitle),
+      XmRImmediate,
+      (XtPointer)True
+   },
+   {
+      "showMenu",
+      "ShowMenu",
+      XmRBoolean,
+      sizeof (Boolean),
+      XtOffset (XsMotifWindow*, _showMenu),
+      XmRImmediate,
+      (XtPointer)True
+   },
+   {
+      "showMinimize",
+      "ShowMinimize",
+      XmRBoolean,
+      sizeof (Boolean),
+      XtOffset (XsMotifWindow*, _showMinimize),
+      XmRImmediate,
+      (XtPointer)True
+   },
+   {
+      "showMaximize",
+      "ShowMaximize",
+      XmRBoolean,
+      sizeof (Boolean),
+      XtOffset (XsMotifWindow*, _showMaximize),
+      XmRImmediate,
+      (XtPointer)True
+   },
+   {
+      "lowerOnIconify",
+      "LowerOnIconify",
+      XmRBoolean,
+      sizeof (Boolean),
+      XtOffset (XsMotifWindow*, _lowerOnIconify),
+      XmRImmediate,
+      (XtPointer)False
+   },
+   {
+      XmNminWidth,
+      XmCMinWidth,
+      XmRDimension,
+      sizeof (Dimension),
+      XtOffset (XsMotifWindow*, _minW),
+      XmRImmediate,
+      (XtPointer)((BorderSize_ + ButtonSize_) * 3)
+   },
+   {
+      XmNmaxWidth,
+      XmCMaxWidth,
+      XmRDimension,
+      sizeof (Dimension),
+      XtOffset (XsMotifWindow*, _maxW),
+      XmRImmediate,
+      (XtPointer)-1
+   },
+   {
+      XmNminHeight,
+      XmCMinHeight,
+      XmRDimension,
+      sizeof (Dimension),
+      XtOffset (XsMotifWindow*, _minH),
+      XmRImmediate,
+      (XtPointer)((BorderSize_ + ButtonSize_) * 3)
+   },
+   {
+      XmNmaxHeight,
+      XmCMaxHeight,
+      XmRDimension,
+      sizeof (Dimension),
+      XtOffset (XsMotifWindow*, _maxH),
+      XmRImmediate,
+      (XtPointer)-1
+   }
+};    
+
+// Constructor
+
+XsMotifWindow::XsMotifWindow (const char *name) : XsMDIWindow (name)
+{
+   int   loop;
+   
+// Initialize
+
+   for (loop = 0; loop < _XsMotifSide::Max; loop++)
+   {
+      _corners[loop] = 0;
+      _sides[loop] = 0;
+   }
+
+   for (loop = 0; loop < _XsMotifButton::Max; loop++)
+      _buttons[loop] = 0;
+
+   _title = 0;
+   _icon = 0;
+   _menu = 0;
+      
+   _maximized = False;
+   _minimized = False;
+}
+   
+// Destructor
+
+XsMotifWindow::~XsMotifWindow ( )
+{
+   int   loop;
+   
+   for (loop = 0; loop < _XsMotifSide::Max; loop++)
+   {
+      delete _corners[loop];
+      delete _sides[loop];
+   }
+
+   for (loop = 0; loop < _XsMotifButton::Max; loop++)
+      delete _buttons[loop];
+
+   delete _title;
+   delete _icon;
+   delete _menu;
+}
+
+// raise
+
+void XsMotifWindow::raise ( )
+{
+   Widget w = (_minimized == True) ? _icon->base ( ) : _base;
+   assert (w != 0);
+   XRaiseWindow (XtDisplay (w), XtWindow (w));
+}
+
+// lower
+
+void XsMotifWindow::lower ( )
+{
+   Widget w = (_minimized == True) ? _icon->base ( ) : _base;
+   assert (w != 0);
+   XLowerWindow (XtDisplay (w), XtWindow (w));
+}
+
+// minimize
+
+void XsMotifWindow::minimize ( )
+{
+   assert (_base != 0);
+   
+// Check if we are already minimized
+
+   if (_minimized == True)
+      return;
+
+// Minimize the window
+
+   hide ( );
+
+   _minimized = True;
+
+// Lower (if necessary)
+
+   if (_lowerOnIconify)
+      lower ( );
+
+   _icon->show ( );
+}
+   
+// maximize
+
+void XsMotifWindow::maximize ( )
+{
+   assert (_base != 0);
+   
+// Check if we are already in this state
+
+   if (_maximized == True)
+      return;
+
+// Restore (if necessary)
+
+   if (_minimized)
+      restore ( );
+      
+// Save current dimensions
+
+   XtVaGetValues (_base, XmNx, &_savedX, XmNy, &_savedY, XmNwidth,
+      &_savedWidth, XmNheight, &_savedHeight, NULL);
+
+/*
+   Constrain the new window size.  The size of the maximized window
+   is equal to the size of the current clip-window of the canvas.
+*/
+
+   const Dimension offset = 5;      // Border around max'd window
+   
+   Widget clipWindow = XtParent (XtParent (_base));
+   assert (clipWindow != 0);
+   Dimension   clipW, clipH;   
+   Window      child;
+   int         newX, newY;
+   
+   XtVaGetValues (clipWindow, XmNheight, &clipH, XmNwidth, &clipW, NULL);
+   
+// Add in offset
+
+   if (clipW > (offset * 2))
+      clipW -= (offset * 2);
+      
+   if (clipH > (offset * 2))
+      clipH -= (offset * 2);
+      
+// Compute the new window position (map clip-window to work-area)
+
+   XTranslateCoordinates (XtDisplay (_base), XtWindow (clipWindow),
+      XtWindow (XtParent (_base)), (int)offset, (int)offset,
+      &newX, &newY, &child);
+   
+// Set new maximum dimensions
+
+   setPosition ((Position)newX, (Position)newY);
+   setSize (clipW, clipH);
+
+   _maximized = True;
+
+// Redraw the maximize button
+
+   _buttons[_XsMotifButton::Maximize]->redraw ( );
+}
+   
+// restore
+
+void XsMotifWindow::restore ( )
+{
+   assert (_base != 0);
+   
+// Check if we are already restored
+
+   if ((_maximized == False) && (_minimized == False))
+      return;
+
+// Either un-minimize or un-maximize
+
+   if (_minimized)
+   {
+
+// Restore the window
+
+      _icon->hide ( );
+      _minimized = False;
+
+// If maximized, restore again
+
+      if (_maximized)
+         restore ( );
+         
+// Show the window
+
+      show ( );
+   }
+   else
+   {
+   
+// Restore saved dimensions
+
+      setPosition (_savedX, _savedY);
+      setSize (_savedWidth, _savedHeight);
+
+      _maximized = False;
+
+// Redraw the maximize button
+
+      _buttons[_XsMotifButton::Maximize]->redraw ( );
+   }
+}
+   
+// close
+
+void XsMotifWindow::close ( )
+{
+
+/*
+   Don't delete the window (because its not ours to delete).
+   Just hide it.
+*/
+   
+   if (_minimized)
+      _icon->hide ( );
+   else
+      hide ( );
+}
+
+// setTitle
+
+void XsMotifWindow::setTitle (const char *title)
+{
+   if (_title != 0)
+      _title->setTitle (title);
+}   
+
+// setIconName
+
+void XsMotifWindow::setIconName (const char *iconName)
+{
+   if (_icon != 0)
+      _icon->setIconName (iconName);
+}
+
+// setPixmap
+
+void XsMotifWindow::setPixmap (Pixmap pixmap)
+{
+   if (_icon != 0)
+      _icon->setPixmap (pixmap);
+}
+   
+// popupMenu
+
+void XsMotifWindow::popupMenu (Boolean b)
+{
+   if (_menu != 0)
+      _menu->popup (b);
+}
+   
+// setPosition
+
+void XsMotifWindow::setPosition (Position x, Position y)
+{
+   if (_base != 0)
+   {
+      Widget w = (_minimized == True) ? _icon->base ( ) : _base;
+      assert (w != 0);
+      XtVaSetValues (w, XmNx, x, XmNy, y, NULL);
+   }
+   else
+      XsMDIWindow::setPosition (x, y);    // Cache the points
+}
+      
+// setSize
+
+void XsMotifWindow::setSize (Dimension w, Dimension h)
+{
+
+// Set the window size
+
+   if (_base != 0)
+   {
+      if (w < _minW)
+         w = _minW;
+      else if ((_maxW != (Dimension)-1) && (w > _maxW))
+         w = _maxW;
+      
+      if (h < _minH)
+         h = _minH;
+      else if ((_maxH != (Dimension)-1) && (h > _maxH))
+         h = _maxH;
+      
+      if (_minimized == False)
+         XtVaSetValues (_base, XmNwidth, w, XmNheight, h, NULL);
+   }
+   else
+      XsMDIWindow::setSize (w, h);     // Cache the points
+}
+      
+// className
+
+const char* XsMotifWindow::className ( ) const
+{
+   return ("XsMotifWindow");
+}
+
+// _createWindow
+
+void XsMotifWindow::_createWindow (Widget parent)
+{
+   assert (parent != 0);
+   
+// Create the window frame
+
+   _base = XtVaCreateWidget (_name, xmFormWidgetClass, parent,
+      XmNborderWidth, (Dimension)1, NULL);
+      
+// Install destroy handler
+
+   _installDestroyHandler ( );
+   
+// Get resources
+   
+   _getResources (_resourceList, XtNumber (_resourceList));
+
+/*
+   Fix configuration inter-dependencies.  Here are the rules:
+
+   1) If there is no border, then there are no resize handles
+   2) If there is no title, then there are no buttons (would look stupid)
+*/
+
+   if (_showBorder == False)
+      _showResize = False;
+      
+   if (_showTitle == False)
+   {
+      _showMenu = False;
+      _showMinimize = False;
+      _showMaximize = False;
+   }      
+
+/*
+   Corners
+*/
+
+   if (_showResize)
+   {
+
+// Top-Left
+
+      _corners[_XsMotifCorner::TopLeft] = new _XsMotifCorner ("topLeft", this, _XsMotifCorner::TopLeft);
+
+      XtVaSetValues (_corners[_XsMotifCorner::TopLeft]->base ( ), XmNtopAttachment,
+         XmATTACH_FORM, XmNbottomAttachment, XmATTACH_NONE, XmNleftAttachment,
+         XmATTACH_FORM, XmNrightAttachment, XmATTACH_NONE, NULL);
+
+// Top-Right
+
+      _corners[_XsMotifCorner::TopRight] = new _XsMotifCorner ("topRight", this, _XsMotifCorner::TopRight);
+
+      XtVaSetValues (_corners[_XsMotifCorner::TopRight]->base ( ), XmNtopAttachment,
+         XmATTACH_FORM, XmNbottomAttachment, XmATTACH_NONE, XmNleftAttachment,
+         XmATTACH_NONE, XmNrightAttachment, XmATTACH_FORM, NULL);
+         
+// Bottom-Left
+
+      _corners[_XsMotifCorner::BottomLeft] = new _XsMotifCorner ("bottomLeft", this, _XsMotifCorner::BottomLeft);
+      
+      XtVaSetValues (_corners[_XsMotifCorner::BottomLeft]->base ( ), XmNtopAttachment,
+         XmATTACH_NONE, XmNbottomAttachment, XmATTACH_FORM, XmNleftAttachment,
+         XmATTACH_FORM, XmNrightAttachment, XmATTACH_NONE, NULL);
+
+// Bottom-Right
+
+      _corners[_XsMotifCorner::BottomRight] = new _XsMotifCorner ("bottomRight", this, _XsMotifCorner::BottomRight);
+
+      XtVaSetValues (_corners[_XsMotifCorner::BottomRight]->base ( ), XmNtopAttachment,
+         XmATTACH_NONE, XmNbottomAttachment, XmATTACH_FORM, XmNleftAttachment,
+         XmATTACH_NONE, XmNrightAttachment, XmATTACH_FORM, NULL);
+   }
+         
+/*
+   Sides
+*/
+
+   if (_showBorder)
+   {
+
+// Top   
+
+      _sides[_XsMotifSide::Top] = new _XsMotifSide ("top", this, _XsMotifSide::Top);
+
+      XtVaSetValues (_sides[_XsMotifSide::Top]->base ( ),  XmNtopAttachment,
+         XmATTACH_FORM, XmNbottomAttachment, XmATTACH_NONE, NULL);
+
+      if (_showResize)
+      {
+         XtVaSetValues (_sides[_XsMotifSide::Top]->base ( ), XmNleftAttachment,
+            XmATTACH_WIDGET, XmNleftWidget, _corners[_XsMotifCorner::TopLeft]->base ( ),
+            XmNrightAttachment, XmATTACH_WIDGET, XmNrightWidget,
+            _corners[_XsMotifCorner::TopRight]->base ( ), NULL);
+      }
+      else
+      {
+         XtVaSetValues (_sides[_XsMotifSide::Top]->base ( ), XmNleftAttachment,
+            XmATTACH_FORM, XmNrightAttachment, XmATTACH_FORM, NULL);
+      }
+      
+// Bottom
+
+      _sides[_XsMotifSide::Bottom] = new _XsMotifSide ("bottom", this, _XsMotifSide::Bottom);
+
+      XtVaSetValues (_sides[_XsMotifSide::Bottom]->base ( ), XmNtopAttachment,
+         XmATTACH_NONE, XmNbottomAttachment, XmATTACH_FORM, NULL);
+
+      if (_showResize)
+      {
+         XtVaSetValues (_sides[_XsMotifSide::Bottom]->base ( ), XmNleftAttachment,
+            XmATTACH_WIDGET, XmNleftWidget, _corners[_XsMotifCorner::BottomLeft]->base ( ),
+            XmNrightAttachment, XmATTACH_WIDGET, XmNrightWidget,
+            _corners[_XsMotifCorner::BottomRight]->base ( ), NULL);
+      }
+      else
+      {
+         XtVaSetValues (_sides[_XsMotifSide::Bottom]->base ( ), XmNleftAttachment,
+            XmATTACH_FORM, XmNrightAttachment, XmATTACH_FORM, NULL);
+      }
+
+// Left side
+
+      _sides[_XsMotifSide::Left] = new _XsMotifSide ("left", this, _XsMotifSide::Left);
+
+      XtVaSetValues (_sides[_XsMotifSide::Left]->base ( ), XmNleftAttachment,
+         XmATTACH_FORM, XmNrightAttachment, XmATTACH_NONE, NULL);
+
+      if (_showResize)
+      {
+         XtVaSetValues (_sides[_XsMotifSide::Left]->base ( ), XmNtopAttachment,
+            XmATTACH_WIDGET, XmNtopWidget, _corners[_XsMotifCorner::TopLeft]->base ( ),
+            XmNbottomAttachment, XmATTACH_WIDGET, XmNbottomWidget,
+            _corners[_XsMotifCorner::BottomLeft]->base ( ), NULL);
+      }
+      else
+      {
+         XtVaSetValues (_sides[_XsMotifSide::Left]->base ( ), XmNtopAttachment,
+            XmATTACH_FORM, XmNbottomAttachment, XmATTACH_FORM, NULL);
+      }
+
+// Right side
+
+      _sides[_XsMotifSide::Right] = new _XsMotifSide ("right", this, _XsMotifSide::Right);
+
+      XtVaSetValues (_sides[_XsMotifSide::Right]->base ( ), XmNleftAttachment,
+         XmATTACH_NONE, XmNrightAttachment, XmATTACH_FORM, NULL);
+
+      if (_showResize)
+      {
+         XtVaSetValues (_sides[_XsMotifSide::Right]->base ( ), XmNtopAttachment,
+            XmATTACH_WIDGET, XmNtopWidget, _corners[_XsMotifCorner::TopRight]->base ( ),
+            XmNbottomAttachment, XmATTACH_WIDGET, XmNbottomWidget,
+            _corners[_XsMotifCorner::BottomRight]->base ( ), NULL);
+      }
+      else
+      {
+         XtVaSetValues (_sides[_XsMotifSide::Right]->base ( ), XmNtopAttachment,
+            XmATTACH_FORM, XmNbottomAttachment, XmATTACH_FORM, NULL);
+      }
+   }
+         
+// Menu button
+
+   if (_showMenu)
+   {
+      _buttons[_XsMotifButton::Menu] = new _XsMotifButton ("menu", this, _XsMotifButton::Menu);
+
+      XtVaSetValues (_buttons[_XsMotifButton::Menu]->base ( ), XmNbottomAttachment,
+         XmATTACH_NONE, XmNrightAttachment, XmATTACH_NONE, NULL);
+
+      if (_showBorder)
+      {
+         XtVaSetValues (_buttons[_XsMotifButton::Menu]->base ( ), XmNleftAttachment,
+            XmATTACH_WIDGET, XmNleftWidget, _sides[_XsMotifSide::Left]->base ( ),
+            XmNtopAttachment, XmATTACH_WIDGET, XmNtopWidget, _sides[_XsMotifSide::Top]->base ( ),
+            NULL);
+      }
+      else
+      {
+         XtVaSetValues (_buttons[_XsMotifButton::Menu]->base ( ), XmNleftAttachment,
+            XmATTACH_FORM, XmNtopAttachment, XmATTACH_FORM, NULL);
+      }
+   }
+   
+// Maximize button
+
+   if (_showMaximize)
+   {
+      _buttons[_XsMotifButton::Maximize] = new _XsMotifButton ("maximize", this, _XsMotifButton::Maximize);
+      
+      XtVaSetValues (_buttons[_XsMotifButton::Maximize]->base ( ), XmNbottomAttachment,
+         XmATTACH_NONE, XmNleftAttachment, XmATTACH_NONE, NULL);
+         
+      if (_showBorder)
+      {
+         XtVaSetValues (_buttons[_XsMotifButton::Maximize]->base ( ), XmNtopAttachment,
+            XmATTACH_WIDGET, XmNtopWidget, _sides[_XsMotifSide::Top]->base ( ),
+            XmNrightAttachment, XmATTACH_WIDGET, XmNrightWidget, _sides[_XsMotifSide::Right]->base ( ),
+            NULL);
+      }
+      else
+      {
+         XtVaSetValues (_buttons[_XsMotifButton::Maximize]->base ( ), XmNtopAttachment,
+            XmATTACH_FORM, XmNrightAttachment, XmATTACH_FORM, NULL);
+      }
+   }
+      
+// Minimize button
+
+   if (_showMinimize)
+   {
+      _buttons[_XsMotifButton::Minimize] = new _XsMotifButton ("minimize", this, _XsMotifButton::Minimize);
+
+      XtVaSetValues (_buttons[_XsMotifButton::Minimize]->base ( ),
+         XmNbottomAttachment, XmATTACH_NONE, XmNleftAttachment, XmATTACH_NONE,
+         NULL);
+         
+      if (_showBorder)
+      {
+         XtVaSetValues (_buttons[_XsMotifButton::Minimize]->base ( ), XmNtopAttachment,
+            XmATTACH_WIDGET, XmNtopWidget, _sides[_XsMotifSide::Top]->base ( ),
+            XmNrightAttachment, XmATTACH_WIDGET, XmNrightWidget,
+            _sides[_XsMotifSide::Right]->base ( ), NULL);
+      }
+      else
+      {
+         XtVaSetValues (_buttons[_XsMotifButton::Minimize]->base ( ),
+            XmNtopAttachment, XmATTACH_FORM, XmNrightAttachment, XmATTACH_FORM,
+            NULL);
+      }
+
+      if (_showMaximize)
+      {
+         XtVaSetValues (_buttons[_XsMotifButton::Minimize]->base ( ),
+            XmNrightAttachment, XmATTACH_WIDGET, XmNrightWidget,
+            _buttons[_XsMotifButton::Maximize]->base ( ), NULL);
+      }
+   }
+      
+/*
+   Titlebar
+*/
+
+   if (_showTitle)
+   {
+      _title = new _XsMotifTitle ("title", this);
+
+      XtVaSetValues (_title->base ( ), XmNbottomAttachment, XmATTACH_NONE,
+         NULL);
+
+      if (_showBorder)
+      {
+         XtVaSetValues (_title->base ( ), XmNtopAttachment, XmATTACH_WIDGET,
+            XmNtopWidget, _sides[_XsMotifSide::Top]->base ( ),
+            XmNleftAttachment, XmATTACH_WIDGET, XmNleftWidget,
+            _sides[_XsMotifSide::Left]->base ( ), XmNrightAttachment,
+            XmATTACH_WIDGET, XmNrightWidget, _sides[_XsMotifSide::Right]->base ( ),
+            NULL);
+      }
+      else
+      {
+         XtVaSetValues (_title->base ( ), XmNtopAttachment, XmATTACH_FORM,
+            XmNleftAttachment, XmATTACH_FORM, XmNrightAttachment, XmATTACH_FORM,
+            NULL);
+      }      
+
+      if (_showMenu)
+      {
+         XtVaSetValues (_title->base ( ), XmNleftAttachment, XmATTACH_WIDGET,
+            XmNleftWidget, _buttons[_XsMotifButton::Menu]->base ( ), NULL);
+      }
+
+      Widget ba = (_buttons[_XsMotifButton::Minimize] != 0) ?
+         _buttons[_XsMotifButton::Minimize]->base ( ) :
+         (_buttons[_XsMotifButton::Maximize] != 0) ?
+         _buttons[_XsMotifButton::Maximize]->base ( ) : 0;
+         
+      if (ba)
+      {
+         XtVaSetValues (_title->base ( ), XmNrightAttachment, XmATTACH_WIDGET,
+            XmNrightWidget, ba, NULL);
+      }
+   }
+      
+/*
+   Icon
+*/
+
+   _icon = new _XsMotifIcon ("icon", this, parent);
+
+/*
+   Menu
+*/
+
+   _menu = new _XsMotifMenu ("menu", this);
+   
+/*
+   Client Area
+*/
+
+   _clientArea = XtVaCreateWidget ("clientArea", xmFormWidgetClass, _base, NULL);
+
+   if (_showBorder)
+   {
+      XtVaSetValues (_clientArea, XmNleftAttachment, XmATTACH_WIDGET,
+         XmNleftWidget, _sides[_XsMotifSide::Left]->base ( ), XmNrightAttachment,
+         XmATTACH_WIDGET, XmNrightWidget, _sides[_XsMotifSide::Right]->base ( ),
+         XmNbottomAttachment, XmATTACH_WIDGET, XmNbottomWidget,
+         _sides[_XsMotifSide::Bottom]->base ( ), NULL);
+   }
+   else
+   {
+      XtVaSetValues (_clientArea, XmNleftAttachment, XmATTACH_FORM,
+         XmNrightAttachment, XmATTACH_FORM, XmNbottomAttachment, XmATTACH_FORM,
+         NULL);
+   }
+   
+   Widget topW = (_showTitle) ? _title->base ( ) :
+                 (_showBorder) ? _sides[_XsMotifSide::Top]->base ( ) : 0;
+                 
+   if (topW)
+   {
+      XtVaSetValues (_clientArea, XmNtopAttachment, XmATTACH_WIDGET,
+         XmNtopWidget, topW, NULL);
+   }
+   else
+      XtVaSetValues (_clientArea, XmNtopAttachment, XmATTACH_FORM, NULL);
+
+// Call the class function to create the contents of the window
+
+   _buildClientArea (_clientArea);
+   
+// Add an event handler to be called when this window is mapped
+
+   XtAddEventHandler (_base, StructureNotifyMask, False, _mapEventHandler, (XtPointer)this);
+
+// Show everything
+
+   int   loop;
+
+   for (loop = 0; loop < _XsMotifSide::Max; loop++)
+   {
+      if (_corners[loop] != 0)
+         _corners[loop]->show ( );
+      if (_sides[loop] != 0)
+         _sides[loop]->show ( );
+   }
+
+   for (loop = 0; loop < _XsMotifButton::Max; loop++)
+   {
+      if (_buttons[loop] != 0)
+         _buttons[loop]->show ( );
+   }
+
+   if (_title != 0)
+      _title->show ( );
+}
+   
+// _mapEvent
+
+void XsMotifWindow::_mapEvent ( )
+{
+      
+// Raise the client-area
+
+   XRaiseWindow (XtDisplay (_clientArea), XtWindow (_clientArea));
+}
+
+// _mapEventHandler
+
+void XsMotifWindow::_mapEventHandler (Widget, XtPointer clientData, XEvent *event, Boolean*)
+{
+   if (event->type == MapNotify)
+   {
+      XsMotifWindow *obj = (XsMotifWindow*)clientData;
+      obj->_mapEvent ( );
+      XtRemoveEventHandler (obj->_base, StructureNotifyMask, False, obj->_mapEventHandler, clientData);
+   }
+}
diff --git a/src/motif/mdi/lib/XsMotifWindow.h b/src/motif/mdi/lib/XsMotifWindow.h
new file mode 100644 (file)
index 0000000..203e13d
--- /dev/null
@@ -0,0 +1,665 @@
+/*
+   Copyright (C) 1996 Scott W. Sadler
+   All rights reserved.
+*/
+
+/*
+   XsMotifWindow.h
+
+   History
+      03-Mar-96 1.0; Scott W. Sadler (sws@iti-oh.com)
+                     Created         
+*/
+
+#ifndef XSMOTIFWINDOW_H
+#define XSMOTIFWINDOW_H
+
+// Includes
+
+#include <Xm/Xm.h>
+#include "XsMDIWindow.h"
+
+// Forward declarations
+
+class XsMotifWindow;
+
+/*
+   ----------------------------------------------------------------------------
+   _XsMotifBase class
+*/
+
+class _XsMotifBase : public XsComponent {
+
+   public:
+   
+// Destructor
+
+      virtual ~_XsMotifBase ( );
+
+// Window actions
+
+      virtual void show ( );
+      
+// Class name
+
+      virtual const char *className ( ) const;
+      
+   protected:
+   
+// Protected constructor
+
+      _XsMotifBase (const char *name, XsMotifWindow *win);
+
+// Component life-cycle
+
+      virtual void _componentDestroyed ( );
+
+// Utilities
+
+      void _drawShadows (Position x, Position y, Dimension width,
+         Dimension height, Dimension thick, Boolean reverse = False);
+
+      void _drawLine (Position x1, Position y1, Position x2, Position y2, GC &gc);
+
+// Implementation
+
+      XsMotifWindow  *_win;
+
+      GC    _topShadowGC;
+      GC    _bottomShadowGC;
+
+// Event handlers
+
+      virtual void _map ( );
+
+// Internal Event handlers      
+
+      static void _mapEventHandler (Widget, XtPointer, XEvent*, Boolean*);
+};      
+
+/*
+   ----------------------------------------------------------------------------
+   _XsMotifComponent class
+*/
+
+class _XsMotifComponent : public _XsMotifBase {
+
+   public:
+
+// Destructor
+
+      virtual ~_XsMotifComponent ( );
+   
+// Enumerations
+
+      enum Cursors {
+         TopCursor = 0, BottomCursor, LeftCursor, RightCursor,
+         TopLeftCursor, TopRightCursor, BottomLeftCursor,
+         BottomRightCursor, NumCursors };
+
+// Class name
+
+      virtual const char *className ( ) const;
+      
+   protected:
+   
+// Protected constructor
+
+      _XsMotifComponent (const char *name, XsMotifWindow *win, Widget parent = 0);
+
+// Cursors
+
+      static Cursor  _cursors[NumCursors];
+      
+// Component parameters
+
+      Dimension   _borderSize;
+      Dimension   _buttonSize;
+      Dimension   _cornerSize;
+      
+// Event handlers
+
+      virtual void _expose (XEvent*) = 0;
+      virtual void _input (XEvent*);
+      
+   private:
+   
+// Internal Event handlers      
+
+      static void _exposeEventHandler (Widget, XtPointer, XEvent*, Boolean*);
+      static void _inputEventHandler (Widget, XtPointer, XEvent*, Boolean*);
+
+// Resources
+
+      static XtResource _resourceList[];
+      
+      static int  _mutex;
+};
+
+/*
+   ----------------------------------------------------------------------------
+   _XsMotifCorner class
+*/
+
+class _XsMotifCorner : public _XsMotifComponent {
+
+   public:
+   
+// Enumerations
+
+      enum Corner { TopLeft = 0, TopRight, BottomLeft, BottomRight, Max };
+      
+// Constructor/Destructor
+
+      _XsMotifCorner (const char *name, XsMotifWindow *win, Corner corner);
+      virtual ~_XsMotifCorner ( );
+
+// Class name
+
+      virtual const char *className ( ) const;
+      
+   protected:
+   
+// Implementation
+
+      Corner      _corner;
+      
+// Event handlers
+
+      virtual void _expose (XEvent*);
+      virtual void _input (XEvent*);
+      virtual void _map ( );
+};
+
+/*
+   ----------------------------------------------------------------------------
+   _XsMotifSide class
+*/
+
+class _XsMotifSide : public _XsMotifComponent {
+
+   public:
+   
+// Enumerations
+
+      enum Side { Top = 0, Bottom, Left, Right, Max };
+
+// Constructor/Destructor
+
+      _XsMotifSide (const char *name, XsMotifWindow *win, Side side);
+      virtual ~_XsMotifSide ( );
+      
+// Class name
+
+      virtual const char *className ( ) const;
+      
+   protected:
+   
+// Implementation
+
+      Side     _side;
+      
+      int         _lastW;
+      int         _lastH;
+
+// Event handlers
+
+      virtual void _expose (XEvent*);
+      virtual void _input (XEvent*);
+      virtual void _map ( );
+      virtual void _configure (XEvent *);
+      
+   private:
+   
+// Callbacks
+
+      static void _configureEventHandler (Widget, XtPointer, XEvent*, Boolean*);
+};
+
+/*
+   ----------------------------------------------------------------------------
+   _XsMotifButton class
+*/
+
+class _XsMotifButton : public _XsMotifComponent {
+
+   public:
+   
+// Enumerations
+
+      enum Button { Menu = 0, Minimize, Maximize, Max };
+
+// Constructor/Destructor
+
+      _XsMotifButton (const char *name, XsMotifWindow *win, Button button);
+      virtual ~_XsMotifButton ( );
+      
+// Utilities
+
+      virtual void redraw ( );
+
+// Class name
+
+      virtual const char *className ( ) const;
+      
+   protected:
+   
+// Implementation
+
+      Boolean     _pressed;
+      Button      _button;
+      
+// Event handlers
+
+      virtual void _expose (XEvent*);
+      virtual void _input (XEvent*);
+      virtual void _map ( );
+};
+
+/*
+   ----------------------------------------------------------------------------
+   _XsMotifTitle class
+*/
+
+class _XsMotifTitle : public _XsMotifComponent {
+
+   public:
+   
+// Constructor/Destructor
+
+      _XsMotifTitle (const char *name, XsMotifWindow *win);
+      virtual ~_XsMotifTitle ( );
+      
+// Title string
+
+      void  setTitle (const char *name);
+      const char *title ( ) const;
+      
+// Class name
+
+      virtual const char *className ( ) const;
+      
+   protected:
+   
+// Implementation
+
+      Boolean     _pressed;
+      String      _titleString;
+      GC          _fontGC;
+      
+      XFontStruct   *_titleFont;
+
+      int         _lastW;
+      int         _lastH;
+      
+// Component life-cycle
+
+      virtual void _componentDestroyed ( );
+
+// Utilities
+
+      virtual void _redraw ( );
+      
+// Event handlers
+
+      virtual void _expose (XEvent*);
+      virtual void _input (XEvent*);
+      virtual void _map ( );
+      virtual void _configure (XEvent*);
+      
+   private:
+   
+// Callbacks
+
+      static void _configureEventHandler (Widget, XtPointer, XEvent*, Boolean*);
+      
+// Resources
+
+      static XtResource _resourceList[];
+};
+
+// Inline member functions
+
+inline const char *_XsMotifTitle::title ( ) const
+{
+   return (_titleString);
+}
+
+/*
+   ----------------------------------------------------------------------------
+   _XsMotifIcon class
+*/
+
+class _XsMotifIcon : public _XsMotifComponent {
+
+   public:
+   
+// Constructor/Destructor
+
+      _XsMotifIcon (const char *name, XsMotifWindow *win, Widget parent);
+      virtual ~_XsMotifIcon ( );
+      
+// Window operations
+
+      virtual void show ( );
+      
+// Icon name/pixmap
+
+      void  setIconName (const char *name);
+      const char *iconName ( ) const;
+      
+      void  setPixmap (Pixmap pm);
+      Pixmap pixmap ( ) const;
+      
+// Class name
+
+      virtual const char *className ( ) const;
+      
+   protected:
+   
+// Implementation
+
+      GC    _fontGC;
+      GC    _pixmapGC;
+      
+      Dimension      _iconSize;
+      String         _iconName;
+      XFontStruct   *_iconFont;
+      Pixmap         _pixmap;
+      Boolean        _freePixmap;
+      
+      Dimension      _width, _height;
+      Position       _iconX, _iconY;
+      Boolean        _placed;
+      
+// Component life-cycle
+
+      virtual void _componentDestroyed ( );
+
+// Event handlers
+
+      virtual void _expose (XEvent*);
+      virtual void _input (XEvent*);
+      virtual void _map ( );
+      
+   private:
+   
+// Resources
+
+      static XtResource _resourceList[];
+};
+
+// Inline member-functions
+
+inline const char *_XsMotifIcon::iconName ( ) const
+{
+   return (_iconName);
+}
+
+inline Pixmap _XsMotifIcon::pixmap ( ) const
+{
+   return (_pixmap);
+}
+
+/*
+   ----------------------------------------------------------------------------
+   _XsMotifMenu class
+*/
+
+class _XsMotifMenu : public _XsMotifBase {
+
+   public:
+   
+// Constructor/Destructor
+
+      _XsMotifMenu (const char *name, XsMotifWindow *win);
+      virtual ~_XsMotifMenu ( );
+      
+// Utilities
+
+      virtual void popup (Boolean atPointer = True);
+      
+// Enumerations
+
+      enum Item {
+         NoItem = -1, Restore, Move, Size, Minimize,
+         Maximize, Raise, Lower, Close, Num
+      };
+      
+// Class name
+
+      virtual const char *className ( ) const;
+
+   protected:
+
+// Dimensions
+
+      enum { ShadowThickness = 1 };
+      enum { VertTextOffset = 3 };
+      enum { HorizTextOffset = 10 };
+            
+// Implementation
+
+      static Cursor  _cursor;
+      static Pixmap  _stipple;
+      static Display *_dpy;
+
+      Boolean        _saveUnder;
+      
+      String         _strings[Num];
+      XFontStruct   *_menuFont;
+
+      GC             _fontGC;
+      GC             _grayGC;
+      GC             _backgroundGC;
+
+      Item           _curItem;
+      
+// Component life-cycle
+
+      virtual void _componentDestroyed ( );
+
+// Menu event processing
+
+      virtual void _processEvents ( );
+      
+// Utilities
+
+      virtual void _processItem (Item item);
+      virtual void _redrawMenu ( );
+
+      void _redrawItem (Item);
+      void _toggleItem (Item, Boolean active = False);
+      Item _trackPointer (XMotionEvent *event);
+      
+// Pointer grabs
+
+      Boolean  _grabPointer ( );
+      void     _ungrabPointer ( );
+      
+// Event handlers
+
+      virtual void _map ( );
+
+   private:
+   
+// Work procedure
+
+      static Boolean _workProc (XtPointer);
+      
+// Resources
+
+      static XtResource _resourceList[];
+      static int  _count;
+};
+
+
+/*
+   ----------------------------------------------------------------------------
+   XsMotifWindow class
+*/
+
+class XsMotifWindow : public XsMDIWindow {
+
+   public:
+
+// Constructor/Destructor
+
+      XsMotifWindow (const char *name);
+      virtual ~XsMotifWindow ( );
+   
+// Window manipulation
+
+      virtual void raise ( );
+      virtual void lower ( );
+
+      virtual void minimize ( );
+      virtual void maximize ( );
+      virtual void restore ( );
+
+      virtual void close ( );
+      
+// Window and icon strings
+
+      void  setTitle (const char *name);
+      const char *title ( ) const;
+      
+      void  setIconName (const char *name);
+      const char *iconName ( ) const;
+      
+      void  setPixmap (Pixmap pm);
+      Pixmap pixmap ( ) const;
+      
+// Window icon handle
+
+      Widget   icon ( ) const;
+      
+// Menu settings
+
+      void  popupMenu (Boolean atPointer = True);
+      
+// Utilities
+
+      Boolean  maximized ( ) const;
+      Boolean  minimized ( ) const;
+      
+// Position and size
+
+      virtual void setPosition (Position, Position);
+      virtual void setSize (Dimension, Dimension);
+
+      Dimension minWidth ( ) const;
+      Dimension minHeight ( ) const;
+      
+// Class name
+
+      virtual const char *className ( ) const;
+
+   protected:
+
+// Window creation functions
+
+      virtual void _buildClientArea (Widget parent) = 0;
+      virtual void _createWindow (Widget parent);
+
+// Window components
+
+      _XsMotifCorner   *_corners[_XsMotifCorner::Max];
+      _XsMotifSide     *_sides[_XsMotifSide::Max];
+      _XsMotifButton   *_buttons[_XsMotifButton::Max];
+      _XsMotifTitle    *_title;            
+      _XsMotifIcon     *_icon;
+      _XsMotifMenu     *_menu;
+      
+// Window dimensions
+
+      Dimension   _savedWidth, _savedHeight;
+      Position    _savedX, _savedY;
+      Dimension   _minW, _maxW;
+      Dimension   _minH, _maxH;
+      
+// Window parameters
+
+      Boolean     _showBorder;
+      Boolean     _showResize;
+      Boolean     _showTitle;
+      Boolean     _showMenu;
+      Boolean     _showMinimize;
+      Boolean     _showMaximize;
+      Boolean     _lowerOnIconify;
+      
+// Window state
+
+      Boolean     _maximized;
+      Boolean     _minimized;
+      
+// Callbacks
+
+      virtual void _mapEvent ( );
+      
+   private:
+   
+// Internal event handlers
+
+      static void _mapEventHandler (Widget, XtPointer, XEvent*, Boolean*);
+
+// Resources
+
+      static XtResource _resourceList[];
+};
+
+// Inline member functions
+
+inline Boolean XsMotifWindow::maximized ( ) const
+{
+   return (_maximized);
+}
+
+inline Boolean XsMotifWindow::minimized ( ) const
+{
+   return (_minimized);
+}
+
+inline const char *XsMotifWindow::title ( ) const
+{
+   if (_title != 0)
+      return (_title->title ( ));
+   else
+      return (0);
+}
+      
+inline const char *XsMotifWindow::iconName ( ) const
+{
+   if (_icon != 0)
+      return (_icon->iconName ( ));
+   else
+      return (0);
+}
+      
+inline Pixmap XsMotifWindow::pixmap ( ) const
+{
+   if (_icon != 0)
+      return (_icon->pixmap ( ));
+   else
+      return (None);
+}
+      
+inline Widget XsMotifWindow::icon ( ) const
+{
+   if (_icon != 0)
+      return (_icon->base ( ));
+   else
+      return (0);
+}
+      
+inline Dimension XsMotifWindow::minWidth ( ) const
+{
+   return (_minW);
+}
+   
+inline Dimension XsMotifWindow::minHeight ( ) const
+{
+   return (_minH);
+}
+   
+#endif
diff --git a/src/motif/mdi/lib/XsMoveOutline.C b/src/motif/mdi/lib/XsMoveOutline.C
new file mode 100644 (file)
index 0000000..f00118f
--- /dev/null
@@ -0,0 +1,82 @@
+/*
+   Copyright (C) 1996 Scott W. Sadler
+   All rights reserved.
+*/
+
+/*
+   XsMoveOutline.C
+
+   History
+      03-Mar-96 1.0; Scott W. Sadler (sws@iti-oh.com)
+                     Created         
+*/
+
+// Includes
+
+#include <assert.h>
+#include "XsMoveOutline.h"
+#include <X11/cursorfont.h>
+
+// Static definitions
+
+Cursor XsMoveOutline::_fleur = None;
+
+// Constructor
+
+XsMoveOutline::XsMoveOutline (Widget w) : XsOutline (w)
+{
+   unsigned int mask;      // Not used
+   Window   root;
+   int      xy;
+   
+// Create the cursor (if necessary)
+
+   if (_fleur == None)
+      _fleur = XCreateFontCursor (XtDisplay (_w), XC_fleur);
+
+// Get the current mouse root coordinates
+
+   XQueryPointer (XtDisplay (_w), XtWindow (_w), &root, &root, &_rootX,
+      &_rootY, &xy, &xy, &mask);
+}
+
+// Destructor
+
+XsMoveOutline::~XsMoveOutline ( )
+{
+   // Empty
+}
+
+// _motionHandler
+
+void XsMoveOutline::_motionHandler (XEvent *event)
+{
+   int   curX, curY;
+            
+// Get current mouse position
+
+   curX = event->xbutton.x_root;
+   curY = event->xbutton.y_root;
+               
+// Compute the new window position
+
+   _x += (curX - _rootX);
+   _y += (curY - _rootY);
+
+// Move the window
+
+   _drawOutline (False);
+
+// Save the new root position
+
+   _rootX = curX;
+   _rootY = curY;
+}
+
+// _getCursor
+
+Cursor XsMoveOutline::_getCursor ( ) const
+{
+   return (_fleur);
+}
+
diff --git a/src/motif/mdi/lib/XsMoveOutline.h b/src/motif/mdi/lib/XsMoveOutline.h
new file mode 100644 (file)
index 0000000..7e830c6
--- /dev/null
@@ -0,0 +1,52 @@
+/*
+   Copyright (C) 1996 Scott W. Sadler
+   All rights reserved.
+*/
+
+/*
+   XsMoveOutline.h
+
+   History
+      03-Mar-96 1.0; Scott W. Sadler (sws@iti-oh.com)
+                     Created         
+*/
+
+#ifndef XSMOVEOUTLINE_H
+#define XSMOVEOUTLINE_H
+
+// Includes
+
+#include "XsOutline.h"
+
+// XsMoveOutline class
+
+class XsMoveOutline : public XsOutline {
+
+   public:
+      
+// Constructor/Destructor
+
+      XsMoveOutline (Widget w);
+      virtual ~XsMoveOutline ( );
+
+   protected:
+      
+// Motion handler
+
+      virtual  void _motionHandler (XEvent*);
+
+// Moving cursor
+
+      virtual Cursor _getCursor ( ) const;
+
+   private:
+
+// Implementation
+
+      int      _rootX;
+      int      _rootY;
+
+      static   Cursor   _fleur;
+};
+
+#endif
diff --git a/src/motif/mdi/lib/XsOutline.C b/src/motif/mdi/lib/XsOutline.C
new file mode 100644 (file)
index 0000000..6398046
--- /dev/null
@@ -0,0 +1,241 @@
+/*
+   Copyright (C) 1996 Scott W. Sadler
+   All rights reserved.
+*/
+
+/*
+   XsOutline.C
+
+   History
+      03-Mar-96 1.0; Scott W. Sadler (sws@iti-oh.com)
+                     Created         
+*/
+
+// Includes
+
+#include <assert.h>
+#include <X11/StringDefs.h>
+#include "XsOutline.h"
+
+// Constructor
+
+XsOutline::XsOutline (Widget w)
+{
+   assert (w != 0);
+   
+// Initialize
+
+   _w = w;
+   
+// Get window dimensions
+
+   unsigned int moreJunk;
+   unsigned int uw, uh;
+   Window   junk;
+   
+   XGetGeometry (XtDisplay (_w), XtWindow (_w), &junk, &_x, &_y, &uw, &uh, &moreJunk, &moreJunk);
+
+   _width = uw;
+   _height = uh;
+   
+// Get initial settings
+
+   _savedX = _x;
+   _savedY = _y;
+   _savedH = _savedW = 0;
+   
+// Create the graphics context
+
+   XGCValues   values;
+   unsigned long valuemask;
+
+   Display *dpy = XtDisplay (_w);
+   
+   valuemask = GCFunction | GCLineWidth | GCSubwindowMode;
+   values.function = GXinvert;
+   values.line_width = 0;
+   values.subwindow_mode = IncludeInferiors;
+      
+   _gc = XCreateGC (dpy, XtWindow (_w), valuemask, &values);
+}
+
+// Destructor
+
+XsOutline::~XsOutline ( )
+{
+   XFreeGC (XtDisplay (_w), _gc);
+}
+
+// go
+
+Boolean XsOutline::go (Boolean drawInitial)
+{
+   XtAppContext appContext = XtWidgetToApplicationContext (_w);
+   XEvent event;
+   int   done = 0;
+   
+// Grab the pointer
+
+   if (_grabPointer ( ) == False)
+      return (False);      
+   
+// Draw the initial box (if requested)
+
+   if (drawInitial)
+      _drawOutline (False);
+
+// Process the events locally
+
+   while (!done)
+   {
+      XtAppNextEvent (appContext, &event);
+
+      switch (event.type)
+      {
+         case ButtonRelease:
+         {
+
+// Clear the outline and break
+
+            _drawOutline (True);
+            done = 1;
+            break;
+         }
+         case MotionNotify:
+         {
+            XEvent next;
+            
+// Process only the last motion event
+
+            while (XPending (XtDisplay (_w)) > 0)
+            {
+               XPeekEvent (XtDisplay (_w), &next);
+               if (next.type != MotionNotify)
+                  break;
+               XtAppNextEvent (appContext, &event);
+            }
+               
+// Send this event
+
+            _motionHandler (&event);
+            
+            break;
+         }
+         default:
+         {
+            XtDispatchEvent (&event);
+            break;
+         }
+      }
+   }
+
+// Ungrab the pointer
+
+   _ungrabPointer ( );
+   
+   return (True);
+}
+
+// _drawOutline
+
+void XsOutline::_drawOutline (Boolean clear)
+{
+
+// Clear the current outline
+
+   if (_savedH || _savedW)
+      _drawIt (_savedX, _savedY, _savedW, _savedH);
+   
+// Save current values
+
+   _savedX = _x; _savedY = _y;
+   _savedW = _width; _savedH = _height;
+   
+// Draw the new outline (unless flagged to just clear)
+
+   if (!clear)
+      _drawIt (_x, _y, _width, _height);      
+}
+
+// _getCursor
+
+Cursor XsOutline::_getCursor ( ) const
+{
+   return (None);
+}
+   
+// _grabPointer 
+
+Boolean XsOutline::_grabPointer ( )
+{
+   
+// Sync everything up before being grabby
+
+   XSync (XtDisplay (_w), False);   
+
+// Grab the pointer
+
+   if (XGrabPointer (XtDisplay (_w), XtWindow (_w), False, GrabEventMask, 
+      GrabModeAsync, GrabModeAsync, XtWindow (XtParent (_w)), _getCursor ( ), 
+      CurrentTime) != GrabSuccess)
+   {
+      XBell (XtDisplay (_w), 100);
+      return (False);
+   }
+      
+   return (True);
+}
+
+// _ungrabPointer
+
+void XsOutline::_ungrabPointer ( )
+{
+
+// Ungrab the pointer
+
+   XUngrabPointer (XtDisplay (_w), CurrentTime);
+}
+   
+// _drawIt
+
+void XsOutline::_drawIt (int x, int y, int w, int h)
+{
+   const int nsegs = 8;
+   XSegment    segs[nsegs];
+
+// Across the top
+
+   segs[0].x1 = x; segs[0].y1 = y;
+   segs[0].x2 = x + w - 1; segs[0].y2 = y;
+      
+   segs[1].x1 = x + BorderSize; segs[1].y1 = y + BorderSize;
+   segs[1].x2 = x + w - BorderSize - 1; segs[1].y2 = y + BorderSize;
+      
+// Down the left
+
+   segs[2].x1 = x + w - 1; segs[2].y1 = y + 1;
+   segs[2].x2 = x + w - 1; segs[2].y2 = y + h - 1;
+   
+   segs[3].x1 = x + w - BorderSize - 1; segs[3].y1 = y + BorderSize + 1;
+   segs[3].x2 = x + w - BorderSize - 1; segs[3].y2 = y + h - BorderSize - 1;
+   
+// Across the bottom
+
+   segs[4].x1 = x + 1; segs[4].y1 = y + h - 1;
+   segs[4].x2 = x + w - 2; segs[4].y2 = y + h - 1;
+   
+   segs[5].x1 = x + BorderSize + 1; segs[5].y1 = y + h - BorderSize - 1;
+   segs[5].x2 = x + w - BorderSize - 2; segs[5].y2 = y + h - BorderSize - 1;
+   
+// Up the left
+
+   segs[6].x1 = x; segs[6].y1 = y + h - 1;
+   segs[6].x2 = x; segs[6].y2 = y + 1;
+   
+   segs[7].x1 = x + BorderSize; segs[7].y1 = y + h - BorderSize - 1;
+   segs[7].x2 = x + BorderSize; segs[7].y2 = y + BorderSize + 1;
+   
+// Draw the segments
+
+   XDrawSegments (XtDisplay (_w), XtWindow (XtParent (_w)), _gc, segs, nsegs);
+}
diff --git a/src/motif/mdi/lib/XsOutline.h b/src/motif/mdi/lib/XsOutline.h
new file mode 100644 (file)
index 0000000..51ca749
--- /dev/null
@@ -0,0 +1,109 @@
+/*
+   Copyright (C) 1996 Scott W. Sadler
+   All rights reserved.
+*/
+
+/*
+   XsOutline.h
+
+   History
+      03-Mar-96 1.0; Scott W. Sadler (sws@iti-oh.com)
+                     Created         
+*/
+
+#ifndef XSOUTLINE_H
+#define XSOUTLINE_H
+
+// Includes
+
+#include <X11/Intrinsic.h>
+
+// XsOutline class
+
+class XsOutline {
+
+   public:
+
+// Constructor/Destructor
+      
+      XsOutline (Widget w);
+      virtual ~XsOutline ( );
+      
+// Event handler
+
+      Boolean go (Boolean drawInitial = False);
+      
+// Utilities
+
+      int width ( ) const;
+      int height ( ) const;
+      int x ( ) const;
+      int y ( ) const;
+      
+   protected:
+
+// Enumerations
+
+      enum { BorderSize = 6 };
+      enum { GrabEventMask = (unsigned int)(ButtonPressMask | ButtonReleaseMask | PointerMotionMask) };
+
+// Components
+
+      Widget      _w;
+      
+// Graphics context
+
+      GC          _gc;
+
+// Current dimensions
+
+      int         _x, _y;
+      int         _width;
+      int         _height;
+
+// Outline utilities
+
+      virtual  void _motionHandler (XEvent*) = 0;
+      virtual  Cursor _getCursor ( ) const;
+      void     _drawOutline (Boolean);
+      
+   private:
+   
+// Pointer grabs
+
+      Boolean  _grabPointer ( );
+      void     _ungrabPointer ( );
+      
+// Save dimensions
+
+      int   _savedX, _savedY;
+      int   _savedW, _savedH;
+
+// Drawing
+
+      void  _drawIt (int, int, int, int);
+};
+      
+// Inline member functions
+
+inline int XsOutline::width ( ) const
+{
+   return (_width);
+}
+
+inline int XsOutline::height ( ) const
+{
+   return (_height);
+}
+
+inline int XsOutline::x ( ) const
+{
+   return (_x);
+}
+
+inline int XsOutline::y ( ) const
+{
+   return (_y);
+}
+
+#endif
diff --git a/src/motif/mdi/lib/XsResizeOutline.C b/src/motif/mdi/lib/XsResizeOutline.C
new file mode 100644 (file)
index 0000000..42e662c
--- /dev/null
@@ -0,0 +1,231 @@
+/*
+   Copyright (C) 1996 Scott W. Sadler
+   All rights reserved.
+*/
+
+/*
+   XsResizeOutline.C
+
+   History
+      03-Mar-96 1.0; Scott W. Sadler (sws@iti-oh.com)
+                     Created         
+*/
+
+// Includes
+
+#include <assert.h>
+#include <X11/cursorfont.h>
+#include "XsResizeOutline.h"
+
+// Static definitions
+
+Cursor XsResizeOutline::_cursors[XsResizeOutline::NumCursors];
+int XsResizeOutline::_mutex = 0;
+
+// Constructor
+
+XsResizeOutline::XsResizeOutline (Widget w, int direction) : XsOutline (w)
+{
+   
+// Initialize
+
+   _minWidth = 5;
+   _minHeight = 5;
+   _direction = direction;
+   
+// Translate current window location to root coordinates
+
+   Position xpos, ypos;
+   
+   XtTranslateCoords (XtParent (_w), (Position)_x, (Position)_y, &xpos, &ypos);
+
+   _rootX = (int)xpos;
+   _rootY = (int)ypos;
+
+// Save the original window position and size
+
+   _origX = _x;
+   _origY = _y;
+   _origW = _width;
+   _origH = _height;
+
+   _origRootX = _rootX;
+   _origRootY = _rootY;
+
+// Create the cursors (if necessary)
+
+   if (_mutex == 0)
+   {
+      Display *dpy = XtDisplay (_w);
+      
+// Create cursors
+
+      _cursors[TopCursor] = XCreateFontCursor (dpy, XC_top_side);
+      _cursors[BottomCursor] = XCreateFontCursor (dpy, XC_bottom_side);
+      _cursors[LeftCursor] = XCreateFontCursor (dpy, XC_left_side);
+      _cursors[RightCursor] = XCreateFontCursor (dpy, XC_right_side);
+      _cursors[TopLeftCursor] = XCreateFontCursor (dpy, XC_top_left_corner);
+      _cursors[TopRightCursor] = XCreateFontCursor (dpy, XC_top_right_corner);
+      _cursors[BottomLeftCursor] = XCreateFontCursor (dpy, XC_bottom_left_corner);
+      _cursors[BottomRightCursor] = XCreateFontCursor (dpy, XC_bottom_right_corner);
+      _cursors[Fleur] = XCreateFontCursor (dpy, XC_fleur);
+      _mutex = 1;
+   }
+}
+   
+// Destructor
+
+XsResizeOutline::~XsResizeOutline ( )
+{
+   // Empty
+}
+   
+// setMinSize
+
+void XsResizeOutline::setMinSize (int minWidth, int minHeight)
+{
+   assert (minWidth > 0);
+   assert (minHeight > 0);
+   
+   _minWidth = minWidth;
+   _minHeight = minHeight;
+}
+   
+// _motionHandler
+
+void XsResizeOutline::_motionHandler (XEvent *event)
+{
+   int   curX, curY;
+   int   diff;
+   int   x, y, w, h;
+
+// Get current mouse position
+
+   curX = event->xbutton.x_root;
+   curY = event->xbutton.y_root;
+
+   if (_direction & Undetermined)
+   {
+
+/*
+   Just let the mouse roam around until it crosses the outline. 
+   When it does so, lock in the direction, change the cursor, and let
+   it rip.
+*/
+
+      if (((curX <= _origRootX) || (curX >= (_origRootX + _origW)))
+         || ((curY <= _origRootY) || (curY >= (_origRootY + _origH))))
+      {
+
+         const int CornerOffset = 30;
+         
+// Crossed box.  Figure out where and set direction
+
+         _direction = 0;
+         
+         if (curY <= (_origRootY + CornerOffset))
+            _direction |= Up;
+         else if (curY >= (_origRootY + _origH - CornerOffset))
+            _direction |= Down;
+            
+         if (curX <= (_origRootX + CornerOffset))
+            _direction |= Left;
+         else if (curX >= (_origRootX + _origW - CornerOffset))
+            _direction |= Right;
+
+// Get the new cursor
+
+         XChangeActivePointerGrab (XtDisplay (_w), GrabEventMask,
+            _getCursor ( ), CurrentTime);
+      }
+      else
+         return;
+   }
+            
+// Get the current values
+
+   x = _x; y = _y; w = _width; h = _height;
+   
+// Process the motion
+
+   if (_direction & Up)
+   {
+      if (curY < (_origRootY + _origH - 1 - _minHeight))
+      {
+         diff = _rootY - curY;
+         _rootY = curY;
+         _y -= diff;
+         _height = _origRootY + _origH - curY;
+      }
+      else
+      {
+         _rootY = _origRootY + _origH - 1 - _minHeight;
+         _y = _origY + _origH - 1 - _minHeight;
+         _height = _minHeight;
+      }         
+   }
+   else if (_direction & Down)
+   {
+      if (curY > (_origRootY + _minHeight))
+         _height = curY - _origRootY - 1;
+      else
+         _height = _minHeight;
+   }
+
+   if (_direction & Left)
+   {
+      if (curX < (_origRootX + _origW - 1 - _minWidth))
+      {
+         diff = _rootX - curX;
+         _rootX = curX;
+         _x -= diff;      
+         _width = _origRootX + _origW - curX;         
+      }
+      else
+      {
+         _rootX = _origRootX + _origW - 1 - _minWidth;
+         _x = _origX + _origW - 1 - _minWidth;
+         _width = _minWidth;
+      }         
+   }
+   else if (_direction & Right)
+   {
+      if (curX > (_origRootX + _minWidth))
+         _width = curX - _origRootX - 1;
+      else
+         _width = _minWidth;
+   }
+
+// Check if the values have "really" changed
+
+   if ((w != _width) || (h != _height) || (x != _x) || (y != _y))
+      _drawOutline (False);
+}
+
+// _getCursor
+
+Cursor XsResizeOutline::_getCursor ( ) const
+{
+   if (_direction == Up)
+      return (_cursors[TopCursor]);
+   if (_direction == Down)
+      return (_cursors[BottomCursor]);
+   if (_direction == Left)
+      return (_cursors[LeftCursor]);
+   if (_direction == Right)
+      return (_cursors[RightCursor]);
+   if (_direction == (Up | Left))
+      return (_cursors[TopLeftCursor]);
+   if (_direction == (Up | Right))
+      return (_cursors[TopRightCursor]);
+   if (_direction == (Down | Left))
+      return (_cursors[BottomLeftCursor]);
+   if (_direction == (Down | Right))
+      return (_cursors[BottomRightCursor]);
+   if (_direction == Undetermined)
+      return (_cursors[Fleur]);
+      
+   assert (0);
+   return (None);
+}
+
diff --git a/src/motif/mdi/lib/XsResizeOutline.h b/src/motif/mdi/lib/XsResizeOutline.h
new file mode 100644 (file)
index 0000000..d32f205
--- /dev/null
@@ -0,0 +1,70 @@
+/*
+   Copyright (C) 1996 Scott W. Sadler
+   All rights reserved.
+*/
+
+/*
+   XsResizeOutline.h
+
+   History
+      03-Mar-96 1.0; Scott W. Sadler (sws@iti-oh.com)
+                     Created         
+*/
+
+#ifndef XSRESIZEOUTLINE_H
+#define XSRESIZEOUTLINE_H
+
+// Includes
+
+#include "XsOutline.h"
+
+class XsResizeOutline : public XsOutline {
+
+   public:
+   
+// Enumerations
+
+   enum { Up = 0x0001, Right = 0x0002, Down = 0x0004, Left = 0x0008,
+      Undetermined = 0x0010 };
+   
+   enum Cursors {
+      TopCursor = 0, BottomCursor, LeftCursor, RightCursor, TopLeftCursor,
+      TopRightCursor, BottomLeftCursor, BottomRightCursor, Fleur,
+      NumCursors };
+
+// Constructor/Destructor
+
+      XsResizeOutline (Widget w, int direction);
+      virtual ~XsResizeOutline ( );
+      
+      void  setMinSize (int minWidth, int minHeight);
+
+   protected:
+      
+// Motion handler
+
+      virtual  void _motionHandler (XEvent*);
+
+// Resize cursor
+
+      virtual Cursor _getCursor ( ) const;
+
+   private:
+   
+// Implementation
+
+      int   _rootX, _rootY;               // Root coordinates
+      int   _origRootX, _origRootY;
+      
+      int   _origX, _origY;               // Window coordinates
+      int   _origW, _origH;
+
+      int   _minWidth, _minHeight;
+
+      int   _direction;
+
+      static Cursor  _cursors[NumCursors];
+      static int  _mutex;
+};
+
+#endif
diff --git a/src/motif/mdi/lib/xs_motif_icon.xbm b/src/motif/mdi/lib/xs_motif_icon.xbm
new file mode 100644 (file)
index 0000000..5541657
--- /dev/null
@@ -0,0 +1,27 @@
+/*
+   Copyright (C) 1996 Scott W. Sadler
+   All rights reserved.
+*/
+
+/*
+   xs_motif_icon.xbm
+
+   History
+      03-Mar-96 1.0; Scott W. Sadler (sws@iti-oh.com)
+                     Created         
+*/
+
+#define xs_motif_icon_width 32
+#define xs_motif_icon_height 32
+static char xs_motif_icon_bits[] = {
+   0xff, 0x00, 0x00, 0xc0, 0xfe, 0x01, 0x00, 0xc0, 0xfc, 0x03, 0x00, 0x60,
+   0xf8, 0x07, 0x00, 0x30, 0xf8, 0x07, 0x00, 0x18, 0xf0, 0x0f, 0x00, 0x0c,
+   0xe0, 0x1f, 0x00, 0x06, 0xc0, 0x3f, 0x00, 0x06, 0xc0, 0x3f, 0x00, 0x03,
+   0x80, 0x7f, 0x80, 0x01, 0x00, 0xff, 0xc0, 0x00, 0x00, 0xfe, 0x61, 0x00,
+   0x00, 0xfe, 0x31, 0x00, 0x00, 0xfc, 0x33, 0x00, 0x00, 0xf8, 0x1b, 0x00,
+   0x00, 0xf0, 0x0d, 0x00, 0x00, 0xf0, 0x0e, 0x00, 0x00, 0x60, 0x1f, 0x00,
+   0x00, 0xb0, 0x3f, 0x00, 0x00, 0x98, 0x7f, 0x00, 0x00, 0x98, 0x7f, 0x00,
+   0x00, 0x0c, 0xff, 0x00, 0x00, 0x06, 0xfe, 0x01, 0x00, 0x03, 0xfc, 0x03,
+   0x80, 0x01, 0xfc, 0x03, 0xc0, 0x00, 0xf8, 0x07, 0xc0, 0x00, 0xf0, 0x0f,
+   0x60, 0x00, 0xe0, 0x1f, 0x30, 0x00, 0xe0, 0x1f, 0x18, 0x00, 0xc0, 0x3f,
+   0x0c, 0x00, 0x80, 0x7f, 0x06, 0x00, 0x00, 0xff};
diff --git a/src/motif/mdi/test/Imakefile b/src/motif/mdi/test/Imakefile
new file mode 100644 (file)
index 0000000..a9af9f4
--- /dev/null
@@ -0,0 +1,25 @@
+#include "../config/MDI.tmpl"
+
+SRCS =      MDItest.C
+
+OBJS =      MDItest.o
+
+STD_INCLUDES = -I/usr/include
+
+INCLUDES =  -I../lib
+
+DEPLIBS =   ../lib/libXsw.a
+
+#if defined(SunArchitecture)
+   SYSLIBS = -lgen
+#endif
+
+LOCAL_LIBRARIES = ../lib/libXsw.a
+SYSTEM_LIBRARIES = -lXm -lXt -lX11 $(SYSLIBS)
+
+PROGRAM =   MDItest
+
+AllTarget($(PROGRAM))
+NormalProgramTarget($(PROGRAM),$(OBJS),$(DEPLIBS),$(LOCAL_LIBRARIES),$(SYSTEM_LIBRARIES))
+DependTarget()
+CxxRules()
diff --git a/src/motif/mdi/test/MDItest.C b/src/motif/mdi/test/MDItest.C
new file mode 100644 (file)
index 0000000..e615970
--- /dev/null
@@ -0,0 +1,391 @@
+/*
+   Copyright (C) 1996 Scott W. Sadler
+   All rights reserved.
+*/
+
+/*
+   MDItest.c
+
+   History
+      03-Mar-96 1.0; Scott W. Sadler (sws@iti-oh.com)
+                     Created         
+*/
+
+// Includes
+
+#include <assert.h>
+#include <Xm/MainW.h>
+#include <Xm/RowColumn.h>
+#include <Xm/CascadeBG.h>
+#include <Xm/Text.h>
+#include <Xm/PushBG.h>
+#include <Xm/AtomMgr.h>
+#include <Xm/Protocols.h>
+#include "XsMDICanvas.h"
+#include "XsMotifWindow.h"
+
+// Fallback resources
+
+static char *fallbacks[] = {
+   "*MDItest.height:                500",
+   "*MDItest.width:                 500",
+   "*MDIinner.width:                300",
+   "*MDIinner.height:               300",
+
+   "*fileMenu.labelString:          File",
+   "*fileMenu.mnemonic:             F",
+   "*openMenuItem.labelString:      Open...",
+   "*openMenuItem.mnemonic:         O",
+   "*newMenuItem.labelString:       New...",
+   "*newMenuItem.mnemonic:          N",
+   "*editMenu.labelString:          Edit",
+   "*editMenu.mnemonic:             E",
+   "*cutMenuItem.labelString:       Cut",
+   "*cutMenuItem.mnemonic:          t",
+   "*copyMenuItem.labelString:      Copy",
+   "*copyMenuItem.mnemonic:         C",
+   "*pasteMenuItem.labelString:     Paste",
+   "*pasteMenuItem.mnemonic:        P",
+   "*helpMenu.labelString:          Help",
+   "*helpMenu.mnemonic:             H",
+   "*aboutMenuItem.labelString:     About",
+   "*aboutMenuItem.mnemonic:        A",
+   "*scrolledText.rows:             10",
+   "*scrolledText.columns:          30",
+
+   "*background:              grey",
+   "*fontList:                -*-helvetica-medium-r-normal-*-14-*-*-*-*-*-iso8859-1",
+
+   NULL
+};
+      
+/*
+   ----------------------------------------------------------------------------
+   MyDocument class
+*/
+
+class MyDocument : public XsMotifWindow {
+
+   public:
+
+// Constructor/Destructor
+
+      MyDocument (const char *name, XsMDICanvas *canvas);
+      virtual ~MyDocument ( );
+      
+   protected:
+
+// This member function is called to create the document contents
+
+      virtual void _buildClientArea (Widget);
+
+// Implementation
+
+      XsMDICanvas   *_canvas;
+
+// Callbacks
+
+      void  _newWindow ( );
+      void  _doNothing ( );
+      
+   private:
+   
+// Callbacks
+
+      static void _newWindowCallback (Widget, XtPointer, XtPointer);
+      static void _doNothingCallback (Widget, XtPointer, XtPointer);
+};
+      
+// Constructor
+
+MyDocument::MyDocument (const char *name, XsMDICanvas *canvas) :
+   XsMotifWindow (name)
+{
+   assert (canvas != 0);
+
+// Initialize
+
+   _canvas = canvas;
+}
+
+// Destructor
+
+MyDocument::~MyDocument ( )
+{
+   // Empty
+}
+
+// _buildClientArea (called to create document contents)
+
+void MyDocument::_buildClientArea (Widget parent)
+{
+   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);
+}
+
+// _newWindow
+
+void MyDocument::_newWindow ( )
+{
+   
+// Create a new document (this will leak, but who cares?)
+
+   MyDocument *newDoc = new MyDocument ("Document", _canvas);
+
+// Add it to the canvas
+
+   _canvas->add (newDoc);
+}
+
+// _newWindowCallback
+
+void MyDocument::_newWindowCallback (Widget, XtPointer clientData, XtPointer)
+{
+   MyDocument *obj = (MyDocument*)clientData;
+   obj->_newWindow ( );
+}   
+
+// _doNothingCallback
+
+void MyDocument::_doNothingCallback (Widget w, XtPointer, XtPointer)
+{
+   XBell (XtDisplayOfObject (w), 100);
+}
+   
+/*
+   ----------------------------------------------------------------------------
+   MyDocument2 class
+*/
+
+class MyDocument2 : public XsMotifWindow {
+
+   public:
+
+// Constructor/Destructor
+
+      MyDocument2 (const char *name);
+      virtual ~MyDocument2 ( );
+      
+   protected:
+
+// This member function is called to create the document contents
+
+      virtual void _buildClientArea (Widget);
+
+// Implementation
+
+      XsMDICanvas    *_canvas;
+      MyDocument     *_win1;
+};
+      
+// Constructor
+
+MyDocument2::MyDocument2 (const char *name) : XsMotifWindow (name)
+{
+   _canvas = 0;
+   _win1 = 0;
+}
+
+// Destructor
+
+MyDocument2::~MyDocument2 ( )
+{
+   delete _canvas;
+   delete _win1;
+}
+
+// _buildClientArea
+
+void MyDocument2::_buildClientArea (Widget parent)
+{
+   assert (parent != 0);
+   
+// Create a nested MDI canvas
+
+   _canvas = new XsMDICanvas ("MDIinner", parent);
+      
+// Attach it up
+
+   XtVaSetValues (_canvas->base ( ), XmNtopAttachment, XmATTACH_FORM,
+      XmNbottomAttachment, XmATTACH_FORM, XmNleftAttachment, XmATTACH_FORM,
+      XmNrightAttachment, XmATTACH_FORM, NULL);
+
+// Create a document
+
+   _win1 = new MyDocument ("InnerWin", _canvas);
+
+// Add the document to the canvas
+
+   _canvas->add (_win1);
+
+// Show the canvas
+
+   _canvas->show ( );
+}
+
+/*
+   ----------------------------------------------------------------------------
+   main
+*/
+
+static void _destroyCallback (Widget, XtPointer clientData, XtPointer)
+{
+   Boolean *quit = (Boolean*)clientData;
+   *quit = True;
+}
+   
+int main (int argc, char **argv)
+{
+   XtAppContext   appContext;
+   Widget   topLevel;
+   Boolean  quit = False;
+   
+// Initialize toolkit
+
+   topLevel = XtVaAppInitialize (&appContext, "MDI", NULL, 0, &argc, argv,
+      fallbacks, XmNdeleteResponse, XmDO_NOTHING, NULL);
+      
+   Display *dpy = XtDisplay (topLevel);
+   
+// Add protocols
+
+   Atom WM_DELETE_WINDOW = XmInternAtom (dpy, "WM_DELETE_WINDOW", False);
+
+   XmAddWMProtocolCallback (topLevel, WM_DELETE_WINDOW, _destroyCallback,
+      &quit);
+   
+// Create the MDI canvas
+
+   XsMDICanvas *canvas = new XsMDICanvas ("MDItest", topLevel);
+   
+// Create the MDI documents
+
+   MyDocument *win1 = new MyDocument ("Document", canvas);
+   MyDocument2 *win2 = new MyDocument2 ("Document 2");
+   
+// Add documents to MDI canvas
+
+   canvas->add (win1);
+   canvas->add (win2);
+   
+// Show the canvas
+
+   canvas->show ( );
+
+// Realize everything
+
+   XtRealizeWidget (topLevel);
+   
+// Let 'er rip
+
+   XEvent event;
+
+   while (!quit)
+   {
+      XtAppNextEvent (appContext, &event);
+      XtDispatchEvent (&event);
+   }      
+      
+// Cleanup
+
+   delete win1;
+   delete win2;
+   delete canvas;
+   
+// Close the X connection
+
+   XtDestroyWidget (topLevel);
+   XtCloseDisplay (dpy);
+   XtDestroyApplicationContext (appContext);
+   
+   return (0);
+}
diff --git a/src/motif/xmcombo/combobox.doc b/src/motif/xmcombo/combobox.doc
new file mode 100644 (file)
index 0000000..41ec4ac
--- /dev/null
@@ -0,0 +1,220 @@
+Welcome to the ComboBox widget for Motif 1.1 or 1.2 (maybe even 2.0...)!
+This is now version 1.32.
+THERE ARE A LOT OF NEW RESOURCES AVAILABLE SO PLEASE READ THE
+DOCUMENTATION (in ComboBox_eng.dvi)!!!
+
+If you're in doubt, the primary source of this widget is
+    ftp.informatik.rwth-aachen.de (137.226.112.172)
+    The source is in: /pub/packages/ComboBox/ComboBox.tar.gz
+This is our campus server in Aachen, Germany. From outside Europe
+please also contact:
+    ftp.x.org (198.112.44.100)
+    There you'll find the source in:
+    /contrib/widgets/motif/ComboBox/ComboBox.tar.gz
+There are many local ftp servers that mirror the /contrib directory. Thus
+with a delay of one or two days you'll also find the source on many other
+ftp sites.
+
+PLEASE READ THIS INFORMATION CAREFULLY. IT ALWAYS CONTAINS THE MOST
+RECENT INFORMATION.
+
+Whats new? (changes since the last version are marked with an asterisk)
+  * Some minor changes concerning the drop down list layout have been made in
+    order to correct some minor quirks.
+  * Updated files for VMS users (hellooooo -- where are you?!!)
+  - A real man page for use with troff/groff. It's in ComboBox.groff.
+  - Some applications like GUI development tools or TclMotif were unable to
+    get notice of these special resources because they were implemented
+    through the core's setValues method. Thus they don't appeared in the 
+    resource list because there aren't any instance variables connected to 
+    them. These mirror resources instead belong to child widgets. With 1.23 
+    the resource list (which can be queried by XtGetResourceList()) contains 
+    entries for all mirror resources although the initial value setting is 
+    always zero. But this should'nt matter. You can switch off these entries
+    by setting -DDONT_LOOK_IN_THE_MIRROR when compiling ComboBox.c.
+  - The selection policies XmSINGLE_SELECT and XmBROWSE_SELECT are now
+    supported.
+  - A new resource called XmNstaticList has been added, which switches the combo
+    box into a new mode with the drop down list statically displayed.
+  - Support of XmNautomaticSelection (like the resource known from XmList).
+  - New callbacks XmNunselectionCallback, XmNdefaultActionCallback,
+    XmNmodifyVerifyCallback, XmNmotionVerifyCallback and XmNvalueChangedCallback
+    added (don't know whether I forgot to mention one...).
+  - New convenience function XmComboBoxClearItemSelection() for deselecting
+    any selection in the combo box (if XmNselectionPolicy is XmSINGLE_SELECT).
+  - New demo app called FontSel. It shows how to realize a full blown
+    font selection dialog (even for scalable fonts) using combo boxes.
+  - Some additional casting has been added to the source, so it seems
+    now really to be ANSI compliant.
+  - can be compiled with Motif 1.2. (Tested on Sun & HP yet)
+  - many new resources & a callback that is called whenever the drop down
+    list gets dropped down or hidden.
+  - corrected a few minor typos in the header files (mis-spelled function
+    prototypes) and some minor quirks in the source.
+  - A FULL-BLOWN ENGLISH DOCUMENTATION (dvi file)
+    If you can't process dvi files you can download a post script variant
+    from ftp.informatik.rwth-aachen.de (137.226.112.172) as
+    /pub/packages/ComboBox/ComboBox_eng.ps.gz 
+  - The XmNitems and XmNitemCount resources can now be set at any time (not
+    only when creating the ComboBox widget).
+  - Corrected some minor memory leaks in the source as well as some typos and
+    errors in the documentation.
+  - Drag'n'Drop is now supported with Motif 1.2.
+  - fvwm's handling of FocusOut events supported.
+
+
+Well - if you never heard of ComboBoxes you'll have to figure out
+yourself what these strange widgets really are. The following text
+will only explain how to include it into your own code. (Just as a little
+hint: combo boxes are well known from M$ Windoze. A combo box consists
+of a text input field with an arrow button besides it. When you click
+on the arrow button the combo box pops up a list just below its input
+area. You can now browse in it or pop it down by pressing the arrow button
+again.)
+
+The source code is now in (wide public) use for nearly a year.
+(before this time it was tested for half a year in the Institut fuer
+Geometrie und Praktische Mathematik, where I'm working). So you get a well
+tested piece of widget magic. Please feel free to report any trouble you
+have using the ComboBox widget. But be patient - I'm just a student. In the
+meantime I've received a couple of reports and hopefully the widget now can
+be used on many well known systems as well as with Motif 1.1 and 1.2. I've
+heard of people using the ComboBox widget with Motif 2.0, because they need
+the many features... But there seems to be problems with the subclassing
+mechanism, so the sanity check CheckComboBox() fails. This check is now
+disabled if the source detects a Motif 2.0 release.
+
+BTW - I'm collecting picture postcards...if you have one with a nice picture of 
+the place you're living in, don't hesitate... 8-)
+
+1. To compile you will need at least Motif :-)
+   (or :-( depending on your point of view...)
+   and an *ANSI* c compiler (the code is completely ANSI -
+   no more mess with the old K&R style)!
+   To compile, try something like
+   $ cc -DFUNCPROTO -c ComboBox.c
+   this should do it's work. -DFUNCPROTO is needed because the function
+   prototypes would be K&R style without it. In addition you often need
+   to specify to the compiler that the source is ANSI. (-ansi with gcc)
+
+2. Place a
+   #include "ComboBox.h"
+   at the top of your source file and create the widget just like any
+   other ordinary widget. The class is xmComboBoxWidgetClass. There is
+   no convenience function since it's hardly ever needed with this
+   widget.
+
+   To compile the short demo:
+   $ cc -DFUNCPROTO ComboBoxDemo.c -o ComboBoxDemo ComboBox.o \
+     -lXm -lXt -lX11
+   On some machines you'll need to link additional libs (like network
+   and socket libs).
+   Or use the makefile (first edit it accordingly to your needs):
+   $ make demo
+   Run the demo with:
+   $ ./ComboBoxDemo
+
+   I don't provide a makefile for every system/compiler combination
+   because this widget is intended to be placed seamless into the
+   existing Motif widget set. Thus, compile it and if all is ok, then
+   copy the includes to the Xm directory and the object file to a
+   suitable place in your file system -- but don't even think of
+   /dev/null as a good destination ;-)
+   
+   To compile the FontSel demo:
+   Edit the makefile (if you haven't already done so), then do a:
+   $ make FontSel
+   And run the Font Selector demo:
+   $ ./FontSel
+   
+   If you also have the ButtonFace Library you may want to do a
+   $ make FontSelX
+   instead. This will use my pictural push buttons for okay, cancel and help.
+
+3. The ComboBox consists primarily of a XmManager descendant - the
+   widget you'll get from XtCreateWidget(). This widget contains several
+   more widgets as its childs: a XmTextField and some other widgets.
+   You *must* not modify any resources of the TextField directly - this
+   leads sooner or later to trouble. Instead all the necessary instance
+   variables of the TextField are accessible through the main widget
+   (the one XtCreateWidget() returned).
+   There are many (convenience) functions like the ones for XmTextFields
+   and XmLists to set the TextField's text, add items to the drop down
+   list and and and... please see ComboBox.h for details (you know:
+   the documentation is under work...)
+
+4. There is one special resource called "persistentDropDown". It
+   defaults to "False". Its purpose it not easy to explain since that
+   has to do with the way your window manager is set up. If you're
+   using the explicit focus methode (that is: you move the keyboard
+   focus from application to application by clicking on the top level
+   window) you're lucky - don't ever think of this resource. For all
+   those other people (like me): if the window manager is set up to
+   give the keyboard focus to the top level window the mouse cursor
+   is over you'll notice one annoying "feature". (It's really *not*
+   a bug ;-) ) If you drop down the ComboBox's list (by clicking on
+   the arrow right beside the text field) and move the mouse cursor
+   out of the window the ComboBox resides in the list immediatly
+   disappears. That happens because the ComboBox looses the keyboard
+   focus. You can try to bypass that behavior by setting 
+   "persistentDropDown" to "True" if you like. In the application's
+   resource file a line like
+   *YourApp*ComboBox.persistentDropDown: True
+   should do the job. But remember: whether this will work depends
+   on the window manager you're using. I have testet this with
+   Silicon Graphics' 4dwm (a mwm clone).
+
+5. On some window managers the drop down list gets hidden as soon as
+   the user moves the mouse cursor into the list. If this happens try
+   to set the resource "twmHandlingOn" to "True". You can do this
+   on the command line:
+   ComboBoxDemo -xrm "*.twmHandlingOn: True"
+   This should do it's job with twm as well as fvwm. With olwm you shouldn't
+   need to set one of the special resources.
+
+6. The combo box has been reported to run sucessfully on:
+   Silicon Graphics, Sun, HP, IBM RS6000, PC, even VMS!
+   Linux, of course...!
+   Attention VMS folks! You'll find two files called "motif11.opt" or 
+   "motif12.opt" and "vmsmake.com" in this packages. They are provided by
+   Vincent Li. You'll hopefully know what to do with these two
+   files. They are provided "as is" with no warranty. Please read the file
+   "readme.vms".
+
+42. Known bugs: you will need a german dictionary to understand all the
+    jokes in the source and in the german documentation.
+
+That's it! Enjoy using this ComboBox widget.
+(More than 160 downloads yet within the first 3 weeks -- seems that I've 
+filled in a real gap in Motif. Thanks to all who encouraged me to do
+further work on the ComboBox widget -- especially Chris Marotz!)
+
+You may also want to visit my "Motif Programming Cornor" at
+   file://ftp.igpm.rwth-aachen.de/arc/pub/unix/html/motifcorner.html
+with tips & tricks about Motif.
+
+I really don't understand why the folks at OSF didn't implemented
+something like the M$ Windoze ComboBox in Motif. Maybe they have
+had their moti"f"es... (Rumor has spread it that the mysterious
+Motif 2.0 will have one - whow! after many years, the OSF folk got it!)
+
+P.S.: This software is Free Software. Please refer to the file
+      COPYING, which you should have received together this
+      file and the source code of the combo box widget.
+      However if you find this widget to be usefull, you are encouraged
+      to donate a reasonable amount to a charitable institution --
+      there are enough people out there who need help! Sometimes I got
+      the strong impression that programmers tend to get lost in their
+      own "virtual reality" - sitting in front of their screen, hacking
+      new algorithms and forget about everything around them. So please
+      don't forget about people who need help.
+
+(c) 1993, 1994 Harald Albrecht
+Institut fuer Geometrie und Praktische Mathematik
+Rheinisch-Westfaelische Technische Universitaet Aachen,
+D-52056 Aachen, Germany
+albrecht@igpm.rwth-aachen.de
+
+Bad Aachen -- Die Stadt der Printe. Warum Aachen ein Kurbad ist?
+-- Wieso Kurbad? "Bad" heisst doch nur, dass es hier staendig regnet (wenn
+es eben 'mal nicht schneit...)
diff --git a/src/motif/xmcombo/combobox.man b/src/motif/xmcombo/combobox.man
new file mode 100644 (file)
index 0000000..026f0a3
--- /dev/null
@@ -0,0 +1,1386 @@
+
+
+
+XmComboBox(3Xm)        Harry's Motif Tools        XmComboBox(3Xm)
+
+
+N\bNA\bAM\bME\bE
+       XmComboBox - The Combo Box widget class
+
+S\bSY\bYN\bNO\bOP\bPS\bSI\bIS\bS
+       #\b#i\bin\bnc\bcl\blu\bud\bde\be <\b<C\bCo\bom\bmb\bbo\boB\bBo\box\bx.\b.h\bh>\b>
+
+       Depending on your system's configuration the place of this
+       include file may vary. In doubt, contact your local system
+       administrator. Or run in circles and shout.
+
+
+D\bDE\bES\bSC\bCR\bRI\bIP\bPT\bTI\bIO\bON\bN
+       The  ComboBox  widget  allows  the user to select elements
+       from a list of choices, and enter their own  values  in  a
+       text widget. To conserve screen space, the list of choices
+       is shown only when the user selects the down arrow button.
+       The  choices may then be selected from this list. The list
+       will automatically by removed when  the  user  selects  an
+       item in the list.  When the list is removed, the item that
+       was selected will be placed in the text widget. Typing the
+       escape key when the list is up, cancels the list popup.
+
+     C\bCl\bla\bas\bss\bse\bes\bs
+       ComboBox  inherits  behaviour  and resources from C\bCo\bor\bre\be and
+       C\bCo\bom\bmp\bpo\bos\bsi\bit\bte\be, C\bCo\bon\bns\bst\btr\bra\bai\bin\bnt\bt and X\bXm\bmM\bMa\ban\bna\bag\bge\ber\br classes.
+
+       The class pointer is x\bxm\bmC\bCo\bom\bmb\bbo\boB\bBo\box\bxW\bWi\bid\bdg\bge\bet\btC\bCl\bla\bas\bss\bs.
+
+       The class name is X\bXm\bmC\bCo\bom\bmb\bbo\boB\bBo\box\bx.
+
+     N\bNe\bew\bw R\bRe\bes\bso\bou\bur\brc\bce\bes\bs
+       The following table defines a set of widget resources used
+       by the programmer to specify data. The programmer can also
+       set the resource values for the inherited classes  to  set
+       attributes  for  this  widget.  To reference a resource by
+       name or by class in a .Xdefaults file, remove the  X\bXm\bmN\bN  or
+       X\bXm\bmC\bC  prefix  and use the remaining letters. To specify one
+       of the defined values for a resource in a .Xdefaults file,
+       remove  the  X\bXm\bm  prefix  and use the remaining letters (in
+       either lowercase or uppercase, but include any underscores
+       between words). The codes in the access column indicate if
+       the given resource can be set at creation time (C), set by
+       using X\bXt\btS\bSe\bet\btV\bVa\bal\blu\bue\bes\bs (S), retrieved by using X\bXt\btG\bGe\bet\btV\bVa\bal\blu\bue\bes\bs (G),
+       or is not applicable (N/A).
+
+                           X\bXm\bmC\bCo\bom\bmb\bbo\boB\bBo\box\bx R\bRe\bes\bso\bou\bur\brc\bce\be S\bSe\bet\bt
+       -----------------------------------------------------------------
+        N\bNa\bam\bme\be                            D\bDe\bef\bfa\bau\bul\blt\bt                  A\bAc\bcc\bce\bes\bss\bs
+          C\bCl\bla\bas\bss\bs                           T\bTy\byp\bpe\be
+       -----------------------------------------------------------------
+        XmNactivateCallback             NULL                     C
+          XmCCallback                     XtCallbackList
+       -----------------------------------------------------------------
+
+
+
+
+Version 1.31              20 March 1995                         1
+
+
+
+
+
+XmComboBox(3Xm)        Harry's Motif Tools        XmComboBox(3Xm)
+
+
+        XmNalignment                    XmALIGNMENT_CENTER       CSG
+          XmCAlignment                    unsigned char
+       -----------------------------------------------------------------
+        XmNarrowSpacingOn               False                    CSG
+          XmNCArrowSpacingOn              Boolean
+       -----------------------------------------------------------------
+        XmNautomaticSelection           False                    CSG
+          XmCAutomaticSelection           Boolean
+       -----------------------------------------------------------------
+        XmNblinkRate                    500                      CSG
+          XmCBlinkRate                    int
+       -----------------------------------------------------------------
+        XmNcolumns                      dynamic                  CSG
+          XmCColumns                      short
+       -----------------------------------------------------------------
+        XmNcursorPosition               0                        CSG
+          XmCCursorPosition               XmTextPosition
+       -----------------------------------------------------------------
+        XmNcursorPositionVisible        True                     CSG
+          XmCCursorPositionVisible        Boolean
+       -----------------------------------------------------------------
+        XmNdefaultActionCallback        NULL                     CSG
+          XmCCallback                     XtCallbackList
+       -----------------------------------------------------------------
+        XmNdropDownCallback             NULL                     CSG
+          XmCDropDownCallback             XtCallbackList
+       -----------------------------------------------------------------
+        XmNdropDownCursor               center_ptr               CSG
+          XmCDropDownCursor               Cursor
+       -----------------------------------------------------------------
+        XmNdropDownOffset               dynamic                  CSG
+          XmCDropDownOffset               Position
+       -----------------------------------------------------------------
+        XmNeditable                     False                    CG
+          XmCEditable                     Boolean
+       -----------------------------------------------------------------
+        XmNfontList                     dynamic                  CSG
+          XmCFontList                     XmFontList
+       -----------------------------------------------------------------
+        XmNitemCount                    0                        CSG
+          XmCItemCount                    int
+       -----------------------------------------------------------------
+        XmNitems                        NULL                     CSG
+          XmCItems                        XmStringTable
+       -----------------------------------------------------------------
+        XmNlabelFontList                dynamic                  CSG
+          XmCLabelFontList                XmFontList
+       -----------------------------------------------------------------
+        XmNlabelInsensitivePixmap       XmUNSPECIFIED_PIXMAP     CSG
+          XmCLabelInsensitivePixmap       Pixmap
+       -----------------------------------------------------------------
+        XmNlabelMarginBottom            0                        CSG
+
+
+
+
+
+Version 1.31              20 March 1995                         2
+
+
+
+
+
+XmComboBox(3Xm)        Harry's Motif Tools        XmComboBox(3Xm)
+
+
+          XmCLabelMarginBottom            Dimension
+       -----------------------------------------------------------------
+        XmNlabelMarginHeight            2                        CSG
+          XmCLabelMarginHeight            Dimension
+       -----------------------------------------------------------------
+        XmNlabelMarginLeft              0                        CSG
+          XmCLabelMarginLeft              Dimension
+       -----------------------------------------------------------------
+        XmNlabelMarginRight             0                        CSG
+          XmCLabelMarginRight             Dimension
+       -----------------------------------------------------------------
+        XmNlabelMarginTop               0                        CSG
+          XmCLabelMarginTop               Dimension
+       -----------------------------------------------------------------
+        XmNlabelMarginWidth             0                        CSG
+          XmCLabelMarginWidth             Dimension
+       -----------------------------------------------------------------
+        XmNlabelPixmap                  XmUNSPECIFIED_PIXMAP     CSG
+          XmCLabelPixmap                  Pixmap
+       -----------------------------------------------------------------
+        XmNlabelString                  dynamic                  CSG
+          XmCXmString                     XmString
+       -----------------------------------------------------------------
+        XmNlabelType                    XmSTRING                 CSG
+          XmCLabelType                    unsigned char
+       -----------------------------------------------------------------
+        XmNlistMarginHeight             0                        CSG
+          XmCListMarginHeight             Dimension
+       -----------------------------------------------------------------
+        XmNlistMarginWidth              0                        CSG
+          XmCListMarginWidth              Dimension
+       -----------------------------------------------------------------
+        XmNlistSizePolicy               XmVARIABLE               CG
+          XmCListSizePolicy               unsigned char
+       -----------------------------------------------------------------
+        XmNlistSpacing                  0                        CSG
+          XmCListSpacing                  Dimension
+       -----------------------------------------------------------------
+        XmNmarginHeight                 5                        CSG
+          XmCMarginHeight                 Dimension
+       -----------------------------------------------------------------
+        XmNmarginWidth                  5                        CSG
+          XmCMarginWidth                  Dimension
+       -----------------------------------------------------------------
+        XmNmaxLength                    largest integer          CSG
+          XmCMaxLength                    int
+       -----------------------------------------------------------------
+        XmNmodifyVerifyCallback         NULL                     CSG
+          XmCCallback                     XtCallbackList
+       -----------------------------------------------------------------
+        XmNmotionVerifyCallback         NULL                     CSG
+          XmCCallback                     XtCallbackList
+       -----------------------------------------------------------------
+
+
+
+
+Version 1.31              20 March 1995                         3
+
+
+
+
+
+XmComboBox(3Xm)        Harry's Motif Tools        XmComboBox(3Xm)
+
+
+        XmNpersistentDropDown           False                    CSG
+          XmCPersistentDropDown           Boolean
+       -----------------------------------------------------------------
+        XmNscrollBarDisplayPolicy       XmAS_NEEDED              CSG
+          XmCScrollBarDisplayPolicy       unsigned char
+       -----------------------------------------------------------------
+        XmNselectionCallback            NULL                     CSG
+          XmCCallback                     XtCallbackList
+       -----------------------------------------------------------------
+        XmNselectionPolicy              XmBROWSE_SELECT          CG
+          XmCSelectionPolicy              unsigned char
+       -----------------------------------------------------------------
+        XmNselectThreshold              5                        CSG
+          XmCSelectThreshold              int
+       -----------------------------------------------------------------
+        XmNshowLabel                    False                    CG
+          XmCShowLabel                    Boolean
+       -----------------------------------------------------------------
+        XmNsorted                       False                    CSG
+           XmCSorted                      Boolean
+       -----------------------------------------------------------------
+        XmNsortingCallback              NULL                     CSG
+          XmCCallback                     XtCallbackList
+       -----------------------------------------------------------------
+        XmNsquareArrow                  False                    CSG
+          XmCSquareArrow                  Boolean
+       -----------------------------------------------------------------
+        XmNstaticList                   False                    CSG
+          XmCStaticList                   Boolean
+       -----------------------------------------------------------------
+        XmNstringDirection              dynamic                  CSG
+          XmCStringDirection              XmStringDirection
+       -----------------------------------------------------------------
+        XmNtwmHandlingOn                False                    CSG
+          XmCTwmHandlingOn                Boolean
+       -----------------------------------------------------------------
+        XmNtopItemPostion               1                        G
+          XmCTopItemPostion               int
+       -----------------------------------------------------------------
+        XmNunselectionCallback          NULL                     CSG
+          XmCCallback                     XtCallbackList
+       -----------------------------------------------------------------
+        XmNvalue                        ""                       CSG
+          XmCValue                        String
+       -----------------------------------------------------------------
+        XmNvalueChangedCallback         NULL                     CSG
+          XmCCallback                     XtCallbackList
+       -----------------------------------------------------------------
+        XmNvisibleItemCount             8                        CSG
+          XmCVisibleItemCount             Int
+       -----------------------------------------------------------------
+
+       X\bXm\bmN\bNa\bac\bct\bti\biv\bva\bat\bte\beC\bCa\bal\bll\blb\bba\bac\bck\bk
+              Specifies a list of callbacks to be called when the
+
+
+
+Version 1.31              20 March 1995                         4
+
+
+
+
+
+XmComboBox(3Xm)        Harry's Motif Tools        XmComboBox(3Xm)
+
+
+              user  presses either the key "Enter" or "Activate".
+              The type of the structure passed to  this  callback
+              is    X\bXm\bmA\bAn\bny\byC\bCa\bal\bll\blb\bba\bac\bck\bkS\bSt\btr\bru\buc\bct\bt   and   the   reason   is
+              X\bXm\bmC\bCR\bR_\b_A\bAC\bCT\bTI\bIV\bVA\bAT\bTE\bE.
+
+       X\bXm\bmN\bNa\bal\bli\big\bgn\bnm\bme\ben\bnt\bt
+              The alignment (left to right) for the label's  text
+              or    pixmap.    Possible   values   are   X\bXm\bmA\bAL\bLI\bIG\bGN\bN-\b-
+              M\bME\bEN\bNT\bT_\b_B\bBE\bEG\bGI\bIN\bNN\bNI\bIN\bNG\bG,  X\bXm\bmA\bAL\bLI\bIG\bGN\bNM\bME\bEN\bNT\bT_\b_C\bCE\bEN\bNT\bTE\bER\bR,  and  X\bXm\bmA\bAL\bLI\bIG\bGN\bN-\b-
+              M\bME\bEN\bNT\bT_\b_E\bEN\bND\bD.
+
+       X\bXm\bmN\bNa\bau\but\bto\bom\bma\bat\bti\bic\bcS\bSe\bel\ble\bec\bct\bti\bio\bon\bn
+              Indicates   whether   the  X\bXm\bmN\bNs\bse\bel\ble\bec\bct\bti\bio\bon\bnC\bCa\bal\bll\blb\bba\bac\bck\bk  is
+              invoked each time the user moves into a new item if
+              X\bXm\bmN\bNa\bau\but\bto\bom\bma\bat\bti\bic\bcS\bSe\bel\ble\bec\bct\bti\bio\bon\bn  is  T\bTr\bru\bue\be  and  the selection
+              mode is X\bXm\bmB\bBR\bRO\bOW\bWS\bSE\bE_\b_S\bSE\bEL\bLE\bEC\bCT\bT.  If set to F\bFa\bal\bls\bse\be the X\bXm\bmN\bNs\bs-\b-
+              e\bel\ble\bec\bct\bti\bio\bon\bnC\bCa\bal\bll\blb\bba\bac\bck\bk  is  not  invoked  until  the user
+              releases the mouse button.
+
+       X\bXm\bmN\bNa\bar\brr\bro\bow\bwS\bSp\bpa\bac\bci\bin\bng\bgO\bOn\bn
+              Indicates whether a gap is  displayed  between  the
+              arrow  button  and  the  text  input  field if this
+              resource is set to T\bTr\bru\bue\be and X\bXm\bmN\bNe\bed\bdi\bit\bta\bab\bbl\ble\be is also set
+              to  T\bTr\bru\bue\be.   If  this  resource  is set to F\bFa\bal\bls\bse\be the
+              combo box widget will never display a  gab  between
+              the arrow button and the text area, irrespective of
+              the setting  of  X\bXm\bmN\bNe\bed\bdi\bit\bta\bab\bbl\ble\be.   Note  that  setting
+              X\bXm\bmN\bNa\bar\brr\bro\bow\bwS\bSp\bpa\bac\bci\bin\bng\bgO\bOn\bn  to  F\bFa\bal\bls\bse\be  doesn  not conform to
+              common GUI styles. And it prevents  the  user  from
+              easily   recognizing   whether  the  combo  box  is
+              editable or not.
+
+       X\bXm\bmN\bNb\bbl\bli\bin\bnk\bkR\bRa\bat\bte\be
+              The time in milliseconds  that  the  cursor  spends
+              being  visible  or invisible. A value of 0 prevents
+              the cursor from blinking.
+
+       X\bXm\bmN\bNb\bbo\bor\brd\bde\ber\brW\bWi\bid\bdt\bth\bh
+              That's no new resource but is already introduced in
+              the  core  class.  This class overrides the default
+              value and sets it to zero. You can however override
+              it  again  if  you're  dissatisfied  with  the  new
+              default setting.
+
+       X\bXm\bmN\bNc\bco\bol\blu\bum\bmn\bns\bs
+              Specifies the initial width of the input field mea-
+              sured   in  character  spaces.  The  default  value
+              depends on the value of the width of the combo box.
+
+       X\bXm\bmN\bNc\bcu\bur\brs\bso\bor\brP\bPo\bos\bsi\bit\bti\bio\bon\bn
+              Indicates the position in the text where the insert
+              cursor is to be located. Its position is the offset
+              of  characters  and  it starts with offset 0 at the
+              beginning of the text.
+
+
+
+Version 1.31              20 March 1995                         5
+
+
+
+
+
+XmComboBox(3Xm)        Harry's Motif Tools        XmComboBox(3Xm)
+
+
+       X\bXm\bmN\bNc\bcu\bur\brs\bso\bor\brP\bPo\bos\bsi\bit\bti\bio\bon\bnV\bVi\bis\bsi\bib\bbl\ble\be
+              Flags whether the insert cursor position is  marked
+              by a blinking cursor.
+
+       X\bXm\bmN\bNd\bde\bef\bfa\bau\bul\blt\btA\bAc\bct\bti\bio\bon\bnC\bCa\bal\bll\blb\bba\bac\bck\bk
+              Specifies  a list of callbacks that is called every
+              time an item  is  double  clicked.  The  reason  is
+              X\bXm\bmC\bCR\bR_\b_D\bDE\bEF\bFA\bAU\bUL\bLT\bT_\b_A\bAC\bCT\bTI\bIO\bON\bN.    Please  remember  that  you
+              can't use this callback if X\bXm\bmN\bNs\bst\bta\bat\bti\bic\bcL\bLi\bis\bst\bt  is  F\bFa\bal\bls\bse\be
+              because  the  list  is  immediatly hidden after the
+              user selected an item from the list. Thus the  user
+              can't double click on any item within the list.
+
+       X\bXm\bmN\bNd\bdr\bro\bop\bpD\bDo\bow\bwn\bnC\bCa\bal\bll\blb\bba\bac\bck\bk
+              This  is  a list of callbacks to be called when the
+              list is about to be shown or  hidden.  The  reasons
+              are X\bXm\bmC\bCR\bR_\b_S\bSH\bHO\bOW\bW_\b_L\bLI\bIS\bST\bT or X\bXm\bmC\bCR\bR_\b_H\bHI\bID\bDE\bE_\b_L\bLI\bIS\bST\bT.
+
+       X\bXm\bmN\bNd\bdr\bro\bop\bpD\bDo\bow\bwn\bnC\bCu\bur\brs\bso\bor\br
+              Specifies  the cursor to be used whenever the mouse
+              cursor is within the drop down list.
+
+       X\bXm\bmN\bNd\bdr\bro\bop\bpD\bDo\bow\bwn\bnO\bOf\bff\bfs\bse\bet\bt
+              Specifies the distance between the left  border  of
+              the  list  and  the left border of the input field.
+              The default value is set to the width of the  arrow
+              button.  Only  positive values are allowed for X\bXm\bmN\bN-\b-
+              d\bdr\bro\bop\bpD\bDo\bow\bwn\bnO\bOf\bff\bfs\bse\bet\bt, negative ones will be ignored.
+
+       X\bXm\bmN\bNe\bed\bdi\bit\bta\bab\bbl\ble\be
+              Specifies the type of combo box. If  set  to  True,
+              the  combo  box  contains  an editable input field.
+              Therefore, the user is free to select  entries  out
+              of  the list and to enter new text or modify it. In
+              the other case, with XmNeditable set to  False  the
+              user can solely browse in and select entries out of
+              the list.
+
+       X\bXm\bmN\bNf\bfo\bon\bnt\btL\bLi\bis\bst\bt
+              Indicates the font list to be used  for  the  input
+              field  and  the  list. If the value is NULL at ini-
+              tialization, it is initialized by  looking  up  the
+              parent hierarchy of the widget for an ancestor that
+              is a subclass of X\bXm\bmB\bBu\bul\bll\ble\bet\bti\bin\bnB\bBo\boa\bar\brd\bd, X\bXm\bmV\bVe\ben\bnd\bdo\bor\brS\bSh\bhe\bel\bll\bl  or
+              X\bXm\bmM\bMe\ben\bnu\buS\bSh\bhe\bel\bll\bl.   If  such  an ancestor is found, it's
+              font list will be taken by the combo box widget.
+
+       X\bXm\bmN\bNi\bit\bte\bem\bmC\bCo\bou\bun\bnt\bt
+              Specifies the total number of items in the list.
+
+       X\bXm\bmN\bNi\bit\bte\bem\bms\bs
+              Points to an array of compound strings representing
+              the  items to be displayed in the list. By means of
+              this a program can find out  what  items  the  list
+
+
+
+Version 1.31              20 March 1995                         6
+
+
+
+
+
+XmComboBox(3Xm)        Harry's Motif Tools        XmComboBox(3Xm)
+
+
+              contains.  It  is also possible to set the contents
+              of the  list  box  in  one  step  by  setting  this
+              resource to a new array of compound strings. Please
+              remember:  always  set  X\bXm\bmN\bNi\bit\bte\bem\bms\bs  and  X\bXm\bmN\bNi\bit\bte\bem\bmC\bCo\bou\bun\bnt\bt
+              together   in  the  same  call  to  X\bXt\btS\bSe\bet\btV\bVa\bal\blu\bue\bes\bs  or
+              X\bXt\btV\bVa\baS\bSe\bet\btV\bVa\bal\blu\bue\bes\bs.  If you ignore this rule  the  combo
+              box  will  ignore you and your attempt to set these
+              resources.
+
+       X\bXm\bmN\bNl\bla\bab\bbe\bel\blI\bIn\bns\bse\ben\bns\bsi\bit\bti\biv\bve\beP\bPi\bix\bxm\bma\bap\bp
+              Specifies a pixmap used as the button face if  X\bXm\bmN\bN-\b-
+              l\bla\bab\bbe\bel\blT\bTy\byp\bpe\be is set to X\bXm\bmP\bPI\bIX\bXM\bMA\bAP\bP and the combo box wid-
+              get is insensitive.
+
+       X\bXm\bmN\bNl\bla\bab\bbe\bel\blP\bPi\bix\bxm\bma\bap\bp
+              Specifies a pixmap to be displayed to the  left  of
+              the  input  field  if  X\bXm\bmN\bNl\bla\bab\bbe\bel\blT\bTy\byp\bpe\be is X\bXm\bmP\bPI\bIX\bXM\bMA\bAP\bP and
+              X\bXm\bmN\bNs\bsh\bho\bow\bwL\bLa\bab\bbe\bel\bl is True (of course).
+
+       X\bXm\bmN\bNl\bla\bab\bbe\bel\blS\bSt\btr\bri\bin\bng\bg
+              Specifies the the compound string to  be  displayed
+              if X\bXm\bmN\bNl\bla\bab\bbe\bel\blT\bTy\byp\bpe\be is set to X\bXm\bmS\bST\bTR\bRI\bIN\bNG\bG and X\bXm\bmN\bNs\bsh\bho\bow\bwL\bLa\bab\bbe\bel\bl
+              is True.
+
+       X\bXm\bmN\bNl\bla\bab\bbe\bel\blT\bTy\byp\bpe\be
+              The type of label (either string or pixmap). Possi-
+              ble values are X\bXm\bmP\bPI\bIX\bXM\bMA\bAP\bP and X\bXm\bmS\bST\bTR\bRI\bIN\bNG\bG.
+
+       X\bXm\bmN\bNl\bla\bab\bbe\bel\blM\bMa\bar\brg\bgi\bin\bnT\bTo\bop\bp,\b, X\bXm\bmN\bNl\bla\bab\bbe\bel\blM\bMa\bar\brg\bgi\bin\bnB\bBo\bot\btt\bto\bom\bm
+       X\bXm\bmN\bNl\bla\bab\bbe\bel\blM\bMa\bar\brg\bgi\bin\bnL\bLe\bef\bft\bt,\b, X\bXm\bmN\bNl\bla\bab\bbe\bel\blM\bMa\bar\brg\bgi\bin\bnR\bRi\big\bgh\bht\bt
+              The  amount  of space between one side of the label
+              and the nearest margin.
+
+       X\bXm\bmN\bNl\bla\bab\bbe\bel\blM\bMa\bar\brg\bgi\bin\bnH\bHe\bei\big\bgh\bht\bt,\b, X\bXm\bmN\bNl\bla\bab\bbe\bel\blM\bMa\bar\brg\bgi\bin\bnW\bWi\bid\bdt\bth\bh
+              The spacing between one side of the label  and  the
+              nearest edge of a shadow.
+
+       X\bXm\bmN\bNl\bli\bis\bst\btM\bMa\bar\brg\bgi\bin\bnH\bHe\bei\big\bgh\bht\bt,\b, X\bXm\bmN\bNl\bli\bis\bst\btM\bMa\bar\brg\bgi\bin\bnW\bWi\bid\bdt\bth\bh
+              The  height or width of the margin between the bor-
+              der of the list and the items in the list.
+
+       X\bXm\bmN\bNl\bli\bis\bst\btS\bSi\biz\bze\beP\bPo\bol\bli\bic\bcy\by
+              Controls the reaction of  the  list  when  an  item
+              grows  horizontally beyond the current width of the
+              list and X\bXm\bmN\bNs\bst\bta\bat\bti\bic\bcL\bLi\bis\bst\bt is set to T\bTr\bru\bue\be.  If  set  to
+              X\bXm\bmC\bCO\bON\bNS\bST\bTA\bAN\bNT\bT,  the list does not grow, and a horizon-
+              tal scroll bar is shown. If this resource is set to
+              X\bXm\bmV\bVA\bAR\bRI\bIA\bAB\bBL\bLE\bE, the list instead trys to grow such that
+              it match the size of the longest item, thus no hor-
+              izontal  scroll  bar  will  appear.   When X\bXm\bmN\bNl\bli\bis\bst\bt-\b-
+              S\bSi\biz\bze\beP\bPo\bol\bli\bic\bcy\by is the list will again try to  grow  but
+              in  case  the width of the longest item in the list
+              is wider than the viewing area of the list a  hori-
+              zontal scroll bar appears.
+
+
+
+Version 1.31              20 March 1995                         7
+
+
+
+
+
+XmComboBox(3Xm)        Harry's Motif Tools        XmComboBox(3Xm)
+
+
+       X\bXm\bmN\bNl\bli\bis\bst\btS\bSp\bpa\bac\bci\bin\bng\bg
+              The spacing between items in the list.
+
+       X\bXm\bmN\bNm\bma\bar\brg\bgi\bin\bnH\bHe\bei\big\bgh\bht\bt
+              Specifies the distance between the top and the bot-
+              tom of the widget window and the text displayed  in
+              the input field.
+
+       X\bXm\bmN\bNm\bma\bar\brg\bgi\bin\bnW\bWi\bid\bdt\bth\bh
+              Like  XmNmarginHeight  this  resource specifies the
+              distance between the left and the right  border  of
+              the widget window and the text.
+
+       X\bXm\bmN\bNm\bma\bax\bxL\bLe\ben\bng\bgt\bth\bh
+              Specifies  the  maximum  length  of the text string
+              that can be entered  from  the  keyboard  into  the
+              input  field of the combo box. Strings that are put
+              into  the  input  field  using  X\bXm\bmC\bCo\bom\bmb\bbo\boB\bBo\box\bxS\bSe\bet\btS\bSt\btr\bri\bin\bng\bg
+              ignore this resource.
+
+       X\bXm\bmN\bNm\bmo\bod\bdi\bif\bfy\byV\bVe\ber\bri\bif\bfy\byC\bCa\bal\bll\blb\bba\bac\bck\bk
+              Contains  a list of callbacks called before text is
+              deleted from or inserted into the text area of  the
+              combo  box widget. The callbacks are called only if
+              X\bXm\bmN\bNe\bed\bdi\bit\bta\bab\bbl\ble\be  is  set  to  T\bTr\bru\bue\be.   The   reason   is
+              X\bXm\bmC\bCR\bR_\b_M\bMO\bOD\bDI\bIF\bFY\bYI\bIN\bNG\bG_\b_T\bTE\bEX\bXT\bT_\b_V\bVA\bAL\bLU\bUE\bE  and  the  type  of   the
+              structure passed to this  callback  is  X\bXm\bmC\bCo\bom\bmb\bbo\boB\bBo\box\bx-\b-
+              T\bTe\bex\bxt\btV\bVe\ber\bri\bif\bfy\byC\bCa\bal\bll\blb\bba\bac\bck\bkS\bSt\btr\bru\buc\bct\bt.
+
+       X\bXm\bmN\bNm\bmo\bot\bti\bio\bon\bnV\bVe\ber\bri\bif\bfy\byC\bCa\bal\bll\blb\bba\bac\bck\bk
+              Specifies  the  list  of  callbacks  that is called
+              before the insert  cursor  gets  moved  to  another
+              position.  The  reason is X\bXm\bmC\bCR\bR_\b_M\bMO\bOV\bVI\bIN\bNG\bG_\b_I\bIN\bNS\bSE\bER\bRT\bT_\b_C\bCU\bUR\bRS\bSO\bOR\bR
+              and the type of  the  structure  whose  address  is
+              passed to the callback is X\bXm\bmC\bCo\bom\bmb\bbo\boB\bBo\box\bxT\bTe\bex\bxt\btV\bVe\ber\bri\bif\bfy\byC\bCa\bal\bll\bl-\b-
+              b\bba\bac\bck\bk-\b-S\bSt\btr\bru\buc\bct\bt.
+
+       X\bXm\bmN\bNs\bsc\bcr\bro\bol\bll\blB\bBa\bar\brD\bDi\bis\bsp\bpl\bla\bay\byP\bPo\bol\bli\bic\bcy\by
+              Controls the display of the vertical scroll bar  in
+              the  list  when  X\bXm\bmN\bNs\bst\bta\bat\bti\bic\bcL\bLi\bis\bst\bt  is set to T\bTr\bru\bue\be.\b.When
+              X\bXm\bmN\bNs\bsc\bcr\bro\bol\bll\blB\bBa\bar\brD\bDi\bis\bsp\bpl\bla\bay\byP\bPo\bol\bli\bic\bcy\by is  set  to  X\bXm\bmA\bAS\bS_\b_N\bNE\bEE\bED\bDE\bED\bD,
+              the  vertical scroll bar is displayed only when the
+              list contains more items than can be currently dis-
+              played.  If set to X\bXm\bmS\bST\bTA\bAT\bTI\bIC\bC the vertical scroll bar
+              is always displayed.
+
+       X\bXm\bmN\bNp\bpe\ber\brs\bsi\bis\bst\bte\ben\bnt\btD\bDr\bro\bop\bpD\bDo\bow\bwn\bn
+              Welcome to the sad  section  in  the  life  of  X11
+              applications.  This resource and the inherent prob-
+              lems are due to the focus policy of the window man-
+              ager  you're  using. See the further details in the
+              later sections.
+
+
+
+
+
+Version 1.31              20 March 1995                         8
+
+
+
+
+
+XmComboBox(3Xm)        Harry's Motif Tools        XmComboBox(3Xm)
+
+
+       X\bXm\bmN\bNs\bse\bel\ble\bec\bct\bti\bio\bon\bnC\bCa\bal\bll\blb\bba\bac\bck\bk
+              Specifies a list of callbacks that is  called  when
+              an    item    is    selected.     The   reason   is
+              X\bXm\bmC\bCR\bR_\b_S\bSI\bIN\bNG\bGL\bLE\bE_\b_S\bSE\bEL\bLE\bEC\bCT\bT.  The callbacks are  NOT  called
+              when  the  user  browses  through  the items in the
+              list.
+
+       X\bXm\bmN\bNs\bse\bel\ble\bec\bct\bti\bio\bon\bnP\bPo\bol\bli\bic\bcy\by
+              This resource controls whether the user  can  dese-
+              lect  the  currently  selected  item within a combo
+              box.  The  default  value  is  X\bXm\bmB\bBR\bRO\bOW\bWS\bSE\bE_\b_S\bSE\bEL\bLE\bEC\bCT\bT,  so
+              always  one  item gets selected if the combo box is
+              editable. In the case of X\bXm\bmS\bSI\bIN\bNG\bGL\bLE\bE_\b_S\bSE\bEL\bLE\bEC\bCT\bT  the  user
+              may deselect the current item either by clicking on
+              it in the  drop  down  list  or  pressing  the  key
+              "Delete".  Other  values for X\bXm\bmN\bNs\bse\bel\ble\bec\bct\bti\bio\bon\bnP\bPo\bol\bli\bic\bcy\by are
+              currently not allowed. (Multiple selections will be
+              probably availabe with the next release.)
+
+       X\bXm\bmN\bNs\bse\bel\ble\bec\bct\btT\bTh\bhr\bre\bes\bsh\bho\bol\bld\bd
+              Specifies  the amount of pixels the mouse must move
+              until the selection of text is recognized in  click
+              and drag mode.
+
+       X\bXm\bmN\bNs\bsh\bho\bow\bwL\bLa\bab\bbe\bel\bl
+              Specifies,  whether  a  label  containing text or a
+              pixmap should be displayed on the left side of  the
+              combo box. This resource can only be specified dur-
+              ing the creation of the combo  box,  afterwards  it
+              will have no effect.
+
+       X\bXm\bmN\bNs\bso\bor\brt\bte\bed\bd
+              Specifies  whether the items in the list are sorted
+              or not In an unsorted list, the items are shown  in
+              the  order in which they're put into the list. When
+              adding an item to a sorted list, this item will  be
+              put at the right place (alphabetically sorted).
+
+       X\bXm\bmN\bNs\bso\bor\brt\bti\bin\bng\bgC\bCa\bal\bll\blb\bba\bac\bck\bk
+              Contains  a  list of callbacks that is called when-
+              ever a new item is added to the  combo  box  widget
+              and  X\bXm\bmN\bNs\bso\bor\brt\bte\bed\bd is T\bTr\bru\bue\be.  The reason is X\bXm\bmC\bCR\bR_\b_S\bSO\bOR\bRT\bTI\bIN\bNG\bG
+              and the type of  the  structure  whose  address  is
+              passed  to  the  callback is X\bXm\bmC\bCo\bom\bmb\bbo\boB\bBo\box\bxS\bSo\bor\brt\bti\bin\bng\bgC\bCa\bal\bll\bl-\b-
+              b\bba\bac\bck\bk-\b-S\bSt\btr\bru\buc\bct\bt.  For detailed information see the fol-
+              lowing sections.
+
+       X\bXm\bmN\bNs\bsq\bqu\bua\bar\bre\beA\bAr\brr\bro\bow\bw
+              Controls  the  width of the arrow button in respect
+              to its height. If this resource is T\bTr\bru\bue\be  the  arrow
+              button  is  always  layed out square. Otherwise the
+              arrow button's width will be approximatly 4/5th  of
+              its height.
+
+
+
+
+Version 1.31              20 March 1995                         9
+
+
+
+
+
+XmComboBox(3Xm)        Harry's Motif Tools        XmComboBox(3Xm)
+
+
+       X\bXm\bmN\bNs\bst\bta\bat\bti\bic\bcL\bLi\bis\bst\bt
+              Controls whether the list is always statically dis-
+              played right below the text input area of the combo
+              box  if  set  to T\bTr\bru\bue\be.  If you use a combo box with
+              X\bXm\bmN\bNs\bst\bta\bat\bti\bic\bcL\bLi\bis\bst\bt set to T\bTr\bru\bue\be and  X\bXm\bmN\bNe\bed\bdi\bit\bta\bab\bbl\ble\be  set  to
+              F\bFa\bal\bls\bse\be  you should consider using a simple list wid-
+              get instead.
+
+       X\bXm\bmN\bNs\bst\btr\bri\bin\bng\bgD\bDi\bir\bre\bec\bct\bti\bio\bon\bn
+              Specifies the initial direction to draw the  string
+              (from  the  left  to  the  right or in the opposite
+              direction). The whole story seems to  be  incompre-
+              hensible... therefore this resource is provided for
+              completeness only.
+
+       X\bXm\bmN\bNt\btw\bwm\bmH\bHa\ban\bnd\bdl\bli\bin\bng\bgO\bOn\bn
+              If  you  have  trouble  with  the  list  then  this
+              resource may help you.  Set it to True, if the list
+              gets hidden at the moment the mouse  cursor  enters
+              the list.
+
+       X\bXm\bmN\bNt\bto\bop\bpI\bIt\bte\bem\bmP\bPo\bos\bsi\bit\bti\bio\bon\bn
+              This  resource  is intended as an informal hint. It
+              specifies the index of the item which is  displayed
+              at the visible top of the list.
+
+       X\bXm\bmN\bNv\bva\bal\blu\bue\be
+              Contains  the  text  of  the input field. This also
+              concerns combo  boxes  which  are  not  editable  (
+              X\bXm\bmN\bNe\bed\bdi\bit\bta\bab\bbl\ble\be set to False).
+
+       X\bXm\bmN\bNu\bun\bns\bse\bel\ble\bec\bct\bti\bio\bon\bnC\bCa\bal\bll\blb\bba\bac\bck\bk
+              Specifies  a list of callbacks that is called when-
+              ever the currently selected item is deselected  and
+              no other item gets selected. This callback is acti-
+              vated  only  when  X\bXm\bmN\bNs\bse\bel\ble\bec\bct\bti\bio\bon\bnP\bPo\bol\bli\bic\bcy\by   is   X\bXm\bmS\bSI\bIN\bN-\b-
+              G\bGL\bLE\bE_\b_S\bSE\bEL\bLE\bEC\bCT\bT.  The reason is X\bXm\bmC\bCR\bR_\b_U\bUN\bNS\bSE\bEL\bLE\bEC\bCT\bT.  The type
+              of the structure whose address is  passed  to  this
+              callback is X\bXm\bmA\bAn\bny\byC\bCa\bal\bll\blb\bba\bac\bck\bkS\bSt\btr\bru\buc\bct\bt.
+
+       X\bXm\bmN\bNv\bva\bal\blu\bue\be
+              Contains  the  text  of  the input field. This also
+              concerns combo  boxes  which  are  not  editable  (
+              X\bXm\bmN\bNe\bed\bdi\bit\bta\bab\bbl\ble\be set to F\bFa\bal\bls\bse\be).
+
+       X\bXm\bmN\bNv\bva\bal\blu\bue\beC\bCh\bha\ban\bng\bge\bed\bdC\bCa\bal\bll\blb\bba\bac\bck\bk
+              Specifies  a  list  of callbacks to be called after
+              text is deleted from or inserted into the text area
+              of   the   combo   box   widget.   The   reason  is
+              X\bXm\bmC\bCR\bR_\b_V\bVA\bAL\bLU\bUE\bE_\b_C\bCH\bHA\bAN\bNG\bGE\bED\bD.   The  type  of  the  structure
+              whose  address is passed to this callback is X\bXm\bmA\bAn\bny\by-\b-
+              C\bCa\bal\bll\blb\bba\bac\bck\bkS\bSt\btr\bru\buc\bct\bt.
+
+
+
+
+
+Version 1.31              20 March 1995                        10
+
+
+
+
+
+XmComboBox(3Xm)        Harry's Motif Tools        XmComboBox(3Xm)
+
+
+       X\bXm\bmN\bNv\bvi\bis\bsi\bib\bbl\ble\beI\bIt\bte\bem\bmC\bCo\bou\bun\bnt\bt
+              Specifies the number of items that can fit  in  the
+              visible  space of the list. The combo box uses this
+              value to determine the height of its list.
+
+     I\bIn\bnh\bhe\ber\bri\bit\bte\bed\bd R\bRe\bes\bso\bou\bur\brc\bce\bes\bs
+       XmComboBox inherits behaviour and resources from the  fol-
+       lowing  superclasses.  For  a complete description of each
+       resource, refer to the man page for that superclass.
+
+     C\bCa\bal\bll\blb\bba\bac\bck\bk I\bIn\bnf\bfo\bor\brm\bma\bat\bti\bio\bon\bn
+       A pointer to the following  structure  is  passed  to  the
+       X\bXm\bmN\bNd\bdr\bro\bop\bpD\bDo\bow\bwn\bnC\bCa\bal\bll\blb\bba\bac\bck\bk callback:
+
+       t\bty\byp\bpe\bed\bde\bef\bf s\bst\btr\bru\buc\bct\bt {\b{
+         i\bin\bnt\bt            _\br_\be_\ba_\bs_\bo_\bn;\b;
+         X\bXE\bEv\bve\ben\bnt\bt         *\b*_\be_\bv_\be_\bn_\bt;\b;
+       }\b} X\bXm\bmC\bCo\bom\bmb\bbo\boB\bBo\box\bxD\bDr\bro\bop\bpD\bDo\bow\bwn\bnC\bCa\bal\bll\blb\bba\bac\bck\bkS\bSt\btr\bru\buc\bct\bt;\b;
+
+       _\br_\be_\ba_\bs_\bo_\bn         Within this structure, _\br_\be_\ba_\bs_\bo_\bn indicates the
+                      reason why the callback was activated. This
+                      can    be   X\bXm\bmC\bCR\bR_\b_S\bSH\bHO\bOW\bW_\b_L\bLI\bIS\bST\bT   as   well   as
+                      X\bXm\bmC\bCR\bR_\b_H\bHI\bID\bDE\bE_\b_L\bLI\bIS\bST\bT.  A callback is called  with
+                      the  reason  X\bXm\bmC\bCR\bR_\b_S\bSH\bHO\bOW\bW_\b_L\bLI\bIS\bST\bT just before the
+                      list is dropped down, whereas the  callback
+                      is  called  with  X\bXm\bmC\bCR\bR_\b_H\bHI\bID\bDE\bE_\b_L\bLI\bIS\bST\bT  after the
+                      list is hidden.
+
+
+       _\be_\bv_\be_\bn_\bt          Points to the X\bXE\bEv\bve\ben\bnt\bt, which  triggered  the
+                      callback.  May  be  N\bNU\bUL\bLL\bL if the callback is
+                      triggered by a call  to  X\bXm\bmC\bCo\bom\bmb\bbo\boB\bBo\box\bxS\bSh\bho\bow\bwL\bLi\bis\bst\bt
+                      or X\bXm\bmC\bCo\bom\bmb\bbo\boB\bBo\box\bxH\bHi\bid\bde\beL\bLi\bis\bst\bt.
+
+       A  pointer  to  the  following  structure is passed to the
+       X\bXm\bmN\bNa\bac\bct\bti\biv\bva\bat\bte\beC\bCa\bal\bll\blb\bba\bac\bck\bk callback:
+
+       t\bty\byp\bpe\bed\bde\bef\bf s\bst\btr\bru\buc\bct\bt {\b{
+         i\bin\bnt\bt            _\br_\be_\ba_\bs_\bo_\bn;\b;
+         X\bXE\bEv\bve\ben\bnt\bt         *\b*_\be_\bv_\be_\bn_\bt;\b;
+       }\b} X\bXm\bmA\bAn\bny\byC\bCa\bal\bll\blb\bba\bac\bck\bkS\bSt\btr\bru\buc\bct\bt;\b;
+
+       _\br_\be_\ba_\bs_\bo_\bn         Indicates why  the  callback  was  invoked.
+                      This  is X\bXm\bmC\bCR\bR_\b_A\bAC\bCT\bTI\bIV\bVA\bAT\bTE\bE for X\bXm\bmN\bNa\bac\bct\bti\biv\bva\bat\bte\beC\bCa\bal\bll\bl-\b-
+                      b\bba\bac\bck\bk.
+
+       _\be_\bv_\be_\bn_\bt          Points to the X\bXE\bEv\bve\ben\bnt\bt, which  triggered  the
+                      callback.
+
+       A  pointer  to  the  following  structure is passed to the
+       X\bXm\bmN\bNs\bse\bel\ble\bec\bct\bti\bio\bon\bnC\bCa\bal\bll\blb\bba\bac\bck\bk and X\bXm\bmN\bNd\bde\bef\bfa\bau\bul\blt\btA\bAc\bct\bti\bio\bon\bnC\bCa\bal\bll\blb\bba\bac\bck\bk:
+
+       t\bty\byp\bpe\bed\bde\bef\bf s\bst\btr\bru\buc\bct\bt {\b{
+         i\bin\bnt\bt            _\br_\be_\ba_\bs_\bo_\bn;\b;
+
+
+
+Version 1.31              20 March 1995                        11
+
+
+
+
+
+XmComboBox(3Xm)        Harry's Motif Tools        XmComboBox(3Xm)
+
+
+         X\bXE\bEv\bve\ben\bnt\bt         *\b*_\be_\bv_\be_\bn_\bt;\b;
+         X\bXm\bmS\bSt\btr\bri\bin\bng\bg       _\bv_\ba_\bl_\bu_\be;\b;
+         i\bin\bnt\bt            _\bi_\bn_\bd_\be_\bx;\b;
+       }\b} X\bXm\bmC\bCo\bom\bmb\bbo\boB\bBo\box\bxS\bSe\bel\ble\bec\bct\bti\bio\bon\bnC\bCa\bal\bll\blb\bba\bac\bck\bkS\bSt\btr\bru\buc\bct\bt,\b,  X\bXm\bmC\bCo\bom\bmb\bbo\boB\bBo\box\bxD\bDe\bef\bfa\bau\bul\blt\btA\bAc\bc-\b-
+       t\bti\bio\bon\bnC\bCa\bal\bll\blb\bba\bac\bck\bkS\bSt\btr\bru\buc\bct\bt;\b;
+
+       _\br_\be_\ba_\bs_\bo_\bn         Within this structure, _\br_\be_\ba_\bs_\bo_\bn indicates the
+                      reason why the callback was  activated.  At
+                      this   time,   the  reason  can  be  either
+                      X\bXm\bmC\bCR\bR_\b_S\bSI\bIN\bNG\bGL\bLE\bE_\b_S\bSE\bEL\bLE\bEC\bCT\bT or X\bXm\bmC\bCR\bR_\b_B\bBR\bRO\bOW\bWS\bSE\bE_\b_S\bSE\bEL\bLE\bEC\bCT\bT
+                      depending  on  the setting of X\bXm\bmN\bNs\bse\bel\ble\bec\bct\bti\bio\bon\bn-\b-
+                      P\bPo\bol\bli\bic\bcy\by.   It  indicates   that   the   user
+                      selected  a  (potentially  new) item in the
+                      list.  Whether this callback  is  activated
+                      every  time  the user moves into a new item
+                      of the list or only when the user  releases
+                      the  mouse button is controlled through the
+                      setting of X\bXm\bmN\bNa\bau\but\bto\bom\bma\bat\bti\bic\bcS\bSe\bel\ble\bec\bct\bti\bio\bon\bn.
+
+       _\be_\bv_\be_\bn_\bt          Points to the X\bXE\bEv\bve\ben\bnt\bt, which  triggered  the
+                      callback.
+
+       _\bv_\ba_\bl_\bu_\be          Points  to  a  X\bXm\bmS\bSt\btr\bri\bin\bng\bg, which contains the
+                      text of the current  selected  item.   This
+                      X\bXm\bmS\bSt\btr\bri\bin\bng\bg  must never be freed or changed by
+                      the called program code!
+
+       _\bi_\bn_\bd_\be_\bx          Index (starting from 1)  of  the  currently
+                      selected item in the list.
+
+       A  pointer  to  the  following  structure is passed to the
+       X\bXm\bmN\bNu\bun\bns\bse\bel\ble\bec\bct\bti\bio\bon\bnC\bCa\bal\bll\blb\bba\bac\bck\bk callback:
+
+       t\bty\byp\bpe\bed\bde\bef\bf s\bst\btr\bru\buc\bct\bt {\b{
+         i\bin\bnt\bt            _\br_\be_\ba_\bs_\bo_\bn;\b;
+         X\bXE\bEv\bve\ben\bnt\bt         *\b*_\be_\bv_\be_\bn_\bt;\b;
+       }\b} X\bXm\bmC\bCo\bom\bmb\bbo\boB\bBo\box\bxU\bUn\bns\bse\bel\ble\bec\bct\bti\bio\bon\bnC\bCa\bal\bll\blb\bba\bac\bck\bkS\bSt\btr\bru\buc\bct\bt;\b;
+
+       _\br_\be_\ba_\bs_\bo_\bn         Indicates why  the  callback  was  invoked.
+                      This is X\bXm\bmC\bCR\bR_\b_U\bUN\bNS\bSE\bEL\bLE\bEC\bCT\bT.
+
+       _\be_\bv_\be_\bn_\bt          Points  to  the X\bXE\bEv\bve\ben\bnt\bt, which triggered the
+                      callback.
+
+       A pointer to the following  structure  is  passed  to  the
+       X\bXm\bmN\bNm\bmo\bod\bdi\bif\bfy\byV\bVe\ber\bri\bif\bfy\byC\bCa\bal\bll\blb\bba\bac\bck\bk and X\bXm\bmN\bNm\bmo\bot\bti\bio\bon\bnV\bVe\ber\bri\bif\bfy\byC\bCa\bal\bll\blb\bba\bac\bck\bk call-
+       backs:
+
+       t\bty\byp\bpe\bed\bde\bef\bf s\bst\btr\bru\buc\bct\bt {\b{
+         i\bin\bnt\bt            _\br_\be_\ba_\bs_\bo_\bn;\b;
+         X\bXE\bEv\bve\ben\bnt\bt         *\b*_\be_\bv_\be_\bn_\bt;\b;
+         B\bBo\boo\bol\ble\bea\ban\bn        _\bd_\bo_\bi_\bt;\b;
+         P\bPo\bos\bsi\bit\bti\bio\bon\bn       _\bc_\bu_\br_\br_\bI_\bn_\bs_\be_\br_\bt_\b, _\bn_\be_\bw_\bI_\bn_\bs_\be_\br_\bt;\b;
+         P\bPo\bos\bsi\bit\bti\bio\bon\bn       _\bs_\bt_\ba_\br_\bt_\bP_\bo_\bs_\b, _\be_\bn_\bd_\bP_\bo_\bs;\b;
+
+
+
+Version 1.31              20 March 1995                        12
+
+
+
+
+
+XmComboBox(3Xm)        Harry's Motif Tools        XmComboBox(3Xm)
+
+
+         X\bXm\bmT\bTe\bex\bxt\btB\bBl\blo\boc\bck\bk    _\bt_\be_\bx_\bt;\b;
+       }\b} X\bXm\bmC\bCo\bom\bmb\bbo\boB\bBo\box\bxT\bTe\bex\bxt\btV\bVe\ber\bri\bif\bfy\byC\bCa\bal\bll\blb\bba\bac\bck\bkS\bSt\btr\bru\buc\bct\bt,\b, *\b*X\bXm\bmC\bCo\bom\bmb\bbo\boB\bBo\box\bxT\bTe\bex\bxt\btV\bVe\ber\bri\bi-\b-
+       f\bfy\byP\bPt\btr\br;\b;
+
+       _\br_\be_\ba_\bs_\bo_\bn         Indicates  the  reason why the callback was
+                      activated.    This    can     be     either
+                      X\bXm\bmC\bCR\bR_\b_M\bMO\bOD\bDI\bIF\bFY\bYI\bIN\bNG\bG_\b_T\bTE\bEX\bXT\bT_\b_V\bVA\bAL\bLU\bUE\bE                or
+                      X\bXm\bmC\bCR\bR_\b_M\bMO\bOV\bVI\bIN\bNG\bG_\b_I\bIN\bNS\bSE\bER\bRT\bT_\b_C\bCU\bUR\bRS\bSO\bOR\bR.
+
+       _\be_\bv_\be_\bn_\bt          Points to the X\bXE\bEv\bve\ben\bnt\bt, which  triggered  the
+                      callback.
+
+       _\bd_\bo_\bi_\bt           Indicates   whether  the  offending  action
+                      should be performed. Setting this field  of
+                      the  callback structure to F\bFa\bal\bls\bse\be denies the
+                      action.
+
+       _\bc_\bu_\br_\br_\bI_\bn_\bs_\be_\br_\bt     Specifies  the  current  position  of   the
+                      insert cursor.
+
+                      Indicates  the  position  at which the user
+                      attempts to position the cursor.
+
+       _\bs_\bt_\ba_\br_\bt_\bP_\bo_\bs       Indicates the starting position of the text
+                      to     modify.    If    the    reason    is
+                      X\bXm\bmC\bCR\bR_\b_M\bMO\bOV\bVI\bIN\bNG\bG_\b_I\bIN\bNS\bSE\bER\bRT\bT_\b_C\bCU\bUR\bRS\bSO\bOR\bR this value is the
+                      same as c\bcu\bur\brr\brI\bIn\bns\bse\ber\brt\bt.
+
+       _\be_\bn_\bd_\bP_\bo_\bs         Specifies  the  ending position of the text
+                      to  modify.  If  no  text  is  replaced  or
+                      deleted, then the value will be the same as
+                      s\bst\bta\bar\brt\btP\bPo\bos\bs.      If     the     reason     is
+                      X\bXm\bmC\bCR\bR_\b_M\bMO\bOD\bDI\bIF\bFY\bYI\bIN\bNG\bG_\b_T\bTE\bEX\bXT\bT_\b_V\bVA\bAL\bLU\bUE\bE this value is the
+                      same as _\bc_\bu_\br_\br_\bI_\bn_\bs_\be_\br_\bt.
+
+       _\bt_\be_\bx_\bt           Holds the address of a  structure  of  type
+                      X\bXm\bmT\bTe\bex\bxt\btB\bBl\blo\boc\bck\bkR\bRe\bec\bc   which  holds  the  textual
+                      information to be inserted.
+
+       The following table describes the reasons why the individ-
+       ual verification callback structure fields are valid.
+
+                R\bRe\bea\bas\bso\bon\bn                    V\bVa\bal\bli\bid\bd F\bFi\bie\bel\bld\bds\bs
+       -----------------------------------------------------
+       X\bXm\bmC\bCR\bR_\b_M\bMO\bOD\bDI\bIF\bFY\bYI\bIN\bNG\bG_\b_T\bTE\bEX\bXT\bT_\b_V\bVA\bAL\bLU\bUE\bE     _\br_\be_\ba_\bs_\bo_\bn, _\be_\bv_\be_\bn_\bt, _\bd_\bo_\bi_\bt,
+                                     _\bs_\bt_\ba_\br_\bt_\bP_\bo_\bs, _\be_\bn_\bd_\bP_\bo_\bs, _\bt_\be_\bx_\bt
+
+       X\bXm\bmC\bCR\bR_\b_M\bMO\bOV\bVI\bIN\bNG\bG_\b_I\bIN\bNS\bSE\bER\bRT\bT_\b_C\bCU\bUR\bRS\bSO\bOR\bR     _\br_\be_\ba_\bs_\bo_\bn, _\be_\bv_\be_\bn_\bt, _\bd_\bo_\bi_\bt,
+                                     _\bc_\bu_\br_\br_\bI_\bn_\bs_\be_\br_\bt, _\bn_\be_\bw_\bI_\bn_\bs_\be_\br_\bt,
+
+       A pointer to the following structure is passed to the X\bXm\bmN\bN-\b-
+       s\bso\bor\brt\bti\bin\bng\bgC\bCa\bal\bll\blb\bba\bac\bck\bk callback: t\bty\byp\bpe\bed\bde\bef\bf s\bst\btr\bru\buc\bct\bt {\b{
+         i\bin\bnt\bt            _\br_\be_\ba_\bs_\bo_\bn;\b;
+         X\bXE\bEv\bve\ben\bnt\bt         *\b*_\be_\bv_\be_\bn_\bt;\b;
+
+
+
+Version 1.31              20 March 1995                        13
+
+
+
+
+
+XmComboBox(3Xm)        Harry's Motif Tools        XmComboBox(3Xm)
+
+
+         i\bin\bnt\bt            _\bo_\bp_\be_\br_\ba_\bt_\bi_\bo_\bn;\b;
+         v\bvo\boi\bid\bd           *\b*_\bi_\bt_\be_\bm_\b__\bi_\bn_\bt_\be_\br_\bn_\ba_\bl;\b;
+         X\bXm\bmS\bSt\btr\bri\bin\bng\bg       _\bi_\bt_\be_\bm;\b;
+         i\bin\bnt\bt            _\br_\be_\bs_\bu_\bl_\bt;\b;
+       }\b} X\bXm\bmC\bCo\bom\bmb\bbo\boB\bBo\box\bxS\bSo\bor\brt\bti\bin\bng\bgC\bCa\bal\bll\blb\bba\bac\bck\bkS\bSt\btr\bru\buc\bct\bt,\b, *\b*X\bXm\bmC\bCo\bom\bmb\bbo\boB\bBo\box\bxS\bSo\bor\brt\bti\bin\bng\bgP\bPt\btr\br;\b;
+
+       _\br_\be_\ba_\bs_\bo_\bn         Indicates the reason why the  callback  was
+                      activated. This is X\bXm\bmC\bCR\bR_\b_S\bSO\bOR\bRT\bTI\bIN\bNG\bG.
+
+       _\be_\bv_\be_\bn_\bt          Contains  always N\bNU\bUL\bLL\bL and is just there for
+                      compatibility reasons.
+
+       _\bo_\bp_\be_\br_\ba_\bt_\bi_\bo_\bn      Indicates the operation to  carry  out  and
+                      can   be   either   X\bXm\bmO\bOP\bP_\b_I\bIN\bNI\bIT\bT,X\bXm\bmO\bOP\bP_\b_D\bDO\bON\bNE\bE  or
+                      X\bXm\bmO\bOP\bP_\b_C\bCO\bOM\bMP\bPA\bAR\bRE\bE.
+
+       _\bi_\bt_\be_\bm_\b__\bi_\bn_\bt_\be_\br_\bn_\ba_\bl  Must be set during the X\bXm\bmO\bOP\bP_\b_I\bIN\bNI\bIT\bT  operation
+                      to  a  suitable  representation  of the new
+                      item which is to be added to the list.   In
+                      all  subsequent calls to this callback with
+                      X\bXm\bmO\bOP\bP_\b_C\bCO\bOM\bMP\bPA\bAR\bRE\bEorX\bXm\bmO\bOP\bP_\b_D\bDO\bON\bNE\bE  this  field   will
+                      contain  whatever you've put into it during
+                      X\bXm\bmO\bOP\bP_\b_I\bIN\bNI\bIT\bT.  For detailed information  refer
+                      to the documentation "_\bT_\bh_\be _\bC_\bo_\bm_\bb_\bo_\bB_\bo_\bx _\bW_\bi_\bd_\bg_\be_\bt".
+
+       _\bi_\bt_\be_\bm           During X\bXm\bmO\bOP\bP_\b_I\bIN\bNI\bIT\bT this field points  to  the
+                      item  to be added to the list. When sorting
+                      the list ( X\bXm\bmO\bOP\bP_\b_C\bCO\bOM\bMP\bPA\bAR\bRE\bE) the field contains
+                      the  address  of  an item in the list which
+                      should be compared against the new item (as
+                      remembered in _\bi_\bt_\be_\bm_\b__\bi_\bn_\bt_\be_\br_\bn_\ba_\bl).
+
+       _\br_\be_\bs_\bu_\bl_\bt         When comparing an item (out of the list) in
+                      _\bi_\bt_\be_\bm with the new item  (as  remembered  in
+                      _\bi_\bt_\be_\bm_\b__\bi_\bn_\bt_\be_\br_\bn_\ba_\bl)  the result has to be stored
+                      into this structure's field.
+
+       The following table describes  which  individual  callback
+       structure fields are valid during which operations.
+
+          R\bRe\bea\bas\bso\bon\bn               V\bVa\bal\bli\bid\bd F\bFi\bie\bel\bld\bds\bs
+       ---------------------------------------------
+       X\bXm\bmO\bOP\bP_\b_I\bIN\bNI\bIT\bT        _\br_\be_\ba_\bs_\bo_\bn, _\be_\bv_\be_\bn_\bt, _\bo_\bp_\be_\br_\ba_\bt_\bi_\bo_\bn,
+                        _\bi_\bt_\be_\bm, _\bi_\bt_\be_\bm_\b__\bi_\bn_\bt_\be_\br_\bn_\ba_\bl
+       X\bXm\bmO\bOP\bP_\b_D\bDO\bON\bNE\bE        _\br_\be_\ba_\bs_\bo_\bn, _\be_\bv_\be_\bn_\bt, _\bo_\bp_\be_\br_\ba_\bt_\bi_\bo_\bn,
+                        _\bi_\bt_\be_\bm_\b__\bi_\bn_\bt_\be_\br_\bn_\ba_\bl
+       X\bXm\bmO\bOP\bP_\b_C\bCO\bOM\bMP\bPA\bAR\bRE\bE     _\br_\be_\ba_\bs_\bo_\bn, _\be_\bv_\be_\bn_\bt, _\bo_\bp_\be_\br_\ba_\bt_\bi_\bo_\bn,
+                        _\bi_\bt_\be_\bm, _\bi_\bt_\be_\bm_\b__\bi_\bn_\bt_\be_\br_\bn_\ba_\bl, _\br_\be_\bs_\bu_\bl_\bt
+
+       For  more  information about controlling the sorting order
+       see the acompanying documentation "_\bT_\bh_\be _\bC_\bo_\bm_\bb_\bo_\bB_\bo_\bx _\bW_\bi_\bd_\bg_\be_\bt".
+
+     C\bCo\bon\bnv\bve\ben\bni\bie\ben\bnc\bce\be r\bro\bou\but\bti\bin\bne\bes\bs
+       ComboBox has a number of convenience routines  to  control
+
+
+
+Version 1.31              20 March 1995                        14
+
+
+
+
+
+XmComboBox(3Xm)        Harry's Motif Tools        XmComboBox(3Xm)
+
+
+       the behavior and contents of its children.
+
+       v\bvo\boi\bid\bd X\bXm\bmC\bCo\bom\bmb\bbo\boB\bBo\box\bxA\bAd\bdd\bdI\bIt\bte\bem\bm(\b(W\bWi\bid\bdg\bge\bet\bt w\bw,\b, X\bXm\bmS\bSt\btr\bri\bin\bng\bg i\bit\bte\bem\bm,\b, i\bin\bnt\bt p\bpo\bos\bs)\b)
+              Add a new item to the list's contents. If X\bXm\bmN\bNs\bso\bor\brt\bte\bed\bd
+              is set to True, the new item is inserted alphabeti-
+              cally.  If  the  list is unsorted, the same assump-
+              tions can be applied as with X\bXm\bmL\bLi\bis\bst\btA\bAd\bdd\bdI\bIt\bte\bem\bm.
+
+
+       v\bvo\boi\bid\bd   X\bXm\bmC\bCo\bom\bmb\bbo\boB\bBo\box\bxA\bAd\bdd\bdI\bIt\bte\bem\bms\bs(\b(W\bWi\bid\bdg\bge\bet\bt   w\bw,\b,   X\bXm\bmS\bSt\btr\bri\bin\bng\bg   *\b*i\bit\bte\bem\bms\bs,\b,
+              i\bin\bnt\bt i\bit\bte\bem\bm_\b_c\bco\bou\bun\bnt\bt,\b, i\bin\bnt\bt p\bpo\bos\bs)\b)
+              Similar to X\bXm\bmC\bCo\bom\bmb\bbo\boB\bBo\box\bxA\bAd\bdd\bdI\bIt\bte\bem\bm.  Also  see  X\bXm\bmL\bLi\bis\bst\btA\bAd\bd-\b-
+              d\bdI\bIt\bte\bem\bms\bs.
+
+
+       v\bvo\boi\bid\bd  X\bXm\bmC\bCo\bom\bmb\bbo\boB\bBo\box\bxA\bAd\bdd\bdI\bIt\bte\bem\bmU\bUn\bns\bse\bel\ble\bec\bct\bte\bed\bd(\b(W\bWi\bid\bdg\bge\bet\bt  w\bw,\b,  X\bXm\bmS\bSt\btr\bri\bin\bng\bg
+              i\bit\bte\bem\bm,\b, i\bin\bnt\bt p\bpo\bos\bs)\b)
+              See X\bXm\bmL\bLi\bis\bst\btA\bAd\bdd\bdI\bIt\bte\bem\bmU\bUn\bns\bse\bel\ble\bec\bct\bte\bed\bd.
+
+
+       v\bvo\boi\bid\bd X\bXm\bmC\bCo\bom\bmb\bbo\boB\bBo\box\bxC\bCl\ble\bea\bar\brI\bIt\bte\bem\bmS\bSe\bel\ble\bec\bct\bti\bio\bon\bn(\b(W\bWi\bid\bdg\bge\bet\bt w\bw)\b)
+              Deselects   all   currently   selected  items  when
+              X\bXm\bmN\bNs\bse\bel\ble\bec\bct\bti\bio\bon\bnP\bPo\bol\bli\bic\bcy\by is X\bXm\bmS\bSI\bIN\bNG\bGL\bLE\bE_\b_S\bSE\bEL\bLE\bEC\bCT\bT.
+
+
+       v\bvo\boi\bid\bd X\bXm\bmC\bCo\bom\bmb\bbo\boB\bBo\box\bxD\bDe\bel\ble\bet\bte\beI\bIt\bte\bem\bm(\b(W\bWi\bid\bdg\bge\bet\bt w\bw,\b, X\bXm\bmS\bSt\btr\bri\bin\bng\bg i\bit\bte\bem\bm)\b)
+              See X\bXm\bmL\bLi\bis\bst\btD\bDe\bel\ble\bet\bte\beI\bIt\bte\bem\bm.
+
+
+       v\bvo\boi\bid\bd  X\bXm\bmC\bCo\bom\bmb\bbo\boB\bBo\box\bxD\bDe\bel\ble\bet\bte\beI\bIt\bte\bem\bms\bs(\b(W\bWi\bid\bdg\bge\bet\bt  w\bw,\b,   X\bXm\bmS\bSt\btr\bri\bin\bng\bg
+              *\b*i\bit\bte\bem\bms\bs,\b,   i\bin\bnt\bt i\bit\bte\bem\bm_\b_c\bco\bou\bun\bnt\bt)\b)
+              See X\bXm\bmL\bLi\bis\bst\btD\bDe\bel\ble\bet\bte\beI\bIt\bte\bem\bms\bs.
+
+
+       v\bvo\boi\bid\bd X\bXm\bmC\bCo\bom\bmb\bbo\boB\bBo\box\bxD\bDe\bel\ble\bet\bte\beP\bPo\bos\bs(\b(W\bWi\bid\bdg\bge\bet\bt w\bw,\b, i\bin\bnt\bt p\bpo\bos\bs)\b)
+              See X\bXm\bmL\bLi\bis\bst\btD\bDe\bel\ble\bet\bte\beP\bPo\bos\bs.
+
+
+       v\bvo\boi\bid\bd X\bXm\bmC\bCo\bom\bmb\bbo\boB\bBo\box\bxD\bDe\bel\ble\bet\bte\beI\bIt\bte\bem\bms\bsP\bPo\bos\bs(\b(W\bWi\bid\bdg\bge\bet\bt w\bw,\b, i\bin\bnt\bt i\bit\bte\bem\bm_\b_c\bco\bou\bun\bnt\bt,\b,
+              i\bin\bnt\bt p\bpo\bos\bs)\b)
+              See X\bXm\bmL\bLi\bis\bst\btD\bDe\bel\ble\bet\bte\beI\bIt\bte\bem\bms\bsP\bPo\bos\bs.
+
+
+       v\bvo\boi\bid\bd X\bXm\bmC\bCo\bom\bmb\bbo\boB\bBo\box\bxD\bDe\bel\ble\bet\bte\beA\bAl\bll\blI\bIt\bte\bem\bms\bs(\b(W\bWi\bid\bdg\bge\bet\bt w\bw)\b)
+              See X\bXm\bmL\bLi\bis\bst\btD\bDe\bel\ble\bet\bte\beA\bAl\bll\blI\bIt\bte\bem\bms\bs.
+
+
+       v\bvo\boi\bid\bd  X\bXm\bmC\bCo\bom\bmb\bbo\boB\bBo\box\bxR\bRe\bep\bpl\bla\bac\bce\beI\bIt\bte\bem\bms\bs(\b(W\bWi\bid\bdg\bge\bet\bt  w\bw,\b,  X\bXm\bmS\bSt\btr\bri\bin\bng\bg
+              *\b*o\bol\bld\bd_\b_i\bit\bte\bem\bms\bs,\b, i\bin\bnt\bt i\bit\bte\bem\bm_\b_c\bco\bou\bun\bnt\bt,\b, X\bXm\bmS\bSt\btr\bri\bin\bng\bg *\b*n\bne\bew\bw_\b_i\bit\bte\bem\bms\bs)\b)
+              See X\bXm\bmL\bLi\bis\bst\btR\bRe\bep\bpl\bla\bac\bce\beI\bIt\bte\bem\bms\bs.
+
+
+       v\bvo\boi\bid\bd X\bXm\bmC\bCo\bom\bmb\bbo\boB\bBo\box\bxR\bRe\bep\bpl\bla\bac\bce\beI\bIt\bte\bem\bms\bsP\bPo\bos\bs(\b(W\bWi\bid\bdg\bge\bet\bt w\bw,\b, X\bXm\bmS\bSt\btr\bri\bin\bng\bg
+              *\b*n\bne\bew\bw_\b_i\bit\bte\bem\bms\bs,\b, i\bin\bnt\bt i\bit\bte\bem\bm_\b_c\bco\bou\bun\bnt\bt,\b, i\bin\bnt\bt p\bpo\bos\bsi\bit\bti\bio\bon\bn)\b)
+
+
+
+Version 1.31              20 March 1995                        15
+
+
+
+
+
+XmComboBox(3Xm)        Harry's Motif Tools        XmComboBox(3Xm)
+
+
+              See X\bXm\bmL\bLi\bis\bst\btR\bRe\bep\bpl\bla\bac\bce\beI\bIt\bte\bem\bms\bsP\bPo\bos\bs.
+
+
+       B\bBo\boo\bol\ble\bea\ban\bn X\bXm\bmC\bCo\bom\bmb\bbo\boB\bBo\box\bxI\bIt\bte\bem\bmE\bEx\bxi\bis\bst\bts\bs(\b(W\bWi\bid\bdg\bge\bet\bt w\bw,\b, X\bXm\bmS\bSt\btr\bri\bin\bng\bg i\bit\bte\bem\bm)\b)
+              See X\bXm\bmL\bLi\bis\bst\btI\bIt\bte\bem\bmE\bEx\bxi\bis\bst\bts\bs.
+
+
+       i\bin\bnt\bt X\bXm\bmC\bCo\bom\bmb\bbo\boB\bBo\box\bxI\bIt\bte\bem\bmP\bPo\bos\bs(\b(W\bWi\bid\bdg\bge\bet\bt w\bw,\b, X\bXm\bmS\bSt\btr\bri\bin\bng\bg i\bit\bte\bem\bm)\b)
+              See X\bXm\bmL\bLi\bis\bst\btI\bIt\bte\bem\bmP\bPo\bos\bs.
+
+
+       B\bBo\boo\bol\ble\bea\ban\bn   X\bXm\bmC\bCo\bom\bmb\bbo\boB\bBo\box\bxG\bGe\bet\btM\bMa\bat\btc\bch\bhP\bPo\bos\bs(\b(W\bWi\bid\bdg\bge\bet\bt   w\bw,\b,  X\bXm\bmS\bSt\btr\bri\bin\bng\bg
+              i\bit\bte\bem\bm,\b,  i\bin\bnt\bt *\b**\b*p\bpo\bos\bs_\b_l\bli\bis\bst\bt,\b, i\bin\bnt\bt *\b*p\bpo\bos\bs_\b_c\bco\bou\bun\bnt\bt)\b)
+              See X\bXm\bmL\bLi\bis\bst\btG\bGe\bet\btM\bMa\bat\btc\bch\bhP\bPo\bos\bs.
+
+
+       v\bvo\boi\bid\bd X\bXm\bmC\bCo\bom\bmb\bbo\boB\bBo\box\bxS\bSe\bel\ble\bec\bct\btP\bPo\bos\bs(\b(W\bWi\bid\bdg\bge\bet\bt w\bw,\b, i\bin\bnt\bt p\bpo\bos\bs,\b, B\bBo\boo\bol\ble\bea\ban\bn
+              n\bno\bot\bti\bif\bfy\by)\b)
+              See X\bXm\bmL\bLi\bis\bst\btS\bSe\bel\ble\bec\bct\btP\bPo\bos\bs.
+
+
+       v\bvo\boi\bid\bd  X\bXm\bmC\bCo\bom\bmb\bbo\boB\bBo\box\bxS\bSe\bel\ble\bec\bct\btI\bIt\bte\bem\bm(\b(W\bWi\bid\bdg\bge\bet\bt  w\bw,\b,  X\bXm\bmS\bSt\btr\bri\bin\bng\bg   i\bit\bte\bem\bm,\b,
+              B\bBo\boo\bol\ble\bea\ban\bn n\bno\bot\bti\bif\bfy\by)\b)
+              See X\bXm\bmL\bLi\bis\bst\btS\bSe\bel\ble\bec\bct\btI\bIt\bte\bem\bm.
+
+
+       i\bin\bnt\bt X\bXm\bmC\bCo\bom\bmb\bbo\boB\bBo\box\bxG\bGe\bet\btS\bSe\bel\ble\bec\bct\bte\bed\bdP\bPo\bos\bs(\b(W\bWi\bid\bdg\bge\bet\bt w\bw)\b)
+              This function  differs  from  X\bXm\bmL\bLi\bis\bst\btG\bGe\bet\btS\bSe\bel\ble\bec\bct\bte\bed\bdP\bPo\bos\bs.
+              The  list  in  a  combo  box  can  contain only one
+              selected item. Therefore this function returns  the
+              index  of the selected item in the list or zero, if
+              none is currently selected.
+
+
+       v\bvo\boi\bid\bd X\bXm\bmC\bCo\bom\bmb\bbo\boB\bBo\box\bxC\bCl\ble\bea\bar\brS\bSe\bel\ble\bec\bct\bti\bio\bon\bn(\b(W\bWi\bid\bdg\bge\bet\bt w\bw,\b, T\bTi\bim\bme\be t\bti\bim\bme\be)\b)
+              See X\bXm\bmT\bTe\bex\bxt\btF\bFi\bie\bel\bld\bdC\bCl\ble\bea\bar\brS\bSe\bel\ble\bec\bct\bti\bio\bon\bn.
+
+
+       B\bBo\boo\bol\ble\bea\ban\bn X\bXm\bmC\bCo\bom\bmb\bbo\boB\bBo\box\bxC\bCo\bop\bpy\by(\b(W\bWi\bid\bdg\bge\bet\bt w\bw,\b, T\bTi\bim\bme\be t\bti\bim\bme\be)\b)
+              See X\bXm\bmT\bTe\bex\bxt\btF\bFi\bie\bel\bld\bdC\bCo\bop\bpy\by.
+
+
+       B\bBo\boo\bol\ble\bea\ban\bn X\bXm\bmC\bCo\bom\bmb\bbo\boB\bBo\box\bxC\bCu\but\bt(\b(W\bWi\bid\bdg\bge\bet\bt w\bw,\b, T\bTi\bim\bme\be t\bti\bim\bme\be)\b)
+              See X\bXm\bmT\bTe\bex\bxt\btF\bFi\bie\bel\bld\bdC\bCu\but\bt.
+
+
+       X\bXm\bmT\bTe\bex\bxt\btP\bPo\bos\bsi\bit\bti\bio\bon\bn X\bXm\bmC\bCo\bom\bmb\bbo\boB\bBo\box\bxG\bGe\bet\btI\bIn\bns\bse\ber\brt\bti\bio\bon\bnP\bPo\bos\bsi\bit\bti\bio\bon\bn(\b(W\bWi\bid\bdg\bge\bet\bt w\bw)\b)
+              See X\bXm\bmT\bTe\bex\bxt\btF\bFi\bie\bel\bld\bdG\bGe\bet\btI\bIn\bns\bse\ber\brt\bti\bio\bon\bnP\bPo\bos\bsi\bit\bti\bio\bon\bn.
+
+
+       X\bXm\bmT\bTe\bex\bxt\btP\bPo\bos\bsi\bit\bti\bio\bon\bn X\bXm\bmC\bCo\bom\bmb\bbo\boB\bBo\box\bxG\bGe\bet\btL\bLa\bas\bst\btP\bPo\bos\bsi\bit\bti\bio\bon\bn(\b(W\bWi\bid\bdg\bge\bet\bt w\bw)\b)
+              See X\bXm\bmT\bTe\bex\bxt\btF\bFi\bie\bel\bld\bdG\bGe\bet\btL\bLa\bas\bst\btP\bPo\bos\bsi\bit\bti\bio\bon\bn.
+
+
+
+
+
+Version 1.31              20 March 1995                        16
+
+
+
+
+
+XmComboBox(3Xm)        Harry's Motif Tools        XmComboBox(3Xm)
+
+
+       i\bin\bnt\bt X\bXm\bmC\bCo\bom\bmb\bbo\boB\bBo\box\bxG\bGe\bet\btM\bMa\bax\bxL\bLe\ben\bng\bgt\bth\bh(\b(W\bWi\bid\bdg\bge\bet\bt w\bw)\b)
+              See X\bXm\bmT\bTe\bex\bxt\btF\bFi\bie\bel\bld\bdG\bGe\bet\btM\bMa\bax\bxL\bLe\ben\bng\bgt\bth\bh.
+
+
+       c\bch\bha\bar\br *\b*X\bXm\bmC\bCo\bom\bmb\bbo\boB\bBo\box\bxG\bGe\bet\btS\bSe\bel\ble\bec\bct\bti\bio\bon\bn(\b(W\bWi\bid\bdg\bge\bet\bt w\bw)\b)
+              See X\bXm\bmT\bTe\bex\bxt\btF\bFi\bie\bel\bld\bdG\bGe\bet\btS\bSe\bel\ble\bec\bct\bti\bio\bon\bn.
+
+
+       B\bBo\boo\bol\ble\bea\ban\bn X\bXm\bmC\bCo\bom\bmb\bbo\boB\bBo\box\bxG\bGe\bet\btS\bSe\bel\ble\bec\bct\bti\bio\bon\bnP\bPo\bos\bsi\bit\bti\bio\bon\bn(\b(W\bWi\bid\bdg\bge\bet\bt  w\bw,\b,
+              X\bXm\bmT\bTe\bex\bxt\btP\bPo\bos\bsi\bit\bti\bio\bon\bn *\b*l\ble\bef\bft\bt,\b, X\bXm\bmT\bTe\bex\bxt\btP\bPo\bos\bsi\bit\bti\bio\bon\bn *\b*r\bri\big\bgh\bht\bt)\b)
+              See X\bXm\bmT\bTe\bex\bxt\btF\bFi\bie\bel\bld\bdG\bGe\bet\btS\bSe\bel\ble\bec\bct\bti\bio\bon\bnP\bPo\bos\bsi\bit\bti\bio\bon\bn.
+
+
+       c\bch\bha\bar\br *\b*X\bXm\bmC\bCo\bom\bmb\bbo\boB\bBo\box\bxG\bGe\bet\btS\bSt\btr\bri\bin\bng\bg(\b(W\bWi\bid\bdg\bge\bet\bt w\bw)\b)
+              See X\bXm\bmT\bTe\bex\bxt\btF\bFi\bie\bel\bld\bdG\bGe\bet\btS\bSt\btr\bri\bin\bng\bg.
+
+
+       v\bvo\boi\bid\bd X\bXm\bmC\bCo\bom\bmb\bbo\boB\bBo\box\bxI\bIn\bns\bse\ber\brt\bt(\b(W\bWi\bid\bdg\bge\bet\bt  w\bw,\b,  X\bXm\bmT\bTe\bex\bxt\btP\bPo\bos\bsi\bit\bti\bio\bon\bn
+              p\bpo\bos\bsi\bit\bti\bio\bon\bn,\b,  c\bch\bha\bar\br *\b*v\bva\bal\blu\bue\be)\b)
+              See X\bXm\bmT\bTe\bex\bxt\btF\bFi\bie\bel\bld\bdI\bIn\bns\bse\ber\brt\bt.
+
+
+       B\bBo\boo\bol\ble\bea\ban\bn X\bXm\bmC\bCo\bom\bmb\bbo\boB\bBo\box\bxP\bPa\bas\bst\bte\be(\b(W\bWi\bid\bdg\bge\bet\bt w\bw)\b)
+              See X\bXm\bmT\bTe\bex\bxt\btF\bFi\bie\bel\bld\bdP\bPa\bas\bst\bte\be.
+
+
+       B\bBo\boo\bol\ble\bea\ban\bn X\bXm\bmC\bCo\bom\bmb\bbo\boB\bBo\box\bxR\bRe\bem\bmo\bov\bve\be(\b(W\bWi\bid\bdg\bge\bet\bt w\bw)\b)
+              See X\bXm\bmT\bTe\bex\bxt\btF\bFi\bie\bel\bld\bdR\bRe\bem\bmo\bov\bve\be.
+
+
+       v\bvo\boi\bid\bd   X\bXm\bmC\bCo\bom\bmb\bbo\boB\bBo\box\bxR\bRe\bep\bpl\bla\bac\bce\be(\b(W\bWi\bid\bdg\bge\bet\bt   w\bw,\b,   X\bXm\bmT\bTe\bex\bxt\btP\bPo\bos\bsi\bit\bti\bio\bon\bn
+              f\bfr\bro\bom\bm_\b_p\bpo\bos\bs,\b, X\bXm\bmT\bTe\bex\bxt\btP\bPo\bos\bsi\bit\bti\bio\bon\bn t\bto\bo_\b_p\bpo\bos\bs,\b, c\bch\bha\bar\br *\b*v\bva\bal\blu\bue\be)\b)
+              See X\bXm\bmT\bTe\bex\bxt\btF\bFi\bie\bel\bld\bdR\bRe\bep\bpl\bla\bac\bce\be.
+
+
+       v\bvo\boi\bid\bd X\bXm\bmC\bCo\bom\bmb\bbo\boB\bBo\box\bxS\bSe\bet\btA\bAd\bdd\bdM\bMo\bod\bde\be(\b(W\bWi\bid\bdg\bge\bet\bt w\bw,\b, B\bBo\boo\bol\ble\bea\ban\bn s\bst\bta\bat\bte\be)\b)
+              See X\bXm\bmT\bTe\bex\bxt\btF\bFi\bie\bel\bld\bdS\bSe\bet\btA\bAd\bdd\bdM\bMo\bod\bde\be.
+
+
+       v\bvo\boi\bid\bd  X\bXm\bmC\bCo\bom\bmb\bbo\boB\bBo\box\bxS\bSe\bet\btH\bHi\big\bgh\bhl\bli\big\bgh\bht\bt(\b(W\bWi\bid\bdg\bge\bet\bt   w\bw,\b,   X\bXm\bmT\bTe\bex\bxt\btP\bPo\bos\bsi\bit\bti\bio\bon\bn
+              l\ble\bef\bft\bt,\b, X\bXm\bmT\bTe\bex\bxt\btP\bPo\bos\bsi\bit\bti\bio\bon\bn r\bri\big\bgh\bht\bt,\b, X\bXm\bmH\bHi\big\bgh\bhl\bli\big\bgh\bht\btM\bMo\bod\bde\be m\bmo\bod\bde\be)\b)
+              See X\bXm\bmT\bTe\bex\bxt\btF\bFi\bie\bel\bld\bdS\bSe\bet\btH\bHi\big\bgh\bhl\bli\big\bgh\bht\bt.
+
+
+       v\bvo\boi\bid\bd  X\bXm\bmC\bCo\bom\bmb\bbo\boB\bBo\box\bxS\bSe\bet\btI\bIn\bns\bse\ber\brt\bti\bio\bon\bnP\bPo\bos\bsi\bit\bti\bio\bon\bn(\b(W\bWi\bid\bdg\bge\bet\bt   w\bw,\b,
+              X\bXm\bmT\bTe\bex\bxt\btP\bPo\bos\bsi\bit\bti\bio\bon\bn p\bpo\bos\bsi\bit\bti\bio\bon\bn)\b)
+              See X\bXm\bmT\bTe\bex\bxt\btF\bFi\bie\bel\bld\bdS\bSe\bet\btI\bIn\bns\bse\ber\brt\bti\bio\bon\bnP\bPo\bos\bsi\bit\bti\bio\bon\bn.
+
+
+       v\bvo\boi\bid\bd X\bXm\bmC\bCo\bom\bmb\bbo\boB\bBo\box\bxS\bSe\bet\btM\bMa\bax\bxL\bLe\ben\bng\bgt\bth\bh(\b(W\bWi\bid\bdg\bge\bet\bt w\bw,\b, i\bin\bnt\bt m\bma\bax\bx_\b_l\ble\ben\bng\bgt\bth\bh)\b)
+              See X\bXm\bmT\bTe\bex\bxt\btF\bFi\bie\bel\bld\bdS\bSe\bet\btM\bMa\bax\bxL\bLe\ben\bng\bgt\bth\bh.
+
+
+
+
+
+
+Version 1.31              20 March 1995                        17
+
+
+
+
+
+XmComboBox(3Xm)        Harry's Motif Tools        XmComboBox(3Xm)
+
+
+       v\bvo\boi\bid\bd  X\bXm\bmC\bCo\bom\bmb\bbo\boB\bBo\box\bxS\bSe\bet\btS\bSe\bel\ble\bec\bct\bti\bio\bon\bn(\b(W\bWi\bid\bdg\bge\bet\bt  w\bw,\b,   X\bXm\bmT\bTe\bex\bxt\btP\bPo\bos\bsi\bit\bti\bio\bon\bn
+              f\bfi\bir\brs\bst\bt,\b, X\bXm\bmT\bTe\bex\bxt\btP\bPo\bos\bsi\bit\bti\bio\bon\bn l\bla\bas\bst\bt,\b, T\bTi\bim\bme\be t\bti\bim\bme\be)\b)
+              See X\bXm\bmT\bTe\bex\bxt\btF\bFi\bie\bel\bld\bdS\bSe\bet\btS\bSe\bel\ble\bec\bct\bti\bio\bon\bn.
+
+
+       v\bvo\boi\bid\bd X\bXm\bmC\bCo\bom\bmb\bbo\boB\bBo\box\bxS\bSe\bet\btS\bSt\btr\bri\bin\bng\bg(\b(W\bWi\bid\bdg\bge\bet\bt w\bw,\b, c\bch\bha\bar\br *\b*v\bva\bal\blu\bue\be)\b)
+              At least Motif 1.1 contains a very anoying bug.  If
+              you try to set the contents of an XmTextField to an
+              empty string (""), you'll get garbage, when  asking
+              the  XmTextField  for its contents afterwards. This
+              interface function provides a work around. Also see
+              X\bXm\bmT\bTe\bex\bxt\btF\bFi\bie\bel\bld\bdS\bSe\bet\btS\bSt\btr\bri\bin\bng\bg.
+
+
+       v\bvo\boi\bid\bd X\bXm\bmC\bCo\bom\bmb\bbo\boB\bBo\box\bxS\bSh\bho\bow\bwP\bPo\bos\bsi\bit\bti\bio\bon\bn(\b(W\bWi\bid\bdg\bge\bet\bt w\bw,\b, X\bXm\bmT\bTe\bex\bxt\btP\bPo\bos\bsi\bit\bti\bio\bon\bn p\bpo\bos\bsi\bi-\b-
+              t\bti\bio\bon\bn)\b)
+              See X\bXm\bmT\bTe\bex\bxt\btF\bFi\bie\bel\bld\bdS\bSh\bho\bow\bwP\bPo\bos\bsi\bit\bti\bio\bon\bn.
+
+
+     T\bTh\bhe\be D\bDi\bis\bsl\bli\bik\bke\bed\bd K\bKe\bey\byb\bbo\boa\bar\brd\bd F\bFo\boc\bcu\bus\bs
+       Now I'll  annotate  a  somewhat  tricky  subject.  If  the
+       resource  X\bXm\bmN\bNp\bpe\ber\brs\bsi\bis\bst\bte\ben\bnt\btD\bDr\bro\bop\bpD\bDo\bow\bwn\bn  defaults  to  its initial
+       value of F\bFa\bal\bls\bse\be, one can observe the following effect (this
+       may be annoying).
+
+       When the user drops down the list and then moves the mouse
+       cursor out of the window where the combo box  resides  in,
+       the  list  will be hidden. This is because the widget lost
+       the keyboard focus. Some users are irritated because  they
+       didn't  expect  that behavior, because they just moved the
+       mouse to get it out of the way. If your  window  manager's
+       focus  policy  is  "pointer  focus", i.e.  if you move the
+       pointer into another window, that  window  will  automati-
+       cally  get  the keyboard focus. On the other hand, if your
+       window manager's focus policy is "explicit", you  have  to
+       move  the  pointer  into  another window and click a mouse
+       button to give that window the  keyboard  focus.  This  is
+       often  referred  to  as  the  "click-to-type"  method.  In
+       "explicit" mode, you will never see  the  list's  annoying
+       behavior.
+
+       To  bypass  this behavior on some window managers a really
+       dirty hack was used. The user can activate that  hack,  if
+       he sets X\bXm\bmN\bNp\bpe\ber\brs\bsi\bis\bst\bte\ben\bnt\btD\bDr\bro\bop\bpD\bDo\bow\bwn\bn to T\bTr\bru\bue\be in the application's
+       resources. Sorry, on some window managers  this  will  not
+       fix the annoying behavior.
+
+       Try  it  if  you  like  -  but  don't complain at me if it
+       doesn't work as expected. But at least it  worked  on  the
+       author's machine: a cute little SGI Indigo running 4dwm as
+       the window manager.
+
+       On some other window  managers  like  twm  you  will  face
+       another problem: the list gets hidden as soon as the mouse
+
+
+
+Version 1.31              20 March 1995                        18
+
+
+
+
+
+XmComboBox(3Xm)        Harry's Motif Tools        XmComboBox(3Xm)
+
+
+       cursor enters the list. Try  to  set  X\bXm\bmN\bNt\btw\bwm\bmH\bHa\ban\bnd\bdl\bli\bin\bng\bgO\bOn\bn  to
+       T\bTr\bru\bue\be.  This resource will also work with other window man-
+       agers.
+
+
+     C\bCr\bre\bea\bat\bti\bin\bng\bg a\ba C\bCo\bom\bmb\bbo\boB\bBo\box\bx
+       Using the combo box in your own  programs  is  easy.  Just
+       create  the  widget  with one of the innumerable X toolkit
+       functions (like  X\bXt\btC\bCr\bre\bea\bat\bte\beM\bMa\ban\bna\bag\bge\bed\bdW\bWi\bid\bdg\bge\bet\bt  or  X\bXt\btV\bVa\baC\bCr\bre\bea\bat\bte\beM\bMa\ban\bn-\b-
+       a\bag\bge\bed\bdW\bWi\bid\bdg\bge\bet\bt).
+
+
+       Specify as the widget class xmComboBoxWidgetClass - that's
+       all. There is also a so-called creation convenience  func-
+       tion  called X\bXm\bmC\bCr\bre\bea\bat\bte\beC\bCo\bom\bmb\bbo\boB\bBo\box\bx, but it isn't really needed.
+
+       W\bWi\bid\bdg\bge\bet\bt X\bXm\bmC\bCr\bre\bea\bat\bte\beC\bCo\bom\bmb\bbo\boB\bBo\box\bx(\b(_\bp_\ba_\br_\be_\bn_\bt_\b, _\bn_\ba_\bm_\be_\b, _\ba_\br_\bg_\bl_\bi_\bs_\bt_\b, _\ba_\br_\bg_\bc_\bo_\bu_\bn_\bt)\b)
+         W\bWi\bid\bdg\bge\bet\bt         _\bp_\ba_\br_\be_\bn_\bt;
+         S\bSt\btr\bri\bin\bng\bg         _\bn_\ba_\bm_\be;
+         A\bAr\brg\bgL\bLi\bis\bst\bt        _\ba_\br_\bg_\bl_\bi_\bs_\bt;
+         C\bCa\bar\brd\bdi\bin\bna\bal\bl       _\ba_\br_\bg_\bc_\bo_\bu_\bn_\bt;
+
+       Somewhere in your program you'll need something  like  the
+       following code fragment:
+
+
+            Widget ComboBox;
+
+            ComboBox = XtVaCreateManagedWidget("combobox",
+                           xmComboBoxWidgetClass, Parent,
+                           XmNeditable, True or False,
+                           other Resources...
+                           NULL);
+
+
+       Setting  the resource X\bXm\bmN\bNe\bed\bdi\bit\bta\bab\bbl\ble\be is not absolutely neces-
+       sary, but it's better to do so.
+
+       After creation, items can be added to the combo box's list
+       by   means   of  interface  functions  like  X\bXm\bmC\bCo\bom\bmb\bbo\boB\bBo\box\bxA\bAd\bd-\b-
+       d\bdI\bIt\bte\bem\bm(\b(.\b..\b..\b.)\b).  Which item the user selected  can  be  deter-
+       mined by calling X\bXm\bmC\bCo\bom\bmb\bbo\boB\bBo\box\bxG\bGe\bet\btS\bSt\btr\bri\bin\bng\bg(\b(.\b..\b..\b.)\b).
+
+
+       If  you  want  to  preselect  an  item  (that is setting a
+       default item to the input field of the combo box) you  can
+       use  several convenience functions.  On a combo box with a
+       non editable input field there are two ways to  select  an
+       item:
+
+
+            XmComboBoxSelectPos(ComboBox, item #, False);
+
+       or:
+
+
+
+Version 1.31              20 March 1995                        19
+
+
+
+
+
+XmComboBox(3Xm)        Harry's Motif Tools        XmComboBox(3Xm)
+
+
+            XmComboBoxSelectItem(ComboBox, itemString, False);
+
+       The  third parameter in these two function calls indicates
+       whether the X\bXm\bmN\bNs\bse\bel\ble\bec\bct\bti\bio\bon\bnC\bCa\bal\bll\blb\bba\bac\bck\bk  should  be  called.  The
+       only  difference  between these functions is the first one
+       is expecting an item number whereas the second one expects
+       a  XmString. The list is then searched for this string and
+       if it is found the input field will be updated.
+
+       On a combo box with X\bXm\bmN\bNe\bed\bdi\bit\bta\bab\bbl\ble\be set to  T\bTr\bru\bue\be  use  another
+       function:
+
+            XmComboBoxSetString(ComboBox, string);
+
+       This  sets the contents of the text input field to string.
+
+
+
+B\bBU\bUG\bGS\bS
+       Not more than currently available in Motif 1.2.3 or  Motif
+       1.2.4,  but  less  than in the upcomming Motif 2.0. Report
+       bugs to albrecht@igpm.rwth-aachen.de. Include a thoroughly
+       description,  and say which version of the ComboBox widget
+       you are using.
+
+
+
+C\bCO\bOP\bPY\bYR\bRI\bIG\bGH\bHT\bT
+       Copyright 1993, 1994 Harald Albrecht.
+
+       The ComboBox widget is free software; you can redistribute
+       it  and/or  modify  it  under the terms of the GNU General
+       Public License as published by the Free  Software  Founda-
+       tion; either version 2, or (at your option) any later ver-
+       sion.
+
+
+
+A\bAV\bVA\bAI\bIL\bLA\bAB\bBI\bIL\bLI\bIT\bTY\bY
+       The most recent released version of the ComboBox widget is
+       always available for anonymous ftp from either
+
+              ftp.x.org (198.112.44.100)
+              /contrib/widgets/motif/ComboBox
+
+       or from
+
+              ftp.informatik.rwth-aachen.de (137.226.112.172)
+              /pub/packages/ComboBox
+
+
+
+A\bAU\bUT\bTH\bHO\bOR\bR
+       Author of Software & Documentation:
+
+
+
+Version 1.31              20 March 1995                        20
+
+
+
+
+
+XmComboBox(3Xm)        Harry's Motif Tools        XmComboBox(3Xm)
+
+
+              Harald Albrecht
+              Institut fuer Geometrie und Praktische Mathematik
+              RWTH Aachen, Bundesrepublik Deutschland
+              e-mail: albrecht@igpm.rwth-aachen.de
+
+       English Documentation:
+              Chris Marotz
+              Sterling Software ITD
+              e-mail: marotz@itd.sterling.com
+
+
+
+R\bRE\bEL\bLA\bAT\bTE\bED\bD I\bIN\bNF\bFO\bOR\bRM\bMA\bAT\bTI\bIO\bON\bN
+       "_\bT_\bh_\be _\bC_\bo_\bm_\bb_\bo_\bB_\bo_\bx _\bW_\bi_\bd_\bg_\be_\bt" documentation
+       C\bCo\bor\bre\be(\b(3\b3X\bX)\b), X\bXm\bmC\bCo\bom\bmp\bpo\bos\bsi\bit\bte\be(\b(3\b3X\bX)\b), X\bXm\bmL\bLi\bis\bst\bt(\b(3\b3X\bX)\b),  X\bXm\bmT\bTe\bex\bxt\btF\bFi\bie\bel\bld\bd(\b(3\b3X\bX)\b)
+       _\bD_\bo_\bu_\bg_\bl_\ba_\bs _\bA_\bd_\ba_\bm_\bs_\b: _\bT_\bh_\be _\bH_\bi_\bt_\bc_\bh_\bh_\bi_\bk_\be_\br_\b'_\bs _\bG_\bu_\bi_\bd_\be _\bt_\bo _\bt_\bh_\be _\bG_\ba_\bl_\ba_\bx_\by_\b.
+       f\bfi\bil\ble\be:\b:/\b//\b/1\b13\b34\b4.\b.1\b13\b30\b0.\b.1\b16\b61\b1.\b.3\b30\b0/\b/a\bar\brc\bc/\b/p\bpu\bub\bb/\b/u\bun\bni\bix\bx/\b/h\bht\btm\bml\bl/\b/m\bmo\bot\bti\bif\bfc\bco\bor\brn\bne\ber\br.\b.h\bht\btm\bml\bl
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Version 1.31              20 March 1995                        21
+
+
diff --git a/src/motif/xmcombo/combop.h b/src/motif/xmcombo/combop.h
new file mode 100644 (file)
index 0000000..3e1c859
--- /dev/null
@@ -0,0 +1,131 @@
+/*
+ * ComboBoxP.h - Das schon lange schmerzlich vermisste Combo-Box-
+ *               Widget -- nun endlich auf fuer Motif!
+ *               Wahlweise Motif 1.1 oder 1.2.
+ * 
+ * Letzte Modifikation: 04.10.1995    Revisionsstand: 1.32a
+ * 
+ * (c) 1993, 1994 Harald Albrecht
+ * Institut fuer Geometrie und Praktische Mathematik
+ * RWTH Aachen, Germany
+ * albrecht@igpm.rwth-aachen.de
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program (see the file COPYING for more details);
+ * if not, write to the Free Software Foundation, Inc., 675 Mass Ave, 
+ * Cambridge, MA 02139, USA.
+ *
+ */
+#ifndef __ComboBoxWidgetP_h
+#define __ComboBoxWidgetP_h
+
+#include "xmcombo.h"
+#include <Xm/XmP.h>
+#if (XmVersion > 1001) /* sounds like tales from 1000 and 1 night.... */
+#include <Xm/ManagerP.h>
+#endif
+
+/*********************************************************************
+ * Klassendefinition
+ *********************************************************************/
+/* Neue Datenfelder fuer den Klassenrecord der Center-Widgetklasse */
+typedef struct _XmComboBoxClassPart {
+    int Just_to_keep_the_compiler_happy; /* Der Name ist Programm */
+} XmComboBoxClassPart;
+/*
+ * Nun folgt die vollstaendige Klassenstruktur, mit all' den Felder,
+ * die bereits von den Vorfahren geerbt wurden.
+ */
+typedef struct _XmComboBoxClassRec {
+    CoreClassPart       core_class;
+    CompositeClassPart  composite_class;
+    ConstraintClassPart constraint_class;
+    XmManagerClassPart  manager_class;
+    XmComboBoxClassPart combobox_class;
+} XmComboBoxClassRec;
+extern XmComboBoxClassRec xmComboBoxClassRec;
+
+/*********************************************************************
+ *Instanzdefinition
+ *********************************************************************/
+typedef struct _XmComboBoxPart {
+/* Resourcen ... hierauf darf von aussen zugegriffen werden! */
+    Boolean        Editable;           /* Editierbare Eingabezeile ? */
+    Boolean        StaticList;         /* Liste immer dargestellt?   */
+    unsigned char   SelectionPolicy;   /* Was geht hier ab?!         */
+    unsigned char   ScrollBarDisplayPolicy;
+    unsigned char   ListSizePolicy;    /* Rollbalken!                */
+    Boolean        AutomaticSelection; /* Wann Callbacks aufrufen?   */
+    Boolean        Sorted;             /* Liste sortiert             */
+    XtCallbackList  SortingCBL;                /* Wie wird extern sortiert?  */
+    int                    VisibleItemCount;   /* Anz dargstellte Eintraege  */
+    XmFontList     Font;               /* verwendete Fonts           */
+    XtCallbackList  SelectionCBL;       /* Auswahl aus Liste          */
+    XtCallbackList  UnselectionCBL;    /* Auswahl zurueckgenommen    */
+    XtCallbackList  DefaultActionCBL;  /* bei Doppelklick            */
+    XtCallbackList  DropDownCBL;        /* Liste angezeigt/versteckt  */
+    XtCallbackList  ModifyVerifyCBL;   /* Vor Aenderung im Textfeld  */
+    XtCallbackList  ValueChangedCBL;   /* Danach...                  */
+    XtCallbackList  MotionVerifyCBL;   /* Der Cursor bewegt sich doch*/
+    XtCallbackList  ActivateCBL;       /* Eingabe beendet?           */
+    Boolean         SquareArrow;        /* Quadratischer Pfeil?       */
+    Boolean         ArrowSpacingOn;     /* Abstand zw. Pfeil und Text */
+    Boolean        Persistent;         /* Liste & Focus-Out          */
+    Boolean        TwmHandlingOn;      /* dto.                       */
+    Boolean        ShowLabel;          /* Label anzeigen?            */
+    Position       DropDownOffset;     /* delta Ecke Eingabefeld,
+                                                 Liste                */
+    
+/* Ab hier wird's privat! */
+    Widget         EditCtrl;   /* Editorzeile */
+    Widget         ArrowCtrl;  /* Pfeil nach unten */
+    Widget         LabelCtrl;  /* Text links neben dem Eingabefeld */
+    
+    Widget         PopupShell; /* Shell, in der die Liste liegt */
+    Widget         ListCtrl;   /* Listenfeld */
+
+    Widget         MyNextShell;
+    
+    Cursor          ArrowCursor;
+    Boolean         InInit;
+    
+    int                    LastSelection;
+
+    Boolean         ListVisible;
+    Boolean        IgnoreFocusOut;
+    Boolean         PendingFocusOut;
+    Boolean        PendingOverrideInOut;
+    XtWorkProcId    WorkProcID;
+    XEvent          xevent;
+    
+    Boolean        PassVerification;
+    Boolean        ConvertBitmapToPixmap, 
+                    ConvertBitmapToPixmapInsensitive;
+    Pixmap         LabelPixmap, LabelInsensitivePixmap;
+
+    XtPointer      Dummy;
+} XmComboBoxPart;
+
+/*
+ * vollstaengige Instanzenstruktur
+ */
+typedef struct _XmComboBoxRec {
+    CorePart       core;
+    CompositePart  composite;
+    ConstraintPart constraint;
+    XmManagerPart  manager;
+    XmComboBoxPart combobox;
+} XmComboBoxRec;
+
+#endif
+/* Ende von ComboBoxP.h */
diff --git a/src/motif/xmcombo/copying.txt b/src/motif/xmcombo/copying.txt
new file mode 100644 (file)
index 0000000..e77696a
--- /dev/null
@@ -0,0 +1,339 @@
+                   GNU GENERAL PUBLIC LICENSE
+                      Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+                          675 Mass Ave, Cambridge, MA 02139, USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+                           Preamble
+
+  The licenses for most software are designed to take away your
+freedom to share and change it.  By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users.  This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it.  (Some other Free Software Foundation software is covered by
+the GNU Library General Public License instead.)  You can apply it to
+your programs, too.
+
+  When we speak of free software, we are referring to freedom, not
+price.  Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+  To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+  For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have.  You must make sure that they, too, receive or can get the
+source code.  And you must show them these terms so they know their
+rights.
+
+  We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+  Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software.  If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+  Finally, any free program is threatened constantly by software
+patents.  We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary.  To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.
+\f
+                   GNU GENERAL PUBLIC LICENSE
+   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+  0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License.  The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language.  (Hereinafter, translation is included without limitation in
+the term "modification".)  Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope.  The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+  1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+  2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+    a) You must cause the modified files to carry prominent notices
+    stating that you changed the files and the date of any change.
+
+    b) You must cause any work that you distribute or publish, that in
+    whole or in part contains or is derived from the Program or any
+    part thereof, to be licensed as a whole at no charge to all third
+    parties under the terms of this License.
+
+    c) If the modified program normally reads commands interactively
+    when run, you must cause it, when started running for such
+    interactive use in the most ordinary way, to print or display an
+    announcement including an appropriate copyright notice and a
+    notice that there is no warranty (or else, saying that you provide
+    a warranty) and that users may redistribute the program under
+    these conditions, and telling the user how to view a copy of this
+    License.  (Exception: if the Program itself is interactive but
+    does not normally print such an announcement, your work based on
+    the Program is not required to print an announcement.)
+\f
+These requirements apply to the modified work as a whole.  If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works.  But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+  3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+    a) Accompany it with the complete corresponding machine-readable
+    source code, which must be distributed under the terms of Sections
+    1 and 2 above on a medium customarily used for software interchange; or,
+
+    b) Accompany it with a written offer, valid for at least three
+    years, to give any third party, for a charge no more than your
+    cost of physically performing source distribution, a complete
+    machine-readable copy of the corresponding source code, to be
+    distributed under the terms of Sections 1 and 2 above on a medium
+    customarily used for software interchange; or,
+
+    c) Accompany it with the information you received as to the offer
+    to distribute corresponding source code.  (This alternative is
+    allowed only for noncommercial distribution and only if you
+    received the program in object code or executable form with such
+    an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it.  For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable.  However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+\f
+  4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License.  Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+  5. You are not required to accept this License, since you have not
+signed it.  However, nothing else grants you permission to modify or
+distribute the Program or its derivative works.  These actions are
+prohibited by law if you do not accept this License.  Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+  6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions.  You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+  7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all.  For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices.  Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+\f
+  8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded.  In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+  9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time.  Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number.  If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation.  If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+  10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission.  For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this.  Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+                           NO WARRANTY
+
+  11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+  12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+                    END OF TERMS AND CONDITIONS
+\f
+           How to Apply These Terms to Your New Programs
+
+  If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+  To do so, attach the following notices to the program.  It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+    <one line to give the program's name and a brief idea of what it does.>
+    Copyright (C) 19yy  <name of author>
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+    Gnomovision version 69, Copyright (C) 19yy name of author
+    Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+    This is free software, and you are welcome to redistribute it
+    under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License.  Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary.  Here is a sample; alter the names:
+
+  Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+  `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+  <signature of Ty Coon>, 1 April 1989
+  Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs.  If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library.  If this is what you want to do, use the GNU Library General
+Public License instead of this License.
diff --git a/src/motif/xmcombo/demo.c b/src/motif/xmcombo/demo.c
new file mode 100644 (file)
index 0000000..797f62b
--- /dev/null
@@ -0,0 +1,214 @@
+/*
+ * demo.c -- Example how to use a ComboBox
+ * 
+ * compile and link with:
+ * $ cc -DFUNCPROTO ComboBoxDemo.c ComboBox.o -o ComboBoxDemo \
+ *   -lXm -lXt -lX11
+ * then run:
+ * $ ./ComboBoxDemo
+ * 
+ * (c) 1993, 1994 Harald Albrecht
+ * Institut fuer Geometrie und Praktische Mathematik
+ * RWTH Aachen, Germany
+ * albrecht@igpm.rwth-aachen.de
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program (see the file COPYING for more details);
+ * if not, write to the Free Software Foundation, Inc., 675 Mass Ave, 
+ * Cambridge, MA 02139, USA.
+ *
+ */
+#include <stdio.h>
+#include <Xm/Xm.h>
+#include <Xm/Form.h>
+#include <Xm/Label.h>
+#include <Xm/Separator.h>
+#include <Xm/PushB.h>
+#include "combobox.h"
+
+Widget TopLevel, Form, Button, Text, Sepp, ComboBox1, ComboBox2, ComboBox3, Label;
+
+void QuitCB(Widget w, caddr_t pClientData, caddr_t pCallData)
+{
+    char *text;
+
+    text = XmComboBoxGetString(ComboBox1);
+    fprintf(stderr, "You choosed \"%s\" out of the first ComboBox\n", text);
+    XtFree(text);
+    text = XmComboBoxGetString(ComboBox2);
+    fprintf(stderr, "You entered \"%s\" into the second ComboBox\n", text);
+    XtFree(text);
+    fprintf(stderr, "Bye! ... have fun with XmComboBox!\n");
+    exit(0);
+} /* QuitCB */
+
+int main(int argc, String argv[])
+{
+    XmString         str;
+    Boolean          Trav;
+    XtAppContext     AppContext;
+
+#if (XmREVISION > 1)
+    XtSetLanguageProc(NULL,NULL,NULL); 
+#endif
+    TopLevel = XtAppInitialize(&AppContext, "XFontSelDemo", NULL, 0, 
+#if (XmREVISION > 1)
+                              &argc, 
+#else
+                               (Cardinal *) &argc,
+#endif
+                              argv, NULL, NULL, 0);
+    Form = XtVaCreateManagedWidget("form", xmFormWidgetClass, TopLevel, NULL);
+    str = XmStringCreateLtoR("Click to quit", XmSTRING_DEFAULT_CHARSET);
+    Button = XtVaCreateManagedWidget("quit", xmPushButtonWidgetClass, Form, 
+                       XmNlabelString, str, 
+                       XmNleftAttachment, XmATTACH_FORM, 
+                       XmNleftOffset, 8, 
+                       XmNtopAttachment,  XmATTACH_FORM, 
+                       XmNtopOffset, 8, 
+                       NULL);
+    XmStringFree(str);
+    XtAddCallback(Button, XmNactivateCallback, (XtCallbackProc) QuitCB, NULL);
+
+    Sepp = XtVaCreateManagedWidget("separator1", xmSeparatorWidgetClass, Form, 
+                       XmNleftAttachment, XmATTACH_FORM, 
+                       XmNrightAttachment, XmATTACH_FORM,
+                       XmNtopAttachment, XmATTACH_WIDGET, 
+                       XmNtopOffset, 8, 
+                       XmNtopWidget, Button, 
+                       NULL); 
+                       
+    str = XmStringCreateLtoR("Choose one:", XmSTRING_DEFAULT_CHARSET);
+    ComboBox1 = XtVaCreateManagedWidget("combobox1", xmComboBoxWidgetClass, Form, 
+                       XmNeditable, False,
+                       XmNsorted, True,  
+                       XmNleftAttachment, XmATTACH_FORM, 
+                       XmNleftOffset, 8, 
+                       XmNrightAttachment, XmATTACH_FORM,
+                       XmNrightOffset, 8, 
+                       XmNtopAttachment, XmATTACH_WIDGET, 
+                       XmNtopOffset, 8, 
+                       XmNtopWidget, Sepp, 
+                       XmNshowLabel, True, 
+                       XmNlabelString, str,
+                       NULL);
+    XmStringFree(str);
+    /* Put string unordered into the combo box! They'll get sorted
+     * by the box.
+     */
+    str = XmStringCreateLtoR("William the conquerior", XmSTRING_DEFAULT_CHARSET);
+    XmComboBoxAddItem(ComboBox1, str, 0); XmStringFree(str);
+    str = XmStringCreateLtoR("Karl der Gro\337e", XmSTRING_DEFAULT_CHARSET);
+    XmComboBoxAddItem(ComboBox1, str, 0); XmStringFree(str);
+    str = XmStringCreateLtoR("Henry VIII & his chicken band", XmSTRING_DEFAULT_CHARSET);
+    XmComboBoxAddItem(ComboBox1, str, 0); XmStringFree(str);
+    str = XmStringCreateLtoR("Louis XIV", XmSTRING_DEFAULT_CHARSET);
+    XmComboBoxAddItem(ComboBox1, str, 0); XmStringFree(str);
+    str = XmStringCreateLtoR("Louis de Funes", XmSTRING_DEFAULT_CHARSET);
+    XmComboBoxAddItem(ComboBox1, str, 0); XmStringFree(str);
+    str = XmStringCreateLtoR("Helmut Kohl", XmSTRING_DEFAULT_CHARSET);
+    XmComboBoxAddItem(ComboBox1, str, 0); XmStringFree(str);
+    str = XmStringCreateLtoR("James Major", XmSTRING_DEFAULT_CHARSET);
+    XmComboBoxAddItem(ComboBox1, str, 0); XmStringFree(str);
+    str = XmStringCreateLtoR("James Bond", XmSTRING_DEFAULT_CHARSET);
+    XmComboBoxAddItem(ComboBox1, str, 0); XmStringFree(str);
+    str = XmStringCreateLtoR("Billy Boy (M$ Windoze)", XmSTRING_DEFAULT_CHARSET);
+    XmComboBoxAddItem(ComboBox1, str, 0); XmStringFree(str);
+    str = XmStringCreateLtoR("Francois Mitterand", XmSTRING_DEFAULT_CHARSET);
+    XmComboBoxAddItem(ComboBox1, str, 0);
+    XmComboBoxSelectItem(ComboBox1, str, False);
+    XmStringFree(str);
+
+    str = XmStringCreateLtoR("Choose/edit:", XmSTRING_DEFAULT_CHARSET);
+    ComboBox2 = XtVaCreateManagedWidget("combobox2", xmComboBoxWidgetClass, Form, 
+                       XmNeditable, True,
+                       XmNsorted, True,  
+                       XmNleftAttachment, XmATTACH_FORM, 
+                       XmNleftOffset, 8, 
+                       XmNrightAttachment, XmATTACH_FORM,
+                       XmNrightOffset, 8, 
+                       XmNtopAttachment, XmATTACH_WIDGET, 
+                       XmNtopOffset, 8, 
+                       XmNtopWidget, ComboBox1, 
+                       XmNshowLabel, True, 
+                       XmNlabelString, str, 
+                       NULL);
+    str = XmStringCreateLtoR("item can be edited after choosing it", XmSTRING_DEFAULT_CHARSET);
+    XmComboBoxAddItem(ComboBox2, str, 0); XmStringFree(str);
+    str = XmStringCreateLtoR("just to fill the list", XmSTRING_DEFAULT_CHARSET);
+    XmComboBoxAddItem(ComboBox2, str, 0); XmStringFree(str);
+    str = XmStringCreateLtoR("so it contains more entries", XmSTRING_DEFAULT_CHARSET);
+    XmComboBoxAddItem(ComboBox2, str, 0); XmStringFree(str);
+
+    str = XmStringCreateLtoR("Static ComboBox:", XmSTRING_DEFAULT_CHARSET);
+    ComboBox3 = XtVaCreateManagedWidget("combobox3", xmComboBoxWidgetClass, Form, 
+                       XmNeditable, True,
+                       XmNstaticList, True,
+                       XmNsorted, False,
+                       XmNcolumns, 30,  
+                       XmNleftAttachment, XmATTACH_FORM, 
+                       XmNleftOffset, 8, 
+                       XmNrightAttachment, XmATTACH_FORM,
+                       XmNrightOffset, 8, 
+                       XmNtopAttachment, XmATTACH_WIDGET,
+                       XmNtopOffset, 8, 
+                       XmNtopWidget, ComboBox2, 
+                       XmNshowLabel, True, 
+                       XmNlabelString, str, 
+                       NULL);
+    XmStringFree(str);
+    str = XmStringCreateLtoR("ComboBox (noneditable)", XmSTRING_DEFAULT_CHARSET);
+    XmComboBoxAddItem(ComboBox3, str, 0); XmStringFree(str);
+    str = XmStringCreateLtoR("ComboBox (editable)", XmSTRING_DEFAULT_CHARSET);
+    XmComboBoxAddItem(ComboBox3, str, 0); XmStringFree(str);
+    str = XmStringCreateLtoR("ComboBox (editable & static List)", XmSTRING_DEFAULT_CHARSET);
+    XmComboBoxAddItem(ComboBox3, str, 0); XmStringFree(str);
+    str = XmStringCreateLtoR("Center widget", XmSTRING_DEFAULT_CHARSET);
+    XmComboBoxAddItem(ComboBox3, str, 0); XmStringFree(str);
+    str = XmStringCreateLtoR("The ButtonFace Library", XmSTRING_DEFAULT_CHARSET);
+    XmComboBoxAddItem(ComboBox3, str, 0); XmStringFree(str); 
+
+    Sepp = XtVaCreateManagedWidget("separator", xmSeparatorWidgetClass, Form, 
+                       XmNleftAttachment, XmATTACH_FORM, 
+                       XmNrightAttachment, XmATTACH_FORM,
+                       XmNtopAttachment, XmATTACH_WIDGET, 
+                       XmNtopOffset, 8, 
+                       XmNtopWidget, ComboBox3, 
+                       NULL); 
+
+    str = XmStringCreateLtoR(
+"xmComboBoxWidgetClass Demo\n\nby Harald Albrecht\n\n\
+albrecht@igpm.rwth-aachen.de", XmSTRING_DEFAULT_CHARSET); 
+    Label = XtVaCreateManagedWidget("label", xmLabelWidgetClass, Form, 
+                       XmNlabelString, str, 
+                       XmNleftAttachment, XmATTACH_FORM, 
+                       XmNleftOffset, 80, 
+                       XmNrightAttachment, XmATTACH_FORM, 
+                       XmNrightOffset, 80, 
+                       XmNbottomAttachment, XmATTACH_FORM, 
+                       XmNbottomOffset, 24, 
+                       XmNtopAttachment, XmATTACH_WIDGET, 
+                       XmNtopWidget, Sepp, 
+                       XmNtopOffset, 24, 
+                       NULL); 
+    XmStringFree(str);
+
+    XtRealizeWidget(TopLevel);
+
+    XtAppMainLoop(AppContext);
+    return 0; /* Never will reach this */
+} /* main */
+
+
+/* End of ComboBoxDemo.c */
diff --git a/src/motif/xmcombo/xmcombo.c b/src/motif/xmcombo/xmcombo.c
new file mode 100644 (file)
index 0000000..f612df4
--- /dev/null
@@ -0,0 +1,3543 @@
+/*
+ * ComboBox.c - Das schon lange schmerzlich vermisste Combo-Box-
+ *              Widget -- nun endlich auf fuer Motif!
+ * 
+ * Version 1.32a -- 04.10.95
+ *
+ * Letzte Modifikation:
+ * 04.10.1995    Layoutfehler behoben, der bei angezeigter horizontaler Liste
+ *               dazu fuehrt, dass das Listenfeld schrumpft. Daneben wird
+ *               jetzt auch der Fall beruecksichtigt, dass das Listenfeld am
+ *               unteren Bildschirmrand abgeschnitten wuerde. In diesem Fall
+ *               erscheint das Listenfeld oberhalb des Eingabefeldes.
+ * 20.03.1995    XmNscrollbarDisplayPolicy,... koennen nun immer vom Pro-
+ *               grammierer gesetzt werden, statische Liste hin und her.
+ * 21.10.1994    Fehler in SetValues behoben, der auftritt, wenn man versucht,
+ *               XmNitems und XmNitemCount zu setzen.
+ * 01.10.1994    Externe Sortierung wird nun unterstuetzt sowie seitenweises
+ *              Rollen in der Liste mittels PgUp und PgDn.
+ * 25.09.1994    Unterstuetzung fuer XmNautomaticSelection implementiert.
+ *              Damit wird die Sache noch ein bischen runder in der Bedienung.
+ *              Des weiteren sind etliche Callbacks neu hinzugekommen.
+ * 04.09.1994    Erweiterungen fuer XmSINGLE_SELECT eingebaut. Ausserdem
+ *              kann die Liste jetzt auch statisch unterhalb des Eingabe-
+ *              felds erscheinen. Damit sind wir nun noch kompatibler ge-
+ *              worden -- fragt sich nur, zu was?!
+ * 29.08.1994    Alle Mirror-Ressourcen tauchen nun auch in der Ressourcen-
+ *              liste der ComboBox-Klasse auf. Allerdings stehen keine
+ *              sinnvollen Werte fuer die Initialisierung 'drin. Weiterhin
+ *              den GeometryManager so veraendert, dass ab sofort das
+ *              Label in der Breite wachsen oder schrumpfen darf.
+ * 07.06.1994    XmNmnemonic und XmNmnemonicCharSet implementiert.
+ * 29.05.1994    XmNsensitive angepasst. XmNcursorPositionVisible ist nun
+ *               False, falls die ComboBox nicht editierbar ist.
+ * 07.05.1994    Drag'n'Drop funktioniert endlich!!! Zudem Anpassung an
+ *               den fvwm ausgefuehrt ('st vom Focus-Verhalten ja ein halber
+ *               twm). Hach', so'ne Linux-Box mit Motif 1.2 macht doch
+ *               einfach Spass... vor allem geht hier so richtig die Post ab.
+ *               Das kann man ja von M$ Windoze (Windoze for Mondays) nicht
+ *               behaupten!
+ * 14.04.1994    Ein paar Speicherlecks korrigiert.
+ * 21.02.1994    Die Resourcen XmNitems und XmNitemCount lassen sich nun 
+ *               auch von einer Resourcendatei aus initialisieren. ACHTUNG: 
+ *              diese beiden Resourcen mussen immer beide beim Aufruf von 
+ *              XtSetValues zugleich angegeben werden, ansonsten werden
+ *               diese Angaben ignoriert.
+ * 03.02.1994    Convenience-Funktionen auf Vordermann gebracht und noch
+ *              einen Callback eingebaut, der immer dann aufgerufen wird, 
+ *              wenn die List angezeigt oder wieder versteckt wird.
+ * 01.02.1994    Motif 1.2-fest!!! Das wird aber heute abend gefeiert!!
+ *               Endlich EIN Alptraum weniger! Naja, Drag'n'Drop bleibt
+ *              noch zu loesen. Spaeter...
+ * 31.01.1994    VAX-fest (mit Hilfe von Vincenct Li)
+ *               owlm sollte man abschaffen! Aber es scheint so, als ob
+ *               ich jetzt doch noch das FocusOut-Problem geknackt habe.
+ *               Ebenso die OSF...mit viel Arbeit habe ich nun auch noch
+ *               eine anstaendige Initialisierung der Fontliste des Label-
+ *               Kinds erreicht.
+ * 12.01.1994   Revisionsstand: 1.10a
+ *               nun wirklich voll ANSI-faehiger C-Code
+ *               Pixmaps werden ggf. aufgeraeumt; Druckrichtung
+ *               wird vom Vater erfragt und an das Label weiter-
+ *               gegeben.
+ *               ESC-Behandlung implementiert.
+ *               Spiegel-Ressourcen-Initialisierung aus Ressourcen-Daten-
+ *               bank implementiert.
+ *               Weitergabe von neu gesetzten Farben an die Kinder
+ *               implementiert.
+ *               Combo-Box kann jetzt wahlweise auch links neben dem
+ *               Eingabefeld ein Label anzeigen.
+ * 09.12.1993    Revisionsstand: 1.00
+ *               erste oeffentlich zugaengliche Version der Combo-Box
+ * 
+ * (c) 1993, 1994, 1995 Harald Albrecht
+ * Institut fuer Geometrie und Praktische Mathematik
+ * RWTH Aachen, Germany
+ * albrecht@igpm.rwth-aachen.de
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program (see the file COPYING for more details);
+ * if not, write to the Free Software Foundation, Inc., 675 Mass Ave, 
+ * Cambridge, MA 02139, USA.
+ *
+ */
+
+#include <X11/IntrinsicP.h>
+#include <X11/StringDefs.h>
+#include <X11/cursorfont.h>
+#include <X11/Shell.h>
+#ifdef VMS /* Huch, wo gibt's denn noch sowas ... ?! */
+           /* Bitte keine Mail bzgl. dieser Bemerkung schicken...
+           * Ich weiss, das ist ein Vorurteil...aber es gibt
+           * ja auch wahre Vorurteile....
+           */
+#include <Xmu/Converters.h>
+#else
+#include <X11/Xmu/Converters.h>
+#endif
+#include <Xm/ArrowB.h>
+#include <Xm/TextF.h>
+#include <Xm/List.h>
+#include <Xm/LabelP.h>
+#include <string.h>
+#include <ctype.h> /* define toupper */
+#include "combop.h"
+
+#include <stdio.h>
+
+/* --- Systemspezifische Definitionen */
+#ifdef VMS
+#define strcasecmp(s1, s2) strcmp(s1, s2)
+#endif
+
+/* --- sonstiger Quark */
+/* #ifdef DEBUG */
+#if 0
+#define LOG(p1)          fprintf(stderr, p1);
+#define LOG2(p1, p2)     fprintf(stderr, p1, p2);
+#define LOG3(p1, p2, p3) fprintf(stderr, p1, p2, p3);
+#else
+#define LOG(p1)
+#define LOG2(p1, p2)
+#define LOG3(p1, p2, p3)
+#endif
+
+/* ---------------------------------------------------------------------------
+ * Resourcen-Liste...
+ * Hier werden diejenigen Resourcen definiert, die von "aussen" - also  fuer
+ * den Programmierer oder Anwender - benutzbar und veraenderbar sind.
+ * 
+ * Der Aufbau der einzelnen Eintraege ist immer wieder gleich:
+ * Resourcen-Name      XmN... oder XtN
+ * Resourcen-Klasse     XmC... oder XtC
+ * Resourcen-Type       XmR... oder XtR (Datentyp der Variable in der
+ *                      struct der jeweiligen Widgetinstanz)
+ * Resourcen-Groesse   aktuelle Groesse dieses Datentyps
+ * Resourcen-Offset     Lage der Variable innerhalb der struct der
+ *                     Widgetinstanz
+ * Defaultwert-Type     Typ des Defaultwertes
+ * Defaultwert         (normalerweise) Zeiger auf den Defaultwert
+ */
+#define offset(field) XtOffsetOf(XmComboBoxRec, field)
+static XtResource resources[] = {
+    { /* Eingabefeld kann veraendert werden, oder aber es sind nur
+       * die Vorgaben aus der Liste auswaehlbar.
+       */
+       XmNeditable, XmCEditable, XmRBoolean, sizeof(Boolean), 
+       offset(combobox.Editable), XmRString, "False"
+    }, 
+    { /* Liste wird automatisch sortiert -- wie konnten die bei
+       * der OSF denn SOETWAS nur vergessen ??
+       */
+       XmNsorted, XmCSorted, XmRBoolean, sizeof(Boolean),
+       offset(combobox.Sorted), XmRString, "False"
+    }, 
+    { /* externe Sortierreihenfolge */
+       XmNsortingCallback, XmCSortingCallback, XmRCallback, 
+       sizeof(XtCallbackList), 
+       offset(combobox.SortingCBL), XmRCallback, NULL
+    }, 
+    { /* Anzahl auf einmal sichtbarer Eintraege in der Liste (ent-
+       * spricht damit der Listenhoehe.
+       */
+       XmNvisibleItemCount, XmCVisibleItemCount, XmRInt, sizeof(int), 
+       offset(combobox.VisibleItemCount), XmRImmediate, (caddr_t) 8
+    }, 
+    { /* Fuer das Eingabefeld sowie die Liste verwandte Fonts */
+       XmNfontList, XmCFontList, XmRFontList, sizeof(XmFontList), 
+       offset(combobox.Font), XmRImmediate, NULL
+    }, 
+    { /* Rueckruf bei Anwahl */
+       XmNselectionCallback, XmCSelectionCallback, XmRCallback, 
+       sizeof(XtCallbackList), 
+       offset(combobox.SelectionCBL), XmRCallback, NULL
+    }, 
+    { /* Gegenteil zum vorherigen Callback! */
+       XmNunselectionCallback, XmCUnselectionCallback, XmRCallback, 
+       sizeof(XtCallbackList), 
+       offset(combobox.UnselectionCBL), XmRCallback, NULL
+    }, 
+    { /* Doppelklick in der Liste */
+       XmNdefaultActionCallback, XmCCallback, XmRCallback, 
+       sizeof(XtCallbackList), 
+       offset(combobox.DefaultActionCBL), XmRCallback, NULL
+    }, 
+    { /* Rueckruf bei Liste ausklappen/verstecken */
+       XmNdropDownCallback, XmCDropDownCallback, XmRCallback, 
+       sizeof(XtCallbackList), 
+       offset(combobox.DropDownCBL), XmRCallback, NULL
+    }, 
+    { /* Eingabe abchecken... */
+       XmNmodifyVerifyCallback, XmCCallback, XmRCallback, 
+       sizeof(XtCallbackList), 
+       offset(combobox.ModifyVerifyCBL), XmRCallback, NULL
+    }, 
+    {
+       XmNvalueChangedCallback, XmCCallback, XmRCallback, 
+       sizeof(XtCallbackList), 
+       offset(combobox.ValueChangedCBL), XmRCallback, NULL
+    }, 
+    {
+       XmNactivateCallback, XmCCallback, XmRCallback, 
+       sizeof(XtCallbackList), 
+       offset(combobox.ActivateCBL), XmRCallback, NULL
+    }, 
+    {
+       XmNmotionVerifyCallback, XmCCallback, XmRCallback, 
+       sizeof(XtCallbackList), 
+       offset(combobox.MotionVerifyCBL), XmRCallback, NULL
+    }, 
+    { /* Verhalten der ausgeklappten Liste bei Focus-Out */
+       XmNpersistentDropDown, XmCPersistentDropDown, XmRBoolean, 
+       sizeof(Boolean), 
+       offset(combobox.Persistent), XmRString, "False"
+    }, 
+    { /* Wie verhaelt sich der Window-Manager? */
+       XmNtwmHandlingOn, XmCTwmHandlingOn, XmRBoolean, sizeof(Boolean), 
+       offset(combobox.TwmHandlingOn), XmRString, "False"
+    }, 
+    { /* Label anzeigen oder nicht? */
+       XmNshowLabel, XmCShowLabel, XmRBoolean, sizeof(Boolean), 
+       offset(combobox.ShowLabel), XmRString, "False"
+    }, 
+    { /* Abstand zw. linkem Rand Eingabefeld und linkem Rand Liste */
+       XmNdropDownOffset, XmCDropDownOffset, XmRPosition, 
+       sizeof(Position), offset(combobox.DropDownOffset), 
+       XmRImmediate, (caddr_t) -1
+    }, 
+    { /* Neue Voreinstellung bzgl. des Randes */
+       XmNborderWidth, XmCBorderWidth, XmRDimension, sizeof(Dimension), 
+       offset(core.border_width), XmRImmediate, (caddr_t) 0
+    },
+    { /* welcher Cursor soll in der Dropdown-Liste benutzt werden? */
+       XmNdropDownCursor, XmCDropDownCursor, XmRCursor, sizeof(Cursor),
+       offset(combobox.ArrowCursor), XmRString, "center_ptr"
+    }, 
+    { /* wie lassen sich Eintraege auswaehlen? */
+       XmNselectionPolicy, XmCSelectionPolicy, XmRSelectionPolicy, sizeof(unsigned char), 
+       offset(combobox.SelectionPolicy), XmRImmediate, (caddr_t) XmBROWSE_SELECT
+    }, 
+    { /* Wann werden die Callbacks aufgerufen? */
+       XmNautomaticSelection, XmCAutomaticSelection, XmRBoolean, sizeof(Boolean), 
+       offset(combobox.AutomaticSelection), XmRString, "False"
+    }, 
+    { /* erscheint die Liste staendig? */
+       XmNstaticList, XmCStaticList, XmRBoolean, sizeof(Boolean), 
+       offset(combobox.StaticList), XmRString, "False"
+    }, 
+    {
+       XmNscrollBarDisplayPolicy, XmCScrollBarDisplayPolicy, XmRScrollBarDisplayPolicy, sizeof(unsigned char),
+       offset(combobox.ScrollBarDisplayPolicy), XmRImmediate, (caddr_t) XmAS_NEEDED
+    },
+    {
+        XmNlistSizePolicy, XmCListSizePolicy, XmRListSizePolicy, sizeof(unsigned char),
+        offset(combobox.ListSizePolicy), XmRImmediate, (caddr_t) XmVARIABLE
+    },
+    {
+        XmNsquareArrow, XmCSquareArrow, XmRBoolean, sizeof(Boolean),
+        offset(combobox.SquareArrow), XmRString, "False"
+    },
+    {
+        XmNarrowSpacingOn, XmCArrowSpacingOn, XmRBoolean, sizeof(Boolean),
+        offset(combobox.ArrowSpacingOn), XmRString, "True"
+    },
+#ifndef DONT_LOOK_IN_THE_MIRROR
+    /* Mirror-Ressourcen, Adressen sind ungueltig!!!! */
+    {
+       XmNalignment, XmCAlignment, XmRAlignment, sizeof(unsigned char), 
+       offset(combobox.Dummy), XmRImmediate, (caddr_t) 0
+    }, 
+    {
+       XmNblinkRate, XmCBlinkRate, XmRInt, sizeof(int), 
+       offset(combobox.Dummy), XmRImmediate, (caddr_t) 0
+    }, 
+    {
+       XmNcolumns, XmCColumns, XmRShort, sizeof(short), 
+       offset(combobox.Dummy), XmRImmediate, (caddr_t) 0
+    }, 
+    {
+       XmNcursorPosition, XmCCursorPosition, XmRTextPosition, sizeof(XmTextPosition),
+       offset(combobox.Dummy), XmRImmediate, (caddr_t) 0
+    }, 
+    {
+       XmNitemCount, XmCItemCount, XmRInt, sizeof(int), 
+       offset(combobox.Dummy), XmRImmediate, (caddr_t) 0
+    }, 
+    {
+       XmNitems, XmCItems, XmRXmStringTable, sizeof(XmStringTable), 
+       offset(combobox.Dummy), XmRImmediate, (caddr_t) 0
+    }, 
+    {
+       XmNlabelFontList, XmCLabelFontList, XmRFontList, sizeof(XmFontList), 
+       offset(combobox.Dummy), XmRImmediate, (caddr_t) 0
+    }, 
+    {
+       XmNlabelInsensitivePixmap, XmCLabelInsensitivePixmap, XmRPixmap, sizeof(Pixmap), 
+       offset(combobox.Dummy), XmRImmediate, (caddr_t) 0
+    }, 
+    {
+       XmNlabelMarginBottom, XmCLabelMarginBottom, XmRDimension, sizeof(Dimension), 
+       offset(combobox.Dummy), XmRImmediate, (caddr_t) 0
+    }, 
+    {
+       XmNlabelMarginHeight, XmCLabelMarginHeight, XmRDimension, sizeof(Dimension), 
+       offset(combobox.Dummy), XmRImmediate, (caddr_t) 0
+    }, 
+    {
+       XmNlabelMarginLeft, XmCLabelMarginLeft, XmRDimension, sizeof(Dimension), 
+       offset(combobox.Dummy), XmRImmediate, (caddr_t) 0
+    }, 
+    {
+       XmNlabelMarginRight, XmCLabelMarginRight, XmRDimension, sizeof(Dimension), 
+       offset(combobox.Dummy), XmRImmediate, (caddr_t) 0
+    }, 
+    {
+       XmNlabelMarginTop, XmCLabelMarginTop, XmRDimension, sizeof(Dimension), 
+       offset(combobox.Dummy), XmRImmediate, (caddr_t) 0
+    }, 
+    {
+       XmNlabelMarginWidth, XmCLabelMarginWidth, XmRDimension, sizeof(Dimension), 
+       offset(combobox.Dummy), XmRImmediate, (caddr_t) 0
+    }, 
+    {
+       XmNlabelPixmap, XmCLabelPixmap, XmRPixmap, sizeof(Pixmap), 
+       offset(combobox.Dummy), XmRImmediate, (caddr_t) 0
+    }, 
+    {
+       XmNlabelString, XmCLabelString, XmRString, sizeof(XmString), 
+       offset(combobox.Dummy), XmRImmediate, (caddr_t) 0
+    }, 
+    {
+       XmNlabelType, XmCLabelType, XmRLabelType, sizeof(unsigned char), 
+       offset(combobox.Dummy), XmRImmediate, (caddr_t) 0
+    }, 
+    {
+       XmNlistMarginHeight, XmCListMarginHeight, XmRDimension, sizeof(Dimension), 
+       offset(combobox.Dummy), XmRImmediate, (caddr_t) 0
+    }, 
+    {
+       XmNlistMarginWidth, XmCListMarginWidth, XmRDimension, sizeof(Dimension), 
+       offset(combobox.Dummy), XmRImmediate, (caddr_t) 0
+    }, 
+    {
+       XmNlistSpacing, XmCListSpacing, XmRDimension, sizeof(Dimension), 
+       offset(combobox.Dummy), XmRImmediate, (caddr_t) 0
+    }, 
+    {
+       XmNmarginHeight, XmCMarginHeight, XmRDimension, sizeof(Dimension), 
+       offset(combobox.Dummy), XmRImmediate, (caddr_t) 0
+    }, 
+    {
+       XmNmarginWidth, XmCMarginWidth, XmRDimension, sizeof(Dimension), 
+       offset(combobox.Dummy), XmRImmediate, (caddr_t) 0
+    }, 
+    {
+       XmNmaxLength, XmCMaxLength, XmRInt, sizeof(int), 
+       offset(combobox.Dummy), XmRImmediate, (caddr_t) 0
+    }, 
+    {
+       XmNselectThreshold, XmCSelectThreshold, XmRInt, sizeof(int), 
+       offset(combobox.Dummy), XmRImmediate, (caddr_t) 0
+    }, 
+    {
+       XmNstringDirection, XmCStringDirection, XmRStringDirection, sizeof(XmStringDirection), 
+       offset(combobox.Dummy), XmRImmediate, (caddr_t) 0
+    }, 
+    {
+       XmNtopItemPosition, XmCTopItemPosition, XmRInt, sizeof(int), 
+       offset(combobox.Dummy), XmRImmediate, (caddr_t) 0
+    }, 
+    {
+       XmNvalue, XmCValue, XmRString, sizeof(String), 
+       offset(combobox.Dummy), XmRImmediate, (caddr_t) 0
+    }, 
+    {
+       XmNvalue, XmCValue, XmRInt, sizeof(int), 
+       offset(combobox.Dummy), XmRImmediate, (caddr_t) 0
+    }, 
+#endif
+}; /* resources[] */
+
+/* ---------------------------------------------------------------------------
+ * Funktions-Prototypen fuer die 'Methoden' des ComboBox-Widgets. Diese
+ * 'Methoden' werden vom Xt-Toolkit aufgerufen und sorgen dafuer, dass eine
+ * ComboBox sich wie ein anstaendiges Widget verhaelt.
+ */
+static void             Initialize     (Widget, XmComboBoxWidget, ArgList, 
+                                       Cardinal *);
+static void             Destroy        (XmComboBoxWidget);
+static void             Resize         (XmComboBoxWidget);
+static Boolean          SetValues      (XmComboBoxWidget, XmComboBoxWidget, 
+                                        XmComboBoxWidget, ArgList, Cardinal *);
+static void             GetValuesAlmost(XmComboBoxWidget, ArgList, Cardinal *);
+static XtGeometryResult QueryGeometry  (XmComboBoxWidget, XtWidgetGeometry *, 
+                                       XtWidgetGeometry *); 
+static XtGeometryResult GeometryManager(Widget, XtWidgetGeometry *, 
+                                        XtWidgetGeometry *);
+static void            ClassInit      ();
+static void             Realize        (XmComboBoxWidget, Mask *, 
+                                        XSetWindowAttributes *);
+/* ---------------------------------------------------------------------------
+ * diverse restliche Prototypen... naja, hier halt etwas mager! Hierbei
+ */
+static void ShowHideDropDownList       (XmComboBoxWidget w, XEvent *event, 
+                                        Boolean Show);
+static void ShellCallback              (Widget w, XtPointer cbw, 
+                                        XEvent *event, Boolean *ContDispatch);
+static void DoLayout                   (XmComboBoxWidget w);
+/* --------------------------------------------------------------------
+ * Klassen-Definition
+ */
+XmComboBoxClassRec xmComboBoxClassRec = {
+    { /*** core-Klasse ***/
+    /* superclass                  */  (WidgetClass) &xmManagerClassRec, 
+    /* class_name                  */  "XmComboBox",
+    /* widget_size                 */  sizeof(XmComboBoxRec),
+    /* class_initialize            */  (XtProc) ClassInit,
+    /* class_part_initialize       */  NULL,
+    /* class_inited                */  False, /* IMMER mit FALSE initialisieren !! */
+    /* initialize                  */  (XtInitProc) Initialize,
+    /* initialize_hook             */  NULL,
+    /* realize                     */  (XtRealizeProc) Realize,
+    /* actions                     */  NULL,
+    /* num_actions                 */  0,
+    /* resources                   */  resources,
+    /* num_resources               */  XtNumber(resources),
+    /* xrm_class                   */  NULLQUARK,
+    /* compress_motion             */  True,
+    /* compress_exposure           */  XtExposeCompressMultiple,
+    /* compress_enterleave         */  True,
+    /* visible_interest                    */  False,
+    /* destroy                     */  (XtWidgetProc) Destroy,
+    /* resize                      */  (XtWidgetProc) Resize,
+    /* expose                      */  NULL,
+    /* set_values                  */  (XtSetValuesFunc) SetValues,
+    /* set_values_hook             */  NULL,
+    /* set_values_almost           */  XtInheritSetValuesAlmost,
+    /* get_values_hook             */  (XtArgsProc) GetValuesAlmost,
+    /* accept_focus                */  NULL,
+    /* version                     */  XtVersion,
+    /* callback_private            */  NULL,
+    /* tm_table                            */  NULL,
+    /* query_geometry              */  (XtGeometryHandler) QueryGeometry,
+    /* display_accelerator         */  XtInheritDisplayAccelerator,
+    /* extension                   */  NULL
+    }, 
+    { /*** composite-Klasse ***/
+    /* geometry_manager                    */  (XtGeometryHandler) GeometryManager,
+    /* change_managed              */  XtInheritChangeManaged,
+    /* insert_child                */  XtInheritInsertChild,
+    /* delete_child                */  XtInheritDeleteChild,
+    /* extension                   */  NULL
+    }, 
+    { /*** constraint-Klasse ***/
+    /* resources                   */  NULL,
+    /* num_resources               */  0,
+    /* constraint_size             */  sizeof(XmManagerConstraintPart),
+    /* initialize                  */  NULL,
+    /* destroy                     */  NULL,
+    /* set_values                  */  NULL,
+    /* extension                   */  NULL
+    }, 
+    { /*** xmManager-Klasse ***/
+    /* translations                 */ XtInheritTranslations,
+    /* syn_resources                */ NULL,
+    /* num_syn_resources            */ 0,
+    /* syn_constraint_resources     */ NULL,
+    /* num_syn_constraint_resources */ 0,
+    /* parent_process              */  XmInheritParentProcess,
+    /* extension                   */  NULL
+    }, 
+    { /*** combobox-Klasse ***/
+    /*                             */  0
+    }
+}; /* xmComboBoxClassRec */
+WidgetClass xmComboBoxWidgetClass = (WidgetClass) &xmComboBoxClassRec;
+
+/* --------------------------------------------------------------------
+ * --------------------------------------------------------------------
+ * Translation-Tabelle (hier allerdings fuer das Eingabefeld!)
+ * Tjaja....mit der Reihenfolge von Translations ist das schon so eine
+ * ziemlich boese Sache!
+ */
+static char newEditTranslations[] =
+    "Alt<Key>osfDown:      ComboBox-Manager(show-hide-list)    \n\
+     Meta<Key>osfDown:     ComboBox-Manager(show-hide-list)    \n\
+     Alt<Key>osfUp:        ComboBox-Manager(hide-list)         \n\
+     Meta<Key>osfUp:       ComboBox-Manager(hide-list)         \n\
+     <Key>osfUp:           ComboBox-Manager(up)                \n\
+     <Key>osfDown:         ComboBox-Manager(down)              \n\
+     <Key>osfPageUp:       ComboBox-Manager(page-up)           \n\
+     <Key>osfPageDown:     ComboBox-Manager(page-down)         \n\
+     <Key>osfCancel:       ComboBox-Manager(cancel)            \n\
+     <Key>Return:          ComboBox-Manager(activate) activate()"
+    ;
+/* speziell bei der nicht editierbaren Combo-Box sind noch einige
+ * andere Tasten belegt, die sonst dem Eingabefeld alleine gehoeren.
+ * Die dazugehoerigen neuen Translations befinden sich in dieser
+ * zusaetzlichen Tabelle, das Anhaengsel ...NE ist dabei die Ab-
+ * kuerzung fuer "non editable".
+ */
+static char newEditTranslationsNE[] = 
+    "<Key>osfDelete:       ComboBox-Manager(wipe-out)          \n\
+     <Key>osfBeginLine:            ComboBox-Manager(top)               \n\
+     <Key>osfEndLine:      ComboBox-Manager(bottom)              "
+    ;
+/* Momentan gibt es noch Aerger mit dem Drag'n'Drop-Mechanismus
+ * von Motif 1.2. Legen wir ihn deshalb erst einmal still, solange
+ * bis ich weiss, warum, und eine Loesung parat habe. NEU: Nur wenn
+ * Sie mit einer libXm geschlagen sind, die partout nicht funktionieren
+ * will, muessen Sie Drag'n'Drop stillegen, ansonsten klappts doch!
+ */
+#ifdef NODRAGNDROP
+static char newListTranslations[] =
+    "<Btn2Down>:           ComboBox-Manager(no-operation)      ";
+#endif
+static char newListTranslationsE[] =
+    "<Key>osfPageUp:       ComboBox-Manager(page-up)           \n\
+     <Key>osfPageDown:     ComboBox-Manager(page-down)         ";
+   
+/* ---------------------------------------------------------------------------
+ * ---------------------------------------------------------------------------
+ * Aktionen-Tabelle: Hierdurch werden den einzelnen Translations die dazuge-
+ * hoerigen C-Routinen zugeordnet. Da wir hier ein anstaendiges ANSI-C be-
+ * nutzen, werden hier zuerst einmal die Prototypen faellig... Ach ja, noch
+ * ein Hinweis in eigener Sache... der ComboBox-Manager muss applikationsweit
+ * registriert werden, da er auch von Translationen in den Kindern der Combo-
+ * Box aktiviert wird. Bei diesem Namen der 'Aktion' steht aber nicht zu be-
+ * fuerchten, dass er anderweitig bereits in Anwendung ist.
+ */
+static void CBoxManager(Widget w, XEvent *event, String *params, 
+                        Cardinal *num_params);
+
+static XtActionsRec actions[] = {
+    { "ComboBox-Manager", CBoxManager },
+    { NULL, NULL }
+}; /* actions */
+
+    
+/* --------------------------------------------------------------------
+ * Eine Instanz dieser Widget-Klasse wird erstmalig in Betrieb ge-
+ * nommen, daher sind noch Vorbereitungen notwendig, die nun hier
+ * durchgefuehrt werden.
+ */
+static XtTranslations NewEditTranslations, NewEditTranslationsNE, 
+                      NewListTranslations, NewListTranslationsE;
+
+static XtConvertArgRec ConverterScreenConvertArg[] = {
+    { XtBaseOffset, (XtPointer) XtOffset(Widget, core.screen), 
+      sizeof(Screen *) }
+};
+
+static void ClassInit()
+{
+    NewEditTranslations =
+           XtParseTranslationTable(newEditTranslations);
+    NewEditTranslationsNE =
+           XtParseTranslationTable(newEditTranslationsNE);
+#ifdef NODRAGNDROP
+    NewListTranslations =
+           XtParseTranslationTable(newListTranslations);
+#endif
+    NewListTranslationsE =
+           XtParseTranslationTable(newListTranslationsE);
+    XtAddConverter(XtRString, XtRBitmap, 
+                   XmuCvtStringToBitmap, 
+                  ConverterScreenConvertArg, 
+                   XtNumber(ConverterScreenConvertArg));
+} /* ClassInit */
+
+/* ---------------------------------------------------------------------------
+ * Weil es sich bei diesem Widget um ein etwas komplizierteres zusammengesetz-
+ * tes Widget handelt, muessen wir hier - wo eigentlich nur das die Combobox
+ * bildende Fenster auf dem X-Server erzeugt wird - noch einmal das Layout
+ * auf Vordermann bringen. Den Aerger loest dabei das Listenfeld der OSF aus,
+ * das einfach keine Geometrie-Nachfragen verschickt, solange es nicht 
+ * 'realized' ist!!! Nicht, dass ich mich ueber so einen Sauhaufen aufregen 
+ * wuerde...ich doch nicht! ABER MACHT IHR DENN NUR SO'N MIST...? WARUM KOENNT
+ * IHR DENN NICHT EINMAL DIESES ****(BIEP)**** MOTIF TOOLKIT ANSTAENDIG
+ * DOKUMENTIEREN! Ich glaub', ich kann mich nach dem Chaos eigentlich nur noch
+ * hemmungslos besaufen... Die Suche nach der Ursache (bzw. Urheber = OSF) hat
+ * mich doch einige Tage gekostet (jaja...die Mannstunden!).
+ */
+static void Realize(XmComboBoxWidget w, Mask *ValueMask, 
+                    XSetWindowAttributes *Attributes)
+{
+    /* 
+     * Also: wenn die Liste staendig sichtbar ist, dann zuerst noch einmal
+     * das Layout berechnen. Sonst wird vorne und hinten 'was abgeschnitten.
+     */
+    if ( w->combobox.StaticList )
+       DoLayout(w);
+    (*w->core.widget_class->core_class.superclass->core_class.realize)
+       ((Widget) w, ValueMask, Attributes);
+} /* Realize */
+
+/* ---------------------------------------------------------------------------
+ * Suche dasjenige Fenster, in dem unsere Shell liegt, in der wiederum die 
+ * Combo-Box steckt. Diese Information wird benoetigt, um die Drop-Down-Liste
+ * innerhalb des Fensterstacks immer direkt oberhalb der Shell mit der Combo-
+ * Box zu halten. Jajaja -- ich muss halt davon ausgehen, dass der Fenster-
+ * manager ein sog. "reparenting wm" ist; also die Dekorationen in einem
+ * Fenster dargestellt werden und unsere Shell in dieses Fenster hineingepackt
+ * ist. Die Dekoration ist damit ein Kind des 'root window' - wie die Shell,
+ * in der die Drop-Down-Liste steckt. Und da nur Geschwisterfenster (sibling
+ * windows) im gleichen Stapel stecken, reicht das Shellfenster nicht aus.
+ * Alle gaengigen Fenstermanager sind solche "reparenting wm's", so dass ich
+ * hier zu diesem Trick greifen kann, um die Drop-Down-Liste immer ueber der
+ * ComboBox zu halten.
+ *
+ * Parameter:
+ *   w                 Diejenige Combo-Box, fuer die wir dasjenige
+ *                     Fenster des Window-Managers ermitteln sollen,
+ *                     dass direkt unterhalb des Root-Fensters liegt.
+ * Ergebnis:
+ *   besagtes zu suchendes Fenster, dass die Dekoration enthaelt (hoffentlich
+ *   nur echte Bruesseler Spitze!)
+ */
+static Window GetDecorationWindow(XmComboBoxWidget w)
+{
+    Window       Root, Parent, AWindow;
+    Window       *Children;
+    unsigned int NumChildren;
+    
+    Parent = XtWindow((Widget) w);
+    /* Suche nach dem Dekorationsfenster des Window-Managers */
+    do {
+       AWindow = Parent;
+       XQueryTree(XtDisplay((Widget) w), AWindow, 
+                  &Root, &Parent, &Children, &NumChildren);
+       XFree((char *) Children);
+    } while ( Parent != Root );
+    return AWindow;
+} /* GetDecorationWindow */
+
+/* --------------------------------------------------------------------
+ * Eine Combo-Box aus dem Wege raeumen...
+ * Momentan muessen wir hier nur den Cursor wieder los werden sowie
+ * eventuell reservierte Pixmaps.
+ * Ups -- natuerlich muss auch wieder der Callback entfernt werden, 
+ * der noch an der Shell haengt.
+ */
+static void Destroy(XmComboBoxWidget w)
+{
+/*    fprintf(stderr, "Destroy: %08X\n", w->core.window);*/
+    if ( w->combobox.ConvertBitmapToPixmap )
+       XFreePixmap(XtDisplay((Widget) w), 
+                   w->combobox.LabelPixmap);
+    if ( w->combobox.ConvertBitmapToPixmapInsensitive )
+       XFreePixmap(XtDisplay((Widget) w), 
+                   w->combobox.LabelInsensitivePixmap);
+    if ( w->combobox.PendingFocusOut )
+       XtRemoveWorkProc(w->combobox.WorkProcID);
+    XtRemoveEventHandler(w->combobox.MyNextShell, 
+                      StructureNotifyMask | FocusChangeMask, 
+                     True, (XtEventHandler) ShellCallback, 
+                     (XtPointer) w);
+} /* Destroy */
+
+/* ---------------------------------------------------------------------------
+ * Ueberpruefe, ob fuer die Ressource "DropDownOffset" ein gueltiger Wert vom
+ * Benutzer angegeben wurde. Diese Ressource gibt an, wie weit die Drop-Down-
+ * Liste nach rechts gegenueber dem Eingabefeld eingerueckt sein soll. Wenn
+ * hierfuer ein negativer Wert angegeben ist, so berechne statt dessen einen
+ * Standardwert: dieser entspricht der Breite der Pfeilschaltflaeche, was 
+ * optisch ganz gut wirkt (jedenfall nach meinem Dafuerhalten).
+ */
+static void CheckDropDownOffset(XmComboBoxWidget w)
+{
+    if ( w->combobox.DropDownOffset < 0 ) {
+       XtWidgetGeometry ArrowGeom;
+       
+       XtQueryGeometry(w->combobox.ArrowCtrl, NULL, &ArrowGeom);
+       w->combobox.DropDownOffset = ArrowGeom.width;
+    }
+} /* CheckDropDownOffset */
+
+/* --------------------------------------------------------------------
+ * Berechne die voreinzustellende Groesse, die diese Combo-Box be-
+ * sitzen muss, um ausreichenden Raum fuer das Eingabefeld und den
+ * Pfeil rechts daneben zur Verfuegung zu stellen. Bei einer
+ * editierbaren Combo-Box ist zwischen dem Eingabefeld und dem Pfeil
+ * noch ein Angst-Rasen von der halben Breite eines Pfeiles vorhanden.
+ * Wird das Listenfeld staendig dargestellt, so entfallen sowohl Pfeil
+ * als auch der Angstrasen, dafuer muss aber die Hoehe des Listenfelds
+ * beruecksichtigt werden.
+ */
+static void DefaultGeometry(XmComboBoxWidget w, 
+                            Dimension *TotalWidth, 
+                           Dimension *TotalHeight, 
+                           Dimension *EditCtrlWidth, 
+                           Dimension *LabelCtrlWidth)
+{
+    XtWidgetGeometry EditGeom, ArrowGeom, LabelGeom, ListGeom;
+    
+    XtQueryGeometry(w->combobox.EditCtrl,  NULL, &EditGeom);
+    XtQueryGeometry(w->combobox.ArrowCtrl, NULL, &ArrowGeom);
+    XtQueryGeometry(w->combobox.LabelCtrl, NULL, &LabelGeom);
+
+    /*
+     * Soll die Pfeilschaltflaeche quadratisch, praktisch, gut sein?
+     */
+    if ( w->combobox.SquareArrow )
+        ArrowGeom.width = ArrowGeom.height;
+    else
+        ArrowGeom.width = (ArrowGeom.height * 4) / 5;
+
+    /*
+     * Zuerst einmal ein paar einfache Werte ermitteln und zurueckgeben...
+     */    
+    *TotalHeight    = EditGeom.height;
+    *EditCtrlWidth  = EditGeom.width;
+    *LabelCtrlWidth = LabelGeom.width;
+
+    /*
+     * Ermittele nun die Breite, welche die Combobox benoetigt. Je nach-
+     * dem, ob das Eingabefeld oder die Liste breiter sind, wird der
+     * entsprechende Wert genommen. Diese Auswahl zwischen der Breite von
+     * Eingabefeld und Liste findet aber nur statt, wenn die Liste auch
+     * wirklich staendig sichtbar ist. Waehrend der Initialisierung hat
+     * allerdings XmNcolumns, so dass in diesem Moment die List nicht
+     * mehr die Breite kontrollieren kann!
+     */
+    if ( w->combobox.StaticList ) {
+       /*
+        * Beachte: Frage nicht die Listbox, sondern das ScrolledWindow, 
+        * in welchem die Liste eingebettet ist.
+        */
+       CheckDropDownOffset(w);
+       XtQueryGeometry(XtParent(w->combobox.ListCtrl), NULL, &ListGeom);
+       if ( w->combobox.InInit ) {
+           *TotalWidth = EditGeom.width;
+       } else {
+            if ( EditGeom.width < (Dimension)
+                                   (ListGeom.width + w->combobox.DropDownOffset) )
+               *TotalWidth = ListGeom.width + w->combobox.DropDownOffset;
+           else
+               *TotalWidth = EditGeom.width;
+        }
+       *TotalHeight += ListGeom.height;
+    } else {
+       /*
+        * Das Listenfeld interessiert uns hier nicht. Degegen sollte noch
+        * die Breite fuer den Pfeil und ein evtl. Angstrasen beachtet
+        * werden.
+        */
+       *TotalWidth  = EditGeom.width + ArrowGeom.width;
+       if ( w->combobox.Editable && w->combobox.ArrowSpacingOn )
+           *TotalWidth += ArrowGeom.width/2;
+    }
+    
+    /*
+     * Vergiss nicht, auch noch ein evtl. sichtbares Schriftfeld zu berueck-
+     * sichtigen!
+     */
+    if ( w->combobox.ShowLabel )
+       *TotalWidth += LabelGeom.width;
+    
+} /* DefaultGeometry */
+
+/* --------------------------------------------------------------------
+ * Anhand eines Widgets ermittele darueber die Screennummer desjenigen
+ * Screens, auf dem das Widget erscheint.
+ * Parameter:
+ *   w                 betroffenes Widget.
+ * Ergebnis:
+ *   Nummer desjenigen Screens, auf dem das Widget angezeigt wird.
+ */
+static int WidgetToScreen(Widget w)
+{
+    Screen  *screen;
+    Display *display;
+    int     NumScreens, i;
+    
+    screen = XtScreen(w); NumScreens = ScreenCount(XtDisplay(w));
+    display = DisplayOfScreen(screen);
+    for ( i = 0; i < NumScreens; ++i )
+       if ( ScreenOfDisplay(display, i) == screen )
+           return i;
+    XtError("WidgetToScreen: data structures are destroyed.");
+} /* WidgetToScreen */
+
+/* --------------------------------------------------------------------
+ * Positioniere die DropDown-Liste (soweit sie natuerlich auch momentan
+ * sichtbar ist) so auf dem Bildschirm, dass sie sich unterhalb des
+ * Eingabefeldes anschliesst.
+ */
+static void DoDropDownLayout(XmComboBoxWidget w)
+{
+    Position       abs_x, abs_y;
+    Dimension      ArrowWidth, ListWidth, ListHeight;
+    Dimension      ScreenHeight, LabelWidth;
+    Window         Decoration;
+    XWindowChanges WindowChanges;
+
+    /* 
+     * etwa nicht sichtbar ?!! Oder etwa immer sichtbar ?!!
+     * Dann sind wir jetzt sofort fertig. 
+     */
+    if ( !w->combobox.ListVisible || w->combobox.StaticList ) return;
+    /*
+     * Finde zuerst einmal heraus, wo wir uns denn auf dem Bildschirm be-
+     * finden sollen... Beachte dabei auch, dass eventuell die Liste zu schmal
+     * werden koennte und gib' ihr dann ggf. eine Mindestbreite, damit es
+     * keinen core-Dump gibt.
+     */
+    XtVaGetValues(w->combobox.ArrowCtrl, XmNwidth,  &ArrowWidth, NULL);
+    XtTranslateCoords((Widget) w, 0, w->core.height, &abs_x, &abs_y);
+    CheckDropDownOffset(w);
+    ListWidth  = w->core.width - w->combobox.DropDownOffset - 2;
+    abs_x     += w->combobox.DropDownOffset;
+    if ( w->combobox.ShowLabel ) {
+       XtVaGetValues(w->combobox.LabelCtrl, XmNwidth, &LabelWidth, NULL);
+       ListWidth -= LabelWidth;
+       abs_x     += LabelWidth;
+    }
+    if ( ListWidth < 20 ) ListWidth = 20;
+    XtVaGetValues(XtParent(w->combobox.ListCtrl), XmNheight, &ListHeight, NULL);
+    /*
+     * Hier ueberpruefen wir noch, ob die Liste unten aus dem Bildschirm 
+     * herausfallen wuerde. In dem Fall klappen wir die Liste oberhalb des
+     * Eingabefeldes auf.
+     */
+    ScreenHeight = DisplayHeight(XtDisplay((Widget) w), 
+                                 WidgetToScreen((Widget) w));
+    if ( abs_y + ListHeight + 2 > ScreenHeight ) {
+        int y;
+        
+        y = ((int) abs_y) - ListHeight - w->core.height - 1;
+        if ( y < 0 ) y = 0;
+        abs_y = (Position) y;
+    }
+    XtConfigureWidget(w->combobox.PopupShell, 
+                     abs_x, abs_y, ListWidth, ListHeight, 1);
+    /*
+     * So...das hier dient der Kosmetik: hier sorgen wir dafuer, dass die
+     * Liste auch wirklich immer direkt ueber der ComboBox innerhalb des
+     * Fensterstapels schwebt. Siehe dazu auch die Erlaeuterungen und An-
+     * merkungen in GetDecorationWindow().
+     */
+    if ( XtIsRealized((Widget) w) ) {
+       WindowChanges.sibling    = GetDecorationWindow(w);
+       WindowChanges.stack_mode = Above;
+       XReconfigureWMWindow(XtDisplay((Widget) w), 
+           XtWindow(w->combobox.PopupShell), 
+           WidgetToScreen(w->combobox.PopupShell), 
+           CWSibling | CWStackMode, &WindowChanges);
+    }
+} /* DoDropDownLayout */
+
+/* --------------------------------------------------------------------
+ * Naja... diese Routine scheint ja bereits zu einer Institution beim
+ * Schreiben von Composite-Widgets geworden zu sein.
+ * 
+ * Hier beim ComboBox-Widget ist die Aufgabe ziemlich einfach: es
+ * genuegt, die Eingabezeile und den Pfeil-Button entsprechend inner-
+ * halb des ComboBox-Widgets zu plazieren. Seit allerdings noch das
+ * Textlabel hinzukommt, wird's langsam aufwendiger. Nun ja - da sich
+ * das Listenfeld wahlweise auch statisch einblenden laesst, ist nun
+ * noch mehr zu beruecksichtigen, wenn die Kinder-Widgets an ihre
+ * Plaetze geschoben werden.
+ */
+static void DoLayout(XmComboBoxWidget w)
+{
+    Dimension        EditCtrlWidth, ArrowCtrlWidth, LabelCtrlWidth;
+    Dimension        ComboBoxHeight;
+    Dimension        BorderWidth;
+    Dimension        HighlightThickness;
+    Position         EditX;
+    
+    XtVaGetValues(w->combobox.ArrowCtrl,
+                  XmNheight, &ArrowCtrlWidth, NULL);
+    if ( !w->combobox.SquareArrow )
+        ArrowCtrlWidth = (ArrowCtrlWidth * 4) / 5;
+    XtVaGetValues(w->combobox.LabelCtrl, 
+                  XmNwidth, &LabelCtrlWidth, NULL);
+    
+    /* 
+     * In Abhaengigkeit davon, ob die ComboBox editierbar ist und ob das
+     * Listenfeld staendig sichtbar sein soll, hier die Breite einzelner
+     * Widgets bestimmen.
+     */
+    if ( w->combobox.StaticList ) {
+       ComboBoxHeight = w->combobox.EditCtrl->core.height;
+       EditCtrlWidth  = w->core.width;
+    } else {
+       ComboBoxHeight = w->core.height;
+       EditCtrlWidth  = w->core.width - ArrowCtrlWidth;
+       if ( w->combobox.Editable && w->combobox.ArrowSpacingOn )
+           EditCtrlWidth -= ArrowCtrlWidth/2;
+    }
+    /* Beruecksichtige noch ein evtl. ebenfalls anzuzeigendes Schriftfeld
+     * neben dem Eingabefeld.
+     */
+    if ( w->combobox.ShowLabel ) {
+       EditX          = LabelCtrlWidth;
+       EditCtrlWidth -= LabelCtrlWidth;
+    } else
+        EditX = 0;
+    if ( EditCtrlWidth < 20 ) EditCtrlWidth = 20;
+/* Plaziere nun das Eingabefeld... */
+    XtVaGetValues(w->combobox.EditCtrl, 
+                  XmNborderWidth,        &BorderWidth, 
+                 XmNhighlightThickness, &HighlightThickness, 
+                 NULL);
+    XtConfigureWidget(w->combobox.EditCtrl, 
+                      EditX, 0, 
+                     EditCtrlWidth, ComboBoxHeight, BorderWidth);
+/* ...und nun den Pfeil... */
+    XtVaGetValues(w->combobox.ArrowCtrl, 
+                  XtNborderWidth, &BorderWidth, NULL);
+    XtConfigureWidget(w->combobox.ArrowCtrl, 
+                      w->core.width-ArrowCtrlWidth, HighlightThickness, 
+                     ArrowCtrlWidth, 
+                     ComboBoxHeight - 2 * HighlightThickness, 
+                     BorderWidth);
+/* ...und ggf. das Textlabel. */
+    if ( w->combobox.ShowLabel ) {
+       XtVaGetValues(w->combobox.LabelCtrl, 
+                     XmNborderWidth, &BorderWidth, 
+                     NULL);
+       XtConfigureWidget(w->combobox.LabelCtrl, 
+                         0, 0, 
+                         LabelCtrlWidth, ComboBoxHeight, 
+                         BorderWidth);
+    }
+/* Falls da noch die Liste herumgurkt... */
+    if ( w->combobox.StaticList ) {
+       Dimension Width, Height;
+       
+       if ( w->core.height > ComboBoxHeight ) 
+           Height = w->core.height - ComboBoxHeight;
+       else
+           Height = 10;
+           
+       if ( w->core.width > (Dimension)(ArrowCtrlWidth + EditX) )
+           Width = w->core.width - ArrowCtrlWidth - EditX;
+       else
+           Width = 10;
+       
+       XtConfigureWidget(XtParent(w->combobox.ListCtrl),
+           EditX + ArrowCtrlWidth, ComboBoxHeight, Width, Height, 0);
+    } else if ( w->combobox.ListVisible )
+       DoDropDownLayout(w); 
+} /* DoLayout */
+
+/* --------------------------------------------------------------------
+ * Pappi fragt nach, wie gross wir denn sein wollen.
+ * Die hier benutzte Vorgehensweise zur Ermittlung der Groesse:
+ *   Sobald der Vater uns eine Breite (oder aber Hoehe) vorschlaegt, 
+ *   die fuer uns eigentlich zu klein ist, meckern wir und schlagen
+ *   die von uns benoetigte Breite (Hoehe) vor.
+ * Soweit also zur Theorie... leider sieht es beispielsweise das
+ * Motif Form-Widget ueberhaupt nicht ein, uns auch nur ein einziges
+ * Mal nach unseren Wuenschen zu fragen! Damit es bei derart unum-
+ * gaenglichen Widgets dann doch noch geht, muss ChangedManaged die
+ * Kohlen wieder aus dem Feuer holen mit einer Sondertour.
+ * Parameter:
+ *   *Request      Vom Vater vorgeschlagene Geometrie
+ * Ergebnis:
+ *   *Reply        Unsere Antwort auf die vorgeschlagene Geometrie
+ *   sowie XtGeometryYes oder XtGeometryAlmost, je nachdem, wie gut
+ *   uns Pappis Vorschlag in den Kram passt.
+ */
+static XtGeometryResult QueryGeometry(XmComboBoxWidget w, 
+                                      XtWidgetGeometry *Request, 
+                                     XtWidgetGeometry *Reply)
+{
+    XtGeometryResult result = XtGeometryYes;
+    Dimension        minW, minH, editW, labelW;
+    
+/* Elternteil will nichts weiter aendern, also ist uns das
+ * recht so.
+ */
+    Request->request_mode &= CWWidth | CWHeight;
+    if ( Request->request_mode == 0 ) return result;
+
+    DefaultGeometry(w, &minW, &minH, &editW, &labelW);
+
+/* Ueberpruefe, ob uns das in der Breite passt, was Pappi moechte... */
+    if ( Request->request_mode & CWWidth ) {
+       if ( Request->width < minW ) {
+/* Wenn Pappi uns etwas vorschlaegt, was im wahrsten Sinne des Wortes 
+ * vorn und hinten nicht reicht, dann versuchen wir ihn entsprechend
+ * zu korrigieren. ("Versuchen" deshalb, weil er diesen Vorschlag auch
+ * voellig ignorieren kann.)
+ */
+           result               = XtGeometryAlmost;
+           Reply->width         = minW;
+           Reply->request_mode |= CWWidth;
+       }
+    }
+/* Die ganze Chose nun noch vertikal */
+    if ( Request->request_mode & CWHeight ) {
+       if ( Request->height < minH ) {
+           result               = XtGeometryAlmost;
+           Reply->height        = minH;
+           Reply->request_mode |= CWHeight;
+       }
+    }
+    return result;
+} /* QueryGeometry */
+
+/* --------------------------------------------------------------------
+ * Die Groesse des ComboBox-Widgets hat sich veraendert und deshalb
+ * mussen alle Kinder neu positioniert werden.
+ * Letzten Endes laeuft hier alles auf ein ordinaeres DoLayout()
+ * hinaus, um die Kinder umher zu schieben.
+ * Parameter:
+ *   w             Die bereits hinlaenglich bekannte Instanz dieses
+ *                 Widgets
+ */
+static void Resize(XmComboBoxWidget w)
+{
+    DoLayout(w);
+} /* Resize */
+
+/* --------------------------------------------------------------------
+ * Dieses Widget hat sich in irgendeiner Form bewegt (und das nicht
+ * nur relativ zum Vater, sondern moeglicherweise auch der Vater
+ * selbst!) bzw. die Shell, in der sich irgendwo unsere Combo-Box
+ * befindet, hat soeben den Fokus verschusselt und kann ihn nicht
+ * mehr wiederfinden. Daneben kann es auch sein, dass die Shell
+ * ikonisiert wurde. (Welch' Vielfalt! Dieses ist hier halt eine
+ * multifunktionale Routine.)
+ * 
+ * Parameter:
+ *   w             Die naechste Shell in Reichweite ueber unserer
+ *                 Combo-Box.
+ *   cbw           Diese Combo-Box.
+ *   event         ^ auf den Event, enthaelt genauerere Informationen
+ *                 (naja... sieht so aus, als ob Motif hier auch 
+ *                 schon 'mal Schrott 'reinpackt...)
+ *   ContDispatch   Auf True setzen, damit dieser Event noch weiter-
+ *                 gereicht wird an all' die anderen, die auch noch
+ *                 mithoeren.
+ */
+static void ShellCallback(Widget w, XtPointer pClientData, 
+                          XEvent *event, Boolean *ContDispatch)
+{
+    XmComboBoxWidget cbw = (XmComboBoxWidget) pClientData;
+    
+    switch ( event->type ) {
+       case ConfigureNotify:
+       case CirculateNotify:
+           DoDropDownLayout((XmComboBoxWidget) cbw);
+           break;
+       case FocusOut:
+           LOG3("ShellCallback: FocusOut, mode: %i, detail: %i\n",
+                (int)event->xfocus.mode, (int)event->xfocus.detail);
+           if ( cbw->combobox.Persistent )
+               cbw->combobox.IgnoreFocusOut = True;
+           else if ( (event->xfocus.mode == NotifyGrab) &&
+                     cbw->combobox.ListVisible )
+               cbw->combobox.IgnoreFocusOut = True;
+           break;
+       case UnmapNotify:
+           ShowHideDropDownList((XmComboBoxWidget) cbw, 
+                                event, False);
+           break;
+    }
+    *ContDispatch = True;
+} /* ShellCallback */
+
+/* --------------------------------------------------------------------
+ * Diese Routine sorgt dafuer, dass die Liste nicht irrtuemlich bei
+ * manchen Window Managern vom Bildschirm genommen wird, bloss weil
+ * diese der OverrideShell den Tastaturfocus schenken bzw. diesen
+ * dem Combo-Box-Widget wegnehmen, sobald der Mauszeiger in die Liste
+ * bewegt wird.
+ */
+static void OverrideShellCallback(Widget w, XtPointer pClientData,
+                                  XEvent *event, Boolean *ContDispatch)
+
+{
+    XmComboBoxWidget cbw = (XmComboBoxWidget) pClientData;
+    switch ( event->type ) {
+        case EnterNotify:
+           LOG2("OverrideShellCallback: EnterNotify, PendingFO: %s\n", 
+                cbw->combobox.PendingFocusOut ? "True" : "False");
+            if ( cbw->combobox.PendingFocusOut )
+                cbw->combobox.IgnoreFocusOut = True;
+           if ( cbw->combobox.TwmHandlingOn )
+                cbw->combobox.PendingOverrideInOut = True;
+            break;
+        case LeaveNotify:
+            LOG("OverrideShellCallback: LeaveNotify\n");
+           if ( cbw->combobox.TwmHandlingOn )
+              cbw->combobox.PendingOverrideInOut = True;
+            break;
+    }
+} /* OverrideShellCallback */
+
+/* --------------------------------------------------------------------
+ * Ha! Anscheinend kann man das Problem mit der einklappenden Liste,
+ * sobald man den Arrow-Button anklickt, doch loesen! Allerdings geht
+ * das auch nur von hinten durch die Brust in's Auge. Hier war die
+ * Reihenfolge der Events bislang das Problem: Klickt man den Arrow-
+ * Button an, so verliert das Eingabefeld den Focus, dann wird leider
+ * schon die WorkProc aktiviert und laesst die Liste verschwinden.
+ * Danach erst kommt der Arrow-Button-Callback an die Reihe. Um dieses
+ * Dilemma doch noch zu loesen, wird hier darauf gelauert, wann und
+ * welcher LeaveNotify kommt. Klickt der Benutzer den Pfeil an, so
+ * kommt hier noch rechtzeitig ein LeaveNotify vorbei, der aber durch
+ * einen Grab ausgeloest wurde. Und das ist eben nur beim Anklicken
+ * der Fall. Damit wissen wir, das der FocusOut getrost ignoriert
+ * werden darf.
+ * Puhhh -- ist das ein kompliziertes Chaos.
+ * Uebrigends...auch wenn manche Befehle zuerst ueberfluessig er-
+ * scheinen...sie sind erforderlich, damit die ComboBox auch mit unter-
+ * schiedlichen Window Managern zurechtkommt!
+ */
+static void ArrowCrossingCallback(Widget w, XtPointer pClientData,
+                               XEvent *event, Boolean *ContDispatch)
+
+{
+    XmComboBoxWidget cbw = (XmComboBoxWidget) pClientData;
+    switch ( event->type ) {
+        case LeaveNotify:
+           LOG2("ArrowCrossingCallback: LeaveNotify, mode: %i\n", 
+                event->xcrossing.mode);
+            if ( event->xcrossing.mode == NotifyGrab )
+                cbw->combobox.IgnoreFocusOut = True;
+            else
+                cbw->combobox.IgnoreFocusOut = False;
+            break;
+    }
+} /* ArrowCrossingCallback */
+
+/* --------------------------------------------------------------------
+ * Alle Hilfeaufrufe innerhalb der Kinder gehen an das eigentliche
+ * Combo-Box-Widget weiter, so dass auch hier nach aussen hin die
+ * Kinder-Widgets nicht in Erscheinung treten.
+ */
+static void HelpCallback(Widget w, XtPointer cbw, XtPointer CallData)
+{
+    XtCallCallbacks((Widget) cbw, XmNhelpCallback, CallData);
+} /* HelpCallback */
+
+/* --------------------------------------------------------------------
+ * Wenn der Benutzer im Eingabefeld osfActivate drueckt, dann dieses
+ * Ereignis offiziell bekanntgeben.
+ */
+static void ActivateCallback(Widget w, XtPointer cbw, XtPointer CallData)
+{
+    XtCallCallbacks((Widget) cbw, XmNactivateCallback, CallData);
+} /* ActivateCallback */
+
+/* --------------------------------------------------------------------
+ * Ein Kind moechte sein Groesse veraendern und fragt deshalb hier bei
+ * uns an.
+ * Parameter:
+ *   w             Naja...
+ *   *Request      Vorschlag des Kindes
+ * Ergebnis:
+ *   *Reply        Unsere Antwort darauf
+ *   XtGeometryNo, da es uns bislang grundsaetzlich nie passt, es sei
+ *   denn, es ist das Label... Naja, jetzt darf auch schon einmal das
+ *   Listenfeld quengeln (aber nur, wenn es staendig sichtbar ist, 
+ *   ansonsten wird es nicht beruecksichtigt!).
+ */
+static XtGeometryResult GeometryManager(Widget w, 
+                                        XtWidgetGeometry *Request, 
+                                       XtWidgetGeometry *Reply)
+{
+    XmComboBoxWidget cbw = (XmComboBoxWidget) XtParent(w);
+    XtGeometryResult Result = XtGeometryNo;
+    
+    /*
+     * Falls das Listenfeld statisch dargestellt wird, muessen wir seine
+     * Wuensche doch beruecksichtigen. Was fuer ein Aufwand...
+     */
+    if ( (w == XtParent(cbw->combobox.ListCtrl)) && cbw->combobox.StaticList ) {
+        Dimension TotalWidth, TotalHeight, EditWidth, LabelWidth;
+        XtWidgetGeometry MyRequest, YourReply, EditGeom;
+        
+        XtQueryGeometry(cbw->combobox.EditCtrl, NULL, &EditGeom);
+        DefaultGeometry(cbw, &TotalWidth, &TotalHeight,
+                             &EditWidth, &LabelWidth);
+       CheckDropDownOffset(cbw);
+       
+        if ( Request->request_mode && CWWidth )
+            if ( (Dimension)(LabelWidth + cbw->combobox.DropDownOffset + 
+                             Request->width) > TotalWidth )
+                TotalWidth = LabelWidth + cbw->combobox.DropDownOffset + 
+                             Request->width;
+        
+        if ( Request->request_mode && CWHeight )
+            TotalHeight = EditGeom.height + Request->height;
+    /*
+     * Bastele nun eine Anfrage an Pappi zusammen und geh' ihm damit auf den
+     * Keks. Wenn er zustimmt, ist sofort alles gut, wir muessen dann nur
+     * noch das Layout aufpolieren, damit das Listenfeld die neue Groesse
+     * bekommt. Wenn Pappi nur halb zustimmt, akzeptieren wir das und fragen
+     * ihn damit noch einmal....
+     */
+        MyRequest.request_mode = CWWidth | CWHeight;
+        MyRequest.width        = TotalWidth;
+        MyRequest.height       = TotalHeight;
+        Result = XtMakeGeometryRequest((Widget) cbw, &MyRequest, &YourReply);
+       if ( Result == XtGeometryAlmost ) {
+           MyRequest.width  = YourReply.width;
+           MyRequest.height = YourReply.height;
+           Result = XtMakeGeometryRequest((Widget) cbw, &MyRequest, &YourReply);
+       }
+       if ( Result == XtGeometryYes )
+           DoLayout(cbw);
+    } else 
+    /*
+     * Ansonsten darf nur noch das Schriftfeld Ansprueche anmelden.
+     */
+    if ( w != cbw->combobox.LabelCtrl )
+        return XtGeometryNo; /* Was ICH hier vorgegeben habe, gilt! */
+    else if ( cbw->combobox.ShowLabel ) { /* Naja, 'mal schauen! */
+        Dimension TotalWidth, TotalHeight, EditWidth, LabelWidth;
+        XtWidgetGeometry MyRequest;
+        
+        if ( Request->request_mode & CWWidth ) {
+            DefaultGeometry(cbw, &TotalWidth, &TotalHeight,
+                                 &EditWidth, &LabelWidth);
+            TotalWidth = TotalWidth - LabelWidth + 
+                         Request->width;
+            
+            MyRequest.request_mode = CWWidth;
+            MyRequest.width        = TotalWidth;
+            Result = XtMakeGeometryRequest((Widget) cbw, &MyRequest, NULL);
+
+            if ( Result == XtGeometryYes )
+               DoLayout(cbw);
+        }
+    }
+    return Result;
+} /* GeometryManager */
+
+/* --------------------------------------------------------------------
+ * Hier werden auf Wunsch diejenigen Farben, die bei der Combo-Box neu
+ * gesetzt wurden, an alle Kinder weitergegeben.
+ */
+#define BOTTOMSHADOWCOLOR   0x0001
+#define TOPSHADOWCOLOR     0x0002
+#define FOREGROUND         0x0004
+#define BACKGROUND         0x0008
+
+static struct { String Resource; int Flag; }
+       ColorResources[] = {
+          { XmNbottomShadowColor, BOTTOMSHADOWCOLOR }, 
+          { XmNtopShadowColor,    TOPSHADOWCOLOR    }, 
+          { XmNforeground,        FOREGROUND        }, 
+          { XmNbackground,        BACKGROUND        }
+       };
+
+static UpdateColors(XmComboBoxWidget w, int flags)
+{
+    Pixel  Color;
+    int    i, size = XtNumber(ColorResources);
+    Widget ScrolledWin, ScrollBar;
+    
+    ScrolledWin = XtParent(w->combobox.ListCtrl);
+    XtVaGetValues(ScrolledWin, XmNverticalScrollBar, &ScrollBar, NULL);
+    for ( i=0; i<size; i++ )
+       if ( flags & ColorResources[i].Flag ) {
+           XtVaGetValues((Widget) w, ColorResources[i].Resource, &Color,
+                         NULL);
+           XtVaSetValues(w->combobox.ListCtrl, 
+                         ColorResources[i].Resource, Color, NULL);
+           XtVaSetValues(ScrolledWin, 
+                         ColorResources[i].Resource, Color, NULL);
+           XtVaSetValues(ScrollBar, 
+                         ColorResources[i].Resource, Color, NULL);
+           XtVaSetValues(w->combobox.EditCtrl, 
+                         ColorResources[i].Resource, Color, NULL);
+           XtVaSetValues(w->combobox.LabelCtrl, 
+                         ColorResources[i].Resource, Color, NULL);
+           XtVaSetValues(w->combobox.ArrowCtrl, 
+                         ColorResources[i].Resource, Color, NULL);
+           if ( ColorResources[i].Flag & BACKGROUND )
+               XtVaSetValues(ScrollBar, XmNtroughColor, Color, NULL);
+       }
+
+       return 1;
+} /* UpdateColors */
+
+/* --------------------------------------------------------------------
+ * Liste aller vorgespiegelten Resourcen, die automatisch verarbeitet
+ * werden koennen, ohne weiter darueber nachdenken zu muessen...
+ */
+typedef enum  { EDITCTRL, LISTCTRL, LABELCTRL } CHILDCTRL;
+typedef enum { RO, RW, RWS, RWL, RWI, RWIGNORE } aUniqueName;
+typedef struct {
+    String                    rsc;
+    CHILDCTRL                 ctrl;
+/*    enum { RO, RW, RWS, RWL, RWI, RWIGNORE } dir; */
+    aUniqueName dir;
+    /* nur lesen, lesen&schreiben, lesen&schreiben spezial,
+       lesen&schreiben label, lesen&schreiben items */
+} MIRROR;
+
+/* Alle mit !!! gekennzeichneten Eintraege werden auf die richtigen
+ * Namen des entsprechenden Widgets umgesetzt.
+ */
+static MIRROR MirroredResources[] = {
+    { XmNitems,                            LISTCTRL,  RWI }, /* Urgs! */
+    { XmNitemCount,                LISTCTRL,  RWIGNORE  }, /* dto.  */
+    { XmNlistMarginHeight,         LISTCTRL,  RW  }, 
+    { XmNlistMarginWidth,          LISTCTRL,  RW  }, 
+    { XmNlistSpacing,              LISTCTRL,  RW  }, 
+    { XmNstringDirection,          LISTCTRL,  RO  }, /* Naja? */
+    { XmNtopItemPosition,          LISTCTRL,  RO  }, 
+    
+    { XmNblinkRate,                EDITCTRL,  RW  }, 
+    { XmNcolumns,                  EDITCTRL,  RW  }, 
+    { XmNcursorPosition,           EDITCTRL,  RW  }, 
+    { XmNcursorPositionVisible,            EDITCTRL,  RW  }, 
+    { XmNmarginHeight,             EDITCTRL,  RW  }, 
+    { XmNmarginWidth,              EDITCTRL,  RW  }, 
+    { XmNmaxLength,                EDITCTRL,  RW  }, 
+    { XmNselectThreshold,          EDITCTRL,  RW  }, 
+    { XmNvalue,                            EDITCTRL,  RWS }, 
+    
+    { XmNalignment,                LABELCTRL, RW  }, 
+    { XmNmnemonic,                 LABELCTRL, RW  }, 
+    { XmNmnemonicCharSet,          LABELCTRL, RW  }, 
+    { XmNlabelPixmap,              LABELCTRL, RW  }, 
+    { XmNlabelInsensitivePixmap,    LABELCTRL, RW  }, 
+    { XmNlabelString,              LABELCTRL, RW  }, 
+    { XmNlabelType,                LABELCTRL, RW  }, 
+    { XmNlabelMarginBottom,        LABELCTRL, RWL }, /* !!! */
+    { XmNlabelMarginHeight,        LABELCTRL, RWL }, /* !!! */
+    { XmNlabelMarginLeft,          LABELCTRL, RWL }, /* !!! */
+    { XmNlabelMarginRight,         LABELCTRL, RWL }, /* !!! */
+    { XmNlabelMarginTop,           LABELCTRL, RWL }, /* !!! */
+    { XmNlabelMarginWidth,         LABELCTRL, RWL }, /* !!! */
+    { XmNlabelFontList,             LABELCTRL, RWL }, /* !!! */
+};
+
+typedef struct {
+    char *from, *to;
+} TRANSFORMATION;
+static TRANSFORMATION Transformations[] = {
+    { XmNlabelMarginBottom, XmNmarginBottom }, 
+    { XmNlabelMarginHeight, XmNmarginHeight }, 
+    { XmNlabelMarginLeft,   XmNmarginLeft   }, 
+    { XmNlabelMarginRight,  XmNmarginRight  }, 
+    { XmNlabelMarginTop,    XmNmarginTop    }, 
+    { XmNlabelMarginWidth,  XmNmarginWidth  }, 
+    { XmNlabelFontList,     XmNfontList     },
+};
+
+/* --------------------------------------------------------------------
+ * Sobald irgendeine Resource veraendert wird, erfolgt der Aufruf
+ * hierin als Benachrichtigung, einmal nach dem rechten zu sehen.
+ * Parameter:
+ *   current       Kopie der Widget-Instanz, bevor irgendwelche
+ *                 Resourcen veraendert oder set_values()-Methoden
+ *                 aufgerufen wurden.
+ *   req           Kopie der Widget-Instanz, aber bereits mit den
+ *                 durch XtSetValues veraenderten Werten
+ *   new           aktuellster Zustand der Widget-Instanz mit
+ *                 veraenderten Werten (entweder durch XtSetValues
+ *                 oder set_values()-Methoden der Superklasse)
+ *   args          Argumentenliste beim Aufruf von XtSetValues()
+ *   NumArgs       Anzahl der Argumente in der Liste
+ * Ergebnis:
+ *   True, falls Widget neu gezeichnet werden soll.
+ */
+static Boolean SetValues(XmComboBoxWidget current, XmComboBoxWidget req, 
+                         XmComboBoxWidget newW, 
+                        ArgList args, Cardinal *NumArgs)
+{
+    Boolean Update = False;
+    int i, j, MirrorSize = XtNumber(MirroredResources);
+    int k, TransformationSize = XtNumber(Transformations);
+    Arg arg;
+    int Flags;
+    
+/* 
+ * Alle Resourcen, die nicht mehr nach dem Erstellen der Widget-Instanz
+ * veraendert werden koennen.
+ */
+    newW->combobox.Editable        = current->combobox.Editable;
+    newW->combobox.ListCtrl        = current->combobox.ListCtrl;
+    newW->combobox.EditCtrl        = current->combobox.EditCtrl;
+    newW->combobox.LabelCtrl       = current->combobox.LabelCtrl;
+    newW->combobox.SelectionPolicy = current->combobox.SelectionPolicy;
+    newW->combobox.ListSizePolicy  = current->combobox.ListSizePolicy;
+    newW->combobox.StaticList      = current->combobox.StaticList;
+    
+/* 
+ * Kontrolliere nun alle Resourcen, die sich veraendert haben koennten
+ * und gebe die neuen Einstellungen entsprechend weiter...
+ *
+ * Hat sich der Sensitive-Zustand veraendert? Dann muessen wir hier dafuer
+ * sorgen, dass alle Kinder ebenfalls den neuen Zustand annehmen.
+ */
+    if ( current->core.sensitive != newW->core.sensitive ) {
+        XtSetSensitive(newW->combobox.ListCtrl, newW->core.sensitive);
+        XtSetSensitive(newW->combobox.EditCtrl, newW->core.sensitive);
+        XtSetSensitive(newW->combobox.ArrowCtrl, newW->core.sensitive);
+        XtSetSensitive(newW->combobox.ListCtrl, newW->core.sensitive);
+        if ( !newW->core.sensitive )
+            ShowHideDropDownList(newW, NULL, False);
+    }
+/* 
+ * Die ScrollBarPolicy kann nur dann geaendert werden, wenn das Listenfeld
+ * dauerhaft dargestellt wird.
+ */
+    if ( newW->combobox.ScrollBarDisplayPolicy != 
+           current->combobox.ScrollBarDisplayPolicy )
+        if ( newW->combobox.StaticList )
+            XtVaSetValues(newW->combobox.ListCtrl,
+                          XmNscrollBarDisplayPolicy, newW->combobox.ScrollBarDisplayPolicy,
+                          NULL);
+        else
+            XtWarning(
+"XmComboBox: ScrollBarDisplayPolicy can not be changed when StaticList == False."
+            );
+/* Anzahl der in der Liste gleichzeitig darstellbaren Eintraege */
+    if ( current->combobox.VisibleItemCount != 
+           newW->combobox.VisibleItemCount ) {
+       XtVaSetValues(newW->combobox.ListCtrl, 
+                     XmNvisibleItemCount, newW->combobox.VisibleItemCount, 
+                     NULL);
+       Update = True;
+    }
+    if ( current->combobox.AutomaticSelection != 
+           newW->combobox.AutomaticSelection )
+       XtVaSetValues(newW->combobox.ListCtrl, 
+                     XmNautomaticSelection, newW->combobox.AutomaticSelection, 
+                     NULL);
+                                             
+/* 
+ * benutzter Font: hier erhalten Liste und Eingabefeld jeweils die
+ * gleiche Fontliste, wohingegen das Label getrennt behandelt wird.
+ * Das macht auch Sinn, denn Liste und Eingabefeld beinhalten gleich-
+ * artigen Text, so dass hier auch tunlichst der gleiche Font zu
+ * benutzen ist.
+ */
+    if ( current->combobox.Font != newW->combobox.Font ) {
+       XtVaSetValues(newW->combobox.ListCtrl, 
+                     XmNfontList, newW->combobox.Font, NULL);
+       XtVaSetValues(newW->combobox.EditCtrl, 
+                     XmNfontList, newW->combobox.Font, NULL);
+       Update = True;
+    }
+    
+    Flags = 0;
+    if ( newW->manager.top_shadow_color != 
+         current->manager.top_shadow_color    ) Flags |= TOPSHADOWCOLOR;
+    if ( newW->manager.bottom_shadow_color != 
+         current->manager.bottom_shadow_color ) Flags |= BOTTOMSHADOWCOLOR;
+    if ( newW->manager.foreground != 
+         current->manager.foreground          ) Flags |= FOREGROUND;
+    if ( newW->core.background_pixel != 
+         current->core.background_pixel       ) Flags |= BACKGROUND;
+    if ( Flags ) { UpdateColors(newW, Flags); Update = True; }
+    
+    
+    if ( newW->combobox.ArrowCursor != current->combobox.ArrowCursor ) {
+       if ( newW->combobox.ListVisible )
+           XDefineCursor(XtDisplay(newW->combobox.PopupShell), 
+                           XtWindow(newW->combobox.PopupShell), 
+                           newW->combobox.ArrowCursor); 
+   }
+/* Hier werden die vorgespiegelten Resourcen verwaltet, die in
+ * Wirklichkeit zu einem unserer Kinder gehoeren.
+ */
+     for ( i = 0; i < *NumArgs; i++ ) {
+/* Ist es eine vorgespiegelte Resource ? Wenn ja, dann leite die
+ * Anfrage an das entsprechende Kind-Widget weiter.
+ */
+       for ( j = 0; j < MirrorSize; j++ ) {
+           if ( (strcmp(args[i].name, MirroredResources[j].rsc) == 0) ) {
+               switch ( MirroredResources[j].dir ) {
+               case RW:   /* schreibender Zugriff erlaubt */
+                   XtSetValues(MirroredResources[j].ctrl == LISTCTRL ?
+                                 newW->combobox.ListCtrl :  
+                               (MirroredResources[j].ctrl == EDITCTRL ?
+                                 newW->combobox.EditCtrl :
+                                 newW->combobox.LabelCtrl), 
+                       &(args[i]), 1);
+                   break;
+               case RWS:  /* schreibender Zugriff unter Kontrolle */
+                   if ( strcmp(args[i].name, XmNvalue) == 0 ) {
+                       if ( newW->combobox.Editable )
+                           XtSetValues(newW->combobox.EditCtrl, 
+                                       &(args[i]), 1);
+                   }
+                   break;
+               case RWL: /* Transformation in andere Resource beim
+                            Label-Widget */
+                   for ( k = 0; k < TransformationSize; k++ )
+                       if ( strcmp(args[i].name, Transformations[k].from) == 0 ) {
+                           arg.value = args[i].value;
+                           arg.name = Transformations[k].to;
+                           XtSetValues(newW->combobox.LabelCtrl, 
+                                       &arg, 1);
+                           break;
+                       }
+                   break;
+               case RWIGNORE: /* Zugriff auf XmNitemCount */
+                              /* Wird von XmNitems erledigt! */
+                   break;
+               case RWI: /* Zugriff auf XmNitems */
+                   for ( k = 0; k < *NumArgs; k++ )
+                       if ( strcmp(args[k].name, XmNitemCount) == 0 ) {
+                           Arg MyArgs[2];
+                           
+                           MyArgs[0].name  = XmNitems;
+                           MyArgs[0].value = args[i].value;
+                           MyArgs[1].name  = XmNitemCount;
+                           MyArgs[1].value = args[k].value;
+                           XtSetValues(newW->combobox.ListCtrl,
+                                       args, 2);
+                           /*XtVaSetValues(newW->combobox.ListCtrl, 
+                                         XmNitems,     args[i].value, 
+                                         XmNitemCount, args[k].value, 
+                                         NULL);*/
+                           break;
+                       }
+                   break;
+               case RO:
+                   break;
+               } /* case write mode */
+               goto ScanForNextResource;
+           } /* if entry found */
+       } /* for every mirrored entry */
+        ScanForNextResource: ;
+    } /* for every Arg */
+    
+    if ( (newW->combobox.SquareArrow != current->combobox.SquareArrow) ||
+         (newW->combobox.ArrowSpacingOn != current->combobox.ArrowSpacingOn) ) {
+        Update = False;
+        DoLayout(newW);
+    }
+    
+    return Update;
+} /* SetValues */
+
+/* --------------------------------------------------------------------
+ * Werden irgendwelche Resourcen abgefragt, so muessen wir hier erst
+ * noch vor der Rueckkehr zum Frager klaeren, ob davon eine Resource
+ * betroffen ist, die nur vorgespiegelt ist, da sie eigentlich einem
+ * der Widgets gehoert, die von uns hier verwaltet werden, um daraus
+ * eine ordentliche Combo-Box zu machen.
+ * Parameter:
+ *   w             Widget-Instanz
+ *   args          Abgefragte Resourcen
+ *   NumArgs       Anzahl der abgefragten Resourcen
+ */
+static void GetValuesAlmost(XmComboBoxWidget w, ArgList args, 
+                            Cardinal *NumArgs)
+{
+    int i, j, MirrorSize = XtNumber(MirroredResources);
+    int k, TransformationSize = XtNumber(Transformations);
+    Arg arg;
+    
+    for ( i = 0; i < *NumArgs; i++ ) {
+/* Ist es eine vorgespiegelte Resource ? Wenn ja, dann leite die
+ * Anfrage an das entsprechende Kind-Widget weiter.
+ */
+       for ( j = 0; j < MirrorSize; j++ ) {
+           if ( strcmp(args[i].name, MirroredResources[j].rsc) == 0 ) {
+               switch ( MirroredResources[j].dir ) {
+               case RO:
+               case RW:
+               case RWS:
+               case RWI:
+                   XtGetValues(MirroredResources[j].ctrl == LISTCTRL ?
+                                 w->combobox.ListCtrl : 
+                               MirroredResources[j].ctrl == EDITCTRL ?
+                                 w->combobox.EditCtrl :
+                                 w->combobox.LabelCtrl, 
+                       &(args[i]), 1);
+                   break;
+               case RWL: /* Umzuleitende Resource bei Label-Widget */
+                   for ( k = 0; k < TransformationSize; k++ )
+                       if ( strcmp(args[i].name, Transformations[k].from) == 0 ) {
+                           arg.value = args[i].value;
+                           arg.name = Transformations[k].to;
+                           XtGetValues(w->combobox.LabelCtrl, 
+                                       (ArgList) &arg, 1);
+                           break;
+                       }
+                   break;
+               } /* case read mode */
+           } /* if entry found */
+       } /* for every mirrored entry */
+    } /* for every Arg */
+} /* GetValuesAlmost */
+
+/* --------------------------------------------------------------------
+ * Zeige beziehungsweise verstecke die Drop-Down-Liste der Combo-Box.
+ * Falls die Liste bereits den entsprechenden Zustand hat, geht's
+ * sofort zum Aufrufer zurueck.
+ * Parameter:
+ *   w             Her Royal Majesty ComboBox
+ *   Show          True, falls anzuzeigen, andernfalls False
+ */
+static void ShowHideDropDownList(XmComboBoxWidget w, XEvent *event, 
+                                 Boolean Show)
+{
+    XmComboBoxDropDownCallbackStruct info;
+    
+    if ( w->combobox.StaticList || 
+         (Show == w->combobox.ListVisible) ) return;
+    w->combobox.ListVisible = Show;
+    if ( Show ) { /* Klapp' die Liste aus! */
+       DoDropDownLayout(w);
+       info.reason = XmCR_SHOW_LIST;
+       info.event  = event;
+       XtCallCallbacks((Widget) w, XmNdropDownCallback, 
+                       (XtPointer) &info);
+       XDefineCursor(XtDisplay(w->combobox.PopupShell), 
+                       XtWindow(w->combobox.PopupShell), 
+                       w->combobox.ArrowCursor); 
+       XtPopup(w->combobox.PopupShell, XtGrabNone);
+       XtVaSetValues(w->combobox.ArrowCtrl, 
+                     XmNarrowDirection, XmARROW_UP, NULL);
+    } else {      /* Klapp' die Liste wieder ein... */
+       XtPopdown(w->combobox.PopupShell);
+       XtVaSetValues(w->combobox.ArrowCtrl, 
+                     XmNarrowDirection, XmARROW_DOWN, NULL);
+       info.reason = XmCR_HIDE_LIST;
+       info.event  = event;
+       XtCallCallbacks((Widget) w, XmNdropDownCallback, 
+                       (XtPointer) &info);
+    }
+} /* ShowHideDropDownList */
+
+/* --------------------------------------------------------------------
+ * Hier laeuft die Nachricht auf, dass der Pfeil ausgeloest wurde...
+ * (Daraufhin sollte die Liste aus- oder eingeklappt werden)
+ * ...oder dass der Benutzer da draussen auf der anderen Seite der
+ * Mattscheibe den Pfeil bereits anklickte ohne aber bereits losge-
+ * gelassen zu haben. Bereits hier bekommt das Eingabefeld den Fokus
+ * vor den Latz geknallt, denn sonst kann es passieren, dass zwar die
+ * Liste ausgeklappt ist, aber das Eingabefeld noch keinen Tastatur-
+ * fokus erhalten hat. Das sollte aber nicht so sein, denn es ist dann
+ * keine konsequente Tastaturbedienung.
+ */
+static void ArrowCallback(Widget w, XtPointer pClientData, 
+                          XmAnyCallbackStruct *info)
+{
+    XmComboBoxWidget cbw = (XmComboBoxWidget) XtParent(w);
+    
+    switch ( info->reason ) {
+       case XmCR_ARM:
+           LOG("ArrowCallback: XmCR_ARM\n");
+           XmProcessTraversal(cbw->combobox.EditCtrl, XmTRAVERSE_CURRENT);
+           if ( cbw->combobox.TwmHandlingOn && cbw->combobox.ListVisible )
+               cbw->combobox.IgnoreFocusOut = True;
+           break;
+       case XmCR_ACTIVATE:
+           XmProcessTraversal(cbw->combobox.EditCtrl, XmTRAVERSE_CURRENT);
+           ShowHideDropDownList(cbw, info->event, 
+                                (Boolean)(!cbw->combobox.ListVisible));
+           break;
+    }
+} /* ArrowCallback */
+
+/* --------------------------------------------------------------------
+ * Diese Benachrichtigung moechte uns nur mitteilen, dass wir soeben
+ * den Fokus verloren haben (Ohhhh!) Sollte allerdings der Fokus nur
+ * aus dem Grunde perdue sein, dass der Anwender den Mauszeiger ausser-
+ * halb des Applikationsfensters plaziert hat, so koennen wir diese
+ * Nachricht uebergehen. Erst wenn der Fokus an ein anderes Widget in
+ * unserer Applikation verlorenging, muessen wir auf diese Information
+ * reagieren.
+ * Und jetzt zu noch einem total beknackten Problem - alles nur wegen
+ * Motif und den diversen Window-Managern (bspw. olwm)... Leider kommt
+ * beim FocusOut kein richtiger Hinweis auf den tatsaechlichen Event,
+ * der dieses Callback ausloeste -- warum liefert denn dann Motif ueber-
+ * haupt noch den Event???? Und ueberhauupt, die Geschichte mit dem
+ * Fokus ist schon der reinste Horror. Aktueller Ausweg: wenn wir die
+ * Benachrichtigung ueber den Focusabgang bekommen, registrieren wir
+ * eine Work-Prozedur, die, sobald der Rechner wieder Luft hat, auf-
+ * gerufen wird. Sie kann dann nachschauen, ob nicht inzwischen die
+ * OverrideShell den Focus bekahm. Wenn ja, koennen wir den FocusOut
+ * uebergehen, ansonsten muessen wir ihn beruecksichtigen.
+ * -- Ist das eine ^@#$^*(#$^&! (Meine gute Erziehung hindert mich
+ * daran, diesen Begriff hier zu nennen.)
+ */
+static Boolean DelayedFocusOutWorkProc(XtPointer pClientData)
+{
+    XmComboBoxWidget cbw = (XmComboBoxWidget) pClientData;
+    LOG2("DelayedFocusOutWorkProc: IgnoreFocusOut: %s\n", 
+         cbw->combobox.IgnoreFocusOut ? "True" : "False");
+    if ( !cbw->combobox.IgnoreFocusOut )
+        ShowHideDropDownList(cbw, &(cbw->combobox.xevent), False);
+    cbw->combobox.IgnoreFocusOut  = False;
+    cbw->combobox.PendingFocusOut = False;
+    return True; /* diese Routine wird nicht mehr benoetigt. */
+} /* DelayedFocusOutWorkProc */
+
+static void EditFocusCallback(Widget w, XtPointer pClientData, 
+                              XmAnyCallbackStruct *info)
+{
+    XmComboBoxWidget cbw = (XmComboBoxWidget) XtParent(w);
+
+    if ( cbw->combobox.StaticList ) return;
+        
+    if ( info->reason == XmCR_LOSING_FOCUS ) {
+        LOG2("EditFocusCallback: PendingFocusOut: %s, ", 
+            cbw->combobox.PendingFocusOut ? "True" : "False");
+       LOG3("mode: %i, detail: %i, ", (int)info->event->xcrossing.mode,
+                                      (int)info->event->xcrossing.detail);
+       LOG2("PendingOverrideInOut: %s\n",
+            cbw->combobox.PendingOverrideInOut ? "True" : "False");
+        if ( !cbw->combobox.PendingFocusOut &&
+             !cbw->combobox.PendingOverrideInOut ) {
+           /* Normalerweise duerfen aber keine NULL-Events hier
+            * vorbeikommen...aber man weiss ja nie so genau und
+            * sicher ist sicher. Defensiv programmieren!
+            */
+           if ( info->event )
+               cbw->combobox.xevent = *info->event;
+            cbw->combobox.WorkProcID = XtAppAddWorkProc(
+                            XtWidgetToApplicationContext((Widget) cbw),
+                             (XtWorkProc) DelayedFocusOutWorkProc,
+                             (XtPointer) cbw);
+            cbw->combobox.PendingFocusOut = True;
+        }
+        cbw->combobox.PendingOverrideInOut = False;
+    }
+} /* EditFocusCallback */
+
+/* --------------------------------------------------------------------
+ * Hier wird der angegebene Eintrag in der Listbox der Combo-Box
+ * markiert und zudem in den sichtbaren Bereich gerollt, sollte er
+ * sich ausserhalb des dargestellten Bereichs der Liste befinden.
+ * Parameter:
+ *   w             Die Combo-Box (ueblicher Parameter)
+ *   Index         Index des neu zu markierenden Eintrages.
+ *   Notify        Schickt Mitteilung via Callback
+ * Ergebnis:
+ *   Index des markierten Eintrages oder 0, falls die Listbox leer
+ *   war und deshalb auch kein Eintrag markiert werden konnte.
+ */
+static int SetSelectionPos(XmComboBoxWidget w, int Index, Boolean Notify)
+{
+    Widget ListBox = w->combobox.ListCtrl;
+    int            ItemCount;      /* Anzahl Eintraege in Listbox   */
+    int            TopItem, VisibleItems;
+     
+    XtVaGetValues(ListBox, XmNitemCount,        &ItemCount, 
+                          XmNtopItemPosition,  &TopItem, 
+                          XmNvisibleItemCount, &VisibleItems,
+                          NULL);
+    if ( Index < 1         ) Index = 1;
+    if ( Index > ItemCount ) Index = ItemCount;
+    if ( Index != 0 && ItemCount != 0 ) {
+       if ( Index < TopItem )
+           XmListSetPos(ListBox, Index);
+       if ( Index >= TopItem + VisibleItems )
+           XmListSetBottomPos(ListBox, Index);
+       XmListSelectPos(ListBox, Index, Notify);
+       return Index;
+    } else
+       return 0;
+} /* SetSelectionPos */
+
+/* --------------------------------------------------------------------
+ * Diese Routine kuemmert sich darum, denjenigen Eintrag aus der List-
+ * box mit der angegebenen Nummer herauszufischen und an die Eingabe-
+ * zeile zu uebergeben. Dabei wird der Index auf den Eintrag auto-
+ * matisch auf den zulaessigen Bereich begrenzt. Zugleich wird auch
+ * noch der angegebene Eintrag in der Listbox markiert.
+ */
+static void TransferToEditCtrl(XmComboBoxWidget w, int SelectionIndex, 
+                               Boolean MayWipeOut)
+{
+    Widget ListBox = w->combobox.ListCtrl;
+    XmStringTable  Items;
+    char           *pItemText;
+    
+    XtVaGetValues(ListBox, XmNitems, &Items, NULL);
+    
+    if ( MayWipeOut &&
+         (SelectionIndex == w->combobox.LastSelection) &&
+         (w->combobox.SelectionPolicy == XmSINGLE_SELECT) ) {
+       SelectionIndex = 0;
+    }
+    
+    if ( (SelectionIndex == 0) && 
+         (w->combobox.SelectionPolicy == XmSINGLE_SELECT) ) {
+       XmListDeselectAllItems(w->combobox.ListCtrl);
+       w->combobox.PassVerification = True;
+       XmTextFieldSetString(w->combobox.EditCtrl, "");
+    } else {
+       SelectionIndex = SetSelectionPos(w, SelectionIndex, False);
+       if ( SelectionIndex > 0 ) {
+           XmStringGetLtoR(Items[SelectionIndex-1], 
+                           XmSTRING_DEFAULT_CHARSET, &pItemText);
+           w->combobox.PassVerification = True;
+           XmTextFieldSetString(w->combobox.EditCtrl, pItemText);
+           XtFree(pItemText);
+       }
+    }
+    w->combobox.LastSelection = SelectionIndex;
+} /* TransferToEditCtrl */
+
+/* --------------------------------------------------------------------
+ * Alle registrierten Callbacks bei Anwahl eines neuen Eintrages in
+ * der Listbox aktivieren.
+ */
+static void CallSelectionCBL(XmComboBoxWidget w, XEvent *Event)
+{
+    int index;
+    
+    index  = XmComboBoxGetSelectedPos((Widget) w);
+    /*
+     * Wenn momentan KEIN Eintrag selektiert ist, dann rufe den neuen
+     * XmNunselectionCallback auf!
+     */
+    if ( index == 0 ) {
+       XmComboBoxUnselectionCallbackStruct info;
+       
+       info.reason = XmCR_UNSELECT;
+       info.event  = Event;
+       XtCallCallbacks((Widget) w, XmNunselectionCallback, (XtPointer) &info);
+    } else {
+    /*
+     * Ansonsten den ueblichen SelectionCallback!
+     */
+       XmComboBoxSelectionCallbackStruct info;
+       XmStringTable                     Items;
+
+       info.reason = w->combobox.SelectionPolicy == XmSINGLE_SELECT ? 
+                           XmCR_SINGLE_SELECT : XmCR_BROWSE_SELECT;
+       info.event  = Event;
+       info.index  = index;
+       XtVaGetValues(w->combobox.ListCtrl, XmNitems, &Items, NULL);
+       info.value  = Items[info.index-1];
+       XtCallCallbacks((Widget) w, XmNselectionCallback, (XtPointer) &info);
+    }
+} /* CallSelectionCBL */
+
+/* --------------------------------------------------------------------
+ * Hier laeuft das Tastatur-Management fuer die ComboBox zusammen.
+ * ACHTUNG: Der 'w'-Parameter wird nur benoetigt, um das eigentliche
+ * ComboBox-Widget zu ermitteln. Er muss daher die ID eines direkten
+ * Kinds der ComboBox enthalten!
+ */
+static void CBoxManager(Widget w, XEvent *Event, String *params, 
+                        Cardinal *num_params)
+{
+    XmComboBoxWidget cbw;
+    Widget           ListBox;
+    int              *SelectionList;
+    int              SelectionCount;
+    int              SelectionIndex; /* Wer denn nun markiert wird... */
+    int              ItemCount;      /* Anzahl Eintraege in Listbox   */
+    int                     VisibleItems;   /* Hoehe der Liste in Eintraegen */
+    char             opt;
+    
+    /*
+     * Nur wenn eine der Translationen page-up und page-down direkt im
+     * Listenfeld ausgeloest wurden, wird auch als "w" die Liste ueber-
+     * geben. Bei allen anderen Faellen ist dieses zumeist das TextField.
+     */
+    if ( XtClass(w) == xmListWidgetClass )
+        cbw = (XmComboBoxWidget) XtParent(XtParent(w));
+    else
+        cbw = (XmComboBoxWidget) XtParent(w);
+    ListBox = cbw->combobox.ListCtrl;
+    
+    switch ( *(params[0]) ) {
+/* --------------------------------------------------------------------
+ * Klappe die Liste auf Wunsch des Benutzers aus oder wieder ein.
+ */
+    case 's': /* show-hide-list */
+       ShowHideDropDownList(cbw, Event, 
+                            (Boolean)(!cbw->combobox.ListVisible));
+       break;
+    case 'h': /* hide-list */
+       ShowHideDropDownList(cbw, Event, False);
+       break;
+/* --------------------------------------------------------------------
+ * Hier werden die Bewegungen in der Listbox behandelt.
+ */
+    case 'u': /* up                */
+    case 'd': /* down              */
+    case 't': /* top               */
+    case 'b': /* bottom            */
+    case 'p': /* page-up/page-down */
+       opt = *(params[0]);
+       XtVaGetValues(ListBox, XmNitemCount,        &ItemCount, 
+                              XmNvisibleItemCount, &VisibleItems, NULL);
+       if ( XmListGetSelectedPos(ListBox,
+                                 &SelectionList, &SelectionCount) ) {
+           SelectionIndex = *SelectionList;
+           XtFree((char *)SelectionList);
+           switch ( opt ) {
+               case 'u': SelectionIndex--;               break;
+               case 'd': SelectionIndex++;               break;
+               case 't': SelectionIndex = 1;             break;
+               case 'b': SelectionIndex = ItemCount;     break;
+               case 'p': if ( *(params[0]+5) == 'u' )
+                             SelectionIndex -= VisibleItems;
+                         else
+                             SelectionIndex += VisibleItems;
+                         break;
+           }
+       } else { /* momentan noch kein Eintrag in der Liste ausgewaehlt */
+           if ( opt == 'b' ) SelectionIndex = ItemCount;
+           else              SelectionIndex = 1; /* nun ersten Eintrag nehmen */
+       }
+       TransferToEditCtrl(cbw, SelectionIndex, False);
+       CallSelectionCBL(cbw, Event);
+       break;
+/* --------------------------------------------------------------------
+ * Der Benutzer hat die Eingabetaste gedrueckt oder einen Eintrag in
+ * der Listbox angeklickt.
+ */
+    case 'a': /* Return = activate */
+    case 'S': /* Selection */
+       if ( !cbw->combobox.StaticList && !cbw->combobox.ListVisible ) break;
+       XtVaGetValues(ListBox, XmNitemCount, &ItemCount, NULL);
+       if ( ItemCount == 0 ) break;
+       if ( XmListGetSelectedPos(ListBox,
+                                 &SelectionList, &SelectionCount) ) {
+           SelectionIndex = *SelectionList;
+           XtFree((char *)SelectionList);
+       } else {
+           if ( cbw->combobox.SelectionPolicy != XmSINGLE_SELECT )
+               SelectionIndex = 1;
+           else
+               SelectionIndex = 0;
+       }
+       
+       TransferToEditCtrl(cbw, SelectionIndex, 
+           *(params[0]) == 'S');
+       CallSelectionCBL(cbw, Event);
+       ShowHideDropDownList(cbw, Event, (Boolean)
+                             (*(params[0]) == 'S' ? True : False));
+       break;
+/* --------------------------------------------------------------------
+ * Der Benutzer hat die ESC-Taste gedrueckt. Ist die Liste zu diesem
+ * Zeitpunkt noch ausgeklappt, so wird sie einfach nur eingeklappt und
+ * weiter passiert nichts. Ist die Liste jedoch eingeklappt, so wird
+ * das ESC an die normale Action-Routine des Eingabefeldes weiter-
+ * gegeben, damit damit bspw. Dialog u.a. abgebrochen werden koennen.
+ */
+    case 'c': /* Cancel */
+       if ( cbw->combobox.ListVisible )
+           ShowHideDropDownList(cbw, Event, False);
+       else
+           XtCallActionProc(cbw->combobox.EditCtrl, 
+                            "process-cancel", Event, NULL, 0);
+       break;
+/* --------------------------------------------------------------------
+ * Wenn es erlaubt ist, dass auch einmal kein Eintrag in einer ComboBox
+ * mit nicht editierbarem Eingabefeld ausgewaehlt ist, dann darf der
+ * Anwender mittels osfDelete den aktuellen Eintrag deselektieren.
+ */
+    case 'w': /* wipe */
+       if ( cbw->combobox.SelectionPolicy == XmSINGLE_SELECT ) {
+           TransferToEditCtrl(cbw, 0, True);
+           CallSelectionCBL(cbw, Event);
+       }
+       break;
+/* --------------------------------------------------------------------
+ * Dummy-Operation
+ */
+    case 'n': /* no-operation */
+        break;
+    }
+} /* CBoxManager */
+
+/* --------------------------------------------------------------------
+ * Der Benutzer hat einen Eintrag in der Listbox angeklickt. Der Ein-
+ * fachkeit halber wird einfach nur ein Druecken der Eingabetaste
+ * simuliert.
+ */
+static void ListSelectionCallback(Widget w, XtPointer pClientData, 
+                                  XmAnyCallbackStruct *info)
+{
+    String           paramsMouse[1] = { "a" }, paramsKeyboard[1] = { "S" };
+    Cardinal         NumParams = 1;
+    XmComboBoxWidget cbw = (XmComboBoxWidget) pClientData;
+/* 
+ * Wurde der Event durch die Tastatur oder einen Mausklick
+ * ausgeloest? Wenn es ein Mausklick auf das Listenfeld war und es
+ * sich um ein staendig angezeigtes Listenfeld einer nicht editierbaren
+ * ComboBox handelt, dann gib' dem Eingabefeld den Tastaturfokus.
+ */
+    if ( info->event == NULL )
+       CBoxManager(cbw->combobox.EditCtrl, info->event, 
+                   paramsKeyboard, &NumParams);
+    else {
+       CBoxManager(cbw->combobox.EditCtrl, info->event, 
+                   paramsMouse, &NumParams);
+       if ( !cbw->combobox.StaticList ||
+            (cbw->combobox.StaticList && !cbw->combobox.Editable) )
+           XmProcessTraversal(cbw->combobox.EditCtrl, 
+                              XmTRAVERSE_CURRENT);
+    }
+} /* ListSelectionCallback */
+
+/* --------------------------------------------------------------------
+ * Nach einem Doppelklick innerhalb des Listenfelds wird diese Routine
+ * aufgerufen. Zunaechst einmal wird ganz normal wie bei einem ein-
+ * fachen Anklicken vorgegangen, danach aber noch der ein spezieller
+ * Callback aufgerufen.
+ */
+static void ListDefaultActionCallback(Widget w, XtPointer pClientData, 
+                                      XmAnyCallbackStruct *OldInfo)
+{
+    XmComboBoxWidget                      cbw = (XmComboBoxWidget) pClientData;
+    XmComboBoxDefaultActionCallbackStruct info;
+    XmStringTable                         Items;
+    
+    ListSelectionCallback(w, pClientData, OldInfo);
+    info.reason = XmCR_DEFAULT_ACTION;
+    info.event  = OldInfo->event;
+    info.index  = XmComboBoxGetSelectedPos((Widget) cbw);
+    XtVaGetValues(cbw->combobox.ListCtrl, XmNitems, &Items, NULL);
+    info.value  = Items[info.index-1];
+    XtCallCallbacks((Widget) cbw, XmNdefaultActionCallback, (XtPointer) &info);
+} /* ListDefaultActionCallback */
+
+
+/* --------------------------------------------------------------------
+ * Ohweh!! Diese Routine wurde erforderlich, um XmNautomaticSelection
+ * zu unterstuetzen. Denn wenn der Benutzer in der Liste herumsucht und
+ * automaticSelection 'True' ist, kommt kein Callback-Aufruf mehr, wenn
+ * die Maustaste losgelassen wird. Und damit wuessten wir sonst nicht, 
+ * wann die Liste einzuklappen ist! Irgendwie wird das alles mit der
+ * Zeit immer konfuser und aufwendiger. Wenn das Chaos gequantelt
+ * sein sollte, dann muss das Chaos-Quant (sog. 'Chaotonen') aber jede
+ * Menge Chaos transportieren!!!
+ */
+static void Button1UpInList(Widget w, XtPointer pClientData, 
+                           XEvent *Event, Boolean *ContDispatch)
+{
+    XmComboBoxWidget cbw = (XmComboBoxWidget) pClientData;
+
+    if ( Event->xbutton.button == Button1 ) {
+       if ( cbw->combobox.AutomaticSelection )
+           ShowHideDropDownList(cbw, Event, False);
+    }
+} /* Button1UpInList */
+
+/* --------------------------------------------------------------------
+ * Sobald sich irgendetwas im Eingabefeld veraenderte, kommt das
+ * TextField-Widget zuerst zu uns gelaufen, um sich unser Okay zu
+ * holen. Bei einer nicht editierbaren Combo-Box wird hierueber die
+ * Schnellsuche realisiert.
+ */
+static void EditVerifyCallback(Widget w, XtPointer pClientData, 
+                               XmTextVerifyCallbackStruct *info)
+{
+    XmComboBoxWidget cbw = (XmComboBoxWidget) XtParent(w);
+
+/* 
+ * Sollte gerade dem Eingabefeld Text aus der Listbox einverleibt
+ * werden, so duerfen wir hier darueber natuerlich nicht meckern, 
+ * sondern unser <<ok>> dazu geben. (D.h. in diesem Fall haben wir
+ * kein Recht, zu intervenieren.)
+ */
+    if ( cbw->combobox.PassVerification ) {
+       cbw->combobox.PassVerification = False;
+       info->doit = True;
+       return;
+    }
+/* 
+ * Ist es eine Combo-Box, in die kein Text vom Benutzer eingegeben
+ * werden kann, so wird bei der Eingabe von Zeichen die Schnellsuche
+ * ausgeloest.
+ */
+    if ( !cbw->combobox.Editable ) {
+       Widget         ListBox = cbw->combobox.ListCtrl;
+       char           WarpCharLow, WarpCharHigh;
+       XmString       Item;
+       XmStringTable  Items;
+       int            *SelectionList;
+       int            SelectionCount;
+       int            i, ItemCount, Start, End;
+       char           *pItem;
+       Boolean        Ignore;
+       
+       info->doit = False;
+       if ( (info->text         == NULL ) ||
+            (info->text->length == 0    ) ) return; /* Hoppala! */
+/* 
+ * Nun aus dem Zeichen einen String (Motif-like) basteln und
+ * in der Listbox danach auf die Suche gehen.
+ */
+        if ( info->text->length > 1 ) {
+            /* Das ist nun endweder ein normaler Paste, oder aber
+             * das Ergebnis einer Drag'n'Drop-Operation.
+             */
+            Item = XmStringCreateSimple(info->text->ptr);
+            XmComboBoxSelectItem((Widget) cbw, Item, True);
+            XmStringFree(Item);
+        } else {
+            /* Ansonsten soll nur eine Schnellsuche ausgefuehrt
+             * werden, der entsprechende Buchstabe ist das einzige 
+             * Zeichen im dem Callback uebergebenen Text.
+             */
+           WarpCharLow  = tolower(*(info->text->ptr));
+           WarpCharHigh = toupper(WarpCharLow);
+
+            XtVaGetValues(ListBox, XmNitemCount, &ItemCount, 
+                                  XmNitems,     &Items,  
+                                  NULL);
+            if ( ItemCount < 1 ) return;
+           /* Ermittele, wo's los geht mit der Suche... */
+           if ( XmListGetSelectedPos(ListBox, 
+                                     &SelectionList, &SelectionCount) ) {
+               Start = *SelectionList; i = Start + 1;
+               XtFree((char *)SelectionList);
+           } else i = Start = 1;
+       
+           if ( i > ItemCount ) i = 1;
+           Ignore = True;
+           while ( i != Start || Ignore ) {
+               Ignore = False;
+               XmStringGetLtoR(Items[i-1], XmSTRING_DEFAULT_CHARSET, 
+                               &pItem);
+               if ( (strchr(pItem, WarpCharLow ) == pItem) ||
+                    (strchr(pItem, WarpCharHigh) == pItem) ) { 
+                   XtFree(pItem);
+                   TransferToEditCtrl(cbw, i, False);
+                   CallSelectionCBL(cbw, info->event);
+                   break;
+               }
+               XtFree(pItem);
+               if ( ++i > ItemCount ) i = 1;
+           }
+       }
+    } else {
+/*
+ * Wenn das Eingabefeld editierbar ist, dann fragen wir ueber die Callbacks
+ * nach, ob es genehm ist, den neuen Text einzufuegen.
+ */
+       XtCallCallbacks((Widget) cbw, XmNmodifyVerifyCallback, 
+                       (XtPointer) info);
+    }
+} /* EditVerifyCallback */
+
+/* --------------------------------------------------------------------
+ * Dieser Callback wird immer dann aufgerufen, wenn in einer ComboBox
+ * mit einem veraenderlichem Eingabefeld der Eingabetext veraendert
+ * wurde. In diesem Fall suchen wir hier nach einem passenden gleich-
+ * lautenden Eintrag. Wenn wir einen finden, heben wir ihn in der Liste
+ * sogleich hervor, ansonsten ist kein Eintrag hervorgehoben.
+ */
+static void EditChangedCallback(Widget w, XtPointer pClientDate, 
+                                XmAnyCallbackStruct *info)
+{
+    XmComboBoxWidget cbw = (XmComboBoxWidget) XtParent(w);
+    XmStringTable    Items;
+    int              ItemCount, i;
+    XmString         EditStr;
+    String           EditLine;
+    
+    /*
+     * Zuerst nach einem passenden Eintrag zum Eingabefeld in der Liste
+     * suchen...
+     */
+    XtVaGetValues(cbw->combobox.EditCtrl, XmNvalue, &EditLine, NULL);
+    XtVaGetValues(cbw->combobox.ListCtrl, 
+                  XmNitemCount, &ItemCount, 
+                 XmNitems,     &Items, 
+                 NULL);
+    EditStr = XmStringCreateSimple(EditLine);
+    XtVaSetValues(cbw->combobox.ListCtrl, XmNselectedItemCount, 0, NULL);
+    if ( ItemCount < 1 ) return;
+    for ( i = 0; i < ItemCount; i++ )
+       if ( XmStringCompare(Items[i], EditStr) ) {
+           SetSelectionPos(cbw, i+1, False);
+           break;
+       }
+    XmStringFree(EditStr);
+    /*
+     * Zum Abschluss noch den Callback aufrufen...
+     */
+    XtCallCallbacks((Widget) cbw, XmNvalueChangedCallback, (XtPointer) info);
+} /* EditChangedCallback */
+
+/* --------------------------------------------------------------------
+ * Dieser Callback wird immer dann aufgerufen, wenn in einer ComboBox
+ * mit einem veraenderlichem Eingabefeld der Cursor bewegt wurde.
+ * Dieser Callback ist nur fuer echte Fans von Callbacks da...
+ */
+static void MotionVerifyCallback(Widget w, XtPointer pClientDate, 
+                                 XmTextVerifyCallbackStruct *info)
+{
+    XmComboBoxWidget cbw = (XmComboBoxWidget) XtParent(w);
+
+    XtCallCallbacks((Widget) cbw, XmNmotionVerifyCallback, (XtPointer) info);
+} /* MotionVerifyCallback */
+
+/* --------------------------------------------------------------------
+ * Bastele einen vollstaendigen Namens- und Klassenbezeichner anhand
+ * des angegebenen Widgets zusammen.
+ */
+static void MakeNameAndClass(Widget w, char *NameBuff, char *ClassBuff)
+{
+    Widget Parent = XtParent(w);
+    
+    if ( Parent ) MakeNameAndClass(Parent, NameBuff, ClassBuff);
+    if ( XtIsSubclass(w, applicationShellWidgetClass) ) {
+       /* Wenn wir ganz oben angekommen sind, holen wir uns den
+        * Namen und die Klasse der Applikation selbst und nicht die
+        * des Widgets.
+        */
+       String AppName, AppClass;
+       XtGetApplicationNameAndClass(
+           XtDisplayOfObject(w), &AppName, &AppClass);
+       strcpy(NameBuff, AppName);
+       strcpy(ClassBuff, AppClass);
+    } else {
+       /* Ansonsten sind wir noch mitten irgendwo in der Hierarchie
+        * und besorgen uns den Namen und die Klasse dieses Widgets
+        */
+       strcat(NameBuff,  "."); 
+       strcat(NameBuff,  XtName(w));
+       strcat(ClassBuff, "."); 
+       strcat(ClassBuff, ((CoreClassRec *) XtClass(w))->core_class.class_name);
+    }
+} /* MakeNameAndClass */
+
+/* --------------------------------------------------------------------
+ * Eine einzelne Resource aus der Datenbank herausholen. Diese Resource
+ * kommt im Allgemeinen immer als String zurueck und muss daher erst
+ * noch in das gewuenschte Zielformat konvertiert werden.
+ */
+static Boolean FetchResource(Widget w, 
+                             char *FullName, char *FullClass, 
+                             char *RscName, char *RscClass, 
+                            XrmValue *RscValue, 
+                            String   *RepresentationType)
+{
+    Boolean ok;
+    char *EndOfName  = FullName  + strlen(FullName);
+    char *EndOfClass = FullClass + strlen(FullClass);
+    
+    strcat(FullName,  "."); strcat(FullName,  RscName);
+    strcat(FullClass, "."); strcat(FullClass, RscClass);
+    ok = XrmGetResource(
+       XtDatabase(XtDisplayOfObject(w)), 
+       FullName, FullClass, RepresentationType, RscValue);
+    /* Wieder den alten Namens- und Klassenrumpf herstellen */
+    *EndOfName = 0; *EndOfClass = 0;
+    return ok;
+} /* FetchResource */
+
+/* --------------------------------------------------------------------
+ * Nun folgen diejenigen Routinen, mit denen die Konvertierung in das
+ * gewuenschte Zielformat einer Resource moeglich ist.
+ * Verfuegbar:
+ *   String --> Int
+ *   String --> Short
+ *   String XmPIXMAP / XmSTRING --> unsigned char
+ *   String --> Dimension
+ *   String --> XmString
+ *   String --> XmStringTable
+ *   String --> XmFontList
+ *   String --> Pixmap (genauer: Bitmap)
+ *   String --> String
+ *   String --> KeySym
+ */
+static Boolean FetchIntResource(Widget w, 
+                                char *FullName, char *FullClass, 
+                                char *RscName, char *RscClass, 
+                               int *pInt)
+{
+    XrmValue RscValue, RscDest;
+    String   RepresentationType;
+    
+    if ( FetchResource(w, FullName, FullClass, 
+                       RscName, RscClass, 
+                      &RscValue, &RepresentationType) ) {
+       RscDest.size = sizeof(int);
+       RscDest.addr = (caddr_t) pInt;
+       if ( XtConvertAndStore(w, RepresentationType, &RscValue, 
+                              XtRInt, &RscDest) )
+           return True;
+    }
+    return False;
+} /* FetchIntResource */
+
+static Boolean FetchShortResource(Widget w, 
+                                char *FullName, char *FullClass, 
+                                char *RscName, char *RscClass, 
+                               short *pShort)
+{
+    XrmValue RscValue, RscDest;
+    String   RepresentationType;
+    
+    if ( FetchResource(w, FullName, FullClass, 
+                       RscName, RscClass, 
+                      &RscValue, &RepresentationType) ) {
+       RscDest.size = sizeof(short);
+       RscDest.addr = (caddr_t) pShort;
+       if ( XtConvertAndStore(w, RepresentationType, &RscValue, 
+                              XtRShort, &RscDest) )
+           return True;
+    }
+    return False;
+} /* FetchShortResource */
+
+static Boolean FetchLabelTypeResource(Widget w, 
+                                char *FullName, char *FullClass, 
+                                char *RscName, char *RscClass, 
+                               unsigned char *pUChar)
+{
+    XrmValue RscValue, RscDest;
+    String   RepresentationType;
+    int      AInt;
+    
+    if ( FetchResource(w, FullName, FullClass, 
+                       RscName, RscClass, 
+                      &RscValue, &RepresentationType) ) {
+       if ( strcasecmp((char *) RscValue.addr, "XmPIXMAP") == 0 )
+           *pUChar = XmPIXMAP;
+       else
+           *pUChar = XmSTRING;
+       return True;
+   }
+    return False;
+} /* FetchLabelTypeResource */
+
+static Boolean FetchDimensionResource(Widget w, 
+                                char *FullName, char *FullClass, 
+                                char *RscName, char *RscClass, 
+                               Dimension *pDimension)
+{
+    XrmValue RscValue, RscDest;
+    String   RepresentationType;
+    
+    if ( FetchResource(w, FullName, FullClass, 
+                       RscName, RscClass, 
+                      &RscValue, &RepresentationType) ) {
+       RscDest.size = sizeof(Dimension);
+       RscDest.addr = (caddr_t) pDimension;
+       if ( XtConvertAndStore(w, RepresentationType, &RscValue, 
+                              XtRDimension, &RscDest) )
+           return True;
+    }
+    return False;
+} /* FetchDimensionResource */
+
+static Boolean FetchStringResource(Widget w, 
+                                char *FullName, char *FullClass, 
+                                char *RscName, char *RscClass, 
+                               String *pString)
+{
+    XrmValue RscValue;
+    String   RepresentationType;
+    
+    if ( FetchResource(w, FullName, FullClass, 
+                       RscName, RscClass, 
+                      &RscValue, &RepresentationType) ) {
+       *pString = (char *) RscValue.addr;
+       return True;
+    }
+    return False;
+} /* FetchStringResource */
+
+static Boolean FetchKeySymResource(Widget w, 
+                                char *FullName, char *FullClass, 
+                                char *RscName, char *RscClass, 
+                               KeySym *pKeySym)
+{
+    XrmValue RscValue, RscDest;
+    String   RepresentationType;
+    
+    if ( FetchResource(w, FullName, FullClass, 
+                       RscName, RscClass, 
+                      &RscValue, &RepresentationType) ) {
+       RscDest.size = sizeof(KeySym);
+       RscDest.addr = (caddr_t) pKeySym;
+       if ( XtConvertAndStore(w, RepresentationType, &RscValue, 
+                              XmRKeySym, &RscDest) )
+           return True;
+    }
+    return False;
+} /* FetchKeySymResource */
+
+static Boolean FetchXmStringResource(Widget w, 
+                                char *FullName, char *FullClass, 
+                                char *RscName, char *RscClass, 
+                               XmString *pString)
+{
+    XrmValue RscValue;
+    String   RepresentationType;
+    
+    if ( FetchResource(w, FullName, FullClass, 
+                       RscName, RscClass, 
+                      &RscValue, &RepresentationType) ) {
+       *pString = XmCvtCTToXmString((char *) RscValue.addr);
+       return True;
+    }
+    return False;
+} /* FetchXmStringResource */
+
+static Boolean FetchXmStringTableResource(Widget w, 
+                                char *FullName, char *FullClass, 
+                                char *RscName, char *RscClass, 
+                               XmStringTable *pStringTable, 
+                               int *pTableSize)
+{
+    XrmValue RscValue;
+    String   RepresentationType;
+    String   TmpList, p, pStart;
+    int      Entries, Entry;
+    
+    if ( FetchResource(w, FullName, FullClass, 
+                       RscName, RscClass, 
+                      &RscValue, &RepresentationType) ) {
+       /* 
+        * Zuerst eine Kopie erzeugen und dann daraus die Liste
+        * zusammenbasteln.
+        */
+       TmpList = XtNewString((String)RscValue.addr);
+       if ( TmpList == NULL ) return False;
+       if ( *TmpList == 0 ) { XtFree(TmpList); return False; }
+       /* Ermittele, wieviele Eintrage in der Liste sind und
+        * erstelle dann daraus die Liste.
+        */
+       Entries = 1; p = TmpList;
+       while ( *p )
+           if ( *p++ == ',' ) ++Entries;
+       *pStringTable = (XmStringTable) 
+           XtMalloc(Entries * sizeof(XmString));
+       
+       p = TmpList;
+       for ( Entry = 0; Entry < Entries; ++Entry ) {
+           pStart = p;
+           while ( (*p != 0) && (*p != ',') ) ++p;
+           *p++ = 0;
+           (*pStringTable)[Entry] = (XmString)
+               XmStringCreateSimple(pStart);
+       }
+       /* Hier geht ausnahmsweise einmal Rueckgabe vor
+        * Entschaedigung... hey, das war doch nur ein
+        * (wenn auch ziemlich miserabler) Scherz
+        */
+       XtFree(TmpList);
+       *pTableSize = Entries;
+       return True;
+    }
+    return False;
+} /* FetchXmStringTableResource */
+
+static Boolean FetchXmFontListResource(Widget w, 
+                                char *FullName, char *FullClass, 
+                                char *RscName, char *RscClass, 
+                               XmFontList *pFontList)
+{
+    XrmValue RscValue, RscDest;
+    String   RepresentationType;
+    
+    if ( FetchResource(w, FullName, FullClass, 
+                       RscName, RscClass, 
+                      &RscValue, &RepresentationType) ) {
+       RscDest.size = sizeof(XmFontList);
+       RscDest.addr = (caddr_t) pFontList;
+       if ( XtConvertAndStore(w, RepresentationType, &RscValue, 
+                              XmRFontList, &RscDest) )
+           return True;
+    }
+    return False;
+} /* FetchXmFontListResource */
+
+static Boolean FetchPixmapResource(Widget w, 
+                                char *FullName, char *FullClass, 
+                                char *RscName, char *RscClass,
+                               Pixmap *pPixmap)
+{
+    XrmValue RscValue, RscDest;
+    String   RepresentationType;
+    
+    if ( FetchResource(w, FullName, FullClass, 
+                       RscName, RscClass, 
+                      &RscValue, &RepresentationType) ) {
+       RscDest.size = sizeof(Pixmap);
+       RscDest.addr = (caddr_t) pPixmap;
+       if ( XtConvertAndStore(w, RepresentationType, &RscValue, 
+                              XtRBitmap, &RscDest) )
+           return True;
+    }
+    return False;
+} /* FetchPixmapResource */
+
+/* --------------------------------------------------------------------
+ * Waehrend der Initialisierung alle gespiegelten Resourcen, fuer die
+ * Eintraege in der Resourcen-Datenbank existieren an die passenden
+ * Kinder-Widgets weiterleiten. Der Trick an der Sache: wir setzen
+ * die betroffenen Resourcen vie XtSetValues mit uns selbst als Ziel.
+ * Dadurch bekommt SetValues die Arbeit aufgehalst, die Resourcen den
+ * richtigen Kindern zuzuordnen...
+ */
+
+#define RInt           0
+#define RShort         1
+#define RLType         2
+#define RDimension     3       
+#define RXmString      4
+#define RPixmap                5
+#define RXmFontList    6
+#define RKeySym                7
+#define RString                8
+#define RXmStringTable 9
+#define RXmItemCount   10
+
+
+typedef struct
+{
+    String Name, Class;
+
+    int Converter;
+    
+} RESOURCEMIRROR;
+
+static RESOURCEMIRROR ResourceMirror[] = {
+    { XmNblinkRate,             XmCBlinkRate,              RInt,          }, 
+    { XmNcolumns,               XmCColumns,                RShort,        }, 
+    { XmNmaxLength,             XmCMaxLength,              RInt,          }, 
+    { XmNmarginHeight,          XmCMarginHeight,           RDimension     }, 
+    { XmNmarginWidth,           XmCMarginWidth,            RDimension     },
+    { XmNselectThreshold,       XmCSelectThreshold,        RInt           }, 
+     
+    { XmNlistMarginHeight,      XmCListMarginHeight,       RDimension     }, 
+    { XmNlistMarginWidth,       XmCListMarginWidth,        RDimension     }, 
+    { XmNlistSpacing,           XmCListSpacing,            RDimension     },
+    { XmNitems,                         XmCItems,                  RXmStringTable },
+    { XmNitemCount,             XmCItemCount,              RXmItemCount   },
+    
+    { XmNmnemonic,              XmCMnemonic,               RKeySym        }, 
+    { XmNmnemonicCharSet,        XmCMnemonicCharSet,        RString        }, 
+    { XmNlabelString,           XmCLabelString,            RXmString      }, 
+    { XmNlabelMarginBottom,     XmCLabelMarginBottom,      RDimension     }, 
+    { XmNlabelMarginHeight,     XmCLabelMarginHeight,      RDimension     }, 
+    { XmNlabelMarginLeft,       XmCLabelMarginLeft,        RDimension     }, 
+    { XmNlabelMarginRight,      XmCLabelMarginRight,       RDimension     }, 
+    { XmNlabelMarginTop,        XmCLabelMarginTop,         RDimension     }, 
+    { XmNlabelMarginWidth,      XmCLabelMarginWidth,       RDimension     }, 
+    { XmNlabelPixmap,           XmCLabelPixmap,            RPixmap        },
+    { XmNlabelInsensitivePixmap, XmCLabelInsensitivePixmap, RPixmap        }, 
+    { XmNlabelType,             XmCLabelType,              RLType         }, 
+    { XmNlabelFontList,          XmCLabelFontList,         RXmFontList    }, 
+};
+
+static void InitMirrorResources(XmComboBoxWidget w)
+{
+    char          FullName[1024], FullClass[1024];
+    int           AInt, TableSize;
+    short         AShort;
+    unsigned char AUChar;
+    Dimension     ADimension;
+    XmString      AXmString;
+    XmStringTable AStringTable;
+    Pixmap        APixmap;
+    XmFontList    AFontList;
+    XrmValue      RscValue;
+    String        AString;
+    KeySym        AKeySym;
+    int           i, size = XtNumber(ResourceMirror);
+    
+    FullName[0] = 0; FullClass[0] = 0;
+    MakeNameAndClass((Widget) w, FullName, FullClass);
+
+    for ( i=0; i < size; i++ ) {
+       switch ( ResourceMirror[i].Converter ) {
+           case RInt:
+               if ( FetchIntResource((Widget) w, 
+                       FullName, FullClass, 
+                       ResourceMirror[i].Name, ResourceMirror[i].Class, 
+                       &AInt) )
+                   XtVaSetValues((Widget) w, ResourceMirror[i].Name, 
+                                 AInt, NULL);
+               break;
+           case RXmItemCount:
+               if ( FetchIntResource((Widget) w, 
+                       FullName, FullClass, 
+                       ResourceMirror[i].Name, ResourceMirror[i].Class, 
+                       &AInt) && ( AInt != 0) )
+                   XtVaSetValues((Widget) w, ResourceMirror[i].Name, 
+                                 AInt, NULL);
+               break;
+           case RShort:
+               if ( FetchShortResource((Widget) w, 
+                       FullName, FullClass, 
+                       ResourceMirror[i].Name, ResourceMirror[i].Class, 
+                       &AShort) )
+                   XtVaSetValues((Widget) w, ResourceMirror[i].Name, 
+                                 AShort, NULL);
+               break;
+           case RLType:
+               if ( FetchLabelTypeResource((Widget) w, 
+                       FullName, FullClass, 
+                       ResourceMirror[i].Name, ResourceMirror[i].Class, 
+                       &AUChar) )
+                   XtVaSetValues((Widget) w, ResourceMirror[i].Name, 
+                                 AUChar, NULL);
+               break;
+           case RDimension:
+               if ( FetchDimensionResource((Widget) w, 
+                       FullName, FullClass, 
+                       ResourceMirror[i].Name, ResourceMirror[i].Class, 
+                       &ADimension) )
+                   XtVaSetValues((Widget) w, ResourceMirror[i].Name, 
+                                 ADimension, NULL);
+               break;
+           case RXmString:
+               if ( FetchXmStringResource((Widget) w, 
+                       FullName, FullClass, 
+                       ResourceMirror[i].Name, ResourceMirror[i].Class, 
+                       &AXmString) )
+                   XtVaSetValues((Widget) w, ResourceMirror[i].Name, 
+                                 AXmString, NULL);
+               break;
+           case RXmStringTable:
+               if ( FetchXmStringTableResource((Widget) w,
+                        FullName, FullClass,
+                        ResourceMirror[i].Name, ResourceMirror[i].Class,
+                        &AStringTable, &TableSize) ) {
+                   XtVaSetValues((Widget) w, 
+                        XmNitems, (XtPointer) AStringTable, 
+                        XmNitemCount, TableSize, NULL);
+               }
+               break;
+           case RKeySym:
+               if ( FetchKeySymResource((Widget) w, 
+                       FullName, FullClass, 
+                       ResourceMirror[i].Name, ResourceMirror[i].Class, 
+                       &AKeySym) )
+                   XtVaSetValues((Widget) w, ResourceMirror[i].Name, 
+                                 AKeySym, NULL);
+               break;
+           case RString:
+               if ( FetchStringResource((Widget) w, 
+                       FullName, FullClass, 
+                       ResourceMirror[i].Name, ResourceMirror[i].Class, 
+                       &AString) )
+                   XtVaSetValues((Widget) w, ResourceMirror[i].Name, 
+                                 AString, NULL);
+               break;
+           case RPixmap:
+               if ( FetchPixmapResource((Widget) w, 
+                       FullName, FullClass, 
+                       ResourceMirror[i].Name, ResourceMirror[i].Class, 
+                       &APixmap) ) {
+                   XtVaSetValues((Widget) w, ResourceMirror[i].Name, 
+                                 APixmap, NULL);
+                   if ( strcmp(ResourceMirror[i].Name, XmNlabelPixmap) == 0 )
+                       w->combobox.ConvertBitmapToPixmap = True;
+                   else
+                       w->combobox.ConvertBitmapToPixmapInsensitive = True;
+               }
+               break;
+           case RXmFontList:
+               if ( FetchXmFontListResource((Widget) w,
+                      FullName, FullClass,
+                      ResourceMirror[i].Name, ResourceMirror[i].Class,
+                      &AFontList) )
+                   XtVaSetValues((Widget) w, ResourceMirror[i].Name,
+                                 AFontList, NULL);
+               break;
+       }
+    }
+} /* InitMirrorResources */
+
+/* --------------------------------------------------------------------
+ * Wandelt ein 1-Bit tiefes Bitmap in ein n-Bit tiefes Pixmap um, dass
+ * die gleiche Tiefe besitzt, wie der Bildschirm, auf dem das Pixmap
+ * spaeter erscheinen soll.
+ */
+static Pixmap BitmapToPixmap(XmComboBoxWidget w, 
+                           String Resource, GC ColorGC)
+{
+    Pixmap       LabelPixmap, LabelBitmap;
+    Display      *display = XtDisplay(w);
+    Window       root;
+    int          PixX, PixY;
+    unsigned int PixW, PixH, PixBW, PixDepth;
+
+    XtVaGetValues(w->combobox.LabelCtrl, Resource, &LabelBitmap, NULL);
+    XGetGeometry(display, LabelBitmap, &root, 
+                &PixX, &PixY, &PixW, &PixH, &PixBW, &PixDepth);
+    LabelPixmap = XCreatePixmap(
+                       display, RootWindowOfScreen(XtScreen(w)), 
+                       PixW, PixH, 
+                       (w->combobox.LabelCtrl)->core.depth);
+    XCopyPlane(display, LabelBitmap, LabelPixmap, 
+              ColorGC, 0, 0, PixW, PixH, 0, 0, 1);
+    XtVaSetValues(w->combobox.LabelCtrl, Resource, LabelPixmap, NULL);
+    XFreePixmap(display, LabelBitmap);
+    return LabelPixmap;
+} /* BitmapToPixmap */
+
+/* --------------------------------------------------------------------
+ * Alles initialisieren, sobald das Widget eingerichtet wird. Das sagt
+ * sich hier so einfach, ist es aber *definitiv* nicht!!!!
+ */
+static void Initialize(Widget request, XmComboBoxWidget newW, 
+                       ArgList wargs, Cardinal *ArgCount)
+{
+    Dimension    width, height, dummy;
+    Widget       w;
+    Arg          args[10];
+    int          n = 0;
+    XmString     xmstr;
+    Pixel        BackgroundColor;
+    
+/* 
+ * Da zu allem Ueberfluss die einzelnen Instanzen einer XmComboBox
+ * auf verschiedenen Displays auftauchen koennen, wird hier:
+ * 1. pro Widget ein eigener Cursor erzeugt (benoetigt fuer die Liste)
+ * 2. pro Widget (hier = pro Applikation) die benoetigte Action-Routine
+ * registiert. Doppelte Registrierung macht dem Toolkit nichts aus, da es
+ * dann eine evtl. aeltere Definition loescht.
+ */
+    XtAppAddActions(XtWidgetToApplicationContext((Widget) newW), 
+                       actions, XtNumber(actions));
+    
+/* Allgemeine Initialisierungen... */
+    newW->combobox.ConvertBitmapToPixmap            = False;
+    newW->combobox.ConvertBitmapToPixmapInsensitive = False;
+    
+    newW->combobox.LastSelection                    = 0;
+    
+    newW->combobox.InInit                           = True;
+    
+/* 
+ * Das folgende Problem mit der Kontrolle, ob sich das Widget absolut auf
+ * dem Bildschirm verschoben hat, trifft uns nur, wenn die Liste nicht
+ * dauernd auf dem Bildschirm erscheint:
+ * Lass' dich benachrichtigen, sobald dieses Widget in irgendeiner
+ * Form bewegt wird -- und sei es nur, dass das gesamte Applikations-
+ * fenster umhergeschoben wurde. Um die Benachrichtigung ueberhaupt
+ * zu erreichen, ist es erforderlich, sich benachrichtigen zu lassen, 
+ * sobald die naechste Shell (oder ein Nachkomme) im Widget-Instanzen-
+ * Baum verschoben wurde.
+ */
+    if ( !newW->combobox.StaticList ) {
+       w = (Widget) newW;
+       while ( !XtIsSubclass(w, shellWidgetClass) )
+           w = XtParent(w);
+       newW->combobox.MyNextShell = w;
+       XtAddEventHandler(w, 
+                         StructureNotifyMask | FocusChangeMask, 
+                         False, (XtEventHandler) ShellCallback, 
+                         (XtPointer) newW);
+    }
+/* Richte nun alle zu diesem Widget gehoerenden Kinder ein, als da
+ * waeren:
+ * 1 x editierbares Eingabefeld
+ * 1 x ein Pfeil nach unten
+ * 1 x ein Schriftfeld
+ */
+    newW->combobox.EditCtrl = XtVaCreateManagedWidget(
+       "edit", xmTextFieldWidgetClass, (Widget) newW,
+       XmNverifyBell, False, 
+       NULL);
+    XtAddCallback(newW->combobox.EditCtrl, 
+                  XmNlosingFocusCallback, 
+                 (XtCallbackProc) EditFocusCallback, NULL);
+    XtAddCallback(newW->combobox.EditCtrl, 
+                  XmNmodifyVerifyCallback, 
+                 (XtCallbackProc) EditVerifyCallback, NULL);
+    XtAddCallback(newW->combobox.EditCtrl, 
+                  XmNvalueChangedCallback, 
+                 (XtCallbackProc) EditChangedCallback, NULL);
+    XtAddCallback(newW->combobox.EditCtrl, 
+                  XmNhelpCallback, 
+                 (XtCallbackProc) HelpCallback, 
+                 (XtPointer) newW);
+    XtAddCallback(newW->combobox.EditCtrl, 
+                  XmNactivateCallback, 
+                 (XtCallbackProc) ActivateCallback, 
+                 (XtPointer) newW);
+    if ( newW->combobox.Editable )
+       XtAddCallback(newW->combobox.EditCtrl, 
+                     XmNmotionVerifyCallback, 
+                     (XtCallbackProc) MotionVerifyCallback, 
+                     (XtPointer) newW);
+/* Neue Translations fuer das Eingabefeld aufnehmen */
+    XtOverrideTranslations(newW->combobox.EditCtrl, 
+                           NewEditTranslations);
+    if ( !newW->combobox.Editable ) {
+       XtOverrideTranslations(newW->combobox.EditCtrl, 
+                               NewEditTranslationsNE);
+        XtVaSetValues(newW->combobox.EditCtrl, 
+                      XmNcursorPositionVisible, False, NULL);
+    }
+#ifdef NODRAGNDROP
+    XtOverrideTranslations(newW->combobox.EditCtrl, 
+                           NewListTranslations); /* Btn2Dwn aus! */
+#endif
+
+/* --- */
+    newW->combobox.ArrowCtrl = XtVaCreateManagedWidget(
+       "arrow", xmArrowButtonWidgetClass, (Widget) newW, 
+       XmNarrowDirection,     XmARROW_DOWN, 
+       XmNtraversalOn,        False, 
+       XmNnavigationType,     XmNONE,
+       XmNborderWidth,        0, 
+       XmNhighlightThickness, 0, 
+       NULL);
+    XmRemoveTabGroup(newW->combobox.ArrowCtrl);
+    if ( newW->combobox.StaticList ) {
+       XtVaSetValues(newW->combobox.ArrowCtrl, 
+           XmNmappedWhenManaged, False, NULL);
+    } else {
+       XtAddEventHandler(newW->combobox.ArrowCtrl, 
+                         EnterWindowMask | LeaveWindowMask,
+                         False, (XtEventHandler) ArrowCrossingCallback,
+                         (XtPointer) newW);
+       XtAddCallback(newW->combobox.ArrowCtrl, 
+                     XmNactivateCallback, 
+                     (XtCallbackProc) ArrowCallback, NULL);
+       XtAddCallback(newW->combobox.ArrowCtrl, 
+                     XmNarmCallback, 
+                     (XtCallbackProc) ArrowCallback, NULL);
+       XtAddCallback(newW->combobox.ArrowCtrl, 
+                     XmNhelpCallback, 
+                     (XtCallbackProc) HelpCallback, 
+                     (XtPointer) newW);
+    }
+
+/* --- */
+    newW->combobox.LabelCtrl = XtVaCreateWidget(
+       "label", xmLabelWidgetClass, (Widget) newW, 
+       XmNstringDirection, newW->manager.string_direction, 
+       NULL);
+    if ( newW->combobox.ShowLabel ) {
+       XtManageChild((Widget) newW->combobox.LabelCtrl);
+       XtAddCallback(newW->combobox.LabelCtrl, 
+                     XmNhelpCallback, 
+                     (XtCallbackProc) HelpCallback, 
+                     (XtPointer) newW);
+    }
+
+/* 
+ * Zuerst noch die Shell erzeugen, die so einfach mir nichts dir nichts
+ * frei auf dem Bildschirm herumschweben kann und damit das Ausklappen
+ * der Liste erst ermoeglicht -- und uns allerhand Scherereien bereitet!
+ * War das ein bloeder Fehler in Motif 1.2! Diese Version vertraegt ab-
+ * solut keine ShellWidgetClass noch overrideShellWidgetClass!!!! Naja,
+ * mit einer vendorShellWidgetClass laesst sich aber exakt der gleiche
+ * Effekt erreichen. NEU: vor allem funktioniert dann endlich auch
+ * Drag'n'Drop!!!
+ * Noch neuer: Wenn die Liste dauerhaft angezeigt werden muss, entfaellt
+ * diese Shell zwangslaeufig. Dann ist das Listenfeld ein direktes Kind
+ * der ComboBox.
+ */
+    if ( !newW->combobox.StaticList ) {
+       newW->combobox.PopupShell = XtVaCreateWidget(
+           "combobox_shell", vendorShellWidgetClass, (Widget) newW, 
+           XmNoverrideRedirect, True,
+           XmNsaveUnder,        False,
+           XmNallowShellResize, True, 
+           NULL);
+       XtAddEventHandler(newW->combobox.PopupShell, 
+                         EnterWindowMask | LeaveWindowMask, 
+                         False, (XtEventHandler) OverrideShellCallback, 
+                         (XtPointer) newW);
+    } else {
+    /*
+     * Sieht ja pervers nach einer Rekursion aus...daher: OBACHT!
+     */
+       newW->combobox.PopupShell = (Widget) newW;
+    }
+
+/*
+ * Nun kommt die Drop-Down-Liste an die Reihe. Die Liste muss dabei
+ * mit einer Convenience-Funktion erstellt werden, damit ein Rollbalken
+ * 'dran ist und das Ganze wird dann in eine Override-Shell gepackt.
+ * Nicht zu vergessen ist der XtManageChild-Aufruf, damit die Liste
+ * sofort nach dem Aufklappen der Shell sichtbar wird.
+ */
+    XtSetArg(args[n], XmNselectionPolicy, newW->combobox.SelectionPolicy); n++;
+    
+    if ( !newW->combobox.StaticList ) {
+    /*
+     * Es gibt halt so eine ganze Reihe von Einstellungen, die koennen nicht
+     * veraendert werden, wenn das Listenfeld nur bei Bedarf ausgeklappt wird.
+     */
+       XtSetArg(args[n], XmNhighlightThickness, 0); n++;
+    }
+    XtSetArg(args[n], XmNlistSizePolicy, 
+                      newW->combobox.ListSizePolicy); n++;
+    XtSetArg(args[n], XmNscrollBarDisplayPolicy, 
+                      newW->combobox.ScrollBarDisplayPolicy); n++;
+    
+    XtSetArg(args[n], XmNautomaticSelection, 
+                      newW->combobox.AutomaticSelection); n++;
+    XtSetArg(args[n], XmNvisibleItemCount, 
+                      newW->combobox.VisibleItemCount); n++;
+    newW->combobox.ListCtrl = XmCreateScrolledList(
+       newW->combobox.PopupShell, "list",  
+       args, n);
+
+/*
+ * Fuer den Fall, dass die Liste in einer eigenen Shell steckt und daher frei
+ * auf dem Bildschirm herumschweben kann, sollten wir sicherheitshalber die
+ * Tastaturbedienung (Fokus) abschalten, um Probleme zu vermeiden (jedenfalls
+ * hoffentlich...!)
+ */
+    if ( !newW->combobox.StaticList ) {
+       XtVaSetValues(newW->combobox.ListCtrl, 
+                     XmNtraversalOn,  False,  NULL);
+       XtVaSetValues(XtParent(newW->combobox.ListCtrl), 
+                     XmNtraversalOn, False, NULL);
+    } else {
+       if ( !newW->combobox.Editable ) {
+           XtVaSetValues(XtParent(newW->combobox.ListCtrl), 
+                     XmNtraversalOn, False, NULL);
+           XmRemoveTabGroup(newW->combobox.ListCtrl);
+       }
+    }
+    
+    XtManageChild(newW->combobox.ListCtrl);
+    XtAddCallback(newW->combobox.ListCtrl, 
+                  XmNsingleSelectionCallback, 
+                 (XtCallbackProc) ListSelectionCallback, 
+                 (XtPointer) newW);
+    XtAddCallback(newW->combobox.ListCtrl, 
+                  XmNbrowseSelectionCallback, 
+                 (XtCallbackProc) ListSelectionCallback, 
+                 (XtPointer) newW);
+    XtAddCallback(newW->combobox.ListCtrl, 
+                  XmNdefaultActionCallback, 
+                 (XtCallbackProc) ListDefaultActionCallback, 
+                 (XtPointer) newW);
+    XtAddCallback(newW->combobox.ListCtrl, 
+                  XmNhelpCallback, 
+                 (XtCallbackProc) HelpCallback, 
+                 (XtPointer) newW);
+    
+    XtAddEventHandler(newW->combobox.ListCtrl, 
+                      ButtonReleaseMask, 
+                     False, (XtEventHandler) Button1UpInList, 
+                     (XtPointer) newW);
+
+#ifdef NODRAGNDROP
+    XtOverrideTranslations(newW->combobox.ListCtrl, 
+                           NewListTranslations);
+#endif
+    if ( newW->combobox.StaticList && newW->combobox.Editable )
+        XtOverrideTranslations(newW->combobox.ListCtrl, 
+                               NewListTranslationsE);
+
+/* Jetzt wird es dann erst richtig spannend... Zuerst alle evtl.
+ * in der Resource-Datenbank abgelegten Resourcen an die Kinder
+ * weitergeben. Danach die uebergebenen Parameter ebenfalls an
+ * die Kinder weiterreichen und schliesslich das Layout ermitteln.
+ */
+    InitMirrorResources(newW);
+    UpdateColors(newW, -1);
+    SetValues(newW, newW, newW, wargs, ArgCount);
+    
+    if ( newW->combobox.ConvertBitmapToPixmap ) 
+       newW->combobox.LabelPixmap = 
+           BitmapToPixmap(newW, XmNlabelPixmap, 
+                      ((XmLabelRec *) newW->combobox.LabelCtrl)->
+                        label.normal_GC);
+    if ( newW->combobox.ConvertBitmapToPixmapInsensitive ) 
+       newW->combobox.LabelInsensitivePixmap = 
+           BitmapToPixmap(newW, XmNlabelInsensitivePixmap, 
+                      ((XmLabelRec *) newW->combobox.LabelCtrl)->
+                        label.insensitive_GC);
+    
+    DefaultGeometry(newW, &width, &height, &dummy, &dummy);
+    if ( newW->core.width == 0 )
+       newW->core.width  = width;
+    if ( newW->core.height == 0 )
+       newW->core.height = height;
+
+/*
+ * Falls wir keine Fontliste besitzen, dann nehmen wir die von
+ * dem Eingabefeld...
+ */
+    if ( newW->combobox.Font == NULL ) {
+       XtVaGetValues(newW->combobox.EditCtrl, 
+                     XmNfontList, &newW->combobox.Font, NULL);
+       XtVaSetValues(newW->combobox.ListCtrl, 
+                     XmNfontList, newW->combobox.Font, NULL);
+    } else {
+       XtVaSetValues(newW->combobox.ListCtrl, 
+                     XmNfontList, newW->combobox.Font, NULL);
+       XtVaSetValues(newW->combobox.EditCtrl, 
+                     XmNfontList, newW->combobox.Font, NULL);
+    }
+    
+/* 
+ * Initialisiere alle Statusflaggen, die mit diesem unseligen Focus-
+ * problem zu tun haben...
+ */
+    newW->combobox.ListVisible          = False;
+    newW->combobox.IgnoreFocusOut       = False;
+    newW->combobox.PendingFocusOut      = False;
+    newW->combobox.PendingOverrideInOut = False;
+    
+    newW->combobox.PassVerification = False;
+
+/* 
+ * Jooa... bei der OSF pennen die wohl komplett?! Zusammen mit Form-
+ * Widgets gibt das wohl immer Aerger...daher hier ein DoLayout()
+ * aufrufen, damit Eingabefeld und Pfeil sowie das Listenfeld an der 
+ * richtigen Stelle sitzen!
+ */
+    DoLayout(newW);
+/* 
+ * Endlich fertig mit der Initialisierung. Das hier ist aber auch
+ * wirklich viel Arbeit fuer so ein Widget!
+ */    
+    newW->combobox.InInit = False;
+} /* Initialize */
+
+/* --------------------------------------------------------------------
+ * Diese Funktionen bitte nur im aeussersten Notfall benutzen, da sie
+ * die Abstraktion dieser neuen Klasse umgehen und Informationen ueber
+ * den internen Aufbau voraussetzen.
+ */
+Widget XmComboBoxGetEditWidget(Widget w)
+{
+    return ((XmComboBoxWidget) w)->combobox.EditCtrl;
+} /* XmComboBoxGetEditWidget */
+
+Widget XmComboBoxGetListWidget(Widget w)
+{
+    return ((XmComboBoxWidget) w)->combobox.ListCtrl;
+} /* XmComboBoxGetListWidget */
+
+Widget XmComboBoxGetLabelWidget(Widget w)
+{
+    return ((XmComboBoxWidget) w)->combobox.LabelCtrl;
+} /* XmComboBoxGetLabelWidget */
+
+
+/* --------------------------------------------------------------------
+ * Sobald sich im Listenfeld Eintraege veraenderten, sei es, dass sie
+ * geloescht wurden, sei es, dass sie veraendert wurden, so muss hier
+ * gegebenenfalls auch der Text im Eingabefeld angepasst werden.
+ * Letzteres betrifft aber nur Combo-Boxen mit nicht editierbarem
+ * Eingabefeld. In jedem Fall wird aber bei jeder Combo-Box-Type in
+ * dem Fall, dass ein Eintrag geloescht wird, der darauffolgende
+ * Eintrag markiert. Eigentlich ist dieses nur eine nette Geste
+ * gegenueber dem Benutzer...
+ * 
+ * Parameter:
+ *   w             Combo-Box-Widget
+ *   Index         Index auf denjenigen Eintrag der sich geaendert
+ *                 hat, oder der geloescht wurde.
+ *   Deleted       Zeigt an, ob der Eintrag geloescht wurde (True)
+ *                 oder sich nur veraenderte (False)
+ */
+static UpdateComboBox(XmComboBoxWidget w, int Index, Boolean Deleted)
+{
+    int OldIndex, ItemCount;
+    
+    OldIndex = XmComboBoxGetSelectedPos((Widget) w);
+    if ( OldIndex == Index ) {
+/* Es betrifft den Eintrag, der auch momentan ausgewaehlt ist.
+ * Sollte er geloescht werden, so nimm' (soweit vorhanden) den
+ * naechsten Eintrag, wurde er ausgetauscht, so lass ihn ausge-
+ * waehlt.
+ */
+       if ( Deleted ) {
+           XtVaGetValues(w->combobox.ListCtrl, 
+                         XmNitemCount, &ItemCount, NULL);
+           if ( ItemCount != 0 ) {
+               if ( Index >= ItemCount ) Index = ItemCount;
+               /* Markieren des Eintrags, ohne jedoch jetzt schon
+                * den Eintrag in die Eingabezeile zu kopieren.
+                */
+               SetSelectionPos(w, Index, False);
+           }
+       }
+    }
+/* Das Problem betrifft uns nur bei nicht editierbaren Combo-Boxen
+ * im vollen Umfang. Denn dann muss auch der Text im Eingabefeld
+ * veraendert werden.
+ */
+    if ( !w->combobox.Editable ) {
+       TransferToEditCtrl(w, Index, False);
+    }
+
+    return 1;
+} /* UpdateComboBox */
+
+
+/* --------------------------------------------------------------------
+ * Die Eintragsposition finden, an der der Eintrag sortiert stehen
+ * muesste. Naja, es wurde ja 'mal langsam Zeit, diese Routine etwas
+ * aufzupolieren, damit sie schneller wird.
+ */
+static int FindSortedItemPos(XmComboBoxWidget w, XmString item)
+{
+    Widget                          ListBox = w->combobox.ListCtrl;
+    XmStringTable                   Items;
+    int                             ItemCount, index, Left, Right, Result;
+    char                            *pItemText, *pCompareText;
+    Boolean                        ExternSort;
+    XmComboBoxSortingCallbackStruct data;
+    
+    XtVaGetValues(ListBox, XmNitems,     &Items, 
+                           XmNitemCount, &ItemCount, NULL);
+    if ( ItemCount == 0 ) return 1;
+    
+    /*
+     * Moechte das Programm die Kontrolle ueber den Sortiervorgang
+     * uebernehmen? Dann bereite alles vor...
+     */
+    ExternSort = XtHasCallbacks((Widget) w, XmNsortingCallback) == 
+                     XtCallbackHasSome;
+    if ( ExternSort ) {
+        data.reason    = XmCR_SORTING;
+        data.event     = NULL;
+        data.operation = XmOP_INIT;
+        data.item      = item;
+        XtCallCallbacks((Widget) w, XmNsortingCallback, (XtPointer) &data);
+    } else
+        XmStringGetLtoR(item, XmSTRING_DEFAULT_CHARSET, &pCompareText);
+
+    Left = 0; Right = ItemCount - 1;    
+    do {
+       index = (Left + Right) / 2;
+       if ( ExternSort ) {
+           data.operation = XmOP_COMPARE;
+           data.item      = Items[index];
+           data.result    = 1;
+            XtCallCallbacks((Widget) w, XmNsortingCallback, (XtPointer) &data);
+            Result = data.result;
+       } else {
+           XmStringGetLtoR(Items[index], XmSTRING_DEFAULT_CHARSET, &pItemText);
+           Result = strcmp(pCompareText, pItemText);
+           XtFree(pItemText);
+       }
+       if      ( Result < 0 ) Right = index - 1;
+       else if ( Result > 0 ) Left  = index + 1;
+    } while ( (Result != 0) && (Left <= Right) );
+
+    /*
+     * Nach Gebrauch wieder alles aufraeumen (bei einer externen Sortierung
+     * muss das das Programm uebernehmen!)
+     */
+    if ( ExternSort ) {
+        data.operation = XmOP_DONE;
+        XtCallCallbacks((Widget) w, XmNsortingCallback, (XtPointer) &data);
+    } else
+        XtFree(pCompareText);
+        
+    if ( Result < 0 )
+       return index + 1; /* Beachte, dass Indizes mit 1 beginnen! */
+    else
+       return index + 2; /* Beachte, dass Indizes mit 1 beginnen! */
+} /* FindSortedItemPos */
+
+/* --------------------------------------------------------------------
+ * Kontrolliere, ob es sich ueberhaupt um eine Combo-Box (bzw. einen
+ * hypothetischen Nachkommen) handelt -- ansonsten mecker kraeftig
+ * herum!
+ * Ergebnis:
+ *   True, falls wir hier ein falsches Widget untergejubelt bekommen!
+ */
+static Boolean CheckComboBox(Widget w, char *pFuncName)
+{
+    char buff[256];
+    char *pWName;
+
+#if (XmVersion >= 2000)
+    return False; /* temporary workaround */
+#else    
+    if ( XmIsComboBox(w) ) return False;
+    pWName = XrmQuarkToString(w->core.xrm_name);
+    sprintf(buff, 
+"Warning: %s called on widget named %s beeing \
+not a descendant of class XmComboBox!", 
+                 pFuncName, pWName);
+    XtWarning(buff);
+    return True;
+#endif
+} /* CheckComboBox */
+
+/* --------------------------------------------------------------------
+ * Saemtliche Interface-Routinen zur Combo-Box
+ */
+/* Zunaechst alles fuer die Listbox */
+#define ListBox (((XmComboBoxWidget) w)->combobox.ListCtrl)
+#define EditBox (((XmComboBoxWidget) w)->combobox.EditCtrl)
+#define ComboBox ((XmComboBoxWidget) w)
+
+/* !!!
+ * So angepasst, dass bei doppelt auftretenden Eintraegen, der
+ * alte Eintrag weiterhin markiert bleibt. Diese Massnahme soll
+ * eigentlich nur verhindern, dass zufaellig zwei Eintraege
+ * markiert sind, falls nach der Anwahl eines Eintrages ein zweiter
+ * gleichlautender Eintrag hinzugefuegt wurde.
+ * Was hier die reine Lehre (oder war das die Leere?) anbetrifft:
+ * in einer Combo-Box sollten sich sowieso nie gleichlautende
+ * Eintraege befinden, da sie dort unsinnig sind und den Benutzer
+ * nur verwirren...
+ */
+void    XmComboBoxAddItem(Widget w, XmString item, int pos)
+{
+    int OldIndex = XmComboBoxGetSelectedPos(w);
+    
+    if ( CheckComboBox(w, "XmComboBoxAddItem") ) return;
+    if ( ComboBox->combobox.Sorted )
+       pos = FindSortedItemPos(ComboBox, item);
+    XmListAddItem(ListBox, item, pos);
+    if ( OldIndex != XmComboBoxGetSelectedPos(w) )
+        /* Hier SetSelectionPos() statt XmComboBoxSelectPos(),
+        * da der Text nicht in das Eingabefeld uebertragen werden
+        * soll!
+        */
+       SetSelectionPos(ComboBox, OldIndex, False);
+} /* XmComboBoxAddItem */
+/* !!!
+ * Hier gilt das bereits oben gesagte (siehe XmComboBoxAddItem).
+ * Bei sortierten Listboxen wird die Sortierung beim Gebrauch dieser
+ * Funktion zerstoert!
+ */
+void    XmComboBoxAddItems(Widget w, XmString *items, int item_count, int pos)
+{
+    int OldIndex = XmComboBoxGetSelectedPos(w);
+
+    if ( CheckComboBox(w, "XmComboBoxAddItems") ) return;
+    XmListAddItems(ListBox, items, item_count, pos);
+    if ( OldIndex != XmComboBoxGetSelectedPos(w) )
+       /* Siehe Anmerkung in XmComboBoxAddItem */
+       SetSelectionPos(ComboBox, OldIndex, False);
+} /* XmComboBoxAddItems */
+
+void    XmComboBoxAddItemUnselected(Widget w, XmString item, int pos)
+{ XmListAddItemUnselected(ListBox, item, pos); }
+
+/* !!!
+ * Da bei den folgenden Routinen jeweils ein oder mehrere Eintraege
+ * geloescht oder veraendert werden, muss gegebenefalls das Eingabe-
+ * feld bei nicht editierbaren Combo-Boxen auf Vordermann gebracht
+ * werden.
+ */
+void    XmComboBoxDeleteItem(Widget w, XmString item)
+{
+    int Index = XmListItemPos(ListBox, item);
+
+    if ( CheckComboBox(w, "XmComboBoxDeleteItem") ) return;
+    if ( Index ) XmComboBoxDeletePos(w, Index);
+} /* XmComboBoxDeleteItem */
+
+void    XmComboBoxDeleteItems(Widget w, XmString *items, int item_count)
+{
+    int i;
+
+    if ( CheckComboBox(w, "XmComboBoxDeleteItems") ) return;
+    for ( i = 0; i < item_count; i++ )
+       XmListDeleteItem(w, items[i]);
+} /* XmComboBoxDeleteItems */
+
+void    XmComboBoxDeletePos(Widget w, int pos)
+{
+    int OldIndex = XmComboBoxGetSelectedPos(w);
+    
+    if ( CheckComboBox(w, "XmComboBoxDeletePos") ) return;
+    XmListDeletePos(ListBox, pos);
+    if ( pos == OldIndex ) UpdateComboBox(ComboBox, pos, True);
+} /* XmComboBoxDeletePos */
+
+void    XmComboBoxDeleteItemsPos(Widget w, int item_count, int pos)
+{
+    int i;
+
+    if ( CheckComboBox(w, "XmComboBoxDeleteItemsPos") ) return;
+    for ( i = 0; i < item_count; i++ )
+       XmComboBoxDeletePos(w, pos++);
+} /* XmComboBoxDeleteItemsPos */
+
+void    XmComboBoxDeleteAllItems(Widget w)
+{
+    if ( CheckComboBox(w, "XmComboBoxAllDeleteItems") ) return;
+    XmListDeleteAllItems(ListBox);
+    UpdateComboBox(ComboBox, 0, True);
+} /* XmComboBoxDeleteAllItems */
+
+/* !!!
+ * Werden Eintraege ausgetauscht, so heisst es fuer uns, auch hierbei
+ * auf der Hut zu sein.
+ */
+void    XmComboBoxReplaceItems(Widget w, XmString *old_items, int item_count, XmString *new_items)
+{
+    if ( CheckComboBox(w, "XmComboBoxReplaceItems") ) return;
+    XmListReplaceItems(ListBox, old_items, item_count, new_items);
+    UpdateComboBox(ComboBox, XmComboBoxGetSelectedPos(w), False);
+} /* XmComboBoxReplaceItems */
+
+void    XmComboBoxReplaceItemsPos(Widget w, XmString *new_items, int item_count, int position)
+{
+    int OldIndex = XmComboBoxGetSelectedPos(w);
+
+    if ( CheckComboBox(w, "XmComboBoxReplaceItemsPos") ) return;
+    XmListReplaceItemsPos(ListBox, new_items, item_count, position);
+    if ( (OldIndex >= position) && (OldIndex < position + item_count) )
+       UpdateComboBox(ComboBox, OldIndex, False);
+} /* XmComboBoxReplaceItemsPos */
+
+Boolean XmComboBoxItemExists(Widget w, XmString item)
+{
+    if ( CheckComboBox(w, "XmComboBoxItemExists") ) return False;
+    return XmListItemExists(ListBox, item);
+} /* XmComboBoxItemExists */
+
+int     XmComboBoxItemPos(Widget w, XmString item)
+{
+    if ( CheckComboBox(w, "XmComboBoxItemPos") ) return 0;
+    return XmListItemPos(ListBox, item);
+} /* XmComboBoxItemPos */
+
+Boolean XmComboBoxGetMatchPos(Widget w, XmString item, int **pos_list, int *pos_count)
+{
+    if ( CheckComboBox(w, "XmComboBoxGetMatchPos") ) return False;
+    return XmListGetMatchPos(ListBox, item, pos_list, pos_count);
+} /* XmComboBoxGetMatchPos */
+
+/* !!!
+ * Sobald ein anderer Eintrag in der Listbox ausgewaehlt werden soll,
+ * muessen wir hier helfend eingreifen.
+ */
+void    XmComboBoxSelectPos(Widget w, int pos, Boolean notify)
+{
+    int index;
+    
+    if ( CheckComboBox(w, "XmComboBoxSelectPos") ) return;
+    index = SetSelectionPos(ComboBox, pos, notify);
+    if ( index ) TransferToEditCtrl(ComboBox, index, False);
+} /* XmComboBoxSelectPos */
+
+/* !!!
+ * dto. analog zu XmComboBoxSelectPos, nur statt des Index wird der
+ * Eintragstext angegeben, um einen Eintrag in der Listbox zu
+ * markieren.
+ */
+void    XmComboBoxSelectItem(Widget w, XmString item, Boolean notify)
+{
+    int index;
+    
+    if ( CheckComboBox(w, "XmComboBoxSelectItem") ) return;
+    XmListSelectItem(ListBox, item, notify);
+    index = SetSelectionPos(ComboBox, XmComboBoxGetSelectedPos(w), False);
+    if ( index ) TransferToEditCtrl(ComboBox, index, False);
+} /* XmComboBoxSelectItem */
+
+/* !!!
+ * Geaendert gegenueber dem ListBox-Pendant! Da in einer Combo-Box die
+ * Liste nur maximal einen ausgewaehlten Eintrag besitzt, macht die
+ * 'alte' Funktionalitaet von XmListGetSelectedPos ziemlich wenig Sinn.
+ * Die neue Routine liefert statt dessen direkt den Index des aus-
+ * gewaehlten Eintrages oder 0 zurueck.
+ */
+int     XmComboBoxGetSelectedPos(Widget w)
+{
+    int *SelectionList, SelectionCount, SelectionIndex;
+    
+    if ( CheckComboBox(w, "XmComboBoxGetSelectedPos") ) return 0;
+    if ( XmListGetSelectedPos(ListBox,
+                             &SelectionList, &SelectionCount) ) {
+       SelectionIndex = *SelectionList;
+       XtFree((char *)SelectionList);
+    } else SelectionIndex = 0;
+    return SelectionIndex;
+} /* XmComboBoxGetSelectedPos */
+
+
+
+void    XmComboBoxClearSelection(Widget w, Time time)
+{
+    XmTextFieldClearSelection(EditBox, time);
+} /* XmComboBoxClearSelection */
+
+Boolean XmComboBoxCopy(Widget w, Time time)
+{
+    return XmTextFieldCopy(EditBox, time);
+} /* XmComboBoxCopy */
+
+Boolean XmComboBoxCut(Widget w, Time time)
+{
+    return XmTextFieldCut(EditBox, time);
+} /* XmComboBoxCut */
+
+XmTextPosition XmComboBoxGetInsertionPosition(Widget w)
+{
+    return XmTextFieldGetInsertionPosition(EditBox);
+} /* XmComboBoxGetInsertionPosition */
+
+XmTextPosition XmComboBoxGetLastPosition(Widget w)
+{
+    return XmTextFieldGetLastPosition(EditBox);
+} /* XmComboBoxGetLastPosition */
+
+int     XmComboBoxGetMaxLength(Widget w)
+{
+    return XmTextFieldGetMaxLength(EditBox);
+} /* XmComboBoxGetMaxLength */
+
+char *  XmComboBoxGetSelection(Widget w)
+{
+    return XmTextFieldGetSelection(EditBox);
+} /* XmComboBoxGetSelection */
+
+Boolean XmComboBoxGetSelectionPosition(Widget w, XmTextPosition *left, 
+                                       XmTextPosition *right)
+{
+    return XmTextFieldGetSelectionPosition(EditBox, left, right);
+} /* XmComboBoxGetSelectionPosition */
+
+char *  XmComboBoxGetString(Widget w)
+{
+    return XmTextFieldGetString(EditBox);
+} /* XmComboBoxGetString */
+
+void    XmComboBoxInsert(Widget w, XmTextPosition position, char *value)
+{
+    XmTextFieldInsert(EditBox, position, value);
+} /* XmComboBoxInsert */
+
+Boolean XmComboBoxPaste(Widget w)
+{
+    return XmTextFieldPaste(EditBox);
+} /* XmComboBoxPaste */
+
+Boolean XmComboBoxRemove(Widget w)
+{
+    return XmTextFieldRemove(EditBox);
+} /* XmComboBoxRemove */
+
+void    XmComboBoxReplace(Widget w, XmTextPosition from_pos, 
+                          XmTextPosition to_pos, char *value)
+{
+    XmTextFieldReplace(EditBox, from_pos, to_pos, value);
+} /* XmComboBoxReplace */
+
+void    XmComboBoxSetAddMode(Widget w, Boolean state)
+{
+    XmTextFieldSetAddMode(EditBox, state);
+} /* XmComboBoxSetAddMode */
+
+void    XmComboBoxSetHighlight(Widget w, XmTextPosition left, 
+                               XmTextPosition right, XmHighlightMode mode)
+{
+    XmTextFieldSetHighlight(EditBox, left, right, mode);
+} /* XmComboBoxSetHighlight */
+
+void    XmComboBoxSetInsertionPosition(Widget w, XmTextPosition position)
+{
+    XmTextFieldSetInsertionPosition(EditBox, position);
+} /* XmComboBoxSetInsertionPosition */
+
+void    XmComboBoxSetMaxLength(Widget w, int max_length)
+{
+    XmTextFieldSetMaxLength(EditBox, max_length);
+} /* XmComboBoxSetMaxLength */
+
+void    XmComboBoxSetSelection(Widget w, XmTextPosition first, 
+                               XmTextPosition last, Time time)
+{
+    XmTextFieldSetSelection(EditBox, first, last, time);
+} /* XmComboBoxSetSelection */
+
+void    XmComboBoxSetString(Widget w, char *value)
+{
+/* Liebe OSF...ihr ^&*#%$*&)*(@$(*^(*&%# habt doch einen ziemlich gemeinen
+ * Fehler in XmTextFieldSetString() drin... wenn man einen leeren String
+ * (also "") angiebt, gibt's nur noch Aerger, wenn man spaeter wieder an
+ * den Inhalt des Eingabefeldes heranwill.
+ */
+    if ( (value == NULL) || (*value == 0) )
+        XtVaSetValues(w, XmNvalue, "", NULL);
+    else
+       XmTextFieldSetString(EditBox, value);
+} /* XmComboBoxSetString */
+
+void    XmComboBoxShowPosition(Widget w, XmTextPosition position)
+{
+    XmTextFieldShowPosition(EditBox, position);
+} /* XmComboBoxShowPosition */
+
+/*
+ * Loescht einen evtl. noch ausgewaehlten Eintrag in einer Combo Box, 
+ * wenn diese eine SelectionPolicy von XmSINGLE_SELECT hat.
+ */
+void XmComboBoxClearItemSelection(Widget w)
+{
+    int index;
+
+    if ( CheckComboBox(w, "XmComboBoxClearItemSelection") ) return;
+    
+    /*
+     * Wenn bereits kein Eintrag markiert ist, dann loeschen wir nur noch
+     * eben das Eingabefeld.
+     */
+    index = XmComboBoxGetSelectedPos(w);
+    if ( index == 0 ) {
+       XmComboBoxSetString(w, "");
+    } else {
+    /*
+     * Ansonsten aktuellen Eintrag entsorgen (wie bei der Methode wipe-out)
+     */
+       TransferToEditCtrl(ComboBox, 0, True);
+       CallSelectionCBL(ComboBox, NULL);
+    }
+} /* XmComboBoxClearItemSelection */
+
+/* Die Drop-Down-Liste ein oder ausklappen */
+void    XmComboBoxShowList(Widget w)
+{
+    if ( CheckComboBox(w, "XmComboBoxShowList") ) return;
+    ShowHideDropDownList((XmComboBoxWidget) w, NULL, False);
+} /* XmComboBoxShowList */
+
+void    XmComboBoxHideList(Widget w)
+{
+    if ( CheckComboBox(w, "XmComboBoxHideList") ) return;
+    ShowHideDropDownList((XmComboBoxWidget) w, NULL, True);
+} /* XmComboBoxShowList */
+
+/*
+ * Naja, ich komm' ja doch nicht um diese olle Funktion herum...
+ */
+Widget XmCreateComboBox(Widget parent, String name, ArgList arglist,
+                           Cardinal argcount)
+{
+    return XtCreateWidget(name, xmComboBoxWidgetClass, parent,
+                          arglist, argcount);
+} /* XmCreateComboBox */
+
+/* Ende von ComboBox.c */
diff --git a/src/motif/xmcombo/xmcombo.h b/src/motif/xmcombo/xmcombo.h
new file mode 100644 (file)
index 0000000..3a7a10a
--- /dev/null
@@ -0,0 +1,223 @@
+/*
+ * ComboBox.h - Das schon lange schmerzlich vermisste Combo-Box-
+ *              Widget -- nun endlich auf fuer Motif!
+ * 
+ * Letzte Modifikation: 04.10.1995    Revisionsstand: 1.32a
+ * 
+ * (c) 1993, 1994 Harald Albrecht
+ * Institut fuer Geometrie und Praktische Mathematik
+ * RWTH Aachen, Germany
+ * albrecht@igpm.rwth-aachen.de
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program (see the file COPYING for more details);
+ * if not, write to the Free Software Foundation, Inc., 675 Mass Ave, 
+ * Cambridge, MA 02139, USA.
+ *
+ */
+#ifndef __ComboBoxWidget_h
+#define __ComboBoxWidget_h
+
+#include <Xm/Xm.h>
+
+#if defined(__cplusplus) || defined(c_plusplus)
+extern "C" {
+#endif
+
+#define XmNselectionCallback           "selectionCallback"
+#define XmCSelectionCallback           "SelectionCallback"
+#define XmNunselectionCallback         "unselectionCallback"
+#define XmCUnselectionCallback         "UnselectionCallback"
+#define XmNdropDownCallback            "dropDownCallback"
+#define XmCDropDownCallback            "DropDownCallback"
+
+#define XmNdropDownCursor              "dropDownCursor"
+#define XmCDropDownCursor              "DropDownCursor"
+
+/* ICH GLAUB' ES JA EINFACH NICHT! DIESE @#$!%^ BEI DER OSF HABEN
+ * DOCH TATSAECHLICH VERGESSEN, DASS DIE EINTRAEGE IN DER LISTBOX
+ * VIELLEICHT AUCH SORTIERT SEIN SOLLEN -- MUSS MAN DENN ALLES
+ * SELBST MACHEN?!
+ */
+#define XmNsorted                      "sorted"
+#define XmCSorted                      "Sorted"
+#define XmNsortingCallback             "sortingCallback"
+#define XmCSortingCallback             "SortingCallback"
+
+#define XmNstaticList                  "staticList"
+#define XmCStaticList                  "StaticList"
+
+#define XmNsquareArrow                 "squareArrow"
+#define XmCSquareArrow                 "SquareArrow"
+#define XmNarrowSpacingOn              "arrowSpacingOn"
+#define XmCArrowSpacingOn              "ArrowSpacingOn"
+
+/*
+ * Wie verhaeltsich die Liste, wenn der Focus verloren geht, sobald
+ * der Mauszeiger aus dem Dialog herausbewegt wird?
+ */
+#define XmNpersistentDropDown          "persistentDropDown"
+#define XmCPersistentDropDown          "PersistentDropDown"
+#define XmNtwmHandlingOn               "twmHandlingOn"
+#define XmCTwmHandlingOn               "TwmHandlingOn"
+/*
+ * alles fuer das Label...
+ */
+#define XmNshowLabel                   "showLabel"
+#define XmCShowLabel                   "ShowLabel"
+#define XmNdropDownOffset              "dropDownOffset"
+#define XmCDropDownOffset              "DropDownOffset"
+
+#define XmNlabelMarginBottom           "labelMarginBottom"
+#define XmCLabelMarginBottom           "LabelMarginBottom"
+#define XmNlabelMarginHeight           "labelMarginHeight"
+#define XmCLabelMarginHeight           "LabelMarginHeight"
+#define XmNlabelMarginLeft             "labelMarginLeft"
+#define XmCLabelMarginLeft             "LabelMarginLeft"
+#define XmNlabelMarginRight            "labelMarginRight"
+#define XmCLabelMarginRight            "LabelMarginRight"
+#define XmNlabelMarginTop              "labelMarginTop"
+#define XmCLabelMarginTop              "LabelMarginTop"
+#define XmNlabelMarginWidth            "labelMarginWidth"
+#define XmCLabelMarginWidth            "LabelMarginWidth"
+
+/* Callback reasons: (part. predefined)
+ *
+ * XmCR_SINGLE_SELECT      user selected item in the list
+ */
+
+typedef struct {
+    int      reason;   /* Grund                  */
+    XEvent   *event;   /* Ausloesender Event     */
+    XmString value;     /* Ausgewaehlter Eintrag  */
+    int      index;    /* Index dieses Eintrages */
+} XmComboBoxSelectionCallbackStruct,XmComboBoxDefaultActionCallbackStruct;
+
+typedef struct {
+    int         reason;
+    XEvent      *event;
+    Boolean     doit;
+    Position    currInsert, newInsert;
+    Position    startPos, endPos;
+    XmTextBlock text;
+} XmComboBoxTextVerifyCallbackStruct, *XmComboBoxTextVerifyPtr;
+
+/* Callback reasons: new
+ * 
+ * XmCR_SHOW_LIST          list is dropping down
+ * XmCR_HIDE_LIST          list is getting hidden
+ * 
+ * XmCR_UNSELECT           unselecting item from list or osfDelete
+ */
+#define XmCR_SHOW_LIST 4200    /* ten times "42", that should   */
+#define XmCR_HIDE_LIST 4201    /* explain everything of live... */
+#define XmCR_UNSELECT   4202
+typedef struct {
+    int             reason;    /* Grund                  */
+    XEvent   *event;    /* Ausloesender Event     */
+} XmComboBoxDropDownCallbackStruct, XmComboBoxUnselectionCallbackStruct;
+
+#define XmCR_SORTING   4203
+#define XmOP_INIT      1
+#define XmOP_DONE      2
+#define XmOP_COMPARE   3
+typedef struct {
+    int      reason;
+    XEvent   *event;    /* IMMER NULL!! */
+    int      operation;
+    void     *item_internal;
+    XmString item;
+    int      result;
+} XmComboBoxSortingCallbackStruct, *XmComboBoxSortingPtr;
+
+/* Alle Funktionen, um auf die Liste der Combo-Box zuzugreifen.
+ * Bitte immer diese Funktionen dazu benutzen und nicht direkt
+ * auf das entsprechende Widget in der Combo-Box zugreifen!
+ * Aus diesem Grunde sind auch nicht alle Funktionen einer Listbox
+ * verfuegbar, da sich einige Funktionen mit der Verwaltung der
+ * Combo-Box beissen wuerden.
+ */
+extern void    XmComboBoxAddItem(Widget w, XmString item, int pos);
+extern void    XmComboBoxAddItems(Widget w, XmString *items, int item_count, int pos);
+extern void    XmComboBoxAddItemUnselected(Widget w, XmString item, int pos);
+extern void    XmComboBoxDeleteItem(Widget w, XmString item);
+extern void    XmComboBoxDeleteItems(Widget w, XmString *items, int item_count);
+extern void    XmComboBoxDeletePos(Widget w, int pos);
+extern void    XmComboBoxDeleteItemsPos(Widget w, int item_count, int pos);
+extern void    XmComboBoxDeleteAllItems(Widget w);
+extern void    XmComboBoxReplaceItems(Widget w, XmString *old_items, int item_count, XmString *new_items);
+extern void    XmComboBoxReplaceItemsPos(Widget w, XmString *new_items, int item_count, int position);
+extern Boolean XmComboBoxItemExists(Widget w, XmString item);
+extern int     XmComboBoxItemPos(Widget w, XmString item);
+extern Boolean XmComboBoxGetMatchPos(Widget w, XmString item, int **pos_list, int *pos_count);
+extern void    XmComboBoxSelectPos(Widget w, int pos, Boolean notify);
+extern void    XmComboBoxSelectItem(Widget w, XmString item, Boolean notify);
+/* Etwas anders als bei der Listbox, da es sowieso nur einen ausge-
+ * waehlten Eintrag in der Listbox geben kann!
+ * Liefert Index des ausgewaehlten Eintrages oder 0.
+ */
+extern int     XmComboBoxGetSelectedPos(Widget w);
+extern void    XmComboBoxClearItemSelection(Widget w);
+/*
+ * Nun alle Funktionen, die auf das Eingabefeld zugreifen...
+ * Auch hier gilt wieder, es gibt 'was auf die Finger, wenn jemand
+ * versucht, direkt auf das Eingabefeld direkt zuzugreifen!
+ */
+extern void    XmComboBoxClearSelection(Widget w, Time time);
+extern Boolean XmComboBoxCopy(Widget w, Time time);
+extern Boolean XmComboBoxCut(Widget w, Time time);
+extern XmTextPosition XmComboBoxGetInsertionPosition(Widget w);
+extern XmTextPosition XmComboBoxGetLastPosition(Widget w);
+extern int     XmComboBoxGetMaxLength(Widget w);
+extern char *  XmComboBoxGetSelection(Widget w);
+extern Boolean XmComboBoxGetSelectionPosition(Widget w, XmTextPosition *left, 
+                                               XmTextPosition *right);
+extern char *  XmComboBoxGetString(Widget w);
+extern void    XmComboBoxInsert(Widget w, XmTextPosition position, char *value);
+extern Boolean XmComboBoxPaste(Widget w);
+extern Boolean XmComboBoxRemove(Widget w);
+extern void    XmComboBoxReplace(Widget w, XmTextPosition from_pos, 
+                                 XmTextPosition to_pos, char *value);
+extern void    XmComboBoxSetAddMode(Widget w, Boolean state);
+extern void    XmComboBoxSetHighlight(Widget w, XmTextPosition left, 
+                                      XmTextPosition right, XmHighlightMode mode);
+extern void    XmComboBoxSetInsertionPosition(Widget w, XmTextPosition position);
+extern void    XmComboBoxSetMaxLength(Widget w, int max_length);
+extern void    XmComboBoxSetSelection(Widget w, XmTextPosition first, 
+                                      XmTextPosition last, Time time);
+extern void    XmComboBoxSetString(Widget w, char *value);
+extern void    XmComboBoxShowPosition(Widget w, XmTextPosition position);
+
+extern WidgetClass xmComboBoxWidgetClass; /* Die Klasse hoechstselbst */
+
+#ifndef XmIsComboBox
+#define XmIsComboBox(w)            XtIsSubclass(w, xmComboBoxWidgetClass)
+#endif /* XmIsComboBox */
+
+typedef struct _XmComboBoxClassRec *XmComboBoxWidgetClass;
+typedef struct _XmComboBoxRec      *XmComboBoxWidget;
+
+extern Widget XmCreateComboBox(Widget parent, String name, ArgList arglist,
+                               Cardinal argcount);
+
+/* PLEASE do not use this functions if you really not need to do so !!! */
+extern Widget XmComboBoxGetEditWidget(Widget w);
+extern Widget XmComboBoxGetListWidget(Widget w);
+extern Widget XmComboBoxGetLabelWidget(Widget w);
+
+#if defined(__cplusplus) || defined(c_plusplus)
+}
+#endif
+
+#endif /* __ComboBoxWidget_h */
+/* Ende von ComboBox.h */
index 073d3883ccf0eb5ccc4f8f01da0322cd96b44323..3428239c56195fd22c4340d566ddae4c051229f8 100644 (file)
@@ -258,7 +258,7 @@ $(COMMDIR)/y_tab.$(OBJSUFF):    $(COMMDIR)/y_tab.c $(COMMDIR)/lex_yy.c
 # problems with lex_yy.c. See also note about LEX_SCANNER
 # above.
 $(COMMDIR)/lex_yy.c:   $(COMMDIR)/lexer.l
 # problems with lex_yy.c. See also note about LEX_SCANNER
 # above.
 $(COMMDIR)/lex_yy.c:   $(COMMDIR)/lexer.l
-       $(LEX) $(COMMDIR)/lexer.l > $(COMMDIR)/lex_yy.c
+       $(LEX) -o$(COMMDIR)/lex_yy.c $(COMMDIR)/lexer.l
 
 #      sed -e "s/BUFSIZ/5000/g" < lex.yy.c | \
 #      sed -e "s/yyoutput(c)/void yyoutput(c)/g" | \
 
 #      sed -e "s/BUFSIZ/5000/g" < lex.yy.c | \
 #      sed -e "s/yyoutput(c)/void yyoutput(c)/g" | \