1 ///////////////////////////////////////////////////////////////////////////// 
   2 // Name:        src/motif/window.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" 
  30     #include "wx/dcclient.h" 
  31     #include "wx/button.h" 
  33     #include "wx/settings.h" 
  34     #include "wx/scrolwin.h" 
  35     #include "wx/layout.h" 
  36     #include "wx/menuitem.h" 
  37     #include "wx/module.h" 
  40 #include "wx/evtloop.h" 
  41 #include "wx/unix/utilsx11.h" 
  43 #if  wxUSE_DRAG_AND_DROP 
  47 // DoSetSizeIntr and DoMoveWindowIntr 
  49 // under Motif composite controls (such as wxCalendarCtrl or generic wxSpinCtrl 
  50 // did not work and/or segfaulted because 
  51 // 1) wxWindow::Create calls SetSize, 
  52 //    which results in a call to DoSetSize much earlier than in the other ports 
  53 // 2) if wxWindow::Create is called (wxControl::Create calls it) 
  54 //    then DoSetSize is never called, causing layout problems in composite 
  58 // 1) don't call SetSize, DoSetSize, DoMoveWindow, DoGetPosition, 
  59 //    DoSetPosition directly or indirectly from wxWindow::Create 
  60 // 2) call DoMoveWindow from DoSetSize, allowing controls to override it 
  63     #pragma message disable nosimpint 
  67 #include <Xm/DrawingA.h> 
  68 #include <Xm/ScrolledW.h> 
  69 #include <Xm/ScrollBar.h> 
  72 #include <Xm/RowColumn.h>           // for XmMenuPosition 
  74     #pragma message enable nosimpint 
  77 #include "wx/motif/private.h" 
  78 #include "wx/motif/dcclient.h" 
  82 // ---------------------------------------------------------------------------- 
  83 // global variables for this module 
  84 // ---------------------------------------------------------------------------- 
  86 extern wxHashTable 
*wxWidgetHashTable
; 
  87 static wxWindow
