1 ///////////////////////////////////////////////////////////////////////////// 
   2 // Name:        src/motif/windows.cpp 
   4 // Author:      Julian Smart 
   8 // Copyright:   (c) Julian Smart 
   9 // Licence:     wxWindows licence 
  10 ///////////////////////////////////////////////////////////////////////////// 
  12 // ============================================================================ 
  14 // ============================================================================ 
  16 // ---------------------------------------------------------------------------- 
  18 // ---------------------------------------------------------------------------- 
  20 // For compilers that support precompilation, includes "wx.h". 
  21 #include "wx/wxprec.h" 
  24 #define XtDisplay XTDISPLAY 
  25 #define XtWindow XTWINDOW 
  26 #define XtScreen XTSCREEN 
  36     #include "wx/dcclient.h" 
  37     #include "wx/button.h" 
  39     #include "wx/settings.h" 
  42 #include "wx/layout.h" 
  43 #include "wx/scrolwin.h" 
  44 #include "wx/module.h" 
  45 #include "wx/menuitem.h" 
  46 #include "wx/evtloop.h" 
  48 #if  wxUSE_DRAG_AND_DROP 
  52 // DoSetSizeIntr and DoMoveWindowIntr 
  54 // under Motif composite controls (such as wxCalendarCtrl or generic wxSpinCtrl 
  55 // did not work and/or segfaulted because 
  56 // 1) wxWindow::Create calls SetSize, 
  57 //    which results in a call to DoSetSize much earlier than in the other ports 
  58 // 2) if wxWindow::Create is called (wxControl::Create calls it) 
  59 //    then DoSetSize is never called, causing layout problems in composite 
  63 // 1) don't call SetSize, DoSetSize, DoMoveWindow, DoGetPosition, 
  64 //    DoSetPosition directly or indirectly from wxWindow::Create 
  65 // 2) call DoMoveWindow from DoSetSize, allowing controls to override it 
  68 #pragma message disable nosimpint 
  72 #include <Xm/DrawingA.h> 
  73 #include <Xm/ScrolledW.h> 
  74 #include <Xm/ScrollBar.h> 
  77 #include <Xm/RowColumn.h>           // for XmMenuPosition 
  79 #pragma message enable nosimpint 
  82 #include "wx/motif/private.h" 
  86 // ---------------------------------------------------------------------------- 
  87 // global variables for this module 
  88 // ---------------------------------------------------------------------------- 
  90 extern wxHashTable 
*wxWidgetHashTable
; 
  91 static wxWindow