* g_captureWindow 
= NULL
; 
  90 // ---------------------------------------------------------------------------- 
  92 // ---------------------------------------------------------------------------- 
  94 static void wxCanvasRepaintProc(Widget
, XtPointer
, XmDrawingAreaCallbackStruct 
* cbs
); 
  95 static void wxCanvasInputEvent(Widget drawingArea
, XtPointer data
, XmDrawingAreaCallbackStruct 
* cbs
); 
  96 static void wxCanvasMotionEvent(Widget
, XButtonEvent 
* event
); 
  97 static void wxCanvasEnterLeave(Widget drawingArea
, XtPointer clientData
, XCrossingEvent 
* event
); 
  98 static void wxScrollBarCallback(Widget widget
, XtPointer clientData
, 
  99                                 XmScrollBarCallbackStruct 
*cbs
); 
 100 static void wxPanelItemEventHandler(Widget    wid
, 
 101                                     XtPointer client_data
, 
 103                                     Boolean  
*continueToDispatch
); 
 108 // Helper function for 16-bit fonts 
 109 static int str16len(const char *s
) 
 113     while (s
[0] && s
[1]) { 
 123 // ---------------------------------------------------------------------------- 
 125 // ---------------------------------------------------------------------------- 
 127 #define event_left_is_down(x) ((x)->xbutton.state & Button1Mask) 
 128 #define event_middle_is_down(x) ((x)->xbutton.state & Button2Mask) 
 129 #define event_right_is_down(x) ((x)->xbutton.state & Button3Mask) 
 131 // ---------------------------------------------------------------------------- 
 133 // ---------------------------------------------------------------------------- 
 135     BEGIN_EVENT_TABLE(wxWindow
, wxWindowBase
) 
 136         EVT_SYS_COLOUR_CHANGED(wxWindow::OnSysColourChanged
) 
 139 // ============================================================================ 
 141 // ============================================================================ 
 143 // ---------------------------------------------------------------------------- 
 145 // ---------------------------------------------------------------------------- 
 147 void wxWindow::UnmanageAndDestroy(WXWidget widget
) 
 149     Widget w 
= (Widget
)widget
; 
 157 bool wxWindow::MapOrUnmap(WXWidget widget
, bool domap
) 
 159     Widget w 
= (Widget
)widget
; 
 163     //   Rationale: a lot of common operations (including but not 
 164     // limited to moving, resizing and appending items to a listbox) 
 165     // unmamange the widget, do their work, then manage it again. 
 166     // This means that, for example adding an item to a listbox will show it, 
 167     // or that most controls are shown every time they are moved or resized! 
 168     XtSetMappedWhenManaged( w
, domap 
); 
 170     // if the widget is not unmanaged, it still intercepts 
 171     // mouse events, even if it is not mapped (and hence invisible) 
 186 // ---------------------------------------------------------------------------- 
 188 // ---------------------------------------------------------------------------- 
 190 void wxWindow::Init() 
 193     m_needsRefresh 
= true; 
 194     m_mainWidget 
= (WXWidget
) 0; 
 196     m_winCaptured 
= false; 
 204     m_drawingArea 
= (WXWidget
) 0; 
 209     m_backingPixmap 
= (WXPixmap
) 0; 
 220 // real construction (Init() must have been called before!) 
 221 bool wxWindow::Create(wxWindow 
*parent
, wxWindowID id
, 
 225                       const wxString
& name
) 
 227     // Get default border 
 228     wxBorder border 
= GetBorder(style
); 
 229     style 
&= ~wxBORDER_MASK
; 
 232     wxCHECK_MSG( parent
, false, "can't create wxWindow without parent" ); 
 234     CreateBase(parent
, id
, pos
, size
, style
, wxDefaultValidator
, name
); 
 236     parent
->AddChild(this); 
 239     //// TODO: we should probably optimize by only creating a 
 240     //// a drawing area if we have one or more scrollbars (wxVSCROLL/wxHSCROLL). 
 241     //// But for now, let's simplify things by always creating the 
 242     //// drawing area, since otherwise the translations are different. 
 244     // New translations for getting mouse motion feedback 
 245     static const String translations 
= wxMOTIF_STR( 
 246 "<Btn1Motion>: wxCanvasMotionEvent() DrawingAreaInput() ManagerGadgetButtonMotion()\n\ 
 247 <Btn2Motion>: wxCanvasMotionEvent() DrawingAreaInput() ManagerGadgetButtonMotion()\n\ 
 248 <Btn3Motion>: wxCanvasMotionEvent() DrawingAreaInput() ManagerGadgetButtonMotion()\n\ 
 249 <BtnMotion>: wxCanvasMotionEvent() DrawingAreaInput() ManagerGadgetButtonMotion()\n\ 
 250 <Btn1Down>: DrawingAreaInput() ManagerGadgetArm()\n\ 
 251 <Btn2Down>: DrawingAreaInput() ManagerGadgetArm()\n\ 
 252 <Btn3Down>: DrawingAreaInput() ManagerGadgetArm()\n\ 
 253 <Btn1Up>: DrawingAreaInput() ManagerGadgetActivate()\n\ 
 254 <Btn2Up>: DrawingAreaInput() ManagerGadgetActivate()\n\ 
 255 <Btn3Up>: DrawingAreaInput() ManagerGadgetActivate()\n\ 
 256 <Motion>: wxCanvasMotionEvent() DrawingAreaInput()\n\ 
 257 <EnterWindow>: wxCanvasMotionEvent() DrawingAreaInput()\n\ 
 258 <LeaveWindow>: wxCanvasMotionEvent() DrawingAreaInput()\n\ 
 259 <Key>: DrawingAreaInput()"); 
 261     XtActionsRec actions
[1]; 
 262     actions
[0].string 
= wxMOTIF_STR("wxCanvasMotionEvent"); 
 263     actions
[0].proc 
= (XtActionProc
) wxCanvasMotionEvent
; 
 264     XtAppAddActions ((XtAppContext
) wxTheApp
->GetAppContext(), actions
, 1); 
 266     Widget parentWidget 
= (Widget
) parent
->GetClientWidget(); 
 267     m_borderWidget 
= wxCreateBorderWidget( (WXWidget
)parentWidget
, style 
); 
 269     m_scrolledWindow 
= (WXWidget
)XtVaCreateManagedWidget
 
 272                                   xmScrolledWindowWidgetClass
, 
 273                                   m_borderWidget 
? (Widget
) m_borderWidget
 
 275                                   XmNresizePolicy
, XmRESIZE_NONE
, 
 277                                   XmNscrollingPolicy
, XmAPPLICATION_DEFINED
, 
 278                                   //XmNscrollBarDisplayPolicy, XmAS_NEEDED, 
 282     XtTranslations ptr 
= XtParseTranslationTable(translations
); 
 283     m_drawingArea 
= (WXWidget
)XtVaCreateWidget
 
 286                                xmDrawingAreaWidgetClass
, (Widget
) m_scrolledWindow
, 
 287                                XmNunitType
, XmPIXELS
, 
 288                                // XmNresizePolicy, XmRESIZE_ANY, 
 289                                XmNresizePolicy
, XmRESIZE_NONE
, 
 292                                XmNtranslations
, ptr
, 
 295     XtFree((char *) ptr
); 
 298     if (GetWindowStyleFlag() & wxOVERRIDE_KEY_TRANSLATIONS
) 
 300         ptr 
= XtParseTranslationTable ("<Key>: DrawingAreaInput()"); 
 301         XtOverrideTranslations ((Widget
) m_drawingArea
, ptr
); 
 302         XtFree ((char *) ptr
); 
 306     wxAddWindowToTable((Widget
) m_drawingArea
, this); 
 307     wxAddWindowToTable((Widget
) m_scrolledWindow
, this); 
 309     // This order is very important in Motif 1.2.1 
 310     XtRealizeWidget ((Widget
) m_scrolledWindow
); 
 311     XtRealizeWidget ((Widget
) m_drawingArea
); 
 312     XtManageChild ((Widget
) m_drawingArea
); 
 314     ptr 
= XtParseTranslationTable("<Configure>: resize()"); 
 315     XtOverrideTranslations((Widget
) m_drawingArea
, ptr
); 
 316     XtFree ((char *) ptr
); 
 318     XtAddCallback ((Widget
) m_drawingArea
, XmNexposeCallback
, (XtCallbackProc
) wxCanvasRepaintProc
, (XtPointer
) this); 
 319     XtAddCallback ((Widget
) m_drawingArea
, XmNinputCallback
, (XtCallbackProc
) wxCanvasInputEvent
, (XtPointer
) this); 
 322                       (Widget
)m_drawingArea
, 
 323                        PointerMotionHintMask 
| EnterWindowMask 
| 
 324                        LeaveWindowMask 
| FocusChangeMask
, 
 326                        (XtEventHandler
) wxCanvasEnterLeave
, 
 330     XmScrolledWindowSetAreas( 
 331                              (Widget
)m_scrolledWindow
, 
 332                              (Widget
) 0, (Widget
) 0, 
 333                              (Widget
) m_drawingArea
); 
 337     // Without this, the cursor may not be restored properly (e.g. in splitter 
 339     SetCursor(*wxSTANDARD_CURSOR
); 
 340     DoSetSizeIntr(pos
.x
, pos
.y
, size
.x
,size
.y
, wxSIZE_AUTO
, true); 
 345 wxWindow::~wxWindow() 
 349     if (g_captureWindow 
== this) 
 350         g_captureWindow 
= NULL
; 
 352     // Motif-specific actions first 
 353     WXWidget wMain 
= GetMainWidget(); 
 356         // Removes event handlers 
 360     // If m_drawingArea, we're a fully-fledged window with drawing area, 
 361     // scrollbars etc. (what wxCanvas used to be) 
 364         // Destroy children before destroying self 
 368             XFreePixmap (XtDisplay ((Widget
) GetMainWidget()), (Pixmap
) m_backingPixmap
); 
 370         Widget w 
= (Widget
) m_drawingArea
; 
 371         wxDeleteWindowFromTable(w
); 
 376             m_drawingArea 
= (WXWidget
) 0; 
 379         // Only if we're _really_ a canvas (not a dialog box/panel) 
 380         if (m_scrolledWindow
) 
 382             wxDeleteWindowFromTable((Widget
) m_scrolledWindow
); 
 387             wxDeleteWindowFromTable((Widget
) m_hScrollBar
); 
 388             XtUnmanageChild((Widget
) m_hScrollBar
); 
 392             wxDeleteWindowFromTable((Widget
) m_vScrollBar
); 
 393             XtUnmanageChild((Widget
) m_vScrollBar
); 
 397             XtDestroyWidget((Widget
) m_hScrollBar
); 
 399             XtDestroyWidget((Widget
) m_vScrollBar
); 
 401         UnmanageAndDestroy(m_scrolledWindow
); 
 405             XtDestroyWidget ((Widget
) m_borderWidget
); 
 406             m_borderWidget 
= (WXWidget
) 0; 
 409     else // Why wasn't this here before? JACS 8/3/2000 
 413     // Destroy the window 
 416         // If this line (XtDestroyWidget) causes a crash, you may comment it out. 
 417         // Child widgets will get destroyed automatically when a frame 
 418         // or dialog is destroyed, but before that you may get some memory 
 419         // leaks and potential layout problems if you delete and then add 
 422         // GRG, Feb/2000: commented this out when adding support for 
 423         //   wxSCROLL[WIN]_THUMBRELEASE events. Also it was reported 
 424         //   that this call crashed wxMotif under OS/2, so it seems 
 425         //   that leaving it out is the right thing to do. 
 426         // SN, Feb/2000: newgrid/griddemo shows why it is needed :-( 
 427         XtDestroyWidget((Widget
) GetMainWidget()); 
 428         SetMainWidget((WXWidget
) NULL
); 
 432 // ---------------------------------------------------------------------------- 
 433 // scrollbar management 
 434 // ---------------------------------------------------------------------------- 
 436 WXWidget 
wxWindow::DoCreateScrollBar(WXWidget parent
, 
 437                                      wxOrientation orientation
, 
 440     int orient 
= ( orientation 
& wxHORIZONTAL 
) ? XmHORIZONTAL 
: XmVERTICAL
; 
 442         XtVaCreateManagedWidget( "scrollBarWidget", 
 443                                  xmScrollBarWidgetClass
, (Widget
)parent
, 
 444                                  XmNorientation
, orient
, 
 449     XtPointer o 
= (XtPointer
)orientation
; 
 450     XtCallbackProc cb 
= (XtCallbackProc
)callback
; 
 452     XtAddCallback( sb
, XmNvalueChangedCallback
, cb
, o 
); 
 453     XtAddCallback( sb
, XmNdragCallback
, cb
, o 
); 
 454     XtAddCallback( sb
, XmNincrementCallback
, cb
, o 
); 
 455     XtAddCallback( sb
, XmNdecrementCallback
, cb
, o 
); 
 456     XtAddCallback( sb
, XmNpageIncrementCallback
, cb
, o 
); 
 457     XtAddCallback( sb
, XmNpageDecrementCallback
, cb
, o 
); 
 458     XtAddCallback( sb
, XmNtoTopCallback
, cb
, o 
); 
 459     XtAddCallback( sb
, XmNtoBottomCallback
, cb
, o 
); 
 465 void wxWindow::CreateScrollbar(wxOrientation orientation
) 
 467     wxCHECK_RET( m_drawingArea
, "this window can't have scrollbars" ); 
 469     XtVaSetValues( (Widget
) m_scrolledWindow
, 
 470                    XmNresizePolicy
, XmRESIZE_NONE
, 
 473     wxColour backgroundColour 
= wxSystemSettings::GetColour(wxSYS_COLOUR_3DFACE
); 
 474     // Add scrollbars if required 
 475     if (orientation 
== wxHORIZONTAL
) 
 477         m_hScrollBar 
= DoCreateScrollBar( m_scrolledWindow
, wxHORIZONTAL
, 
 478                                           (void (*)())wxScrollBarCallback 
); 
 480         wxDoChangeBackgroundColour(m_hScrollBar
, backgroundColour
, true); 
 482         XtRealizeWidget( (Widget
)m_hScrollBar 
); 
 484         XtVaSetValues((Widget
) m_scrolledWindow
, 
 485             XmNhorizontalScrollBar
, (Widget
) m_hScrollBar
, 
 488         wxAddWindowToTable( (Widget
)m_hScrollBar
, this ); 
 490     else if (orientation 
== wxVERTICAL
) 
 492         m_vScrollBar 
= DoCreateScrollBar( m_scrolledWindow
, wxVERTICAL
, 
 493                                           (void (*)())wxScrollBarCallback 
); 
 495         wxDoChangeBackgroundColour(m_vScrollBar
, backgroundColour
, true); 
 497         XtRealizeWidget((Widget
)m_vScrollBar
); 
 499         XtVaSetValues((Widget
) m_scrolledWindow
, 
 500             XmNverticalScrollBar
, (Widget
) m_vScrollBar
, 
 503         wxAddWindowToTable( (Widget
)m_vScrollBar
, this ); 
 506     XtVaSetValues( (Widget
) m_scrolledWindow
, 
 507                    XmNresizePolicy
, XmRESIZE_ANY
, 
 511 void wxWindow::DestroyScrollbar(wxOrientation orientation
) 
 513     wxCHECK_RET( m_drawingArea
, "this window can't have scrollbars" ); 
 515     XtVaSetValues((Widget
) m_scrolledWindow
, 
 516                   XmNresizePolicy
, XmRESIZE_NONE
, 
 518     String stringSB 
= orientation 
== wxHORIZONTAL 
? 
 519         XmNhorizontalScrollBar 
: XmNverticalScrollBar
; 
 520     WXWidget
* widgetSB 
= orientation 
== wxHORIZONTAL 
? 
 521         &m_hScrollBar 
: &m_vScrollBar
; 
 525         wxDeleteWindowFromTable( (Widget
)*widgetSB 
); 
 526         XtDestroyWidget( (Widget
)*widgetSB 
); 
 527         *widgetSB 
= (WXWidget
)NULL
; 
 530     XtVaSetValues( (Widget
)m_scrolledWindow
, 
 531                    stringSB
, (Widget
) 0, 
 534     XtVaSetValues((Widget
) m_scrolledWindow
, 
 535                   XmNresizePolicy
, XmRESIZE_ANY
, 
 539 // --------------------------------------------------------------------------- 
 541 // --------------------------------------------------------------------------- 
 543 void wxWindow::SetFocus() 
 545     Widget wMain 
= (Widget
) GetMainWidget(); 
 546     XmProcessTraversal(wMain
, XmTRAVERSE_CURRENT
); 
 547     XmProcessTraversal((Widget
) GetMainWidget(), XmTRAVERSE_CURRENT
); 
 550 // Get the window with the focus 
 551 wxWindow 
*wxWindowBase::DoFindFocus() 
 554     // (1) Can there be multiple focussed widgets in an application? 
 555     // In which case we need to find the top-level window that's 
 557     // (2) The widget with the focus may not be in the widget table 
 558     // depending on which widgets I put in the table 
 559     wxWindow 
*winFocus 
= NULL
; 
 560     for ( wxWindowList::compatibility_iterator node 
= wxTopLevelWindows
.GetFirst(); 
 562           node 
= node
->GetNext() ) 
 564         wxWindow 
*win 
= node
->GetData(); 
 566         Widget w 
= XmGetFocusWidget ((Widget
) win
->GetTopWidget()); 
 568         if (w 
!= (Widget
) NULL
) 
 570             winFocus 
= wxGetWindowFromTable(w
); 
 579 bool wxWindow::Enable(bool enable
) 
 581     if ( !wxWindowBase::Enable(enable
) ) 
 584     Widget wMain 
= (Widget
)GetMainWidget(); 
 587         XtSetSensitive(wMain
, enable
); 
 588         XmUpdateDisplay(wMain
); 
 594 bool wxWindow::Show(bool show
) 
 596     if ( !wxWindowBase::Show(show
) ) 
 599     if (m_borderWidget 
|| m_scrolledWindow
) 
 601         MapOrUnmap(m_borderWidget 
? m_borderWidget 
: m_scrolledWindow
, show
); 
 602         // MapOrUnmap(m_drawingArea, show); 
 606         if ( !MapOrUnmap(GetTopWidget(), show
) ) 
 607             MapOrUnmap(GetMainWidget(), show
); 
 613 // Raise the window to the top of the Z order 
 614 void wxWindow::Raise() 
 616     Widget wTop 
= (Widget
) GetTopWidget(); 
 617     Window window 
= XtWindow(wTop
); 
 618     XRaiseWindow(XtDisplay(wTop
), window
); 
 621 // Lower the window to the bottom of the Z order 
 622 void wxWindow::Lower() 
 624     Widget wTop 
= (Widget
) GetTopWidget(); 
 625     Window window 
= XtWindow(wTop
); 
 626     XLowerWindow(XtDisplay(wTop
), window
); 
 629 void wxWindow::SetLabel(const wxString
& label
) 
 631     XtVaSetValues((Widget
)GetMainWidget(), XmNtitle
, 
 632                   (const char*)label
.mb_str(), NULL
); 
 635 wxString 
wxWindow::GetLabel() const 
 638     XtVaGetValues((Widget
)GetMainWidget(), XmNtitle
, &label
, NULL
); 
 640     return wxString(label
); 
 643 void wxWindow::DoCaptureMouse() 
 645     g_captureWindow 
= this; 
 649     Widget wMain 
= (Widget
)GetMainWidget(); 
 651         XtAddGrab(wMain
, True
, False
); 
 653     m_winCaptured 
= true; 
 656 void wxWindow::DoReleaseMouse() 
 658     g_captureWindow 
= NULL
; 
 659     if ( !m_winCaptured 
) 
 662     Widget wMain 
= (Widget
)GetMainWidget(); 
 666     m_winCaptured 
= false; 
 669 bool wxWindow::SetFont(const wxFont
& font
) 
 671     if ( !wxWindowBase::SetFont(font
) ) 
 682 bool wxWindow::SetCursor(const wxCursor
& cursor
) 
 684     if ( !wxWindowBase::SetCursor(cursor
) ) 
 690     //    wxASSERT_MSG( m_cursor.IsOk(), 
 691     //                  wxT("cursor must be valid after call to the base version")); 
 692     const wxCursor
* cursor2 
= NULL
; 
 694         cursor2 
= & m_cursor
; 
 696         cursor2 
= wxSTANDARD_CURSOR
; 
 698     WXDisplay 
*dpy 
= GetXDisplay(); 
 699     WXCursor x_cursor 
= cursor2
->GetXCursor(dpy
); 
 701     Widget w 
= (Widget
) GetMainWidget(); 
 702     Window win 
= XtWindow(w
); 
 703     XDefineCursor((Display
*) dpy
, win
, (Cursor
) x_cursor
); 
 708 // Coordinates relative to the window 
 709 void wxWindow::WarpPointer (int x
, int y
) 
 711     Widget wClient 
= (Widget
)GetClientWidget(); 
 713     XWarpPointer(XtDisplay(wClient
), None
, XtWindow(wClient
), 0, 0, 0, 0, x
, y
); 
 716 // --------------------------------------------------------------------------- 
 718 // --------------------------------------------------------------------------- 
 720 int wxWindow::GetScrollPos(int orient
) const 
 722     if (orient 
== wxHORIZONTAL
) 
 728     Widget scrollBar 
= (Widget
) ((orient 
== wxHORIZONTAL
) ? m_hScrollBar 
: m_vScrollBar
); 
 732         XtVaGetValues(scrollBar
, XmNvalue
, &pos
, NULL
); 
 740 // This now returns the whole range, not just the number of positions that we 
 742 int wxWindow::GetScrollRange(int orient
) const 
 744     Widget scrollBar 
= (Widget
)GetScrollbar((wxOrientation
)orient
); 
 745     // CE scintilla windows don't always have these scrollbars 
 746     // and it tends to pile up a whole bunch of asserts 
 747     //wxCHECK_MSG( scrollBar, 0, "no such scrollbar" ); 
 751         XtVaGetValues(scrollBar
, XmNmaximum
, &range
, NULL
); 
 755 int wxWindow::GetScrollThumb(int orient
) const 
 757     Widget scrollBar 
= (Widget
)GetScrollbar((wxOrientation
)orient
); 
 758     //wxCHECK_MSG( scrollBar, 0, "no such scrollbar" ); 
 762         XtVaGetValues(scrollBar
, XmNsliderSize
, &thumb
, NULL
); 
 766 void wxWindow::SetScrollPos(int orient
, int pos
, bool WXUNUSED(refresh
)) 
 768     Widget scrollBar 
= (Widget
)GetScrollbar((wxOrientation
)orient
); 
 772         XtVaSetValues (scrollBar
, XmNvalue
, pos
, NULL
); 
 775     SetInternalScrollPos((wxOrientation
)orient
, pos
); 
 778 // New function that will replace some of the above. 
 779 void wxWindow::SetScrollbar(int orient
, int pos
, int thumbVisible
, 
 780                             int range
, bool WXUNUSED(refresh
)) 
 783     GetSize(& oldW
, & oldH
); 
 787     if (thumbVisible 
== 0) 
 790     if (thumbVisible 
> range
) 
 791         thumbVisible 
= range
; 
 793     // Save the old state to see if it changed 
 794     WXWidget oldScrollBar 
= GetScrollbar((wxOrientation
)orient
); 
 796     if (orient 
== wxHORIZONTAL
) 
 798         if (thumbVisible 
== range
) 
 801                 DestroyScrollbar(wxHORIZONTAL
); 
 806                 CreateScrollbar(wxHORIZONTAL
); 
 809     if (orient 
== wxVERTICAL
) 
 811         if (thumbVisible 
== range
) 
 814                 DestroyScrollbar(wxVERTICAL
); 
 819                 CreateScrollbar(wxVERTICAL
); 
 822     WXWidget newScrollBar 
=  GetScrollbar((wxOrientation
)orient
); 
 824     if (oldScrollBar 
!= newScrollBar
) 
 826         // This is important! Without it, scrollbars misbehave badly. 
 827         XtUnrealizeWidget((Widget
) m_scrolledWindow
); 
 828         XmScrolledWindowSetAreas ((Widget
) m_scrolledWindow
, (Widget
) m_hScrollBar
, (Widget
) m_vScrollBar
, (Widget
) m_drawingArea
); 
 829         XtRealizeWidget((Widget
) m_scrolledWindow
); 
 830         XtManageChild((Widget
) m_scrolledWindow
); 
 835         XtVaSetValues((Widget
) newScrollBar
, 
 839         XmNsliderSize
, thumbVisible
, 
 843     SetInternalScrollPos((wxOrientation
)orient
, pos
); 
 846     GetSize(& newW
, & newH
); 
 848     // Adjusting scrollbars can resize the canvas accidentally 
 849     if (newW 
!= oldW 
|| newH 
!= oldH
) 
 850         SetSize(wxDefaultCoord
, wxDefaultCoord
, oldW
, oldH
); 
 853 // Does a physical scroll 
 854 void wxWindow::ScrollWindow(int dx
, int dy
, const wxRect 
*rect
) 
 859         // Use specified rectangle 
 860         x 
= rect
->x
; y 
= rect
->y
; w 
= rect
->width
; h 
= rect
->height
; 
 864         // Use whole client area 
 866         GetClientSize(& w
, & h
); 
 869     int x1 
= (dx 
>= 0) ? x 
: x 
- dx
; 
 870     int y1 
= (dy 
>= 0) ? y 
: y 
- dy
; 
 871     int w1 
= w 
- abs(dx
); 
 872     int h1 
= h 
- abs(dy
); 
 873     int x2 
= (dx 
>= 0) ? x 
+ dx 
: x
; 
 874     int y2 
= (dy 
>= 0) ? y 
+ dy 
: y
; 
 877     wxClientDCImpl 
* const 
 878         dcimpl 
= static_cast<wxClientDCImpl 
*>(dc
.GetImpl()); 
 879     GC 
const gc 
= (GC
) dcimpl
->GetGC(); 
 881     dc
.SetLogicalFunction (wxCOPY
); 
 883     Widget widget 
= (Widget
) GetMainWidget(); 
 884     Window window 
= XtWindow(widget
); 
 885     Display
* display 
= XtDisplay(widget
); 
 887     XCopyArea(display
, window
, window
, gc
, x1
, y1
, w1
, h1
, x2
, y2
); 
 889     dcimpl
->SetAutoSetting(true); 
 890     wxBrush 
brush(GetBackgroundColour(), wxSOLID
); 
 891     dc
.SetBrush(brush
); // FIXME: needed? 
 893     wxWindowList::compatibility_iterator cnode 
= m_children
.GetFirst(); 
 896         wxWindow 
*child 
= cnode
->GetData(); 
 899         child
->GetSize( &sx
, &sy 
); 
 900         wxPoint 
pos( child
->GetPosition() ); 
 901         child
->SetSize( pos
.x 
+ dx
, pos
.y 
+ dy
, sx
, sy
, wxSIZE_ALLOW_MINUS_ONE 
); 
 902         cnode 
= cnode
->GetNext(); 
 905     // We'll add rectangles to the list of update rectangles according to which 
 906     // bits we've exposed. 
 911         wxRect 
*rect 
= new wxRect
; 
 917         XFillRectangle(display
, window
, gc
, rect
->x
, rect
->y
, rect
->width
, rect
->height
); 
 921         rect
->width 
= rect
->width
; 
 922         rect
->height 
= rect
->height
; 
 924         updateRects
.Append((wxObject
*) rect
); 
 928         wxRect 
*rect 
= new wxRect
; 
 930         rect
->x 
= x 
+ w 
+ dx
; 
 935         XFillRectangle(display
, window
, gc
, rect
->x
, rect
->y
, rect
->width
, rect
->height
); 
 939         rect
->width 
= rect
->width
; 
 940         rect
->height 
= rect
->height
; 
 942         updateRects
.Append((wxObject
*) rect
); 
 946         wxRect 
*rect 
= new wxRect
; 
 953         XFillRectangle(display
, window
, gc
, rect
->x
, rect
->y
, rect
->width
, rect
->height
); 
 957         rect
->width 
= rect
->width
; 
 958         rect
->height 
= rect
->height
; 
 960         updateRects
.Append((wxObject
*) rect
); 
 964         wxRect 
*rect 
= new wxRect
; 
 967         rect
->y 
= y 
+ h 
+ dy
; 
 971         XFillRectangle(display
, window
, gc
, rect
->x
, rect
->y
, rect
->width
, rect
->height
); 
 975         rect
->width 
= rect
->width
; 
 976         rect
->height 
= rect
->height
; 
 978         updateRects
.Append((wxObject
*) rect
); 
 980     dc
.SetBrush(wxNullBrush
); 
 982     // Now send expose events 
 984     wxList::compatibility_iterator  node 
= updateRects
.GetFirst(); 
 987         wxRect
* rect 
= (wxRect
*) node
->GetData(); 
 991         event
.display 
= display
; 
 992         event
.send_event 
= True
; 
 993         event
.window 
= window
; 
 997         event
.width 
= rect
->width
; 
 998         event
.height 
= rect
->height
; 
1002         XSendEvent(display
, window
, False
, ExposureMask
, (XEvent 
*)&event
); 
1004         node 
= node
->GetNext(); 
1008     // Delete the update rects 
1009     node 
= updateRects
.GetFirst(); 
1012         wxRect
* rect 
= (wxRect
*) node
->GetData(); 
1014         node 
= node
->GetNext(); 
1017     XmUpdateDisplay((Widget
) GetMainWidget()); 
1020 // --------------------------------------------------------------------------- 
1022 // --------------------------------------------------------------------------- 
1024 #if wxUSE_DRAG_AND_DROP 
1026 void wxWindow::SetDropTarget(wxDropTarget 
* WXUNUSED(pDropTarget
)) 
1033 // Old style file-manager drag&drop 
1034 void wxWindow::DragAcceptFiles(bool WXUNUSED(accept
)) 
1039 // ---------------------------------------------------------------------------- 
1041 // ---------------------------------------------------------------------------- 
1045 void wxWindow::DoSetToolTip(wxToolTip 
* WXUNUSED(tooltip
)) 
1050 #endif // wxUSE_TOOLTIPS 
1052 // ---------------------------------------------------------------------------- 
1054 // ---------------------------------------------------------------------------- 
1058 bool wxWindow::DoPopupMenu(wxMenu 
*menu
, int x
, int y
) 
1060     if ( x 
== wxDefaultCoord 
&& y 
== wxDefaultCoord 
) 
1062         wxPoint mouse 
= ScreenToClient(wxGetMousePosition()); 
1063         x 
= mouse
.x
; y 
= mouse
.y
; 
1066     Widget widget 
= (Widget
) GetMainWidget(); 
1068     /* The menuId field seems to be usused, so we'll use it to 
1069     indicate whether a menu is popped up or not: 
1070     0: Not currently created as a popup 
1071     -1: Created as a popup, but not active 
1075     if (menu
->GetParent() && (menu
->GetId() != -1)) 
1078     if (menu
->GetMainWidget()) 
1080         menu
->DestroyMenu(true); 
1083     menu
->SetId(1); /* Mark as popped-up */ 
1084     menu
->CreateMenu(NULL
, widget
, menu
, 0); 
1088     //  menu->SetParent(parent); 
1089     //  parent->children->Append(menu);  // Store menu for later deletion 
1091     Widget menuWidget 
= (Widget
) menu
->GetMainWidget(); 
1099     if (this->IsKindOf(CLASSINFO(wxCanvas))) 
1101     wxCanvas *canvas = (wxCanvas *) this; 
1102     deviceX = canvas->GetDC ()->LogicalToDeviceX (x); 
1103     deviceY = canvas->GetDC ()->LogicalToDeviceY (y); 
1107     Display 
*display 
= XtDisplay (widget
); 
1108     Window rootWindow 
= RootWindowOfScreen (XtScreen((Widget
)widget
)); 
1109     Window thisWindow 
= XtWindow (widget
); 
1111     XTranslateCoordinates (display
, thisWindow
, rootWindow
, (int) deviceX
, (int) deviceY
, 
1112         &rootX
, &rootY
, &childWindow
); 
1114     XButtonPressedEvent event
; 
1115     event
.type 
= ButtonPress
; 
1121     event
.x_root 
= rootX
; 
1122     event
.y_root 
= rootY
; 
1124     XmMenuPosition (menuWidget
, &event
); 
1125     XtManageChild (menuWidget
); 
1127     // The ID of a pop-up menu is 1 when active, and is set to 0 by the 
1128     // idle-time destroy routine. 
1129     // Waiting until this ID changes causes this function to block until 
1130     // the menu has been dismissed and the widgets cleaned up. 
1131     // In other words, once this routine returns, it is safe to delete 
1133     // Ian Brown <ian.brown@printsoft.de> 
1135     wxEventLoop evtLoop
; 
1137     while (menu
->GetId() == 1) 
1139         wxDoEventLoopIteration( evtLoop 
); 
1147 // --------------------------------------------------------------------------- 
1148 // moving and resizing 
1149 // --------------------------------------------------------------------------- 
1151 bool wxWindow::PreResize() 
1157 void wxWindow::DoGetSize(int *x
, int *y
) const 
1159     Widget widget 
= (Widget
)( !m_drawingArea 
? GetTopWidget() : 
1160                               ( m_borderWidget 
? m_borderWidget 
: 
1161                                 m_scrolledWindow 
? m_scrolledWindow 
: 
1166         XtVaGetValues( widget
, 
1170     if(x
) *x 
= widget 
? xx 
: -1; 
1171     if(y
) *y 
= widget 
? yy 
: -1; 
1174 void wxWindow::DoGetPosition(int *x
, int *y
) const 
1176     Widget widget 
= (Widget
) 
1178           ( m_borderWidget 
? m_borderWidget 
: m_scrolledWindow 
) : 
1182     XtVaGetValues(widget
, XmNx
, &xx
, XmNy
, &yy
, NULL
); 
1184     // We may be faking the client origin. So a window that's really at (0, 30) 
1185     // may appear (to wxWin apps) to be at (0, 0). 
1188         wxPoint 
pt(GetParent()->GetClientAreaOrigin()); 
1189         xx 
= (Position
)(xx 
- pt
.x
); 
1190         yy 
= (Position
)(yy 
- pt
.y
); 
1197 void wxWindow::DoScreenToClient(int *x
, int *y
) const 
1199     Widget widget 
= (Widget
) GetClientWidget(); 
1200     Display 
*display 
= XtDisplay((Widget
) GetMainWidget()); 
1201     Window rootWindow 
= RootWindowOfScreen(XtScreen(widget
)); 
1202     Window thisWindow 
= XtWindow(widget
); 
1205     int xx 
= x 
? *x 
: 0; 
1206     int yy 
= y 
? *y 
: 0; 
1207     XTranslateCoordinates(display
, rootWindow
, thisWindow
, 
1208                           xx
, yy
, x 
? x 
: &xx
, y 
? y 
: &yy
, 
1212 void wxWindow::DoClientToScreen(int *x
, int *y
) const 
1214     Widget widget 
= (Widget
) GetClientWidget(); 
1215     Display 
*display 
= XtDisplay(widget
); 
1216     Window rootWindow 
= RootWindowOfScreen(XtScreen(widget
)); 
1217     Window thisWindow 
= XtWindow(widget
); 
1220     int xx 
= x 
? *x 
: 0; 
1221     int yy 
= y 
? *y 
: 0; 
1222     XTranslateCoordinates(display
, thisWindow
, rootWindow
, 
1223                           xx
, yy
, x 
? x 
: &xx
, y 
? y 
: &yy
, 
1228 // Get size *available for subwindows* i.e. excluding menu bar etc. 
1229 void wxWindow::DoGetClientSize(int *x
, int *y
) const 
1231     Widget widget 
= (Widget
) GetClientWidget(); 
1233     XtVaGetValues(widget
, XmNwidth
, &xx
, XmNheight
, &yy
, NULL
); 
1234     if(x
) *x 
= xx
; if(y
) *y 
= yy
; 
1237 void wxWindow::DoSetSize(int x
, int y
, int width
, int height
, int sizeFlags
) 
1239     DoSetSizeIntr(x
, y
, width
, height
, sizeFlags
, false); 
1242 void wxWindow::DoSetSizeIntr(int x
, int y
, int width
, int height
, 
1243                              int sizeFlags
, bool fromCtor
) 
1245     // A bit of optimization to help sort out the flickers. 
1246     int oldX 
= -1, oldY 
= -1, oldW 
= -1, oldH 
= -1; 
1250         GetSize(& oldW
, & oldH
); 
1251         GetPosition(& oldX
, & oldY
); 
1259     if ( !(sizeFlags 
& wxSIZE_ALLOW_MINUS_ONE
) ) 
1267     wxSize 
size(wxDefaultSize
); 
1270         if ( ( sizeFlags 
& wxSIZE_AUTO_WIDTH 
) && !fromCtor 
) 
1272             size 
= DoGetBestSize(); 
1283         if( ( sizeFlags 
& wxSIZE_AUTO_HEIGHT 
) && !fromCtor 
) 
1285             if( size
.x 
== -1 ) size 
= DoGetBestSize(); 
1294     if ( x 
!= oldX 
|| y 
!= oldY 
|| width 
!= oldW 
|| height 
!= oldH
 
1295          || !wxNoOptimize::CanOptimize() ) 
1308                 flags 
|= wxMOVE_WIDTH
; 
1311                 flags 
|= wxMOVE_HEIGHT
; 
1313             int xx 
= x
; int yy 
= y
; 
1314             AdjustForParentClientOrigin(xx
, yy
, sizeFlags
); 
1316                 DoMoveWindow( xx
, yy
, width
, height 
); 
1318                 DoMoveWindowIntr( xx
, yy
, width
, height
, flags 
); 
1323         Widget widget 
= (Widget
) GetTopWidget(); 
1327         bool managed 
= XtIsManaged( widget 
); 
1329             XtUnmanageChild(widget
); 
1333         AdjustForParentClientOrigin(xx
, yy
, sizeFlags
); 
1335         DoMoveWindow(xx
, yy
, width
, height
); 
1338             XtManageChild(widget
); 
1342 void wxWindow::DoSetClientSize(int width
, int height
) 
1346         Widget drawingArea 
= (Widget
) m_drawingArea
; 
1348         XtVaSetValues(drawingArea
, XmNresizePolicy
, XmRESIZE_ANY
, NULL
); 
1351             XtVaSetValues(drawingArea
, XmNwidth
, width
, NULL
); 
1353             XtVaSetValues(drawingArea
, XmNheight
, height
, NULL
); 
1355         XtVaSetValues(drawingArea
, XmNresizePolicy
, XmRESIZE_NONE
, NULL
); 
1359     Widget widget 
= (Widget
) GetTopWidget(); 
1362         XtVaSetValues(widget
, XmNwidth
, width
, NULL
); 
1364         XtVaSetValues(widget
, XmNheight
, height
, NULL
); 
1367 void wxWindow::DoMoveWindowIntr(int xx
, int yy
, int w
, int h
, 
1372         Widget drawingArea 
= (Widget
) m_drawingArea
; 
1373         Widget borderOrScrolled 
= m_borderWidget 
? 
1374             (Widget
) m_borderWidget 
: 
1375             (Widget
) m_scrolledWindow
; 
1377         bool managed 
= XtIsManaged(borderOrScrolled
); 
1379             XtUnmanageChild (borderOrScrolled
); 
1380         XtVaSetValues(drawingArea
, XmNresizePolicy
, XmRESIZE_ANY
, NULL
); 
1382         if (flags 
& wxMOVE_X
) 
1383             XtVaSetValues (borderOrScrolled
, 
1386         if (flags 
& wxMOVE_Y
) 
1387             XtVaSetValues (borderOrScrolled
, 
1391         if (flags 
& wxMOVE_WIDTH
) 
1395                 XtVaSetValues ((Widget
) m_borderWidget
, XmNwidth
, w
, NULL
); 
1396                 short thick
, margin
; 
1397                 XtVaGetValues ((Widget
) m_borderWidget
, 
1398                                XmNshadowThickness
, &thick
, 
1399                                XmNmarginWidth
, &margin
, 
1401                 w 
-= 2 * (thick 
+ margin
); 
1405             XtVaSetValues ((Widget
) m_scrolledWindow
, XmNwidth
, w
, NULL
); 
1408         if (flags 
& wxMOVE_HEIGHT
) 
1412                 XtVaSetValues ((Widget
) m_borderWidget
, XmNheight
, h
, NULL
); 
1413                 short thick
, margin
; 
1414                 XtVaGetValues ((Widget
) m_borderWidget
, 
1415                                XmNshadowThickness
, &thick
, 
1416                                XmNmarginHeight
, &margin
, 
1418                 h 
-= 2 * (thick 
+ margin
); 
1422             XtVaSetValues ((Widget
) m_scrolledWindow
, XmNheight
, h
, NULL
); 
1426             XtManageChild (borderOrScrolled
); 
1427         XtVaSetValues(drawingArea
, XmNresizePolicy
, XmRESIZE_NONE
, NULL
); 
1434         XtVaSetValues((Widget
)GetTopWidget(), 
1443 void wxWindow::DoMoveWindow(int x
, int y
, int width
, int height
) 
1445     DoMoveWindowIntr (x
, y
, width
, height
, 
1446                       wxMOVE_X
|wxMOVE_Y
|wxMOVE_WIDTH
|wxMOVE_HEIGHT
); 
1449 // --------------------------------------------------------------------------- 
1451 // --------------------------------------------------------------------------- 
1453 int wxWindow::GetCharHeight() const 
1458         wxGetTextExtent (GetXDisplay(), m_font
, 1.0, 
1459                          "x", NULL
, &height
, NULL
, NULL
); 
1461         wxGetTextExtent (this, "x", NULL
, &height
, NULL
, NULL
); 
1466 int wxWindow::GetCharWidth() const 
1471         wxGetTextExtent (GetXDisplay(), m_font
, 1.0, 
1472                          "x", &width
, NULL
, NULL
, NULL
); 
1474         wxGetTextExtent (this, "x", &width
, NULL
, NULL
, NULL
); 
1479 void wxWindow::DoGetTextExtent(const wxString
& string
, 
1482                                int *externalLeading
, 
1483                                const wxFont 
*theFont
) const 
1485     const wxFont 
*fontToUse 
= theFont 
? theFont 
: &m_font
; 
1487     if (externalLeading
) 
1488         *externalLeading 
= 0; 
1489     if (fontToUse
->IsOk()) 
1490         wxGetTextExtent (GetXDisplay(), *fontToUse
, 1.0, 
1491                          string
, x
, y
, NULL
, descent
); 
1493         wxGetTextExtent (this, string
, x
, y
, NULL
, descent
); 
1496 // ---------------------------------------------------------------------------- 
1498 // ---------------------------------------------------------------------------- 
1500 void wxWindow::AddUpdateRect(int x
, int y
, int w
, int h
) 
1502     m_updateRegion
.Union( x
, y
, w
, h 
); 
1505 void wxWindow::Refresh(bool eraseBack
, const wxRect 
*rect
) 
1507     Widget widget 
= (Widget
) GetMainWidget(); 
1510     m_needsRefresh 
= true; 
1511     Display 
*display 
= XtDisplay(widget
); 
1512     Window thisWindow 
= XtWindow(widget
); 
1514     XExposeEvent dummyEvent
; 
1516     GetSize(&width
, &height
); 
1518     dummyEvent
.type 
= Expose
; 
1519     dummyEvent
.display 
= display
; 
1520     dummyEvent
.send_event 
= True
; 
1521     dummyEvent
.window 
= thisWindow
; 
1524         dummyEvent
.x 
= rect
->x
; 
1525         dummyEvent
.y 
= rect
->y
; 
1526         dummyEvent
.width 
= rect
->width
; 
1527         dummyEvent
.height 
= rect
->height
; 
1533         dummyEvent
.width 
= width
; 
1534         dummyEvent
.height 
= height
; 
1536     dummyEvent
.count 
= 0; 
1540         wxClientDC 
dc(this); 
1541         wxBrush 
backgroundBrush(GetBackgroundColour(), wxSOLID
); 
1542         dc
.SetBackground(backgroundBrush
); 
1544         wxClientDCImpl 
* const 
1545             dcimpl 
= static_cast<wxClientDCImpl 
*>(dc
.GetImpl()); 
1547             dcimpl
->Clear(*rect
); 
1552     XSendEvent(display
, thisWindow
, False
, ExposureMask
, (XEvent 
*)&dummyEvent
); 
1555 void wxWindow::DoPaint() 
1557     //TODO : make a temporary gc so we can do the XCopyArea below 
1558     if (m_backingPixmap 
&& !m_needsRefresh
) 
1562       wxPaintDCImpl 
* const 
1563           dcimpl 
= static_cast<wxPaintDCImpl 
*>(dc
.GetImpl()); 
1565       GC tempGC 
= (GC
) dcimpl
->GetBackingGC(); 
1567       Widget widget 
= (Widget
) GetMainWidget(); 
1572       // We have to test whether it's a wxScrolledWindow (hack!) because 
1573       // otherwise we don't know how many pixels have been scrolled. We might 
1574       // solve this in the future by defining virtual wxWindow functions to get 
1575       // the scroll position in pixels. Or, each kind of scrolled window has to 
1576       // implement backing stores itself, using generic wxWidgets code. 
1577       wxScrolledWindow
* scrolledWindow 
= wxDynamicCast(this, wxScrolledWindow
); 
1578       if ( scrolledWindow 
) 
1581           scrolledWindow
->CalcScrolledPosition(0, 0, &x
, &y
); 
1587       // TODO: This could be optimized further by only copying the areas in the 
1588       //       current update region. 
1590       // Only blit the part visible in the client area. The backing pixmap 
1591       // always starts at 0, 0 but we may be looking at only a portion of it. 
1592       wxSize clientArea 
= GetClientSize(); 
1593       int toBlitX 
= m_pixmapWidth 
- scrollPosX
; 
1594       int toBlitY 
= m_pixmapHeight 
- scrollPosY
; 
1596       // Copy whichever is samller, the amount of pixmap we have to copy, 
1597       // or the size of the client area. 
1598       toBlitX 
= wxMin(toBlitX
, clientArea
.x
); 
1599       toBlitY 
= wxMin(toBlitY
, clientArea
.y
); 
1601       // Make sure we're not negative 
1602       toBlitX 
= wxMax(0, toBlitX
); 
1603       toBlitY 
= wxMax(0, toBlitY
); 
1608        (Pixmap
) m_backingPixmap
, 
1611        scrollPosX
, scrollPosY
, // Start at the scroll position 
1612        toBlitX
, toBlitY
,       // How much of the pixmap to copy 
1618         wxWindowDC 
dc(this); 
1619         // Set an erase event first 
1620         wxEraseEvent 
eraseEvent(GetId(), &dc
); 
1621         eraseEvent
.SetEventObject(this); 
1622         HandleWindowEvent(eraseEvent
); 
1624         wxPaintEvent 
event(GetId()); 
1625         event
.SetEventObject(this); 
1626         HandleWindowEvent(event
); 
1628         m_needsRefresh 
= false; 
1632 // ---------------------------------------------------------------------------- 
1634 // ---------------------------------------------------------------------------- 
1636 // Responds to colour changes: passes event on to children. 
1637 void wxWindow::OnSysColourChanged(wxSysColourChangedEvent
& event
) 
1639     wxWindowList::compatibility_iterator node 
= GetChildren().GetFirst(); 
1642         // Only propagate to non-top-level windows 
1643         wxWindow 
*win 
= node
->GetData(); 
1644         if ( win
->GetParent() ) 
1646             wxSysColourChangedEvent event2
; 
1647             event
.SetEventObject(win
); 
1648             win
->HandleWindowEvent(event2
); 
1651         node 
= node
->GetNext(); 
1655 // ---------------------------------------------------------------------------- 
1657 // ---------------------------------------------------------------------------- 
1659 bool wxWindow::ProcessAccelerator(wxKeyEvent
& event
) 
1662     if (!m_acceleratorTable
.IsOk()) 
1665     int count 
= m_acceleratorTable
.GetCount(); 
1666     wxAcceleratorEntry
* entries 
= m_acceleratorTable
.GetEntries(); 
1668     for (i 
= 0; i 
< count
; i
++) 
1670         wxAcceleratorEntry
* entry 
= & (entries
[i
]); 
1671         if (entry
->MatchesEvent(event
)) 
1673             // Bingo, we have a match. Now find a control that matches the 
1674             // entry command id. 
1676             // Need to go up to the top of the window hierarchy, since it might 
1677             // be e.g. a menu item 
1678             wxWindow
* parent 
= this; 
1679             while ( parent 
&& !parent
->IsTopLevel() ) 
1680                 parent 
= parent
->GetParent(); 
1685             wxFrame
* frame 
= wxDynamicCast(parent
, wxFrame
); 
1689                 // Try for a menu command 
1690                 if (frame
->GetMenuBar()) 
1692                     wxMenuItem
* item 
= frame
->GetMenuBar()->FindItem(entry
->GetCommand()); 
1695                         wxCommandEvent 
commandEvent(wxEVT_COMMAND_MENU_SELECTED
, entry
->GetCommand()); 
1696                         commandEvent
.SetEventObject(frame
); 
1698                         // If ProcessEvent returns true (it was handled), then 
1699                         // the calling code will skip the event handling. 
1700                         return frame
->HandleWindowEvent(commandEvent
); 
1706             // Find a child matching the command id 
1707             wxWindow
* child 
= parent
->FindWindow(entry
->GetCommand()); 
1713             // Now we process those kinds of windows that we can. 
1714             // For now, only buttons. 
1715             if ( wxDynamicCast(child
, wxButton
) ) 
1717                 wxCommandEvent 
commandEvent (wxEVT_COMMAND_BUTTON_CLICKED
, child
->GetId()); 
1718                 commandEvent
.SetEventObject(child
); 
1719                 return child
->HandleWindowEvent(commandEvent
); 
1727     // We didn't match the key event against an accelerator. 
1731 // ============================================================================ 
1732 // Motif-specific stuff from here on 
1733 // ============================================================================ 
1735 // ---------------------------------------------------------------------------- 
1736 // function which maintain the global hash table mapping Widgets to wxWidgets 
1737 // ---------------------------------------------------------------------------- 
1739 bool wxAddWindowToTable(Widget w
, wxWindow 
*win
) 
1741     const long key 
= (long)w
; 
1742     if ( wxWidgetHashTable
->Get(key
)) 
1744         wxLogDebug("Widget table clash: new widget is %ld, %s", 
1745                    key
, win
->GetClassInfo()->GetClassName()); 
1749     wxWidgetHashTable
->Put(key
, win
); 
1751     wxLogTrace("widget", "Widget 0x%p <-> window %p (%s)", 
1752                w
, win
, win
->GetClassInfo()->GetClassName()); 
1757 wxWindow 
*wxGetWindowFromTable(Widget w
) 
1759     return (wxWindow 
*)wxWidgetHashTable
->Get((long) w
); 
1762 void wxDeleteWindowFromTable(Widget w
) 
1764     wxLogTrace("widget", "Widget 0x%p", (WXWidget
)w
); 
1766     wxWidgetHashTable
->Delete((long)w
); 
1769 // ---------------------------------------------------------------------------- 
1770 // add/remove window from the table 
1771 // ---------------------------------------------------------------------------- 
1773 // Add to hash table, add event handler 
1774 bool wxWindow::AttachWidget (wxWindow
* WXUNUSED(parent
), WXWidget mainWidget
, 
1775                              WXWidget formWidget
, int x
, int y
, int width
, int height
) 
1777     wxAddWindowToTable((Widget
) mainWidget
, this); 
1778     XtAddEventHandler( (Widget
) mainWidget
, 
1779                        ButtonPressMask 
| ButtonReleaseMask
 
1780                      | PointerMotionMask
, 
1782                        wxPanelItemEventHandler
, 
1788         XtOverrideTranslations ((Widget
) mainWidget
, 
1789             ptr 
= XtParseTranslationTable ("<Configure>: resize()")); 
1790         XtFree ((char *) ptr
); 
1793     // Some widgets have a parent form widget, e.g. wxRadioBox 
1796         if (!wxAddWindowToTable((Widget
) formWidget
, this)) 
1800         XtOverrideTranslations ((Widget
) formWidget
, 
1801             ptr 
= XtParseTranslationTable ("<Configure>: resize()")); 
1802         XtFree ((char *) ptr
); 
1809     DoSetSize (x
, y
, width
, height
, wxSIZE_USE_EXISTING
); 
1814 // Remove event handler, remove from hash table 
1815 bool wxWindow::DetachWidget(WXWidget widget
) 
1817     XtRemoveEventHandler( (Widget
) widget
, 
1818                           ButtonPressMask 
| ButtonReleaseMask
 
1819                         | PointerMotionMask
, 
1821                           wxPanelItemEventHandler
, 
1824     wxDeleteWindowFromTable((Widget
) widget
); 
1828 // ---------------------------------------------------------------------------- 
1829 // Motif-specific accessors 
1830 // ---------------------------------------------------------------------------- 
1832 WXWindow 
wxWindow::GetClientXWindow() const 
1834     Widget wMain 
= (Widget
)GetClientWidget(); 
1836         return (WXWindow
) XtWindow(wMain
); 
1838         return (WXWindow
) 0; 
1841 // Get the underlying X window 
1842 WXWindow 
wxWindow::GetXWindow() const 
1844     Widget wMain 
= (Widget
)GetMainWidget(); 
1846         return (WXWindow
) XtWindow(wMain
); 
1848         return (WXWindow
) 0; 
1851 // Get the underlying X display 
1852 WXDisplay 
*wxWindow::GetXDisplay() const 
1854     Widget wMain 
= (Widget
)GetMainWidget(); 
1856         return (WXDisplay
*) XtDisplay(wMain
); 
1861 WXWidget 
wxWindow::GetMainWidget() const 
1864         return m_drawingArea
; 
1866         return m_mainWidget
; 
1869 WXWidget 
wxWindow::GetClientWidget() const 
1871     if (m_drawingArea 
!= (WXWidget
) 0) 
1872         return m_drawingArea
; 
1874         return GetMainWidget(); 
1877 WXWidget 
wxWindow::GetTopWidget() const 
1879     return GetMainWidget(); 
1882 WXWidget 
wxWindow::GetLabelWidget() const 
1884     return GetMainWidget(); 
1887 // ---------------------------------------------------------------------------- 
1889 // ---------------------------------------------------------------------------- 
1891 // All widgets should have this as their resize proc. 
1892 // OnSize sent to wxWindow via client data. 
1893 void wxWidgetResizeProc(Widget w
, XConfigureEvent 
*WXUNUSED(event
), 
1894                         String 
WXUNUSED(args
)[], int *WXUNUSED(num_args
)) 
1896     wxWindow 
*win 
= wxGetWindowFromTable(w
); 
1900     if (win
->PreResize()) 
1902         wxSize 
newSize(win
->GetSize()); 
1903         wxSizeEvent 
sizeEvent(newSize
, win
->GetId()); 
1904         sizeEvent
.SetEventObject(win
); 
1905         win
->HandleWindowEvent(sizeEvent
); 
1909 static void wxCanvasRepaintProc(Widget drawingArea
, 
1910                                 XtPointer clientData
, 
1911                                 XmDrawingAreaCallbackStruct 
* cbs
) 
1913     if (!wxGetWindowFromTable(drawingArea
)) 
1916     XEvent 
* event 
= cbs
->event
; 
1917     wxWindow 
* win 
= (wxWindow 
*) clientData
; 
1919     switch (event
->type
) 
1923             win
->AddUpdateRect(event
->xexpose
.x
, event
->xexpose
.y
, 
1924                                event
->xexpose
.width
, event
->xexpose
.height
); 
1926             if (event 
-> xexpose
.count 
== 0) 
1935 // Unable to deal with Enter/Leave without a separate EventHandler (Motif 1.1.4) 
1936 static void wxCanvasEnterLeave(Widget drawingArea
, 
1937                                XtPointer 
WXUNUSED(clientData
), 
1938                                XCrossingEvent 
* event
) 
1940     XmDrawingAreaCallbackStruct cbs
; 
1943     ((XCrossingEvent 
&) ev
) = *event
; 
1945     cbs
.reason 
= XmCR_INPUT
; 
1948     wxCanvasInputEvent(drawingArea
, (XtPointer
) NULL
, &cbs
); 
1951 // Fix to make it work under Motif 1.0 (!) 
1952 static void wxCanvasMotionEvent (Widget 
WXUNUSED(drawingArea
), 
1953                                  XButtonEvent 
*WXUNUSED(event
)) 
1955 #if XmVersion <= 1000 
1956     XmDrawingAreaCallbackStruct cbs
; 
1959     ev 
= *((XEvent 
*) event
); 
1960     cbs
.reason 
= XmCR_INPUT
; 
1963     wxCanvasInputEvent (drawingArea
, (XtPointer
) NULL
, &cbs
); 
1964 #endif // XmVersion <= 1000 
1967 static void wxCanvasInputEvent(Widget drawingArea
, 
1968                                XtPointer 
WXUNUSED(data
), 
1969                                XmDrawingAreaCallbackStruct 
* cbs
) 
1971     wxWindow 
*canvas 
= wxGetWindowFromTable(drawingArea
); 
1972     XEvent
* xevent 
= cbs
->event
; 
1977     if (cbs
->reason 
!= XmCR_INPUT
) 
1980     switch (xevent
->xany
.type
) 
1988             wxMouseEvent 
wxevent(0); 
1989             if (wxTranslateMouseEvent(wxevent
, canvas
, drawingArea
, xevent
)) 
1991                 canvas
->HandleWindowEvent(wxevent
); 
1997             wxKeyEvent 
event (wxEVT_CHAR
); 
1998             if (wxTranslateKeyEvent (event
, canvas
, (Widget
) 0, xevent
)) 
2000                 // Implement wxFrame::OnCharHook by checking ancestor. 
2001                 wxWindow 
*parent 
= canvas
; 
2002                 while (parent 
&& !parent
->IsTopLevel()) 
2003                     parent 
= parent
->GetParent(); 
2007                     event
.SetEventType(wxEVT_CHAR_HOOK
); 
2008                     if (parent
->HandleWindowEvent(event
)) 
2012                 // For simplicity, OnKeyDown is the same as OnChar 
2013                 // TODO: filter modifier key presses from OnChar 
2014                 event
.SetEventType(wxEVT_KEY_DOWN
); 
2016                 // Only process OnChar if OnKeyDown didn't swallow it 
2017                 if (!canvas
->HandleWindowEvent (event
)) 
2019                     event
.SetEventType(wxEVT_CHAR
); 
2020                     canvas
->HandleWindowEvent (event
); 
2027             wxKeyEvent 
event (wxEVT_KEY_UP
); 
2028             if (wxTranslateKeyEvent (event
, canvas
, (Widget
) 0, xevent
)) 
2030                 canvas
->HandleWindowEvent (event
); 
2036             if (xevent
->xfocus
.detail 
!= NotifyPointer
) 
2038                 wxFocusEvent 
event(wxEVT_SET_FOCUS
, canvas
->GetId()); 
2039                 event
.SetEventObject(canvas
); 
2040                 canvas
->HandleWindowEvent(event
); 
2046             if (xevent
->xfocus
.detail 
!= NotifyPointer
) 
2048                 wxFocusEvent 
event(wxEVT_KILL_FOCUS
, canvas
->GetId()); 
2049                 event
.SetEventObject(canvas
); 
2050                 canvas
->HandleWindowEvent(event
); 
2059 static void wxPanelItemEventHandler(Widget    wid
, 
2060                                     XtPointer 
WXUNUSED(client_data
), 
2062                                     Boolean  
*continueToDispatch
) 
2064     // Widget can be a label or the actual widget. 
2066     wxWindow 
*window 
= wxGetWindowFromTable(wid
); 
2069         wxMouseEvent 
wxevent(0); 
2070         if (wxTranslateMouseEvent(wxevent
, window
, wid
, event
)) 
2072             window
->HandleWindowEvent(wxevent
); 
2076     // TODO: probably the key to allowing default behaviour to happen. Say we 
2077     // set a m_doDefault flag to false at the start of this function. Then in 
2078     // e.g. wxWindow::OnMouseEvent we can call Default() which sets this flag to 
2079     // true, indicating that default processing can happen. Thus, behaviour can 
2080     // appear to be overridden just by adding an event handler and not calling 
2081     // wxWindow::OnWhatever. ALSO, maybe we can use this instead of the current 
2082     // way of handling drawing area events, to simplify things. 
2083     *continueToDispatch 
= True
; 
2086 static void wxScrollBarCallback(Widget scrollbar
, 
2087                                 XtPointer clientData
, 
2088                                 XmScrollBarCallbackStruct 
*cbs
) 
2090     wxWindow 
*win 
= wxGetWindowFromTable(scrollbar
); 
2091     wxCHECK_RET( win
, wxT("invalid widget in scrollbar callback") ); 
2093     wxOrientation orientation 
= (wxOrientation
)wxPtrToUInt(clientData
); 
2095     wxEventType eventType 
= wxEVT_NULL
; 
2096     switch (cbs
->reason
) 
2098     case XmCR_INCREMENT
: 
2100             eventType 
= wxEVT_SCROLLWIN_LINEDOWN
; 
2103     case XmCR_DECREMENT
: 
2105             eventType 
= wxEVT_SCROLLWIN_LINEUP
; 
2110             eventType 
= wxEVT_SCROLLWIN_THUMBTRACK
; 
2113     case XmCR_VALUE_CHANGED
: 
2115             eventType 
= wxEVT_SCROLLWIN_THUMBRELEASE
; 
2118     case XmCR_PAGE_INCREMENT
: 
2120             eventType 
= wxEVT_SCROLLWIN_PAGEDOWN
; 
2123     case XmCR_PAGE_DECREMENT
: 
2125             eventType 
= wxEVT_SCROLLWIN_PAGEUP
; 
2130             eventType 
= wxEVT_SCROLLWIN_TOP
; 
2133     case XmCR_TO_BOTTOM
: 
2135             eventType 
= wxEVT_SCROLLWIN_BOTTOM
; 
2140             // Should never get here 
2141             wxFAIL_MSG("Unknown scroll event."); 
2146     wxScrollWinEvent 
event(eventType
, 
2149     event
.SetEventObject( win 
); 
2150     win
->HandleWindowEvent(event
); 
2153 // For repainting arbitrary windows 
2154 void wxUniversalRepaintProc(Widget w
, XtPointer 
WXUNUSED(c_data
), XEvent 
*event
, char *) 
2156     wxWindow
* win 
= wxGetWindowFromTable(w
); 
2160     switch ( event
->type 
) 
2164             win
->AddUpdateRect(event
->xexpose
.x
, event
->xexpose
.y
, 
2165                                event
->xexpose
.width
, event
->xexpose
.height
); 
2167             if ( event
->xexpose
.count 
== 0 ) 
2177 // ---------------------------------------------------------------------------- 
2178 // TranslateXXXEvent() functions 
2179 // ---------------------------------------------------------------------------- 
2181 bool wxTranslateMouseEvent(wxMouseEvent
& wxevent
, wxWindow 
*win
, 
2182                            Widget widget
, const XEvent 
*xevent
) 
2184     switch (xevent
->xany
.type
) 
2189             fprintf(stderr
, "Widget 0x%p <-> window %p (%s), %s\n", 
2190                     (WXWidget
)widget
, win
, win
->GetClassInfo()->GetClassName(), 
2191                     (xevent
->xany
.type 
== EnterNotify 
? "ENTER" : "LEAVE")); 
2197             int eventx 
= xevent
->xbutton
.x
, eventy 
= xevent
->xbutton
.y
; 
2199             wxEventType eventType 
= wxEVT_NULL
; 
2201             if (xevent
->xany
.type 
== LeaveNotify
) 
2203                 eventType 
= wxEVT_LEAVE_WINDOW
; 
2205             if (xevent
->xany
.type 
== EnterNotify
) 
2207                 eventType 
= wxEVT_ENTER_WINDOW
; 
2209             else if (xevent
->xany
.type 
== MotionNotify
) 
2211                 eventType 
= wxEVT_MOTION
; 
2213                 if (xevent
->xmotion
.is_hint 
== NotifyHint
) 
2218                     Display 
*dpy 
= XtDisplay (widget
); 
2220                     XQueryPointer (dpy
, XtWindow (widget
), 
2222                         &x_root
, &y_root
, &eventx
, &eventy
, &state
); 
2225             else if (xevent
->xany
.type 
== ButtonPress
) 
2227                 wxevent
.SetTimestamp(xevent
->xbutton
.time
); 
2229                 if (xevent
->xbutton
.button 
== Button1
) 
2231                     eventType 
= wxEVT_LEFT_DOWN
; 
2234                 else if (xevent
->xbutton
.button 
== Button2
) 
2236                     eventType 
= wxEVT_MIDDLE_DOWN
; 
2239                 else if (xevent
->xbutton
.button 
== Button3
) 
2241                     eventType 
= wxEVT_RIGHT_DOWN
; 
2245                 // check for a double click 
2247                 long dclickTime 
= XtGetMultiClickTime(xevent
->xany
.display
); 
2248                 long ts 
= wxevent
.GetTimestamp(); 
2250                 int buttonLast 
= win
->GetLastClickedButton(); 
2251                 long lastTS 
= win
->GetLastClickTime(); 
2252                 if ( buttonLast 
&& buttonLast 
== button 
&& 
2253                      (ts 
- lastTS
) < dclickTime 
) 
2256                     win
->SetLastClick(0, ts
); 
2257                     if ( eventType 
== wxEVT_LEFT_DOWN 
) 
2258                         eventType 
= wxEVT_LEFT_DCLICK
; 
2259                     else if ( eventType 
== wxEVT_MIDDLE_DOWN 
) 
2260                         eventType 
= wxEVT_MIDDLE_DCLICK
; 
2261                     else if ( eventType 
== wxEVT_RIGHT_DOWN 
) 
2262                         eventType 
= wxEVT_RIGHT_DCLICK
; 
2266                     // not fast enough or different button 
2267                     win
->SetLastClick(button
, ts
); 
2270             else if (xevent
->xany
.type 
== ButtonRelease
) 
2272                 if (xevent
->xbutton
.button 
== Button1
) 
2274                     eventType 
= wxEVT_LEFT_UP
; 
2276                 else if (xevent
->xbutton
.button 
== Button2
) 
2278                     eventType 
= wxEVT_MIDDLE_UP
; 
2280                 else if (xevent
->xbutton
.button 
== Button3
) 
2282                     eventType 
= wxEVT_RIGHT_UP
; 
2292             wxevent
.SetEventType(eventType
); 
2295             XtVaGetValues(widget
, XmNx
, &x1
, XmNy
, &y1
, NULL
); 
2298             win
->GetPosition(&x2
, &y2
); 
2300             // The button x/y must be translated to wxWidgets 
2301             // window space - the widget might be a label or button, 
2305             if (widget 
!= (Widget
)win
->GetMainWidget()) 
2311             wxevent
.m_x 
= eventx 
+ dx
; 
2312             wxevent
.m_y 
= eventy 
+ dy
; 
2314             wxevent
.m_leftDown 
= ((eventType 
== wxEVT_LEFT_DOWN
) 
2315                 || (event_left_is_down (xevent
) 
2316                 && (eventType 
!= wxEVT_LEFT_UP
))); 
2317             wxevent
.m_middleDown 
= ((eventType 
== wxEVT_MIDDLE_DOWN
) 
2318                 || (event_middle_is_down (xevent
) 
2319                 && (eventType 
!= wxEVT_MIDDLE_UP
))); 
2320             wxevent
.m_rightDown 
= ((eventType 
== wxEVT_RIGHT_DOWN
) 
2321                 || (event_right_is_down (xevent
) 
2322                 && (eventType 
!= wxEVT_RIGHT_UP
))); 
2324             wxevent
.m_shiftDown 
= (xevent
->xbutton
.state 
& ShiftMask
) == ShiftMask
; 
2325             wxevent
.m_controlDown 
= (xevent
->xbutton
.state 
& ControlMask
) == ControlMask
; 
2326             wxevent
.m_altDown 
= (xevent
->xbutton
.state 
& Mod3Mask
) == Mod3Mask
; 
2327             wxevent
.m_metaDown 
= (xevent
->xbutton
.state 
& Mod1Mask
) == Mod1Mask
; 
2329             wxevent
.SetId(win
->GetId()); 
2330             wxevent
.SetEventObject(win
); 
2338 bool wxTranslateKeyEvent(wxKeyEvent
& wxevent
, wxWindow 
*win
, 
2339                          Widget 
WXUNUSED(widget
), const XEvent 
*xevent
) 
2341     switch (xevent
->xany
.type
) 
2349             (void) XLookupString((XKeyEvent 
*)xevent
, buf
, 20, &keySym
, NULL
); 
2350             int id 
= wxCharCodeXToWX (keySym
); 
2351             // id may be WXK_xxx code - these are outside ASCII range, so we 
2352             // can't just use toupper() on id 
2353             if (id 
>= 'a' && id 
<= 'z') 
2356             if (xevent
->xkey
.state 
& ShiftMask
) 
2357                 wxevent
.m_shiftDown 
= true; 
2358             if (xevent
->xkey
.state 
& ControlMask
) 
2359                 wxevent
.m_controlDown 
= true; 
2360             if (xevent
->xkey
.state 
& Mod3Mask
) 
2361                 wxevent
.m_altDown 
= true; 
2362             if (xevent
->xkey
.state 
& Mod1Mask
) 
2363                 wxevent
.m_metaDown 
= true; 
2364             wxevent
.SetEventObject(win
); 
2365             wxevent
.m_keyCode 
= id
; 
2366             wxevent
.SetTimestamp(xevent
->xkey
.time
); 
2368             wxevent
.m_x 
= xevent
->xbutton
.x
; 
2369             wxevent
.m_y 
= xevent
->xbutton
.y
; 
2382 // ---------------------------------------------------------------------------- 
2384 // ---------------------------------------------------------------------------- 
2386 #define YAllocColor XAllocColor 
2387 XColor g_itemColors
[5]; 
2388 int wxComputeColours (Display 
*display
, const wxColour 
* back
, const wxColour 
* fore
) 
2391     static XmColorProc colorProc
; 
2393     result 
= wxNO_COLORS
; 
2397         g_itemColors
[0].red 
= (unsigned short)(((long) back
->Red ()) << 8); 
2398         g_itemColors
[0].green 
= (unsigned short)(((long) back
->Green ()) << 8); 
2399         g_itemColors
[0].blue 
= (unsigned short)(((long) back
->Blue ()) << 8); 
2400         g_itemColors
[0].flags 
= DoRed 
| DoGreen 
| DoBlue
; 
2401         if (colorProc 
== (XmColorProc
) NULL
) 
2403             // Get a ptr to the actual function 
2404             colorProc 
= XmSetColorCalculation ((XmColorProc
) NULL
); 
2405             // And set it back to motif. 
2406             XmSetColorCalculation (colorProc
); 
2408         (*colorProc
) (&g_itemColors
[wxBACK_INDEX
], 
2409             &g_itemColors
[wxFORE_INDEX
], 
2410             &g_itemColors
[wxSELE_INDEX
], 
2411             &g_itemColors
[wxTOPS_INDEX
], 
2412             &g_itemColors
[wxBOTS_INDEX
]); 
2413         result 
= wxBACK_COLORS
; 
2417         g_itemColors
[wxFORE_INDEX
].red 
= (unsigned short)(((long) fore
->Red ()) << 8); 
2418         g_itemColors
[wxFORE_INDEX
].green 
= (unsigned short)(((long) fore
->Green ()) << 8); 
2419         g_itemColors
[wxFORE_INDEX
].blue 
= (unsigned short)(((long) fore
->Blue ()) << 8); 
2420         g_itemColors
[wxFORE_INDEX
].flags 
= DoRed 
| DoGreen 
| DoBlue
; 
2421         if (result 
== wxNO_COLORS
) 
2422             result 
= wxFORE_COLORS
; 
2425     Display 
*dpy 
= display
; 
2426     Colormap cmap 
= (Colormap
) wxTheApp
->GetMainColormap((WXDisplay
*) dpy
); 
2430         /* 5 Colours to allocate */ 
2431         for (int i 
= 0; i 
< 5; i
++) 
2432             if (!YAllocColor (dpy
, cmap
, &g_itemColors
[i
])) 
2433                 result 
= wxNO_COLORS
; 
2437         /* Only 1 colour to allocate */ 
2438         if (!YAllocColor (dpy
, cmap
, &g_itemColors
[wxFORE_INDEX
])) 
2439             result 
= wxNO_COLORS
; 
2445 // Changes the foreground and background colours to be derived from the current 
2446 // background colour. To change the foreground colour, you must call 
2447 // SetForegroundColour explicitly. 
2448 void wxWindow::ChangeBackgroundColour() 
2450     WXWidget mainWidget 
= GetMainWidget(); 
2452         wxDoChangeBackgroundColour(mainWidget
, m_backgroundColour
); 
2453     if ( m_scrolledWindow 
&& mainWidget 
!= m_scrolledWindow 
) 
2454         wxDoChangeForegroundColour(m_scrolledWindow
, m_backgroundColour
); 
2457 void wxWindow::ChangeForegroundColour() 
2459     WXWidget mainWidget 
= GetMainWidget(); 
2461         wxDoChangeForegroundColour(mainWidget
, m_foregroundColour
); 
2462     if ( m_scrolledWindow 
&& mainWidget 
!= m_scrolledWindow 
) 
2463         wxDoChangeForegroundColour(m_scrolledWindow
, m_foregroundColour
); 
2466 bool wxWindow::SetBackgroundColour(const wxColour
& col
) 
2468     if ( !wxWindowBase::SetBackgroundColour(col
) ) 
2471     ChangeBackgroundColour(); 
2476 bool wxWindow::SetForegroundColour(const wxColour
& col
) 
2478     if ( !wxWindowBase::SetForegroundColour(col
) ) 
2481     ChangeForegroundColour(); 
2486 void wxWindow::ChangeFont(bool keepOriginalSize
) 
2488     // Note that this causes the widget to be resized back 
2489     // to its original size! We therefore have to set the size 
2490     // back again. TODO: a better way in Motif? 
2491     Widget w 
= (Widget
) GetLabelWidget(); // Usually the main widget 
2492     if (w 
&& m_font
.IsOk()) 
2494         int width
, height
, width1
, height1
; 
2495         GetSize(& width
, & height
); 
2497         wxDoChangeFont( w
, m_font 
); 
2499         GetSize(& width1
, & height1
); 
2500         if (keepOriginalSize 
&& (width 
!= width1 
|| height 
!= height1
)) 
2502             SetSize(wxDefaultCoord
, wxDefaultCoord
, width
, height
); 
2508 void wxWindow::PostCreation() 
2511     ChangeForegroundColour(); 
2512     ChangeBackgroundColour(); 
2516 void wxWindow::PreCreation() 
2518     InheritAttributes(); 
2521 // ---------------------------------------------------------------------------- 
2523 // ---------------------------------------------------------------------------- 
2525 wxWindow 
*wxGetActiveWindow() 
2528     wxFAIL_MSG("Not implemented"); 
2533 wxWindow 
*wxWindowBase::GetCapture() 
2535     return (wxWindow 
*)g_captureWindow
; 
2539 // Find the wxWindow at the current mouse position, returning the mouse 
2541 wxWindow
* wxFindWindowAtPointer(wxPoint
& pt
) 
2543     pt 
= wxGetMousePosition(); 
2544     return wxFindWindowAtPoint(pt
); 
2547 void wxGetMouseState(int& rootX
, int& rootY
, unsigned& maskReturn
) 
2549     Display 
*display 
= wxGlobalDisplay(); 
2550     Window rootWindow 
= RootWindowOfScreen (DefaultScreenOfDisplay(display
)); 
2551     Window rootReturn
, childReturn
; 
2554     XQueryPointer (display
, 
2558                    &rootX
, &rootY
, &winX
, &winY
, &maskReturn
); 
2561 // Get the current mouse position. 
2562 wxPoint 
wxGetMousePosition() 
2567     wxGetMouseState(x
, y
, mask
); 
2568     return wxPoint(x
, y
); 
2571 wxMouseState 
wxGetMouseState() 
2577     wxGetMouseState(x
, y
, mask
); 
2582     ms
.SetLeftDown(mask 
& Button1Mask
); 
2583     ms
.SetMiddleDown(mask 
& Button2Mask
); 
2584     ms
.SetRightDown(mask 
& Button3Mask
); 
2586     ms
.SetControlDown(mask 
& ControlMask
); 
2587     ms
.SetShiftDown(mask 
& ShiftMask
); 
2588     ms
.SetAltDown(mask 
& Mod3Mask
); 
2589     ms
.SetMetaDown(mask 
& Mod1Mask
); 
2595 #if wxMOTIF_NEW_FONT_HANDLING 
2599 void wxGetTextExtent(const wxWindow
* window
, const wxString
& str
, 
2600                      int* width
, int* height
, int* ascent
, int* descent
) 
2604     XmRendition rendition 
= NULL
; 
2605     XmRenderTable table 
= NULL
; 
2606     Widget w 
= (Widget
) window
->GetLabelWidget(); 
2608     XtVaGetValues( w
, XmNrenderTable
, &table
, NULL 
); 
2610         table 
= XmeGetDefaultRenderTable(w
, XmTEXT_RENDER_TABLE
); 
2612     rendition 
= XmRenderTableGetRendition( table
, "" ); 
2613     XtSetArg( args
[count
], XmNfont
, 0 ); ++count
; 
2614     XtSetArg( args
[count
], XmNfontType
, 0 ); ++count
; 
2615     XmRenditionRetrieve( rendition
, args
, count 
); 
2617     if (args
[1].value 
== XmFONT_IS_FONTSET
) 
2619         XRectangle ink
, logical
; 
2620         WXFontSet fset 
= (WXFontSet
) args
[0].value
; 
2622         XmbTextExtents( (XFontSet
)fset
, str
.c_str(), str
.length(), 
2625         if( width 
) *width 
= logical
.width
; 
2626         if( height 
) *height 
= logical
.height
; 
2627         if( ascent 
) *ascent 
= -logical
.y
; 
2628         if( descent 
) *descent 
= logical
.height 
+ logical
.y
; 
2632         int direction
, ascent2
, descent2
; 
2633         XCharStruct overall
; 
2634         XFontStruct
* fontStruct
; 
2636         XmeRenderTableGetDefaultFont( table
, &fontStruct 
); 
2637         XTextExtents(fontStruct
, (const char*)str
.c_str(), str
.length(), 
2638                      &direction
, &ascent2
, &descent2
, &overall
); 
2640         if ( width 
) *width 
= overall
.width
; 
2641         if ( height 
) *height 
= ascent2 
+ descent2
; 
2642         if ( descent 
) *descent 
= descent2
; 
2643         if ( ascent 
) *ascent 
= ascent2
; 
2647 #else // if !wxMOTIF_NEW_FONT_HANDLING 
2649 void wxGetTextExtent(const wxWindow
* window
, const wxString
& str
, 
2650                      int* width
, int* height
, int* ascent
, int* descent
) 
2652     XmFontList list 
= NULL
; 
2655     Widget w 
= (Widget
) window
->GetLabelWidget(); 
2657     XtVaGetValues( w
, XmNfontList
, &list
, NULL 
); 
2658     XmFontListInitFontContext( &cxt
, list 
); 
2660     XmFontListEntry entry 
= XmFontListNextEntry( cxt 
); 
2661     XmFontListFreeFontContext( cxt 
); 
2662     XtPointer thing 
= XmFontListEntryGetFont( entry
, &type 
); 
2664     if (type 
== XmFONT_IS_FONTSET
) 
2666         XRectangle ink
, logical
; 
2668         XmbTextExtents( (XFontSet
)thing
, str
.c_str(), str
.length(), 
2671         if( width 
) *width 
= logical
.width
; 
2672         if( height 
) *height 
= logical
.height
; 
2673         if( ascent 
) *ascent 
= -logical
.y
; 
2674         if( descent 
) *descent 
= logical
.height 
+ logical
.y
; 
2678         int direction
, ascent2
, descent2
; 
2679         XCharStruct overall
; 
2681         XTextExtents( (XFontStruct
*)thing
, (char*)(const char*)str
.c_str(), str
.length(), 
2682                      &direction
, &ascent2
, &descent2
, &overall
); 
2684         if ( width 
) *width 
= overall
.width
; 
2685         if ( height 
) *height 
= ascent2 
+ descent2
; 
2686         if ( descent 
) *descent 
= descent2
; 
2687         if ( ascent 
) *ascent 
= ascent2
; 
2691 #endif // !wxMOTIF_NEW_FONT_HANDLING 
2693 // ---------------------------------------------------------------------------- 
2694 // wxNoOptimize: switch off size optimization 
2695 // ---------------------------------------------------------------------------- 
2697 int wxNoOptimize::ms_count 
= 0;