* g_captureWindow 
= NULL
; 
  94 // ---------------------------------------------------------------------------- 
  96 // ---------------------------------------------------------------------------- 
  98 static void wxCanvasRepaintProc(Widget
, XtPointer
, XmDrawingAreaCallbackStruct 
* cbs
); 
  99 static void wxCanvasInputEvent(Widget drawingArea
, XtPointer data
, XmDrawingAreaCallbackStruct 
* cbs
); 
 100 static void wxCanvasMotionEvent(Widget
, XButtonEvent 
* event
); 
 101 static void wxCanvasEnterLeave(Widget drawingArea
, XtPointer clientData
, XCrossingEvent 
* event
); 
 102 static void wxScrollBarCallback(Widget widget
, XtPointer clientData
, 
 103                                 XmScrollBarCallbackStruct 
*cbs
); 
 104 static void wxPanelItemEventHandler(Widget    wid
, 
 105                                     XtPointer client_data
, 
 107                                     Boolean  
*continueToDispatch
); 
 112 // Helper function for 16-bit fonts 
 113 static int str16len(const char *s
) 
 117     while (s
[0] && s
[1]) { 
 127 // ---------------------------------------------------------------------------- 
 129 // ---------------------------------------------------------------------------- 
 131 #define event_left_is_down(x) ((x)->xbutton.state & Button1Mask) 
 132 #define event_middle_is_down(x) ((x)->xbutton.state & Button2Mask) 
 133 #define event_right_is_down(x) ((x)->xbutton.state & Button3Mask) 
 135 // ---------------------------------------------------------------------------- 
 137 // ---------------------------------------------------------------------------- 
 139     IMPLEMENT_DYNAMIC_CLASS(wxWindow
, wxWindowBase
) 
 141     BEGIN_EVENT_TABLE(wxWindow
, wxWindowBase
) 
 142         EVT_SYS_COLOUR_CHANGED(wxWindow::OnSysColourChanged
) 
 145 // ============================================================================ 
 147 // ============================================================================ 
 149 // ---------------------------------------------------------------------------- 
 151 // ---------------------------------------------------------------------------- 
 153 void wxWindow::UnmanageAndDestroy(WXWidget widget
) 
 155     Widget w 
= (Widget
)widget
; 
 163 bool wxWindow::MapOrUnmap(WXWidget widget
, bool domap
) 
 165     Widget w 
= (Widget
)widget
; 
 169     //   Rationale: a lot of common operations (including but not 
 170     // limited to moving, resizing and appending items to a listbox) 
 171     // unmamange the widget, do their work, then manage it again. 
 172     // This means that, for example adding an item to a listbox will show it, 
 173     // or that most controls are shown every time they are moved or resized! 
 174     XtSetMappedWhenManaged( w
, domap 
); 
 176     // if the widget is not unmanaged, it still intercepts 
 177     // mouse events, even if it is not mapped (and hence invisible) 
 192 // ---------------------------------------------------------------------------- 
 194 // ---------------------------------------------------------------------------- 
 196 void wxWindow::Init() 
 199     m_needsRefresh 
= true; 
 200     m_mainWidget 
= (WXWidget
) 0; 
 202     m_winCaptured 
= false; 
 210     m_drawingArea 
= (WXWidget
) 0; 
 215     m_backingPixmap 
= (WXPixmap
) 0; 
 226 // real construction (Init() must have been called before!) 
 227 bool wxWindow::Create(wxWindow 
*parent
, wxWindowID id
, 
 231                       const wxString
& name
) 
 233     wxCHECK_MSG( parent
, false, "can't create wxWindow without parent" ); 
 235     CreateBase(parent
, id
, pos
, size
, style
, wxDefaultValidator
, name
); 
 237     parent
->AddChild(this); 
 239     m_backgroundColour 
= wxSystemSettings::GetColour(wxSYS_COLOUR_3DFACE
); 
 240     m_foregroundColour 
= *wxBLACK
; 
 242     //// TODO: we should probably optimize by only creating a 
 243     //// a drawing area if we have one or more scrollbars (wxVSCROLL/wxHSCROLL). 
 244     //// But for now, let's simplify things by always creating the 
 245     //// drawing area, since otherwise the translations are different. 
 247     // New translations for getting mouse motion feedback 
 248     static const String translations 
= wxMOTIF_STR( 
 249 "<Btn1Motion>: wxCanvasMotionEvent() DrawingAreaInput() ManagerGadgetButtonMotion()\n\ 
 250 <Btn2Motion>: wxCanvasMotionEvent() DrawingAreaInput() ManagerGadgetButtonMotion()\n\ 
 251 <Btn3Motion>: wxCanvasMotionEvent() DrawingAreaInput() ManagerGadgetButtonMotion()\n\ 
 252 <BtnMotion>: wxCanvasMotionEvent() DrawingAreaInput() ManagerGadgetButtonMotion()\n\ 
 253 <Btn1Down>: DrawingAreaInput() ManagerGadgetArm()\n\ 
 254 <Btn2Down>: DrawingAreaInput() ManagerGadgetArm()\n\ 
 255 <Btn3Down>: DrawingAreaInput() ManagerGadgetArm()\n\ 
 256 <Btn1Up>: DrawingAreaInput() ManagerGadgetActivate()\n\ 
 257 <Btn2Up>: DrawingAreaInput() ManagerGadgetActivate()\n\ 
 258 <Btn3Up>: DrawingAreaInput() ManagerGadgetActivate()\n\ 
 259 <Motion>: wxCanvasMotionEvent() DrawingAreaInput()\n\ 
 260 <EnterWindow>: wxCanvasMotionEvent() DrawingAreaInput()\n\ 
 261 <LeaveWindow>: wxCanvasMotionEvent() DrawingAreaInput()\n\ 
 262 <Key>: DrawingAreaInput()"); 
 264     XtActionsRec actions
[1]; 
 265     actions
[0].string 
= wxMOTIF_STR("wxCanvasMotionEvent"); 
 266     actions
[0].proc 
= (XtActionProc
) wxCanvasMotionEvent
; 
 267     XtAppAddActions ((XtAppContext
) wxTheApp
->GetAppContext(), actions
, 1); 
 269     Widget parentWidget 
= (Widget
) parent
->GetClientWidget(); 
 270     m_borderWidget 
= wxCreateBorderWidget( (WXWidget
)parentWidget
, style 
); 
 272     m_scrolledWindow 
= (WXWidget
)XtVaCreateManagedWidget
 
 275                                   xmScrolledWindowWidgetClass
, 
 276                                   m_borderWidget 
? (Widget
) m_borderWidget
 
 278                                   XmNresizePolicy
, XmRESIZE_NONE
, 
 280                                   XmNscrollingPolicy
, XmAPPLICATION_DEFINED
, 
 281                                   //XmNscrollBarDisplayPolicy, XmAS_NEEDED, 
 285     XtTranslations ptr 
= XtParseTranslationTable(translations
); 
 286     m_drawingArea 
= (WXWidget
)XtVaCreateWidget
 
 289                                xmDrawingAreaWidgetClass
, (Widget
) m_scrolledWindow
, 
 290                                XmNunitType
, XmPIXELS
, 
 291                                // XmNresizePolicy, XmRESIZE_ANY, 
 292                                XmNresizePolicy
, XmRESIZE_NONE
, 
 295                                XmNtranslations
, ptr
, 
 298     XtFree((char *) ptr
); 
 301     if (GetWindowStyleFlag() & wxOVERRIDE_KEY_TRANSLATIONS
) 
 303         ptr 
= XtParseTranslationTable ("<Key>: DrawingAreaInput()"); 
 304         XtOverrideTranslations ((Widget
) m_drawingArea
, ptr
); 
 305         XtFree ((char *) ptr
); 
 309     wxAddWindowToTable((Widget
) m_drawingArea
, this); 
 310     wxAddWindowToTable((Widget
) m_scrolledWindow
, this); 
 312     // This order is very important in Motif 1.2.1 
 313     XtRealizeWidget ((Widget
) m_scrolledWindow
); 
 314     XtRealizeWidget ((Widget
) m_drawingArea
); 
 315     XtManageChild ((Widget
) m_drawingArea
); 
 317     ptr 
= XtParseTranslationTable("<Configure>: resize()"); 
 318     XtOverrideTranslations((Widget
) m_drawingArea
, ptr
); 
 319     XtFree ((char *) ptr
); 
 321     XtAddCallback ((Widget
) m_drawingArea
, XmNexposeCallback
, (XtCallbackProc
) wxCanvasRepaintProc
, (XtPointer
) this); 
 322     XtAddCallback ((Widget
) m_drawingArea
, XmNinputCallback
, (XtCallbackProc
) wxCanvasInputEvent
, (XtPointer
) this); 
 325                       (Widget
)m_drawingArea
, 
 326                        PointerMotionHintMask 
| EnterWindowMask 
| 
 327                        LeaveWindowMask 
| FocusChangeMask
, 
 329                        (XtEventHandler
) wxCanvasEnterLeave
, 
 333     // Scrolled widget needs to have its colour changed or we get a little blue 
 334     // square where the scrollbars abutt 
 335     wxColour backgroundColour 
= wxSystemSettings::GetColour(wxSYS_COLOUR_3DFACE
); 
 336     wxDoChangeBackgroundColour(m_scrolledWindow
, backgroundColour
, true); 
 337     wxDoChangeBackgroundColour(m_drawingArea
, backgroundColour
, true); 
 339     XmScrolledWindowSetAreas( 
 340                              (Widget
)m_scrolledWindow
, 
 341                              (Widget
) 0, (Widget
) 0, 
 342                              (Widget
) m_drawingArea
); 
 344     // Without this, the cursor may not be restored properly (e.g. in splitter 
 346     SetCursor(*wxSTANDARD_CURSOR
); 
 347     SetFont(wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT
)); 
 348     DoSetSizeIntr(pos
.x
, pos
.y
, size
.x
,size
.y
, wxSIZE_AUTO
, true); 
 353 wxWindow::~wxWindow() 
 355     if (g_captureWindow 
== this) 
 356         g_captureWindow 
= NULL
; 
 358     m_isBeingDeleted 
= true; 
 360     // Motif-specific actions first 
 361     WXWidget wMain 
= GetMainWidget(); 
 364         // Removes event handlers 
 368     // If m_drawingArea, we're a fully-fledged window with drawing area, 
 369     // scrollbars etc. (what wxCanvas used to be) 
 372         // Destroy children before destroying self 
 376             XFreePixmap (XtDisplay ((Widget
) GetMainWidget()), (Pixmap
) m_backingPixmap
); 
 378         Widget w 
= (Widget
) m_drawingArea
; 
 379         wxDeleteWindowFromTable(w
); 
 384             m_drawingArea 
= (WXWidget
) 0; 
 387         // Only if we're _really_ a canvas (not a dialog box/panel) 
 388         if (m_scrolledWindow
) 
 390             wxDeleteWindowFromTable((Widget
) m_scrolledWindow
); 
 395             wxDeleteWindowFromTable((Widget
) m_hScrollBar
); 
 396             XtUnmanageChild((Widget
) m_hScrollBar
); 
 400             wxDeleteWindowFromTable((Widget
) m_vScrollBar
); 
 401             XtUnmanageChild((Widget
) m_vScrollBar
); 
 405             XtDestroyWidget((Widget
) m_hScrollBar
); 
 407             XtDestroyWidget((Widget
) m_vScrollBar
); 
 409         UnmanageAndDestroy(m_scrolledWindow
); 
 413             XtDestroyWidget ((Widget
) m_borderWidget
); 
 414             m_borderWidget 
= (WXWidget
) 0; 
 417     else // Why wasn't this here before? JACS 8/3/2000 
 421     // Destroy the window 
 424         // If this line (XtDestroyWidget) causes a crash, you may comment it out. 
 425         // Child widgets will get destroyed automatically when a frame 
 426         // or dialog is destroyed, but before that you may get some memory 
 427         // leaks and potential layout problems if you delete and then add 
 430         // GRG, Feb/2000: commented this out when adding support for 
 431         //   wxSCROLL[WIN]_THUMBRELEASE events. Also it was reported 
 432         //   that this call crashed wxMotif under OS/2, so it seems 
 433         //   that leaving it out is the right thing to do. 
 434         // SN, Feb/2000: newgrid/griddemo shows why it is needed :-( 
 435         XtDestroyWidget((Widget
) GetMainWidget()); 
 436         SetMainWidget((WXWidget
) NULL
); 
 440 // ---------------------------------------------------------------------------- 
 441 // scrollbar management 
 442 // ---------------------------------------------------------------------------- 
 444 WXWidget 
wxWindow::DoCreateScrollBar(WXWidget parent
, 
 445                                      wxOrientation orientation
, 
 448     int orient 
= ( orientation 
& wxHORIZONTAL 
) ? XmHORIZONTAL 
: XmVERTICAL
; 
 450         XtVaCreateManagedWidget( "scrollBarWidget", 
 451                                  xmScrollBarWidgetClass
, (Widget
)parent
, 
 452                                  XmNorientation
, orient
, 
 457     XtPointer o 
= (XtPointer
)orientation
; 
 458     XtCallbackProc cb 
= (XtCallbackProc
)callback
; 
 460     XtAddCallback( sb
, XmNvalueChangedCallback
, cb
, o 
); 
 461     XtAddCallback( sb
, XmNdragCallback
, cb
, o 
); 
 462     XtAddCallback( sb
, XmNincrementCallback
, cb
, o 
); 
 463     XtAddCallback( sb
, XmNdecrementCallback
, cb
, o 
); 
 464     XtAddCallback( sb
, XmNpageIncrementCallback
, cb
, o 
); 
 465     XtAddCallback( sb
, XmNpageDecrementCallback
, cb
, o 
); 
 466     XtAddCallback( sb
, XmNtoTopCallback
, cb
, o 
); 
 467     XtAddCallback( sb
, XmNtoBottomCallback
, cb
, o 
); 
 473 void wxWindow::CreateScrollbar(wxOrientation orientation
) 
 475     wxCHECK_RET( m_drawingArea
, "this window can't have scrollbars" ); 
 477     XtVaSetValues( (Widget
) m_scrolledWindow
, 
 478                    XmNresizePolicy
, XmRESIZE_NONE
, 
 481     wxColour backgroundColour 
= wxSystemSettings::GetColour(wxSYS_COLOUR_3DFACE
); 
 482     // Add scrollbars if required 
 483     if (orientation 
== wxHORIZONTAL
) 
 485         m_hScrollBar 
= DoCreateScrollBar( m_scrolledWindow
, wxHORIZONTAL
, 
 486                                           (void (*)())wxScrollBarCallback 
); 
 488         wxDoChangeBackgroundColour(m_hScrollBar
, backgroundColour
, true); 
 490         XtRealizeWidget( (Widget
)m_hScrollBar 
); 
 492         XtVaSetValues((Widget
) m_scrolledWindow
, 
 493             XmNhorizontalScrollBar
, (Widget
) m_hScrollBar
, 
 496         wxAddWindowToTable( (Widget
)m_hScrollBar
, this ); 
 498     else if (orientation 
== wxVERTICAL
) 
 500         m_vScrollBar 
= DoCreateScrollBar( m_scrolledWindow
, wxVERTICAL
, 
 501                                           (void (*)())wxScrollBarCallback 
); 
 503         wxDoChangeBackgroundColour(m_vScrollBar
, backgroundColour
, true); 
 505         XtRealizeWidget((Widget
)m_vScrollBar
); 
 507         XtVaSetValues((Widget
) m_scrolledWindow
, 
 508             XmNverticalScrollBar
, (Widget
) m_vScrollBar
, 
 511         wxAddWindowToTable( (Widget
)m_vScrollBar
, this ); 
 514     XtVaSetValues( (Widget
) m_scrolledWindow
, 
 515                    XmNresizePolicy
, XmRESIZE_ANY
, 
 519 void wxWindow::DestroyScrollbar(wxOrientation orientation
) 
 521     wxCHECK_RET( m_drawingArea
, "this window can't have scrollbars" ); 
 523     XtVaSetValues((Widget
) m_scrolledWindow
, 
 524                   XmNresizePolicy
, XmRESIZE_NONE
, 
 526     String stringSB 
= orientation 
== wxHORIZONTAL 
? 
 527         XmNhorizontalScrollBar 
: XmNverticalScrollBar
; 
 528     WXWidget
* widgetSB 
= orientation 
== wxHORIZONTAL 
? 
 529         &m_hScrollBar 
: &m_vScrollBar
; 
 533         wxDeleteWindowFromTable( (Widget
)*widgetSB 
); 
 534         XtDestroyWidget( (Widget
)*widgetSB 
); 
 535         *widgetSB 
= (WXWidget
)NULL
; 
 538     XtVaSetValues( (Widget
)m_scrolledWindow
, 
 539                    stringSB
, (Widget
) 0, 
 542     XtVaSetValues((Widget
) m_scrolledWindow
, 
 543                   XmNresizePolicy
, XmRESIZE_ANY
, 
 547 // --------------------------------------------------------------------------- 
 549 // --------------------------------------------------------------------------- 
 551 void wxWindow::SetFocus() 
 553     Widget wMain 
= (Widget
) GetMainWidget(); 
 554     XmProcessTraversal(wMain
, XmTRAVERSE_CURRENT
); 
 555     XmProcessTraversal((Widget
) GetMainWidget(), XmTRAVERSE_CURRENT
); 
 558 // Get the window with the focus 
 559 wxWindow 
*wxWindowBase::DoFindFocus() 
 562     // (1) Can there be multiple focussed widgets in an application? 
 563     // In which case we need to find the top-level window that's 
 565     // (2) The widget with the focus may not be in the widget table 
 566     // depending on which widgets I put in the table 
 567     wxWindow 
*winFocus 
= (wxWindow 
*)NULL
; 
 568     for ( wxWindowList::compatibility_iterator node 
= wxTopLevelWindows
.GetFirst(); 
 570           node 
= node
->GetNext() ) 
 572         wxWindow 
*win 
= node
->GetData(); 
 574         Widget w 
= XmGetFocusWidget ((Widget
) win
->GetTopWidget()); 
 576         if (w 
!= (Widget
) NULL
) 
 578             winFocus 
= wxGetWindowFromTable(w
); 
 587 bool wxWindow::Enable(bool enable
) 
 589     if ( !wxWindowBase::Enable(enable
) ) 
 592     Widget wMain 
= (Widget
)GetMainWidget(); 
 595         XtSetSensitive(wMain
, enable
); 
 596         XmUpdateDisplay(wMain
); 
 602 bool wxWindow::Show(bool show
) 
 604     if ( !wxWindowBase::Show(show
) ) 
 607     if (m_borderWidget 
|| m_scrolledWindow
) 
 609         MapOrUnmap(m_borderWidget 
? m_borderWidget 
: m_scrolledWindow
, show
); 
 610         // MapOrUnmap(m_drawingArea, show); 
 614         if ( !MapOrUnmap(GetTopWidget(), show
) ) 
 615             MapOrUnmap(GetMainWidget(), show
); 
 621 // Raise the window to the top of the Z order 
 622 void wxWindow::Raise() 
 624     Widget wTop 
= (Widget
) GetTopWidget(); 
 625     Window window 
= XtWindow(wTop
); 
 626     XRaiseWindow(XtDisplay(wTop
), window
); 
 629 // Lower the window to the bottom of the Z order 
 630 void wxWindow::Lower() 
 632     Widget wTop 
= (Widget
) GetTopWidget(); 
 633     Window window 
= XtWindow(wTop
); 
 634     XLowerWindow(XtDisplay(wTop
), window
); 
 637 void wxWindow::SetLabel(const wxString
& label
) 
 639     XtVaSetValues((Widget
)GetMainWidget(), XmNtitle
, label
.c_str(), NULL
); 
 642 wxString 
wxWindow::GetLabel() const 
 645     XtVaGetValues((Widget
)GetMainWidget(), XmNtitle
, &label
, NULL
); 
 647     return wxString(label
); 
 650 void wxWindow::DoCaptureMouse() 
 652     g_captureWindow 
= this; 
 656     Widget wMain 
= (Widget
)GetMainWidget(); 
 658         XtAddGrab(wMain
, True
, False
); 
 660     m_winCaptured 
= true; 
 663 void wxWindow::DoReleaseMouse() 
 665     g_captureWindow 
= NULL
; 
 666     if ( !m_winCaptured 
) 
 669     Widget wMain 
= (Widget
)GetMainWidget(); 
 673     m_winCaptured 
= false; 
 676 bool wxWindow::SetFont(const wxFont
& font
) 
 678     if ( !wxWindowBase::SetFont(font
) ) 
 689 bool wxWindow::SetCursor(const wxCursor
& cursor
) 
 691     if ( !wxWindowBase::SetCursor(cursor
) ) 
 697     //    wxASSERT_MSG( m_cursor.Ok(), 
 698     //                  wxT("cursor must be valid after call to the base version")); 
 699     const wxCursor
* cursor2 
= NULL
; 
 701         cursor2 
= & m_cursor
; 
 703         cursor2 
= wxSTANDARD_CURSOR
; 
 705     WXDisplay 
*dpy 
= GetXDisplay(); 
 706     WXCursor x_cursor 
= cursor2
->GetXCursor(dpy
); 
 708     Widget w 
= (Widget
) GetMainWidget(); 
 709     Window win 
= XtWindow(w
); 
 710     XDefineCursor((Display
*) dpy
, win
, (Cursor
) x_cursor
); 
 715 // Coordinates relative to the window 
 716 void wxWindow::WarpPointer (int x
, int y
) 
 718     Widget wClient 
= (Widget
)GetClientWidget(); 
 720     XWarpPointer(XtDisplay(wClient
), None
, XtWindow(wClient
), 0, 0, 0, 0, x
, y
); 
 723 // --------------------------------------------------------------------------- 
 725 // --------------------------------------------------------------------------- 
 727 int wxWindow::GetScrollPos(int orient
) const 
 729     if (orient 
== wxHORIZONTAL
) 
 735     Widget scrollBar 
= (Widget
) ((orient 
== wxHORIZONTAL
) ? m_hScrollBar 
: m_vScrollBar
); 
 739         XtVaGetValues(scrollBar
, XmNvalue
, &pos
, NULL
); 
 747 // This now returns the whole range, not just the number of positions that we 
 749 int wxWindow::GetScrollRange(int orient
) const 
 751     Widget scrollBar 
= (Widget
)GetScrollbar((wxOrientation
)orient
); 
 752     // CE scintilla windows don't always have these scrollbars 
 753     // and it tends to pile up a whole bunch of asserts 
 754     //wxCHECK_MSG( scrollBar, 0, "no such scrollbar" ); 
 758         XtVaGetValues(scrollBar
, XmNmaximum
, &range
, NULL
); 
 762 int wxWindow::GetScrollThumb(int orient
) const 
 764     Widget scrollBar 
= (Widget
)GetScrollbar((wxOrientation
)orient
); 
 765     //wxCHECK_MSG( scrollBar, 0, "no such scrollbar" ); 
 769         XtVaGetValues(scrollBar
, XmNsliderSize
, &thumb
, NULL
); 
 773 void wxWindow::SetScrollPos(int orient
, int pos
, bool WXUNUSED(refresh
)) 
 775     Widget scrollBar 
= (Widget
)GetScrollbar((wxOrientation
)orient
); 
 779         XtVaSetValues (scrollBar
, XmNvalue
, pos
, NULL
); 
 782     SetInternalScrollPos((wxOrientation
)orient
, pos
); 
 785 // New function that will replace some of the above. 
 786 void wxWindow::SetScrollbar(int orient
, int pos
, int thumbVisible
, 
 787                             int range
, bool WXUNUSED(refresh
)) 
 790     GetSize(& oldW
, & oldH
); 
 794     if (thumbVisible 
== 0) 
 797     if (thumbVisible 
> range
) 
 798         thumbVisible 
= range
; 
 800     // Save the old state to see if it changed 
 801     WXWidget oldScrollBar 
= GetScrollbar((wxOrientation
)orient
); 
 803     if (orient 
== wxHORIZONTAL
) 
 805         if (thumbVisible 
== range
) 
 808                 DestroyScrollbar(wxHORIZONTAL
); 
 813                 CreateScrollbar(wxHORIZONTAL
); 
 816     if (orient 
== wxVERTICAL
) 
 818         if (thumbVisible 
== range
) 
 821                 DestroyScrollbar(wxVERTICAL
); 
 826                 CreateScrollbar(wxVERTICAL
); 
 829     WXWidget newScrollBar 
=  GetScrollbar((wxOrientation
)orient
); 
 831     if (oldScrollBar 
!= newScrollBar
) 
 833         // This is important! Without it, scrollbars misbehave badly. 
 834         XtUnrealizeWidget((Widget
) m_scrolledWindow
); 
 835         XmScrolledWindowSetAreas ((Widget
) m_scrolledWindow
, (Widget
) m_hScrollBar
, (Widget
) m_vScrollBar
, (Widget
) m_drawingArea
); 
 836         XtRealizeWidget((Widget
) m_scrolledWindow
); 
 837         XtManageChild((Widget
) m_scrolledWindow
); 
 842         XtVaSetValues((Widget
) newScrollBar
, 
 846         XmNsliderSize
, thumbVisible
, 
 850     SetInternalScrollPos((wxOrientation
)orient
, pos
); 
 853     GetSize(& newW
, & newH
); 
 855     // Adjusting scrollbars can resize the canvas accidentally 
 856     if (newW 
!= oldW 
|| newH 
!= oldH
) 
 857         SetSize(wxDefaultCoord
, wxDefaultCoord
, oldW
, oldH
); 
 860 // Does a physical scroll 
 861 void wxWindow::ScrollWindow(int dx
, int dy
, const wxRect 
*rect
) 
 866         // Use specified rectangle 
 867         x 
= rect
->x
; y 
= rect
->y
; w 
= rect
->width
; h 
= rect
->height
; 
 871         // Use whole client area 
 873         GetClientSize(& w
, & h
); 
 876     int x1 
= (dx 
>= 0) ? x 
: x 
- dx
; 
 877     int y1 
= (dy 
>= 0) ? y 
: y 
- dy
; 
 878     int w1 
= w 
- abs(dx
); 
 879     int h1 
= h 
- abs(dy
); 
 880     int x2 
= (dx 
>= 0) ? x 
+ dx 
: x
; 
 881     int y2 
= (dy 
>= 0) ? y 
+ dy 
: y
; 
 885     dc
.SetLogicalFunction (wxCOPY
); 
 887     Widget widget 
= (Widget
) GetMainWidget(); 
 888     Window window 
= XtWindow(widget
); 
 889     Display
* display 
= XtDisplay(widget
); 
 891     XCopyArea(display
, window
, window
, (GC
) dc
.GetGC(), 
 892               x1
, y1
, w1
, h1
, x2
, y2
); 
 894     dc
.SetAutoSetting(true); 
 895     wxBrush 
brush(GetBackgroundColour(), wxSOLID
); 
 896     dc
.SetBrush(brush
); // FIXME: needed? 
 898     wxWindowList::compatibility_iterator cnode 
= m_children
.GetFirst(); 
 901         wxWindow 
*child 
= cnode
->GetData(); 
 904         child
->GetSize( &sx
, &sy 
); 
 905         wxPoint 
pos( child
->GetPosition() ); 
 906         child
->SetSize( pos
.x 
+ dx
, pos
.y 
+ dy
, sx
, sy
, wxSIZE_ALLOW_MINUS_ONE 
); 
 907         cnode 
= cnode
->GetNext(); 
 910     // We'll add rectangles to the list of update rectangles according to which 
 911     // bits we've exposed. 
 916         wxRect 
*rect 
= new wxRect
; 
 922         XFillRectangle(display
, window
, 
 923             (GC
) dc
.GetGC(), rect
->x
, rect
->y
, rect
->width
, rect
->height
); 
 927         rect
->width 
= rect
->width
; 
 928         rect
->height 
= rect
->height
; 
 930         updateRects
.Append((wxObject
*) rect
); 
 934         wxRect 
*rect 
= new wxRect
; 
 936         rect
->x 
= x 
+ w 
+ dx
; 
 941         XFillRectangle(display
, window
, 
 942             (GC
) dc
.GetGC(), rect
->x
, rect
->y
, rect
->width
, 
 947         rect
->width 
= rect
->width
; 
 948         rect
->height 
= rect
->height
; 
 950         updateRects
.Append((wxObject
*) rect
); 
 954         wxRect 
*rect 
= new wxRect
; 
 961         XFillRectangle(display
, window
, 
 962             (GC
) dc
.GetGC(), rect
->x
, rect
->y
, rect
->width
, rect
->height
); 
 966         rect
->width 
= rect
->width
; 
 967         rect
->height 
= rect
->height
; 
 969         updateRects
.Append((wxObject
*) rect
); 
 973         wxRect 
*rect 
= new wxRect
; 
 976         rect
->y 
= y 
+ h 
+ dy
; 
 980         XFillRectangle(display
, window
, 
 981             (GC
) dc
.GetGC(), rect
->x
, rect
->y
, rect
->width
, rect
->height
); 
 985         rect
->width 
= rect
->width
; 
 986         rect
->height 
= rect
->height
; 
 988         updateRects
.Append((wxObject
*) rect
); 
 990     dc
.SetBrush(wxNullBrush
); 
 992     // Now send expose events 
 994     wxList::compatibility_iterator  node 
= updateRects
.GetFirst(); 
 997         wxRect
* rect 
= (wxRect
*) node
->GetData(); 
1000         event
.type 
= Expose
; 
1001         event
.display 
= display
; 
1002         event
.send_event 
= True
; 
1003         event
.window 
= window
; 
1007         event
.width 
= rect
->width
; 
1008         event
.height 
= rect
->height
; 
1012         XSendEvent(display
, window
, False
, ExposureMask
, (XEvent 
*)&event
); 
1014         node 
= node
->GetNext(); 
1018     // Delete the update rects 
1019     node 
= updateRects
.GetFirst(); 
1022         wxRect
* rect 
= (wxRect
*) node
->GetData(); 
1024         node 
= node
->GetNext(); 
1027     XmUpdateDisplay((Widget
) GetMainWidget()); 
1030 // --------------------------------------------------------------------------- 
1032 // --------------------------------------------------------------------------- 
1034 #if wxUSE_DRAG_AND_DROP 
1036 void wxWindow::SetDropTarget(wxDropTarget 
* WXUNUSED(pDropTarget
)) 
1043 // Old style file-manager drag&drop 
1044 void wxWindow::DragAcceptFiles(bool WXUNUSED(accept
)) 
1049 // ---------------------------------------------------------------------------- 
1051 // ---------------------------------------------------------------------------- 
1055 void wxWindow::DoSetToolTip(wxToolTip 
* WXUNUSED(tooltip
)) 
1060 #endif // wxUSE_TOOLTIPS 
1062 // ---------------------------------------------------------------------------- 
1064 // ---------------------------------------------------------------------------- 
1068 bool wxWindow::DoPopupMenu(wxMenu 
*menu
, int x
, int y
) 
1070     if ( x 
== wxDefaultCoord 
&& y 
== wxDefaultCoord 
) 
1072         wxPoint mouse 
= ScreenToClient(wxGetMousePosition()); 
1073         x 
= mouse
.x
; y 
= mouse
.y
; 
1076     Widget widget 
= (Widget
) GetMainWidget(); 
1078     /* The menuId field seems to be usused, so we'll use it to 
1079     indicate whether a menu is popped up or not: 
1080     0: Not currently created as a popup 
1081     -1: Created as a popup, but not active 
1085     if (menu
->GetParent() && (menu
->GetId() != -1)) 
1088     if (menu
->GetMainWidget()) 
1090         menu
->DestroyMenu(true); 
1093     menu
->SetId(1); /* Mark as popped-up */ 
1094     menu
->CreateMenu(NULL
, widget
, menu
, 0); 
1095     menu
->SetInvokingWindow(this); 
1099     //  menu->SetParent(parent); 
1100     //  parent->children->Append(menu);  // Store menu for later deletion 
1102     Widget menuWidget 
= (Widget
) menu
->GetMainWidget(); 
1110     if (this->IsKindOf(CLASSINFO(wxCanvas))) 
1112     wxCanvas *canvas = (wxCanvas *) this; 
1113     deviceX = canvas->GetDC ()->LogicalToDeviceX (x); 
1114     deviceY = canvas->GetDC ()->LogicalToDeviceY (y); 
1118     Display 
*display 
= XtDisplay (widget
); 
1119     Window rootWindow 
= RootWindowOfScreen (XtScreen((Widget
)widget
)); 
1120     Window thisWindow 
= XtWindow (widget
); 
1122     XTranslateCoordinates (display
, thisWindow
, rootWindow
, (int) deviceX
, (int) deviceY
, 
1123         &rootX
, &rootY
, &childWindow
); 
1125     XButtonPressedEvent event
; 
1126     event
.type 
= ButtonPress
; 
1132     event
.x_root 
= rootX
; 
1133     event
.y_root 
= rootY
; 
1135     XmMenuPosition (menuWidget
, &event
); 
1136     XtManageChild (menuWidget
); 
1138     // The ID of a pop-up menu is 1 when active, and is set to 0 by the 
1139     // idle-time destroy routine. 
1140     // Waiting until this ID changes causes this function to block until 
1141     // the menu has been dismissed and the widgets cleaned up. 
1142     // In other words, once this routine returns, it is safe to delete 
1144     // Ian Brown <ian.brown@printsoft.de> 
1146     wxEventLoop evtLoop
; 
1148     while (menu
->GetId() == 1) 
1150         wxDoEventLoopIteration( evtLoop 
); 
1158 // --------------------------------------------------------------------------- 
1159 // moving and resizing 
1160 // --------------------------------------------------------------------------- 
1162 bool wxWindow::PreResize() 
1168 void wxWindow::DoGetSize(int *x
, int *y
) const 
1170     Widget widget 
= (Widget
)( !m_drawingArea 
? GetTopWidget() : 
1171                               ( m_borderWidget 
? m_borderWidget 
: 
1172                                 m_scrolledWindow 
? m_scrolledWindow 
: 
1176     XtVaGetValues( widget
, 
1184 void wxWindow::DoGetPosition(int *x
, int *y
) const 
1186     Widget widget 
= (Widget
) 
1188           ( m_borderWidget 
? m_borderWidget 
: m_scrolledWindow 
) : 
1192     XtVaGetValues(widget
, XmNx
, &xx
, XmNy
, &yy
, NULL
); 
1194     // We may be faking the client origin. So a window that's really at (0, 30) 
1195     // may appear (to wxWin apps) to be at (0, 0). 
1198         wxPoint 
pt(GetParent()->GetClientAreaOrigin()); 
1199         xx 
= (Position
)(xx 
- pt
.x
); 
1200         yy 
= (Position
)(yy 
- pt
.y
); 
1207 void wxWindow::DoScreenToClient(int *x
, int *y
) const 
1209     Widget widget 
= (Widget
) GetClientWidget(); 
1210     Display 
*display 
= XtDisplay((Widget
) GetMainWidget()); 
1211     Window rootWindow 
= RootWindowOfScreen(XtScreen(widget
)); 
1212     Window thisWindow 
= XtWindow(widget
); 
1217     XTranslateCoordinates(display
, rootWindow
, thisWindow
, xx
, yy
, x
, y
, &childWindow
); 
1220 void wxWindow::DoClientToScreen(int *x
, int *y
) const 
1222     Widget widget 
= (Widget
) GetClientWidget(); 
1223     Display 
*display 
= XtDisplay(widget
); 
1224     Window rootWindow 
= RootWindowOfScreen(XtScreen(widget
)); 
1225     Window thisWindow 
= XtWindow(widget
); 
1230     XTranslateCoordinates(display
, thisWindow
, rootWindow
, xx
, yy
, x
, y
, &childWindow
); 
1234 // Get size *available for subwindows* i.e. excluding menu bar etc. 
1235 void wxWindow::DoGetClientSize(int *x
, int *y
) const 
1237     Widget widget 
= (Widget
) GetClientWidget(); 
1239     XtVaGetValues(widget
, XmNwidth
, &xx
, XmNheight
, &yy
, NULL
); 
1240     if(x
) *x 
= xx
; if(y
) *y 
= yy
; 
1243 void wxWindow::DoSetSize(int x
, int y
, int width
, int height
, int sizeFlags
) 
1245     DoSetSizeIntr(x
, y
, width
, height
, sizeFlags
, false); 
1248 void wxWindow::DoSetSizeIntr(int x
, int y
, int width
, int height
, 
1249                              int sizeFlags
, bool fromCtor
) 
1251     // A bit of optimization to help sort out the flickers. 
1252     int oldX 
= -1, oldY 
= -1, oldW 
= -1, oldH 
= -1; 
1256         GetSize(& oldW
, & oldH
); 
1257         GetPosition(& oldX
, & oldY
); 
1260     if ( !(sizeFlags 
& wxSIZE_ALLOW_MINUS_ONE
) ) 
1268     wxSize 
size(wxDefaultSize
); 
1271         if ( ( sizeFlags 
& wxSIZE_AUTO_WIDTH 
) && !fromCtor 
) 
1273             size 
= DoGetBestSize(); 
1284         if( ( sizeFlags 
& wxSIZE_AUTO_HEIGHT 
) && !fromCtor 
) 
1286             if( size
.x 
== -1 ) size 
= DoGetBestSize(); 
1295     if ( x 
!= oldX 
|| y 
!= oldY 
|| width 
!= oldW 
|| height 
!= oldH
 
1296          || !wxNoOptimize::CanOptimize() ) 
1302             if (x 
> -1 || (sizeFlags 
& wxSIZE_ALLOW_MINUS_ONE
)) 
1305             if (y 
> -1 || (sizeFlags 
& wxSIZE_ALLOW_MINUS_ONE
)) 
1309                 flags 
|= wxMOVE_WIDTH
; 
1312                 flags 
|= wxMOVE_HEIGHT
; 
1314             int xx 
= x
; int yy 
= y
; 
1315             AdjustForParentClientOrigin(xx
, yy
, sizeFlags
); 
1317                 DoMoveWindow( xx
, yy
, width
, height 
); 
1319                 DoMoveWindowIntr( xx
, yy
, width
, height
, flags 
); 
1324         Widget widget 
= (Widget
) GetTopWidget(); 
1328         bool managed 
= XtIsManaged( widget 
); 
1330             XtUnmanageChild(widget
); 
1334         AdjustForParentClientOrigin(xx
, yy
, sizeFlags
); 
1336         DoMoveWindow(xx
, yy
, width
, height
); 
1339             XtManageChild(widget
); 
1343 void wxWindow::DoSetClientSize(int width
, int height
) 
1347         Widget drawingArea 
= (Widget
) m_drawingArea
; 
1349         XtVaSetValues(drawingArea
, XmNresizePolicy
, XmRESIZE_ANY
, NULL
); 
1352             XtVaSetValues(drawingArea
, XmNwidth
, width
, NULL
); 
1354             XtVaSetValues(drawingArea
, XmNheight
, height
, NULL
); 
1356         XtVaSetValues(drawingArea
, XmNresizePolicy
, XmRESIZE_NONE
, NULL
); 
1360     Widget widget 
= (Widget
) GetTopWidget(); 
1363         XtVaSetValues(widget
, XmNwidth
, width
, NULL
); 
1365         XtVaSetValues(widget
, XmNheight
, height
, NULL
); 
1368 void wxWindow::DoMoveWindowIntr(int xx
, int yy
, int w
, int h
, 
1373         Widget drawingArea 
= (Widget
) m_drawingArea
; 
1374         Widget borderOrScrolled 
= m_borderWidget 
? 
1375             (Widget
) m_borderWidget 
: 
1376             (Widget
) m_scrolledWindow
; 
1378         bool managed 
= XtIsManaged(borderOrScrolled
); 
1380             XtUnmanageChild (borderOrScrolled
); 
1381         XtVaSetValues(drawingArea
, XmNresizePolicy
, XmRESIZE_ANY
, NULL
); 
1383         if (flags 
& wxMOVE_X
) 
1384             XtVaSetValues (borderOrScrolled
, 
1387         if (flags 
& wxMOVE_Y
) 
1388             XtVaSetValues (borderOrScrolled
, 
1392         if (flags 
& wxMOVE_WIDTH
) 
1396                 XtVaSetValues ((Widget
) m_borderWidget
, XmNwidth
, w
, NULL
); 
1397                 short thick
, margin
; 
1398                 XtVaGetValues ((Widget
) m_borderWidget
, 
1399                                XmNshadowThickness
, &thick
, 
1400                                XmNmarginWidth
, &margin
, 
1402                 w 
-= 2 * (thick 
+ margin
); 
1406             XtVaSetValues ((Widget
) m_scrolledWindow
, XmNwidth
, w
, NULL
); 
1409         if (flags 
& wxMOVE_HEIGHT
) 
1413                 XtVaSetValues ((Widget
) m_borderWidget
, XmNheight
, h
, NULL
); 
1414                 short thick
, margin
; 
1415                 XtVaGetValues ((Widget
) m_borderWidget
, 
1416                                XmNshadowThickness
, &thick
, 
1417                                XmNmarginHeight
, &margin
, 
1419                 h 
-= 2 * (thick 
+ margin
); 
1423             XtVaSetValues ((Widget
) m_scrolledWindow
, XmNheight
, h
, NULL
); 
1427             XtManageChild (borderOrScrolled
); 
1428         XtVaSetValues(drawingArea
, XmNresizePolicy
, XmRESIZE_NONE
, NULL
); 
1432         if( xx 
< 0 ) xx 
= 0; 
1433         if( yy 
< 0 ) yy 
= 0; 
1437         XtVaSetValues((Widget
)GetTopWidget(), 
1446 void wxWindow::DoMoveWindow(int x
, int y
, int width
, int height
) 
1448     DoMoveWindowIntr (x
, y
, width
, height
, 
1449                       wxMOVE_X
|wxMOVE_Y
|wxMOVE_WIDTH
|wxMOVE_HEIGHT
); 
1452 // --------------------------------------------------------------------------- 
1454 // --------------------------------------------------------------------------- 
1456 int wxWindow::GetCharHeight() const 
1458     wxCHECK_MSG( m_font
.Ok(), 0, "valid window font needed" ); 
1462     wxGetTextExtent (GetXDisplay(), m_font
, 1.0, 
1463                      "x", NULL
, &height
, NULL
, NULL
); 
1468 int wxWindow::GetCharWidth() const 
1470     wxCHECK_MSG( m_font
.Ok(), 0, "valid window font needed" ); 
1474     wxGetTextExtent (GetXDisplay(), m_font
, 1.0, 
1475                      "x", &width
, NULL
, NULL
, NULL
); 
1480 void wxWindow::GetTextExtent(const wxString
& string
, 
1482                              int *descent
, int *externalLeading
, 
1483                              const wxFont 
*theFont
) const 
1485     const wxFont 
*fontToUse 
= theFont 
? theFont 
: &m_font
; 
1487     wxCHECK_RET( fontToUse
->Ok(), "valid window font needed" ); 
1489     if (externalLeading
) 
1490         *externalLeading 
= 0; 
1491     wxGetTextExtent (GetXDisplay(), *fontToUse
, 1.0, 
1492                      string
, x
, y
, NULL
, descent
); 
1495 // ---------------------------------------------------------------------------- 
1497 // ---------------------------------------------------------------------------- 
1499 void wxWindow::AddUpdateRect(int x
, int y
, int w
, int h
) 
1501     m_updateRegion
.Union( x
, y
, w
, h 
); 
1504 void wxWindow::Refresh(bool eraseBack
, const wxRect 
*rect
) 
1506     m_needsRefresh 
= true; 
1507     Display 
*display 
= XtDisplay((Widget
) GetMainWidget()); 
1508     Window thisWindow 
= XtWindow((Widget
) GetMainWidget()); 
1510     XExposeEvent dummyEvent
; 
1512     GetSize(&width
, &height
); 
1514     dummyEvent
.type 
= Expose
; 
1515     dummyEvent
.display 
= display
; 
1516     dummyEvent
.send_event 
= True
; 
1517     dummyEvent
.window 
= thisWindow
; 
1520         dummyEvent
.x 
= rect
->x
; 
1521         dummyEvent
.y 
= rect
->y
; 
1522         dummyEvent
.width 
= rect
->width
; 
1523         dummyEvent
.height 
= rect
->height
; 
1529         dummyEvent
.width 
= width
; 
1530         dummyEvent
.height 
= height
; 
1532     dummyEvent
.count 
= 0; 
1536         wxClientDC 
dc(this); 
1537         wxBrush 
backgroundBrush(GetBackgroundColour(), wxSOLID
); 
1538         dc
.SetBackground(backgroundBrush
); 
1545     XSendEvent(display
, thisWindow
, False
, ExposureMask
, (XEvent 
*)&dummyEvent
); 
1548 void wxWindow::DoPaint() 
1550     //TODO : make a temporary gc so we can do the XCopyArea below 
1551     if (m_backingPixmap 
&& !m_needsRefresh
) 
1555       GC tempGC 
= (GC
) dc
.GetBackingGC(); 
1557       Widget widget 
= (Widget
) GetMainWidget(); 
1562       // We have to test whether it's a wxScrolledWindow (hack!) because 
1563       // otherwise we don't know how many pixels have been scrolled. We might 
1564       // solve this in the future by defining virtual wxWindow functions to get 
1565       // the scroll position in pixels. Or, each kind of scrolled window has to 
1566       // implement backing stores itself, using generic wxWidgets code. 
1567       wxScrolledWindow
* scrolledWindow 
= wxDynamicCast(this, wxScrolledWindow
); 
1568       if ( scrolledWindow 
) 
1571           scrolledWindow
->CalcScrolledPosition(0, 0, &x
, &y
); 
1577       // TODO: This could be optimized further by only copying the areas in the 
1578       //       current update region. 
1580       // Only blit the part visible in the client area. The backing pixmap 
1581       // always starts at 0, 0 but we may be looking at only a portion of it. 
1582       wxSize clientArea 
= GetClientSize(); 
1583       int toBlitX 
= m_pixmapWidth 
- scrollPosX
; 
1584       int toBlitY 
= m_pixmapHeight 
- scrollPosY
; 
1586       // Copy whichever is samller, the amount of pixmap we have to copy, 
1587       // or the size of the client area. 
1588       toBlitX 
= wxMin(toBlitX
, clientArea
.x
); 
1589       toBlitY 
= wxMin(toBlitY
, clientArea
.y
); 
1591       // Make sure we're not negative 
1592       toBlitX 
= wxMax(0, toBlitX
); 
1593       toBlitY 
= wxMax(0, toBlitY
); 
1598        (Pixmap
) m_backingPixmap
, 
1601        scrollPosX
, scrollPosY
, // Start at the scroll position 
1602        toBlitX
, toBlitY
,       // How much of the pixmap to copy 
1608         wxWindowDC 
dc(this); 
1609         // Set an erase event first 
1610         wxEraseEvent 
eraseEvent(GetId(), &dc
); 
1611         eraseEvent
.SetEventObject(this); 
1612         GetEventHandler()->ProcessEvent(eraseEvent
); 
1614         wxPaintEvent 
event(GetId()); 
1615         event
.SetEventObject(this); 
1616         GetEventHandler()->ProcessEvent(event
); 
1618         m_needsRefresh 
= false; 
1622 // ---------------------------------------------------------------------------- 
1624 // ---------------------------------------------------------------------------- 
1626 // Responds to colour changes: passes event on to children. 
1627 void wxWindow::OnSysColourChanged(wxSysColourChangedEvent
& event
) 
1629     wxWindowList::compatibility_iterator node 
= GetChildren().GetFirst(); 
1632         // Only propagate to non-top-level windows 
1633         wxWindow 
*win 
= node
->GetData(); 
1634         if ( win
->GetParent() ) 
1636             wxSysColourChangedEvent event2
; 
1637             event
.SetEventObject(win
); 
1638             win
->GetEventHandler()->ProcessEvent(event2
); 
1641         node 
= node
->GetNext(); 
1645 void wxWindow::OnInternalIdle() 
1647     // This calls the UI-update mechanism (querying windows for 
1648     // menu/toolbar/control state information) 
1649     if (wxUpdateUIEvent::CanUpdate(this)) 
1650         UpdateWindowUI(wxUPDATE_UI_FROMIDLE
); 
1653 // ---------------------------------------------------------------------------- 
1655 // ---------------------------------------------------------------------------- 
1657 bool wxWindow::ProcessAccelerator(wxKeyEvent
& event
) 
1660     if (!m_acceleratorTable
.Ok()) 
1663     int count 
= m_acceleratorTable
.GetCount(); 
1664     wxAcceleratorEntry
* entries 
= m_acceleratorTable
.GetEntries(); 
1666     for (i 
= 0; i 
< count
; i
++) 
1668         wxAcceleratorEntry
* entry 
= & (entries
[i
]); 
1669         if (entry
->MatchesEvent(event
)) 
1671             // Bingo, we have a match. Now find a control that matches the 
1672             // entry command id. 
1674             // Need to go up to the top of the window hierarchy, since it might 
1675             // be e.g. a menu item 
1676             wxWindow
* parent 
= this; 
1677             while ( parent 
&& !parent
->IsTopLevel() ) 
1678                 parent 
= parent
->GetParent(); 
1683             wxFrame
* frame 
= wxDynamicCast(parent
, wxFrame
); 
1687                 // Try for a menu command 
1688                 if (frame
->GetMenuBar()) 
1690                     wxMenuItem
* item 
= frame
->GetMenuBar()->FindItem(entry
->GetCommand()); 
1693                         wxCommandEvent 
commandEvent(wxEVT_COMMAND_MENU_SELECTED
, entry
->GetCommand()); 
1694                         commandEvent
.SetEventObject(frame
); 
1696                         // If ProcessEvent returns true (it was handled), then 
1697                         // the calling code will skip the event handling. 
1698                         return frame
->GetEventHandler()->ProcessEvent(commandEvent
); 
1704             // Find a child matching the command id 
1705             wxWindow
* child 
= parent
->FindWindow(entry
->GetCommand()); 
1711             // Now we process those kinds of windows that we can. 
1712             // For now, only buttons. 
1713             if ( wxDynamicCast(child
, wxButton
) ) 
1715                 wxCommandEvent 
commandEvent (wxEVT_COMMAND_BUTTON_CLICKED
, child
->GetId()); 
1716                 commandEvent
.SetEventObject(child
); 
1717                 return child
->GetEventHandler()->ProcessEvent(commandEvent
); 
1725     // We didn't match the key event against an accelerator. 
1729 // ============================================================================ 
1730 // Motif-specific stuff from here on 
1731 // ============================================================================ 
1733 // ---------------------------------------------------------------------------- 
1734 // function which maintain the global hash table mapping Widgets to wxWidgets 
1735 // ---------------------------------------------------------------------------- 
1737 bool wxAddWindowToTable(Widget w
, wxWindow 
*win
) 
1739     const long key 
= (long)w
; 
1740     if ( wxWidgetHashTable
->Get(key
)) 
1742         wxLogDebug("Widget table clash: new widget is %ld, %s", 
1743                    key
, win
->GetClassInfo()->GetClassName()); 
1747     wxWidgetHashTable
->Put(key
, win
); 
1749     wxLogTrace("widget", "Widget 0x%p <-> window %p (%s)", 
1750                w
, win
, win
->GetClassInfo()->GetClassName()); 
1755 wxWindow 
*wxGetWindowFromTable(Widget w
) 
1757     return (wxWindow 
*)wxWidgetHashTable
->Get((long) w
); 
1760 void wxDeleteWindowFromTable(Widget w
) 
1762     wxLogTrace("widget", "Widget 0x%p", (WXWidget
)w
); 
1764     wxWidgetHashTable
->Delete((long)w
); 
1767 // ---------------------------------------------------------------------------- 
1768 // add/remove window from the table 
1769 // ---------------------------------------------------------------------------- 
1771 // Add to hash table, add event handler 
1772 bool wxWindow::AttachWidget (wxWindow
* WXUNUSED(parent
), WXWidget mainWidget
, 
1773                              WXWidget formWidget
, int x
, int y
, int width
, int height
) 
1775     wxAddWindowToTable((Widget
) mainWidget
, this); 
1776     XtAddEventHandler( (Widget
) mainWidget
, 
1777                        ButtonPressMask 
| ButtonReleaseMask
 
1778                      | PointerMotionMask
, 
1780                        wxPanelItemEventHandler
, 
1786         XtOverrideTranslations ((Widget
) mainWidget
, 
1787             ptr 
= XtParseTranslationTable ("<Configure>: resize()")); 
1788         XtFree ((char *) ptr
); 
1791     // Some widgets have a parent form widget, e.g. wxRadioBox 
1794         if (!wxAddWindowToTable((Widget
) formWidget
, this)) 
1798         XtOverrideTranslations ((Widget
) formWidget
, 
1799             ptr 
= XtParseTranslationTable ("<Configure>: resize()")); 
1800         XtFree ((char *) ptr
); 
1807     DoSetSize (x
, y
, width
, height
, wxSIZE_USE_EXISTING
); 
1812 // Remove event handler, remove from hash table 
1813 bool wxWindow::DetachWidget(WXWidget widget
) 
1815     XtRemoveEventHandler( (Widget
) widget
, 
1816                           ButtonPressMask 
| ButtonReleaseMask
 
1817                         | PointerMotionMask
, 
1819                           wxPanelItemEventHandler
, 
1822     wxDeleteWindowFromTable((Widget
) widget
); 
1826 // ---------------------------------------------------------------------------- 
1827 // Motif-specific accessors 
1828 // ---------------------------------------------------------------------------- 
1830 WXWindow 
wxWindow::GetClientXWindow() const 
1832     Widget wMain 
= (Widget
)GetClientWidget(); 
1834         return (WXWindow
) XtWindow(wMain
); 
1836         return (WXWindow
) 0; 
1839 // Get the underlying X window 
1840 WXWindow 
wxWindow::GetXWindow() const 
1842     Widget wMain 
= (Widget
)GetMainWidget(); 
1844         return (WXWindow
) XtWindow(wMain
); 
1846         return (WXWindow
) 0; 
1849 // Get the underlying X display 
1850 WXDisplay 
*wxWindow::GetXDisplay() const 
1852     Widget wMain 
= (Widget
)GetMainWidget(); 
1854         return (WXDisplay
*) XtDisplay(wMain
); 
1856         return (WXDisplay
*) NULL
; 
1859 WXWidget 
wxWindow::GetMainWidget() const 
1862         return m_drawingArea
; 
1864         return m_mainWidget
; 
1867 WXWidget 
wxWindow::GetClientWidget() const 
1869     if (m_drawingArea 
!= (WXWidget
) 0) 
1870         return m_drawingArea
; 
1872         return GetMainWidget(); 
1875 WXWidget 
wxWindow::GetTopWidget() const 
1877     return GetMainWidget(); 
1880 WXWidget 
wxWindow::GetLabelWidget() const 
1882     return GetMainWidget(); 
1885 // ---------------------------------------------------------------------------- 
1887 // ---------------------------------------------------------------------------- 
1889 // All widgets should have this as their resize proc. 
1890 // OnSize sent to wxWindow via client data. 
1891 void wxWidgetResizeProc(Widget w
, XConfigureEvent 
*WXUNUSED(event
), 
1892                         String 
WXUNUSED(args
)[], int *WXUNUSED(num_args
)) 
1894     wxWindow 
*win 
= wxGetWindowFromTable(w
); 
1898     if (win
->PreResize()) 
1900         wxSize 
newSize(win
->GetSize()); 
1901         wxSizeEvent 
sizeEvent(newSize
, win
->GetId()); 
1902         sizeEvent
.SetEventObject(win
); 
1903         win
->GetEventHandler()->ProcessEvent(sizeEvent
); 
1907 static void wxCanvasRepaintProc(Widget drawingArea
, 
1908                                 XtPointer clientData
, 
1909                                 XmDrawingAreaCallbackStruct 
* cbs
) 
1911     if (!wxGetWindowFromTable(drawingArea
)) 
1914     XEvent 
* event 
= cbs
->event
; 
1915     wxWindow 
* win 
= (wxWindow 
*) clientData
; 
1917     switch (event
->type
) 
1921             win
->AddUpdateRect(event
->xexpose
.x
, event
->xexpose
.y
, 
1922                                event
->xexpose
.width
, event
->xexpose
.height
); 
1924             if (event 
-> xexpose
.count 
== 0) 
1933 // Unable to deal with Enter/Leave without a separate EventHandler (Motif 1.1.4) 
1934 static void wxCanvasEnterLeave(Widget drawingArea
, 
1935                                XtPointer 
WXUNUSED(clientData
), 
1936                                XCrossingEvent 
* event
) 
1938     XmDrawingAreaCallbackStruct cbs
; 
1941     ((XCrossingEvent 
&) ev
) = *event
; 
1943     cbs
.reason 
= XmCR_INPUT
; 
1946     wxCanvasInputEvent(drawingArea
, (XtPointer
) NULL
, &cbs
); 
1949 // Fix to make it work under Motif 1.0 (!) 
1950 static void wxCanvasMotionEvent (Widget 
WXUNUSED(drawingArea
), 
1951                                  XButtonEvent 
*WXUNUSED(event
)) 
1953 #if XmVersion <= 1000 
1954     XmDrawingAreaCallbackStruct cbs
; 
1957     ev 
= *((XEvent 
*) event
); 
1958     cbs
.reason 
= XmCR_INPUT
; 
1961     wxCanvasInputEvent (drawingArea
, (XtPointer
) NULL
, &cbs
); 
1962 #endif // XmVersion <= 1000 
1965 static void wxCanvasInputEvent(Widget drawingArea
, 
1966                                XtPointer 
WXUNUSED(data
), 
1967                                XmDrawingAreaCallbackStruct 
* cbs
) 
1969     wxWindow 
*canvas 
= wxGetWindowFromTable(drawingArea
); 
1970     XEvent
* xevent 
= cbs
->event
; 
1975     if (cbs
->reason 
!= XmCR_INPUT
) 
1978     switch (xevent
->xany
.type
) 
1986             wxMouseEvent 
wxevent(0); 
1987             if (wxTranslateMouseEvent(wxevent
, canvas
, drawingArea
, xevent
)) 
1989                 canvas
->GetEventHandler()->ProcessEvent(wxevent
); 
1995             wxKeyEvent 
event (wxEVT_CHAR
); 
1996             if (wxTranslateKeyEvent (event
, canvas
, (Widget
) 0, xevent
)) 
1998                 // Implement wxFrame::OnCharHook by checking ancestor. 
1999                 wxWindow 
*parent 
= canvas
; 
2000                 while (parent 
&& !parent
->IsTopLevel()) 
2001                     parent 
= parent
->GetParent(); 
2005                     event
.SetEventType(wxEVT_CHAR_HOOK
); 
2006                     if (parent
->GetEventHandler()->ProcessEvent(event
)) 
2010                 // For simplicity, OnKeyDown is the same as OnChar 
2011                 // TODO: filter modifier key presses from OnChar 
2012                 event
.SetEventType(wxEVT_KEY_DOWN
); 
2014                 // Only process OnChar if OnKeyDown didn't swallow it 
2015                 if (!canvas
->GetEventHandler()->ProcessEvent (event
)) 
2017                     event
.SetEventType(wxEVT_CHAR
); 
2018                     canvas
->GetEventHandler()->ProcessEvent (event
); 
2025             wxKeyEvent 
event (wxEVT_KEY_UP
); 
2026             if (wxTranslateKeyEvent (event
, canvas
, (Widget
) 0, xevent
)) 
2028                 canvas
->GetEventHandler()->ProcessEvent (event
); 
2034             if (xevent
->xfocus
.detail 
!= NotifyPointer
) 
2036                 wxFocusEvent 
event(wxEVT_SET_FOCUS
, canvas
->GetId()); 
2037                 event
.SetEventObject(canvas
); 
2038                 canvas
->GetEventHandler()->ProcessEvent(event
); 
2044             if (xevent
->xfocus
.detail 
!= NotifyPointer
) 
2046                 wxFocusEvent 
event(wxEVT_KILL_FOCUS
, canvas
->GetId()); 
2047                 event
.SetEventObject(canvas
); 
2048                 canvas
->GetEventHandler()->ProcessEvent(event
); 
2057 static void wxPanelItemEventHandler(Widget    wid
, 
2058                                     XtPointer 
WXUNUSED(client_data
), 
2060                                     Boolean  
*continueToDispatch
) 
2062     // Widget can be a label or the actual widget. 
2064     wxWindow 
*window 
= wxGetWindowFromTable(wid
); 
2067         wxMouseEvent 
wxevent(0); 
2068         if (wxTranslateMouseEvent(wxevent
, window
, wid
, event
)) 
2070             window
->GetEventHandler()->ProcessEvent(wxevent
); 
2074     // TODO: probably the key to allowing default behaviour to happen. Say we 
2075     // set a m_doDefault flag to false at the start of this function. Then in 
2076     // e.g. wxWindow::OnMouseEvent we can call Default() which sets this flag to 
2077     // true, indicating that default processing can happen. Thus, behaviour can 
2078     // appear to be overridden just by adding an event handler and not calling 
2079     // wxWindow::OnWhatever. ALSO, maybe we can use this instead of the current 
2080     // way of handling drawing area events, to simplify things. 
2081     *continueToDispatch 
= True
; 
2084 static void wxScrollBarCallback(Widget scrollbar
, 
2085                                 XtPointer clientData
, 
2086                                 XmScrollBarCallbackStruct 
*cbs
) 
2088     wxWindow 
*win 
= wxGetWindowFromTable(scrollbar
); 
2089     wxOrientation orientation 
= (wxOrientation
)wxPtrToUInt(clientData
); 
2091     wxEventType eventType 
= wxEVT_NULL
; 
2092     switch (cbs
->reason
) 
2094     case XmCR_INCREMENT
: 
2096             eventType 
= wxEVT_SCROLLWIN_LINEDOWN
; 
2099     case XmCR_DECREMENT
: 
2101             eventType 
= wxEVT_SCROLLWIN_LINEUP
; 
2106             eventType 
= wxEVT_SCROLLWIN_THUMBTRACK
; 
2109     case XmCR_VALUE_CHANGED
: 
2111             eventType 
= wxEVT_SCROLLWIN_THUMBRELEASE
; 
2114     case XmCR_PAGE_INCREMENT
: 
2116             eventType 
= wxEVT_SCROLLWIN_PAGEDOWN
; 
2119     case XmCR_PAGE_DECREMENT
: 
2121             eventType 
= wxEVT_SCROLLWIN_PAGEUP
; 
2126             eventType 
= wxEVT_SCROLLWIN_TOP
; 
2129     case XmCR_TO_BOTTOM
: 
2131             eventType 
= wxEVT_SCROLLWIN_BOTTOM
; 
2136             // Should never get here 
2137             wxFAIL_MSG("Unknown scroll event."); 
2142     wxScrollWinEvent 
event(eventType
, 
2145     event
.SetEventObject( win 
); 
2146     win
->GetEventHandler()->ProcessEvent(event
); 
2149 // For repainting arbitrary windows 
2150 void wxUniversalRepaintProc(Widget w
, XtPointer 
WXUNUSED(c_data
), XEvent 
*event
, char *) 
2152     wxWindow
* win 
= wxGetWindowFromTable(w
); 
2156     switch ( event
->type 
) 
2160             win
->AddUpdateRect(event
->xexpose
.x
, event
->xexpose
.y
, 
2161                                event
->xexpose
.width
, event
->xexpose
.height
); 
2163             if ( event
->xexpose
.count 
== 0 ) 
2173 // ---------------------------------------------------------------------------- 
2174 // TranslateXXXEvent() functions 
2175 // ---------------------------------------------------------------------------- 
2177 bool wxTranslateMouseEvent(wxMouseEvent
& wxevent
, wxWindow 
*win
, 
2178                            Widget widget
, const XEvent 
*xevent
) 
2180     switch (xevent
->xany
.type
) 
2185             fprintf(stderr
, "Widget 0x%p <-> window %p (%s), %s\n", 
2186                     (WXWidget
)widget
, win
, win
->GetClassInfo()->GetClassName(), 
2187                     (xevent
->xany
.type 
== EnterNotify 
? "ENTER" : "LEAVE")); 
2193             int eventx 
= xevent
->xbutton
.x
, eventy 
= xevent
->xbutton
.y
; 
2195             wxEventType eventType 
= wxEVT_NULL
; 
2197             if (xevent
->xany
.type 
== LeaveNotify
) 
2199                 eventType 
= wxEVT_LEAVE_WINDOW
; 
2201             if (xevent
->xany
.type 
== EnterNotify
) 
2203                 eventType 
= wxEVT_ENTER_WINDOW
; 
2205             else if (xevent
->xany
.type 
== MotionNotify
) 
2207                 eventType 
= wxEVT_MOTION
; 
2209                 if (xevent
->xmotion
.is_hint 
== NotifyHint
) 
2214                     Display 
*dpy 
= XtDisplay (widget
); 
2216                     XQueryPointer (dpy
, XtWindow (widget
), 
2218                         &x_root
, &y_root
, &eventx
, &eventy
, &state
); 
2221             else if (xevent
->xany
.type 
== ButtonPress
) 
2223                 wxevent
.SetTimestamp(xevent
->xbutton
.time
); 
2225                 if (xevent
->xbutton
.button 
== Button1
) 
2227                     eventType 
= wxEVT_LEFT_DOWN
; 
2230                 else if (xevent
->xbutton
.button 
== Button2
) 
2232                     eventType 
= wxEVT_MIDDLE_DOWN
; 
2235                 else if (xevent
->xbutton
.button 
== Button3
) 
2237                     eventType 
= wxEVT_RIGHT_DOWN
; 
2241                 // check for a double click 
2243                 long dclickTime 
= XtGetMultiClickTime(xevent
->xany
.display
); 
2244                 long ts 
= wxevent
.GetTimestamp(); 
2246                 int buttonLast 
= win
->GetLastClickedButton(); 
2247                 long lastTS 
= win
->GetLastClickTime(); 
2248                 if ( buttonLast 
&& buttonLast 
== button 
&& 
2249                      (ts 
- lastTS
) < dclickTime 
) 
2252                     win
->SetLastClick(0, ts
); 
2253                     if ( eventType 
== wxEVT_LEFT_DOWN 
) 
2254                         eventType 
= wxEVT_LEFT_DCLICK
; 
2255                     else if ( eventType 
== wxEVT_MIDDLE_DOWN 
) 
2256                         eventType 
= wxEVT_MIDDLE_DCLICK
; 
2257                     else if ( eventType 
== wxEVT_RIGHT_DOWN 
) 
2258                         eventType 
= wxEVT_RIGHT_DCLICK
; 
2262                     // not fast enough or different button 
2263                     win
->SetLastClick(button
, ts
); 
2266             else if (xevent
->xany
.type 
== ButtonRelease
) 
2268                 if (xevent
->xbutton
.button 
== Button1
) 
2270                     eventType 
= wxEVT_LEFT_UP
; 
2272                 else if (xevent
->xbutton
.button 
== Button2
) 
2274                     eventType 
= wxEVT_MIDDLE_UP
; 
2276                 else if (xevent
->xbutton
.button 
== Button3
) 
2278                     eventType 
= wxEVT_RIGHT_UP
; 
2288             wxevent
.SetEventType(eventType
); 
2291             XtVaGetValues(widget
, XmNx
, &x1
, XmNy
, &y1
, NULL
); 
2294             win
->GetPosition(&x2
, &y2
); 
2296             // The button x/y must be translated to wxWidgets 
2297             // window space - the widget might be a label or button, 
2301             if (widget 
!= (Widget
)win
->GetMainWidget()) 
2307             wxevent
.m_x 
= eventx 
+ dx
; 
2308             wxevent
.m_y 
= eventy 
+ dy
; 
2310             wxevent
.m_leftDown 
= ((eventType 
== wxEVT_LEFT_DOWN
) 
2311                 || (event_left_is_down (xevent
) 
2312                 && (eventType 
!= wxEVT_LEFT_UP
))); 
2313             wxevent
.m_middleDown 
= ((eventType 
== wxEVT_MIDDLE_DOWN
) 
2314                 || (event_middle_is_down (xevent
) 
2315                 && (eventType 
!= wxEVT_MIDDLE_UP
))); 
2316             wxevent
.m_rightDown 
= ((eventType 
== wxEVT_RIGHT_DOWN
) 
2317                 || (event_right_is_down (xevent
) 
2318                 && (eventType 
!= wxEVT_RIGHT_UP
))); 
2320             wxevent
.m_shiftDown 
= (xevent
->xbutton
.state 
& ShiftMask
) == ShiftMask
; 
2321             wxevent
.m_controlDown 
= (xevent
->xbutton
.state 
& ControlMask
) == ControlMask
; 
2322             wxevent
.m_altDown 
= (xevent
->xbutton
.state 
& Mod3Mask
) == Mod3Mask
; 
2323             wxevent
.m_metaDown 
= (xevent
->xbutton
.state 
& Mod1Mask
) == Mod1Mask
; 
2325             wxevent
.SetId(win
->GetId()); 
2326             wxevent
.SetEventObject(win
); 
2334 bool wxTranslateKeyEvent(wxKeyEvent
& wxevent
, wxWindow 
*win
, 
2335                          Widget 
WXUNUSED(widget
), const XEvent 
*xevent
) 
2337     switch (xevent
->xany
.type
) 
2345             (void) XLookupString((XKeyEvent 
*)xevent
, buf
, 20, &keySym
, NULL
); 
2346             int id 
= wxCharCodeXToWX (keySym
); 
2347             // id may be WXK_xxx code - these are outside ASCII range, so we 
2348             // can't just use toupper() on id 
2349             if (id 
>= 'a' && id 
<= 'z') 
2352             if (xevent
->xkey
.state 
& ShiftMask
) 
2353                 wxevent
.m_shiftDown 
= true; 
2354             if (xevent
->xkey
.state 
& ControlMask
) 
2355                 wxevent
.m_controlDown 
= true; 
2356             if (xevent
->xkey
.state 
& Mod3Mask
) 
2357                 wxevent
.m_altDown 
= true; 
2358             if (xevent
->xkey
.state 
& Mod1Mask
) 
2359                 wxevent
.m_metaDown 
= true; 
2360             wxevent
.SetEventObject(win
); 
2361             wxevent
.m_keyCode 
= id
; 
2362             wxevent
.SetTimestamp(xevent
->xkey
.time
); 
2364             wxevent
.m_x 
= xevent
->xbutton
.x
; 
2365             wxevent
.m_y 
= xevent
->xbutton
.y
; 
2378 // ---------------------------------------------------------------------------- 
2380 // ---------------------------------------------------------------------------- 
2382 #define YAllocColor XAllocColor 
2383 XColor g_itemColors
[5]; 
2384 int wxComputeColours (Display 
*display
, const wxColour 
* back
, const wxColour 
* fore
) 
2387     static XmColorProc colorProc
; 
2389     result 
= wxNO_COLORS
; 
2393         g_itemColors
[0].red 
= (unsigned short)(((long) back
->Red ()) << 8); 
2394         g_itemColors
[0].green 
= (unsigned short)(((long) back
->Green ()) << 8); 
2395         g_itemColors
[0].blue 
= (unsigned short)(((long) back
->Blue ()) << 8); 
2396         g_itemColors
[0].flags 
= DoRed 
| DoGreen 
| DoBlue
; 
2397         if (colorProc 
== (XmColorProc
) NULL
) 
2399             // Get a ptr to the actual function 
2400             colorProc 
= XmSetColorCalculation ((XmColorProc
) NULL
); 
2401             // And set it back to motif. 
2402             XmSetColorCalculation (colorProc
); 
2404         (*colorProc
) (&g_itemColors
[wxBACK_INDEX
], 
2405             &g_itemColors
[wxFORE_INDEX
], 
2406             &g_itemColors
[wxSELE_INDEX
], 
2407             &g_itemColors
[wxTOPS_INDEX
], 
2408             &g_itemColors
[wxBOTS_INDEX
]); 
2409         result 
= wxBACK_COLORS
; 
2413         g_itemColors
[wxFORE_INDEX
].red 
= (unsigned short)(((long) fore
->Red ()) << 8); 
2414         g_itemColors
[wxFORE_INDEX
].green 
= (unsigned short)(((long) fore
->Green ()) << 8); 
2415         g_itemColors
[wxFORE_INDEX
].blue 
= (unsigned short)(((long) fore
->Blue ()) << 8); 
2416         g_itemColors
[wxFORE_INDEX
].flags 
= DoRed 
| DoGreen 
| DoBlue
; 
2417         if (result 
== wxNO_COLORS
) 
2418             result 
= wxFORE_COLORS
; 
2421     Display 
*dpy 
= display
; 
2422     Colormap cmap 
= (Colormap
) wxTheApp
->GetMainColormap((WXDisplay
*) dpy
); 
2426         /* 5 Colours to allocate */ 
2427         for (int i 
= 0; i 
< 5; i
++) 
2428             if (!YAllocColor (dpy
, cmap
, &g_itemColors
[i
])) 
2429                 result 
= wxNO_COLORS
; 
2433         /* Only 1 colour to allocate */ 
2434         if (!YAllocColor (dpy
, cmap
, &g_itemColors
[wxFORE_INDEX
])) 
2435             result 
= wxNO_COLORS
; 
2441 // Changes the foreground and background colours to be derived from the current 
2442 // background colour. To change the foreground colour, you must call 
2443 // SetForegroundColour explicitly. 
2444 void wxWindow::ChangeBackgroundColour() 
2446     WXWidget mainWidget 
= GetMainWidget(); 
2448         wxDoChangeBackgroundColour(mainWidget
, m_backgroundColour
); 
2449     if ( m_scrolledWindow 
&& mainWidget 
!= m_scrolledWindow 
) 
2450         wxDoChangeForegroundColour(m_scrolledWindow
, m_backgroundColour
); 
2453 void wxWindow::ChangeForegroundColour() 
2455     WXWidget mainWidget 
= GetMainWidget(); 
2457         wxDoChangeForegroundColour(mainWidget
, m_foregroundColour
); 
2458     if ( m_scrolledWindow 
&& mainWidget 
!= m_scrolledWindow 
) 
2459         wxDoChangeForegroundColour(m_scrolledWindow
, m_foregroundColour
); 
2462 bool wxWindow::SetBackgroundColour(const wxColour
& col
) 
2464     if ( !wxWindowBase::SetBackgroundColour(col
) ) 
2467     ChangeBackgroundColour(); 
2472 bool wxWindow::SetForegroundColour(const wxColour
& col
) 
2474     if ( !wxWindowBase::SetForegroundColour(col
) ) 
2477     ChangeForegroundColour(); 
2482 void wxWindow::ChangeFont(bool keepOriginalSize
) 
2484     // Note that this causes the widget to be resized back 
2485     // to its original size! We therefore have to set the size 
2486     // back again. TODO: a better way in Motif? 
2487     Widget w 
= (Widget
) GetLabelWidget(); // Usually the main widget 
2488     if (w 
&& m_font
.Ok()) 
2490         int width
, height
, width1
, height1
; 
2491         GetSize(& width
, & height
); 
2493         wxDoChangeFont( GetLabelWidget(), m_font 
); 
2495         GetSize(& width1
, & height1
); 
2496         if (keepOriginalSize 
&& (width 
!= width1 
|| height 
!= height1
)) 
2498             SetSize(wxDefaultCoord
, wxDefaultCoord
, width
, height
); 
2503 // ---------------------------------------------------------------------------- 
2505 // ---------------------------------------------------------------------------- 
2507 wxWindow 
*wxGetActiveWindow() 
2510     wxFAIL_MSG("Not implemented"); 
2515 wxWindow 
*wxWindowBase::GetCapture() 
2517     return (wxWindow 
*)g_captureWindow
; 
2521 // Find the wxWindow at the current mouse position, returning the mouse 
2523 wxWindow
* wxFindWindowAtPointer(wxPoint
& pt
) 
2525     pt 
= wxGetMousePosition(); 
2526     return wxFindWindowAtPoint(pt
); 
2529 // Get the current mouse position. 
2530 wxPoint 
wxGetMousePosition() 
2532     Display 
*display 
= wxGlobalDisplay(); 
2533     Window rootWindow 
= RootWindowOfScreen (DefaultScreenOfDisplay(display
)); 
2534     Window rootReturn
, childReturn
; 
2535     int rootX
, rootY
, winX
, winY
; 
2536     unsigned int maskReturn
; 
2538     XQueryPointer (display
, 
2542                    &rootX
, &rootY
, &winX
, &winY
, &maskReturn
); 
2543     return wxPoint(rootX
, rootY
); 
2547 // ---------------------------------------------------------------------------- 
2548 // wxNoOptimize: switch off size optimization 
2549 // ---------------------------------------------------------------------------- 
2551 int wxNoOptimize::ms_count 
= 0;