1 ///////////////////////////////////////////////////////////////////////////// 
   4 // Author:      Julian Smart 
   8 // Copyright:   (c) Julian Smart 
   9 // Licence:     wxWindows licence 
  10 ///////////////////////////////////////////////////////////////////////////// 
  12 // ============================================================================ 
  14 // ============================================================================ 
  16 // ---------------------------------------------------------------------------- 
  18 // ---------------------------------------------------------------------------- 
  21     #pragma implementation "window.h" 
  27 #include "wx/dcclient.h" 
  31 #include "wx/layout.h" 
  32 #include "wx/dialog.h" 
  33 #include "wx/listbox.h" 
  34 #include "wx/button.h" 
  35 #include "wx/settings.h" 
  36 #include "wx/msgdlg.h" 
  38 #include "wx/scrolwin.h" 
  39 #include "wx/module.h" 
  40 #include "wx/menuitem.h" 
  43 #include "wx/listimpl.cpp" 
  45 #if  wxUSE_DRAG_AND_DROP 
  51 #include <Xm/DrawingA.h> 
  52 #include <Xm/ScrolledW.h> 
  53 #include <Xm/ScrollBar.h> 
  56 #include <Xm/RowColumn.h>           // for XmMenuPosition 
  58 #include "wx/motif/private.h" 
  62 // ---------------------------------------------------------------------------- 
  64 // ---------------------------------------------------------------------------- 
  66 static const int SCROLL_MARGIN 
= 4; 
  68 // ---------------------------------------------------------------------------- 
  69 // global variables for this module 
  70 // ---------------------------------------------------------------------------- 
  72 extern wxHashTable 
*wxWidgetHashTable
; 
  74 // ---------------------------------------------------------------------------- 
  76 // ---------------------------------------------------------------------------- 
  78 static void wxCanvasRepaintProc(Widget
, XtPointer
, XmDrawingAreaCallbackStruct 
* cbs
); 
  79 static void wxCanvasInputEvent(Widget drawingArea
, XtPointer data
, XmDrawingAreaCallbackStruct 
* cbs
); 
  80 static void wxCanvasMotionEvent(Widget
, XButtonEvent 
* event
); 
  81 static void wxCanvasEnterLeave(Widget drawingArea
, XtPointer clientData
, XCrossingEvent 
* event
); 
  82 static void wxScrollBarCallback(Widget widget
, XtPointer clientData
, 
  83                                 XmScrollBarCallbackStruct 
*cbs
); 
  84 static void wxPanelItemEventHandler(Widget    wid
, 
  85                                     XtPointer client_data
, 
  87                                     Boolean  
*continueToDispatch
); 
  92 // Helper function for 16-bit fonts 
  93 static int str16len(const char *s
) 
  97     while (s
[0] && s
[1]) { 
 107 // ---------------------------------------------------------------------------- 
 109 // ---------------------------------------------------------------------------- 
 111 #define event_left_is_down(x) ((x)->xbutton.state & Button1Mask) 
 112 #define event_middle_is_down(x) ((x)->xbutton.state & Button2Mask) 
 113 #define event_right_is_down(x) ((x)->xbutton.state & Button3Mask) 
 115 // ---------------------------------------------------------------------------- 
 117 // ---------------------------------------------------------------------------- 
 119 #if !USE_SHARED_LIBRARY 
 120     IMPLEMENT_DYNAMIC_CLASS(wxWindow
, wxWindowBase
) 
 122     BEGIN_EVENT_TABLE(wxWindow
, wxWindowBase
) 
 123         EVT_SYS_COLOUR_CHANGED(wxWindow::OnSysColourChanged
) 
 124         EVT_IDLE(wxWindow::OnIdle
) 
 126 #endif // USE_SHARED_LIBRARY 
 128 // ============================================================================ 
 130 // ============================================================================ 
 132 // ---------------------------------------------------------------------------- 
 134 // ---------------------------------------------------------------------------- 
 136 WX_DEFINE_LIST(wxRectList
); 
 138 // ---------------------------------------------------------------------------- 
 140 // ---------------------------------------------------------------------------- 
 142 void wxWindow::UnmanageAndDestroy(WXWidget widget
) 
 144     Widget w 
= (Widget
)widget
; 
 152 bool wxWindow::MapOrUnmap(WXWidget widget
, bool map
) 
 154     Widget w 
= (Widget
)widget
; 
 166 // ---------------------------------------------------------------------------- 
 168 // ---------------------------------------------------------------------------- 
 170 void wxWindow::Init() 
 172     // generic initializations first 
 176     m_needsRefresh 
= TRUE
; 
 177     m_mainWidget 
= (WXWidget
) 0; 
 181     m_button3Pressed 
= FALSE
; 
 183     m_winCaptured 
= FALSE
; 
 186     m_isBeingDeleted 
= FALSE
; 
 192     m_drawingArea 
= (WXWidget
) 0; 
 200     m_backingPixmap 
= (WXPixmap
) 0; 
 209     m_canAddEventHandler 
= FALSE
; 
 212 // real construction (Init() must have been called before!) 
 213 bool wxWindow::Create(wxWindow 
*parent
, wxWindowID id
, 
 217                       const wxString
& name
) 
 219     wxCHECK_MSG( parent
, FALSE
, "can't create wxWindow without parent" ); 
 221     CreateBase(parent
, id
, pos
, size
, style
, wxDefaultValidator
, name
); 
 223     parent
->AddChild(this); 
 225     m_backgroundColour 
= wxSystemSettings::GetSystemColour(wxSYS_COLOUR_3DFACE
); 
 226     m_foregroundColour 
= *wxBLACK
; 
 228     //// TODO: we should probably optimize by only creating a 
 229     //// a drawing area if we have one or more scrollbars (wxVSCROLL/wxHSCROLL). 
 230     //// But for now, let's simplify things by always creating the 
 231     //// drawing area, since otherwise the translations are different. 
 233     // New translations for getting mouse motion feedback 
 234     static const String translations 
= 
 235 "<Btn1Motion>: wxCanvasMotionEvent() DrawingAreaInput() ManagerGadgetButtonMotion()\n\ 
 236 <Btn2Motion>: wxCanvasMotionEvent() DrawingAreaInput() ManagerGadgetButtonMotion()\n\ 
 237 <Btn3Motion>: wxCanvasMotionEvent() DrawingAreaInput() ManagerGadgetButtonMotion()\n\ 
 238 <BtnMotion>: wxCanvasMotionEvent() DrawingAreaInput() ManagerGadgetButtonMotion()\n\ 
 239 <Btn1Down>: DrawingAreaInput() ManagerGadgetArm()\n\ 
 240 <Btn2Down>: DrawingAreaInput() ManagerGadgetArm()\n\ 
 241 <Btn3Down>: DrawingAreaInput() ManagerGadgetArm()\n\ 
 242 <Btn1Up>: DrawingAreaInput() ManagerGadgetActivate()\n\ 
 243 <Btn2Up>: DrawingAreaInput() ManagerGadgetActivate()\n\ 
 244 <Btn3Up>: DrawingAreaInput() ManagerGadgetActivate()\n\ 
 245 <Motion>: wxCanvasMotionEvent() DrawingAreaInput()\n\ 
 246 <EnterWindow>: wxCanvasMotionEvent() DrawingAreaInput()\n\ 
 247 <LeaveWindow>: wxCanvasMotionEvent() DrawingAreaInput()\n\ 
 248 <Key>: DrawingAreaInput()"; 
 250     XtActionsRec actions
[1]; 
 251     actions
[0].string 
= "wxCanvasMotionEvent"; 
 252     actions
[0].proc 
= (XtActionProc
) wxCanvasMotionEvent
; 
 253     XtAppAddActions ((XtAppContext
) wxTheApp
->GetAppContext(), actions
, 1); 
 255     Widget parentWidget 
= (Widget
) parent
->GetClientWidget(); 
 256     if (style 
& wxBORDER
) 
 258         m_borderWidget 
= (WXWidget
)XtVaCreateManagedWidget
 
 261                                     xmFrameWidgetClass
, parentWidget
, 
 262                                     XmNshadowType
, XmSHADOW_IN
, 
 267     m_scrolledWindow 
= (WXWidget
)XtVaCreateManagedWidget
 
 270                                   xmScrolledWindowWidgetClass
, 
 271                                   m_borderWidget 
? (Widget
) m_borderWidget
 
 273                                   XmNresizePolicy
, XmRESIZE_NONE
, 
 275                                   XmNscrollingPolicy
, XmAPPLICATION_DEFINED
, 
 276                                   //XmNscrollBarDisplayPolicy, XmAS_NEEDED, 
 280     XtTranslations ptr 
= XtParseTranslationTable(translations
); 
 281     m_drawingArea 
= (WXWidget
)XtVaCreateWidget
 
 284                                xmDrawingAreaWidgetClass
, (Widget
) m_scrolledWindow
, 
 285                                XmNunitType
, XmPIXELS
, 
 286                                // XmNresizePolicy, XmRESIZE_ANY, 
 287                                XmNresizePolicy
, XmRESIZE_NONE
, 
 290                                XmNtranslations
, ptr
, 
 293     XtFree((char *) ptr
); 
 296     if (GetWindowStyleFlag() & wxOVERRIDE_KEY_TRANSLATIONS
) 
 298         ptr 
= XtParseTranslationTable ("<Key>: DrawingAreaInput()"); 
 299         XtOverrideTranslations ((Widget
) m_drawingArea
, ptr
); 
 300         XtFree ((char *) ptr
); 
 304     wxAddWindowToTable((Widget
) m_drawingArea
, this); 
 305     wxAddWindowToTable((Widget
) m_scrolledWindow
, this); 
 307     // This order is very important in Motif 1.2.1 
 308     XtRealizeWidget ((Widget
) m_scrolledWindow
); 
 309     XtRealizeWidget ((Widget
) m_drawingArea
); 
 310     XtManageChild ((Widget
) m_drawingArea
); 
 312     ptr 
= XtParseTranslationTable("<Configure>: resize()"); 
 313     XtOverrideTranslations((Widget
) m_drawingArea
, ptr
); 
 314     XtFree ((char *) ptr
); 
 316     XtAddCallback ((Widget
) m_drawingArea
, XmNexposeCallback
, (XtCallbackProc
) wxCanvasRepaintProc
, (XtPointer
) this); 
 317     XtAddCallback ((Widget
) m_drawingArea
, XmNinputCallback
, (XtCallbackProc
) wxCanvasInputEvent
, (XtPointer
) this); 
 321     display 
= XtDisplay (scrolledWindow
); 
 322     xwindow 
= XtWindow (drawingArea
); 
 326                       (Widget
)m_drawingArea
, 
 327                        PointerMotionHintMask 
| EnterWindowMask 
| 
 328                        LeaveWindowMask 
| FocusChangeMask
, 
 330                        (XtEventHandler
) wxCanvasEnterLeave
, 
 334     // Scrolled widget needs to have its colour changed or we get a little blue 
 335     // square where the scrollbars abutt 
 336     wxColour backgroundColour 
= wxSystemSettings::GetSystemColour(wxSYS_COLOUR_3DFACE
); 
 337     DoChangeBackgroundColour(m_scrolledWindow
, backgroundColour
, TRUE
); 
 338     DoChangeBackgroundColour(m_drawingArea
, backgroundColour
, TRUE
); 
 340     XmScrolledWindowSetAreas( 
 341                              (Widget
)m_scrolledWindow
, 
 342                              (Widget
) 0, (Widget
) 0, 
 343                              (Widget
) m_drawingArea
); 
 347         XtRealizeWidget ((Widget
) m_hScrollBar
); 
 349         XtRealizeWidget ((Widget
) m_vScrollBar
); 
 352     // Without this, the cursor may not be restored properly (e.g. in splitter 
 354     SetCursor(*wxSTANDARD_CURSOR
); 
 355     SetFont(wxSystemSettings::GetSystemFont(wxSYS_DEFAULT_GUI_FONT
)); 
 356     SetSize(pos
.x
, pos
.y
, size
.x
, size
.y
); 
 362 wxWindow::~wxWindow() 
 364     m_isBeingDeleted 
= TRUE
; 
 366     // Motif-specific actions first 
 367     WXWidget wMain 
= GetMainWidget(); 
 370         // Removes event handlers 
 377         m_parent
->RemoveChild( this ); 
 379     // If m_drawingArea, we're a fully-fledged window with drawing area, 
 380     // scrollbars etc. (what wxCanvas used to be) 
 383         // Destroy children before destroying self 
 387             XFreePixmap (XtDisplay ((Widget
) GetMainWidget()), (Pixmap
) m_backingPixmap
); 
 389         Widget w 
= (Widget
) m_drawingArea
; 
 390         wxDeleteWindowFromTable(w
); 
 397         m_mainWidget 
= (WXWidget
) 0; 
 399         // Only if we're _really_ a canvas (not a dialog box/panel) 
 400         if (m_scrolledWindow
) 
 402             wxDeleteWindowFromTable((Widget
) m_scrolledWindow
); 
 407             wxDeleteWindowFromTable((Widget
) m_hScrollBar
); 
 411             wxDeleteWindowFromTable((Widget
) m_vScrollBar
); 
 414         UnmanageAndDestroy(m_hScrollBar
); 
 415         UnmanageAndDestroy(m_vScrollBar
); 
 416         UnmanageAndDestroy(m_scrolledWindow
); 
 420             XtDestroyWidget ((Widget
) m_borderWidget
); 
 421             m_borderWidget 
= (WXWidget
) 0; 
 425     // Destroy the window 
 428         // If this line (XtDestroyWidget) causes a crash, you may comment it out. 
 429         // Child widgets will get destroyed automatically when a frame 
 430         // or dialog is destroyed, but before that you may get some memory 
 431         // leaks and potential layout problems if you delete and then add 
 433         XtDestroyWidget((Widget
) GetMainWidget()); 
 434         SetMainWidget((WXWidget
) NULL
); 
 438 // ---------------------------------------------------------------------------- 
 439 // scrollbar management 
 440 // ---------------------------------------------------------------------------- 
 443 void wxWindow::CreateScrollbar(wxOrientation orientation
) 
 445     wxCHECK_RET( m_drawingArea
, "this window can't have scrollbars" ); 
 447     XtVaSetValues((Widget
) m_scrolledWindow
, XmNresizePolicy
, XmRESIZE_NONE
, NULL
); 
 449     // Add scrollbars if required 
 450     if (orientation 
== wxHORIZONTAL
) 
 452         Widget hScrollBar 
= XtVaCreateManagedWidget ("hsb", 
 453             xmScrollBarWidgetClass
, (Widget
) m_scrolledWindow
, 
 454             XmNorientation
, XmHORIZONTAL
, 
 456         //      XtAddCallback (hScrollBar, XmNvalueChangedCallback, (XtCallbackProc) wxScrollBarCallback, (XtPointer) XmHORIZONTAL); 
 457         XtAddCallback (hScrollBar
, XmNdragCallback
, (XtCallbackProc
) wxScrollBarCallback
, (XtPointer
) XmHORIZONTAL
); 
 458         XtAddCallback (hScrollBar
, XmNincrementCallback
, (XtCallbackProc
) wxScrollBarCallback
, (XtPointer
) XmHORIZONTAL
); 
 459         XtAddCallback (hScrollBar
, XmNdecrementCallback
, (XtCallbackProc
) wxScrollBarCallback
, (XtPointer
) XmHORIZONTAL
); 
 460         XtAddCallback (hScrollBar
, XmNpageIncrementCallback
, (XtCallbackProc
) wxScrollBarCallback
, (XtPointer
) XmHORIZONTAL
); 
 461         XtAddCallback (hScrollBar
, XmNpageDecrementCallback
, (XtCallbackProc
) wxScrollBarCallback
, (XtPointer
) XmHORIZONTAL
); 
 462         XtAddCallback (hScrollBar
, XmNtoTopCallback
, (XtCallbackProc
) wxScrollBarCallback
, (XtPointer
) XmHORIZONTAL
); 
 463         XtAddCallback (hScrollBar
, XmNtoBottomCallback
, (XtCallbackProc
) wxScrollBarCallback
, (XtPointer
) XmHORIZONTAL
); 
 465         XtVaSetValues (hScrollBar
, 
 470         m_hScrollBar 
= (WXWidget
) hScrollBar
; 
 472         wxColour backgroundColour 
= wxSystemSettings::GetSystemColour(wxSYS_COLOUR_3DFACE
); 
 473         DoChangeBackgroundColour(m_hScrollBar
, backgroundColour
, TRUE
); 
 475         XtRealizeWidget(hScrollBar
); 
 477         XtVaSetValues((Widget
) m_scrolledWindow
, 
 478             XmNhorizontalScrollBar
, (Widget
) m_hScrollBar
, 
 483         wxAddWindowToTable( hScrollBar
, this ); 
 486     if (orientation 
== wxVERTICAL
) 
 488         Widget vScrollBar 
= XtVaCreateManagedWidget ("vsb", 
 489             xmScrollBarWidgetClass
, (Widget
) m_scrolledWindow
, 
 490             XmNorientation
, XmVERTICAL
, 
 492         //      XtAddCallback (vScrollBar, XmNvalueChangedCallback, (XtCallbackProc) wxScrollBarCallback, (XtPointer) XmVERTICAL); 
 493         XtAddCallback (vScrollBar
, XmNdragCallback
, (XtCallbackProc
) wxScrollBarCallback
, (XtPointer
) XmVERTICAL
); 
 494         XtAddCallback (vScrollBar
, XmNincrementCallback
, (XtCallbackProc
) wxScrollBarCallback
, (XtPointer
) XmVERTICAL
); 
 495         XtAddCallback (vScrollBar
, XmNdecrementCallback
, (XtCallbackProc
) wxScrollBarCallback
, (XtPointer
) XmVERTICAL
); 
 496         XtAddCallback (vScrollBar
, XmNpageIncrementCallback
, (XtCallbackProc
) wxScrollBarCallback
, (XtPointer
) XmVERTICAL
); 
 497         XtAddCallback (vScrollBar
, XmNpageDecrementCallback
, (XtCallbackProc
) wxScrollBarCallback
, (XtPointer
) XmVERTICAL
); 
 498         XtAddCallback (vScrollBar
, XmNtoTopCallback
, (XtCallbackProc
) wxScrollBarCallback
, (XtPointer
) XmVERTICAL
); 
 499         XtAddCallback (vScrollBar
, XmNtoBottomCallback
, (XtCallbackProc
) wxScrollBarCallback
, (XtPointer
) XmVERTICAL
); 
 501         XtVaSetValues (vScrollBar
, 
 506         m_vScrollBar 
= (WXWidget
) vScrollBar
; 
 507         wxColour backgroundColour 
= wxSystemSettings::GetSystemColour(wxSYS_COLOUR_3DFACE
); 
 508         DoChangeBackgroundColour(m_vScrollBar
, backgroundColour
, TRUE
); 
 510         XtRealizeWidget(vScrollBar
); 
 512         XtVaSetValues((Widget
) m_scrolledWindow
, 
 513             XmNverticalScrollBar
, (Widget
) m_vScrollBar
, 
 518         wxAddWindowToTable( vScrollBar
, this ); 
 521     XtVaSetValues((Widget
) m_scrolledWindow
, XmNresizePolicy
, XmRESIZE_ANY
, NULL
); 
 524 void wxWindow::DestroyScrollbar(wxOrientation orientation
) 
 526     wxCHECK_RET( m_drawingArea
, "this window can't have scrollbars" ); 
 528     XtVaSetValues((Widget
) m_scrolledWindow
, XmNresizePolicy
, XmRESIZE_NONE
, NULL
); 
 529     // Add scrollbars if required 
 530     if (orientation 
== wxHORIZONTAL
) 
 534             wxDeleteWindowFromTable((Widget
)m_hScrollBar
); 
 535             XtDestroyWidget((Widget
) m_hScrollBar
); 
 537         m_hScrollBar 
= (WXWidget
) 0; 
 540         XtVaSetValues((Widget
) m_scrolledWindow
, 
 541             XmNhorizontalScrollBar
, (Widget
) 0, 
 546     if (orientation 
== wxVERTICAL
) 
 550             wxDeleteWindowFromTable((Widget
)m_vScrollBar
); 
 551             XtDestroyWidget((Widget
) m_vScrollBar
); 
 553         m_vScrollBar 
= (WXWidget
) 0; 
 556         XtVaSetValues((Widget
) m_scrolledWindow
, 
 557             XmNverticalScrollBar
, (Widget
) 0, 
 561     XtVaSetValues((Widget
) m_scrolledWindow
, XmNresizePolicy
, XmRESIZE_ANY
, NULL
); 
 564 // --------------------------------------------------------------------------- 
 566 // --------------------------------------------------------------------------- 
 568 void wxWindow::SetFocus() 
 570     Widget wMain 
= (Widget
) GetMainWidget(); 
 571     XmProcessTraversal(wMain
, XmTRAVERSE_CURRENT
); 
 572     XmProcessTraversal((Widget
) GetMainWidget(), XmTRAVERSE_CURRENT
); 
 575 // Get the window with the focus 
 576 wxWindow 
*wxWindowBase::FindFocus() 
 579     // (1) Can there be multiple focussed widgets in an application? 
 580     // In which case we need to find the top-level window that's 
 582     // (2) The widget with the focus may not be in the widget table 
 583     // depending on which widgets I put in the table 
 584     wxWindow 
*winFocus 
= (wxWindow 
*)NULL
; 
 585     for ( wxWindowList::Node 
*node 
= wxTopLevelWindows
.GetFirst(); 
 587           node 
= node
->GetNext() ) 
 589         wxWindow 
*win 
= node
->GetData(); 
 591         Widget w 
= XmGetFocusWidget ((Widget
) win
->GetTopWidget()); 
 593         if (w 
!= (Widget
) NULL
) 
 595             winFocus 
= wxGetWindowFromTable(w
); 
 604 bool wxWindow::Enable(bool enable
) 
 606     if ( !wxWindowBase::Enable(enable
) ) 
 609     Widget wMain 
= (Widget
)GetMainWidget(); 
 612         XtSetSensitive(wMain
, enable
); 
 613         XmUpdateDisplay(wMain
); 
 619 bool wxWindow::Show(bool show
) 
 621     if ( !wxWindowBase::Show(show
) ) 
 624     if (m_borderWidget 
|| m_scrolledWindow
) 
 626         MapOrUnmap(m_drawingArea
, show
); 
 627         MapOrUnmap(m_borderWidget 
? m_borderWidget 
: m_scrolledWindow
, show
); 
 631         if ( !MapOrUnmap(GetTopWidget(), show
) ) 
 632             MapOrUnmap(GetMainWidget(), show
); 
 636     Window xwin 
= (Window
) GetXWindow(); 
 637     Display 
*xdisp 
= (Display
*) GetXDisplay(); 
 639         XMapWindow(xdisp
, xwin
); 
 641         XUnmapWindow(xdisp
, xwin
); 
 647 // Raise the window to the top of the Z order 
 648 void wxWindow::Raise() 
 650     Widget wTop 
= (Widget
) GetTopWidget(); 
 651     Window window 
= XtWindow(wTop
); 
 652     XRaiseWindow(XtDisplay(wTop
), window
); 
 655 // Lower the window to the bottom of the Z order 
 656 void wxWindow::Lower() 
 658     Widget wTop 
= (Widget
) GetTopWidget(); 
 659     Window window 
= XtWindow(wTop
); 
 660     XLowerWindow(XtDisplay(wTop
), window
); 
 663 void wxWindow::SetTitle(const wxString
& title
) 
 665     XtVaSetValues((Widget
)GetMainWidget(), XmNtitle
, title
.c_str(), NULL
); 
 668 wxString 
wxWindow::GetTitle() const 
 671     XtVaGetValues((Widget
)GetMainWidget(), XmNtitle
, &title
, NULL
); 
 673     return wxString(title
); 
 676 void wxWindow::CaptureMouse() 
 681     Widget wMain 
= (Widget
)GetMainWidget(); 
 683         XtAddGrab(wMain
, TRUE
, FALSE
); 
 685     m_winCaptured 
= TRUE
; 
 688 void wxWindow::ReleaseMouse() 
 690     if ( !m_winCaptured 
) 
 693     Widget wMain 
= (Widget
)GetMainWidget(); 
 697     m_winCaptured 
= FALSE
; 
 700 bool wxWindow::SetFont(const wxFont
& font
) 
 702     if ( !wxWindowBase::SetFont(font
) ) 
 713 bool wxWindow::SetCursor(const wxCursor
& cursor
) 
 715     if ( !wxWindowBase::SetCursor(cursor
) ) 
 721     wxASSERT_MSG( m_cursor
.Ok(), 
 722                   wxT("cursor must be valid after call to the base version")); 
 724     WXDisplay 
*dpy 
= GetXDisplay(); 
 725     WXCursor x_cursor 
= m_cursor
.GetXCursor(dpy
); 
 727     Widget w 
= (Widget
) GetMainWidget(); 
 728     Window win 
= XtWindow(w
); 
 729     XDefineCursor((Display
*) dpy
, win
, (Cursor
) x_cursor
); 
 734 // Coordinates relative to the window 
 735 void wxWindow::WarpPointer (int x
, int y
) 
 737     Widget wClient 
= (Widget
)GetClientWidget(); 
 739     XWarpPointer(XtDisplay(wClient
), None
, XtWindow(wClient
), 0, 0, 0, 0, x
, y
); 
 742 // --------------------------------------------------------------------------- 
 744 // --------------------------------------------------------------------------- 
 746 int wxWindow::GetScrollPos(int orient
) const 
 748     if (orient 
== wxHORIZONTAL
) 
 754     Widget scrollBar 
= (Widget
) ((orient 
== wxHORIZONTAL
) ? m_hScrollBar 
: m_vScrollBar
); 
 758         XtVaGetValues(scrollBar
, XmNvalue
, &pos
, NULL
); 
 766 // This now returns the whole range, not just the number of positions that we 
 768 int wxWindow::GetScrollRange(int orient
) const 
 770     Widget scrollBar 
= (Widget
)GetScrollbar((wxOrientation
)orient
); 
 771     wxCHECK_MSG( scrollBar
, 0, "no such scrollbar" ); 
 774     XtVaGetValues(scrollBar
, XmNmaximum
, &range
, NULL
); 
 778 int wxWindow::GetScrollThumb(int orient
) const 
 780     Widget scrollBar 
= (Widget
)GetScrollbar((wxOrientation
)orient
); 
 781     wxCHECK_MSG( scrollBar
, 0, "no such scrollbar" ); 
 784     XtVaGetValues(scrollBar
, XmNsliderSize
, &thumb
, NULL
); 
 788 void wxWindow::SetScrollPos(int orient
, int pos
, bool WXUNUSED(refresh
)) 
 790     Widget scrollBar 
= (Widget
)GetScrollbar((wxOrientation
)orient
); 
 794         XtVaSetValues (scrollBar
, XmNvalue
, pos
, NULL
); 
 797     SetInternalScrollPos((wxOrientation
)orient
, pos
); 
 800 // New function that will replace some of the above. 
 801 void wxWindow::SetScrollbar(int orient
, int pos
, int thumbVisible
, 
 802                             int range
, bool WXUNUSED(refresh
)) 
 805     GetSize(& oldW
, & oldH
); 
 809     if (thumbVisible 
== 0) 
 812     if (thumbVisible 
> range
) 
 813         thumbVisible 
= range
; 
 815     // Save the old state to see if it changed 
 816     WXWidget oldScrollBar 
= GetScrollbar((wxOrientation
)orient
); 
 818     if (orient 
== wxHORIZONTAL
) 
 820         if (thumbVisible 
== range
) 
 823                 DestroyScrollbar(wxHORIZONTAL
); 
 828                 CreateScrollbar(wxHORIZONTAL
); 
 831     if (orient 
== wxVERTICAL
) 
 833         if (thumbVisible 
== range
) 
 836                 DestroyScrollbar(wxVERTICAL
); 
 841                 CreateScrollbar(wxVERTICAL
); 
 844     WXWidget newScrollBar 
=  GetScrollbar((wxOrientation
)orient
); 
 846     if (oldScrollBar 
!= newScrollBar
) 
 848         // This is important! Without it, scrollbars misbehave badly. 
 849         XtUnrealizeWidget((Widget
) m_scrolledWindow
); 
 850         XmScrolledWindowSetAreas ((Widget
) m_scrolledWindow
, (Widget
) m_hScrollBar
, (Widget
) m_vScrollBar
, (Widget
) m_drawingArea
); 
 851         XtRealizeWidget((Widget
) m_scrolledWindow
); 
 852         XtManageChild((Widget
) m_scrolledWindow
); 
 857         XtVaSetValues((Widget
) newScrollBar
, 
 861         XmNsliderSize
, thumbVisible
, 
 865     SetInternalScrollPos((wxOrientation
)orient
, pos
); 
 868     GetSize(& newW
, & newH
); 
 870     // Adjusting scrollbars can resize the canvas accidentally 
 871     if (newW 
!= oldW 
|| newH 
!= oldH
) 
 872         SetSize(-1, -1, oldW
, oldH
); 
 875 // Does a physical scroll 
 876 void wxWindow::ScrollWindow(int dx
, int dy
, const wxRect 
*rect
) 
 881         // Use specified rectangle 
 882         x 
= rect
->x
; y 
= rect
->y
; w 
= rect
->width
; h 
= rect
->height
; 
 886         // Use whole client area 
 888         GetClientSize(& w
, & h
); 
 891     int x1 
= (dx 
>= 0) ? x 
: x 
- dx
; 
 892     int y1 
= (dy 
>= 0) ? y 
: y 
- dy
; 
 893     int w1 
= w 
- abs(dx
); 
 894     int h1 
= h 
- abs(dy
); 
 895     int x2 
= (dx 
>= 0) ? x 
+ dx 
: x
; 
 896     int y2 
= (dy 
>= 0) ? y 
+ dy 
: y
; 
 900     dc
.SetLogicalFunction (wxCOPY
); 
 902     Widget widget 
= (Widget
) GetMainWidget(); 
 903     Window window 
= XtWindow(widget
); 
 904     Display
* display 
= XtDisplay(widget
); 
 906     XCopyArea(display
, window
, window
, (GC
) dc
.GetGC(), 
 907               x1
, y1
, w1
, h1
, x2
, y2
); 
 909     dc
.SetAutoSetting(TRUE
); 
 910     wxBrush 
brush(GetBackgroundColour(), wxSOLID
); 
 911     dc
.SetBrush(brush
); // FIXME: needed? 
 913     // We'll add rectangles to the list of update rectangles according to which 
 914     // bits we've exposed. 
 919         wxRect 
*rect 
= new wxRect
; 
 925         XFillRectangle(display
, window
, 
 926             (GC
) dc
.GetGC(), rect
->x
, rect
->y
, rect
->width
, rect
->height
); 
 930         rect
->width 
= rect
->width
; 
 931         rect
->height 
= rect
->height
; 
 933         updateRects
.Append((wxObject
*) rect
); 
 937         wxRect 
*rect 
= new wxRect
; 
 939         rect
->x 
= x 
+ w 
+ dx
; 
 944         XFillRectangle(display
, window
, 
 945             (GC
) dc
.GetGC(), rect
->x
, rect
->y
, rect
->width
, 
 950         rect
->width 
= rect
->width
; 
 951         rect
->height 
= rect
->height
; 
 953         updateRects
.Append((wxObject
*) rect
); 
 957         wxRect 
*rect 
= new wxRect
; 
 964         XFillRectangle(display
, window
, 
 965             (GC
) dc
.GetGC(), rect
->x
, rect
->y
, rect
->width
, rect
->height
); 
 969         rect
->width 
= rect
->width
; 
 970         rect
->height 
= rect
->height
; 
 972         updateRects
.Append((wxObject
*) rect
); 
 976         wxRect 
*rect 
= new wxRect
; 
 979         rect
->y 
= y 
+ h 
+ dy
; 
 983         XFillRectangle(display
, window
, 
 984             (GC
) dc
.GetGC(), rect
->x
, rect
->y
, rect
->width
, rect
->height
); 
 988         rect
->width 
= rect
->width
; 
 989         rect
->height 
= rect
->height
; 
 991         updateRects
.Append((wxObject
*) rect
); 
 993     dc
.SetBrush(wxNullBrush
); 
 995     // Now send expose events 
 997     wxNode
* node 
= updateRects
.First(); 
1000         wxRect
* rect 
= (wxRect
*) node
->Data(); 
1003         event
.type 
= Expose
; 
1004         event
.display 
= display
; 
1005         event
.send_event 
= True
; 
1006         event
.window 
= window
; 
1010         event
.width 
= rect
->width
; 
1011         event
.height 
= rect
->height
; 
1015         XSendEvent(display
, window
, False
, ExposureMask
, (XEvent 
*)&event
); 
1017         node 
= node
->Next(); 
1021     // Delete the update rects 
1022     node 
= updateRects
.First(); 
1025         wxRect
* rect 
= (wxRect
*) node
->Data(); 
1027         node 
= node
->Next(); 
1030     XmUpdateDisplay((Widget
) GetMainWidget()); 
1033 // --------------------------------------------------------------------------- 
1035 // --------------------------------------------------------------------------- 
1037 #if wxUSE_DRAG_AND_DROP 
1039 void wxWindow::SetDropTarget(wxDropTarget 
* WXUNUSED(pDropTarget
)) 
1046 // Old style file-manager drag&drop 
1047 void wxWindow::DragAcceptFiles(bool WXUNUSED(accept
)) 
1052 // ---------------------------------------------------------------------------- 
1054 // ---------------------------------------------------------------------------- 
1058 void wxWindow::DoSetToolTip(wxToolTip 
* WXUNUSED(tooltip
)) 
1063 #endif // wxUSE_TOOLTIPS 
1065 // ---------------------------------------------------------------------------- 
1067 // ---------------------------------------------------------------------------- 
1069 bool wxWindow::DoPopupMenu(wxMenu 
*menu
, int x
, int y
) 
1071     Widget widget 
= (Widget
) GetMainWidget(); 
1073     /* The menuId field seems to be usused, so we'll use it to 
1074     indicate whether a menu is popped up or not: 
1075     0: Not currently created as a popup 
1076     -1: Created as a popup, but not active 
1080     if (menu
->GetParent() && (menu
->GetId() != -1)) 
1083     if (menu
->GetMainWidget()) { 
1084         menu
->DestroyMenu(TRUE
); 
1087     menu
->SetId(1); /* Mark as popped-up */ 
1088     menu
->CreateMenu(NULL
, widget
, menu
); 
1089     menu
->SetInvokingWindow(this); 
1093     //  menu->SetParent(parent); 
1094     //  parent->children->Append(menu);  // Store menu for later deletion 
1096     Widget menuWidget 
= (Widget
) menu
->GetMainWidget(); 
1104     if (this->IsKindOf(CLASSINFO(wxCanvas))) 
1106     wxCanvas *canvas = (wxCanvas *) this; 
1107     deviceX = canvas->GetDC ()->LogicalToDeviceX (x); 
1108     deviceY = canvas->GetDC ()->LogicalToDeviceY (y); 
1112     Display 
*display 
= XtDisplay (widget
); 
1113     Window rootWindow 
= RootWindowOfScreen (XtScreen((Widget
)widget
)); 
1114     Window thisWindow 
= XtWindow (widget
); 
1116     XTranslateCoordinates (display
, thisWindow
, rootWindow
, (int) deviceX
, (int) deviceY
, 
1117         &rootX
, &rootY
, &childWindow
); 
1119     XButtonPressedEvent event
; 
1120     event
.type 
= ButtonPress
; 
1126     event
.x_root 
= rootX
; 
1127     event
.y_root 
= rootY
; 
1129     XmMenuPosition (menuWidget
, &event
); 
1130     XtManageChild (menuWidget
); 
1135 // --------------------------------------------------------------------------- 
1136 // moving and resizing 
1137 // --------------------------------------------------------------------------- 
1139 bool wxWindow::PreResize() 
1145 void wxWindow::DoGetSize(int *x
, int *y
) const 
1149         CanvasGetSize(x
, y
); 
1153     Widget widget 
= (Widget
) GetTopWidget(); 
1155     XtVaGetValues(widget
, XmNwidth
, &xx
, XmNheight
, &yy
, NULL
); 
1159 void wxWindow::DoGetPosition(int *x
, int *y
) const 
1163         CanvasGetPosition(x
, y
); 
1166     Widget widget 
= (Widget
) GetTopWidget(); 
1168     XtVaGetValues(widget
, XmNx
, &xx
, XmNy
, &yy
, NULL
); 
1170     // We may be faking the client origin. So a window that's really at (0, 30) 
1171     // may appear (to wxWin apps) to be at (0, 0). 
1174         wxPoint 
pt(GetParent()->GetClientAreaOrigin()); 
1182 void wxWindow::DoScreenToClient(int *x
, int *y
) const 
1184     Widget widget 
= (Widget
) GetClientWidget(); 
1185     Display 
*display 
= XtDisplay((Widget
) GetMainWidget()); 
1186     Window rootWindow 
= RootWindowOfScreen(XtScreen(widget
)); 
1187     Window thisWindow 
= XtWindow(widget
); 
1192     XTranslateCoordinates(display
, rootWindow
, thisWindow
, xx
, yy
, x
, y
, &childWindow
); 
1195 void wxWindow::DoClientToScreen(int *x
, int *y
) const 
1197     Widget widget 
= (Widget
) GetClientWidget(); 
1198     Display 
*display 
= XtDisplay(widget
); 
1199     Window rootWindow 
= RootWindowOfScreen(XtScreen(widget
)); 
1200     Window thisWindow 
= XtWindow(widget
); 
1205     XTranslateCoordinates(display
, thisWindow
, rootWindow
, xx
, yy
, x
, y
, &childWindow
); 
1209 // Get size *available for subwindows* i.e. excluding menu bar etc. 
1210 void wxWindow::DoGetClientSize(int *x
, int *y
) const 
1212     Widget widget 
= (Widget
) GetClientWidget(); 
1214     XtVaGetValues(widget
, XmNwidth
, &xx
, XmNheight
, &yy
, NULL
); 
1218 void wxWindow::DoSetSize(int x
, int y
, int width
, int height
, int sizeFlags
) 
1220     // A bit of optimization to help sort out the flickers. 
1221     int oldX
, oldY
, oldW
, oldH
; 
1222     GetSize(& oldW
, & oldH
); 
1223     GetPosition(& oldX
, & oldY
); 
1225     bool useOldPos 
= FALSE
; 
1226     bool useOldSize 
= FALSE
; 
1228     if ((x 
== -1) && (x 
== -1) && ((sizeFlags 
& wxSIZE_ALLOW_MINUS_ONE
) == 0)) 
1230     else if (x 
== oldX 
&& y 
== oldY
) 
1233     if ((width 
== -1) && (height 
== -1)) 
1235     else if (width 
== oldW 
&& height 
== oldH
) 
1238     if (!wxNoOptimize::CanOptimize()) 
1240         useOldSize 
= FALSE
; useOldPos 
= FALSE
; 
1243     if (useOldPos 
&& useOldSize
) 
1248         CanvasSetSize(x
, y
, width
, height
, sizeFlags
); 
1251     Widget widget 
= (Widget
) GetTopWidget(); 
1255     bool managed 
= XtIsManaged( widget 
); 
1257         XtUnmanageChild(widget
); 
1259     int xx 
= x
; int yy 
= y
; 
1260     AdjustForParentClientOrigin(xx
, yy
, sizeFlags
); 
1264         if (x 
> -1 || (sizeFlags 
& wxSIZE_ALLOW_MINUS_ONE
)) 
1265             XtVaSetValues(widget
, XmNx
, xx
, NULL
); 
1266         if (y 
> -1 || (sizeFlags 
& wxSIZE_ALLOW_MINUS_ONE
)) 
1267             XtVaSetValues(widget
, XmNy
, yy
, NULL
); 
1272             XtVaSetValues(widget
, XmNwidth
, width
, NULL
); 
1274             XtVaSetValues(widget
, XmNheight
, height
, NULL
); 
1278         XtManageChild(widget
); 
1280     // How about this bit. Maybe we don't need to generate size events 
1281     // all the time -- they'll be generated when the window is sized anyway. 
1283     wxSizeEvent 
sizeEvent(wxSize(width
, height
), GetId()); 
1284     sizeEvent
.SetEventObject(this); 
1286       GetEventHandler()->ProcessEvent(sizeEvent
); 
1290 void wxWindow::DoSetClientSize(int width
, int height
) 
1294         CanvasSetClientSize(width
, height
); 
1298     Widget widget 
= (Widget
) GetTopWidget(); 
1301         XtVaSetValues(widget
, XmNwidth
, width
, NULL
); 
1303         XtVaSetValues(widget
, XmNheight
, height
, NULL
); 
1305     wxSizeEvent 
sizeEvent(wxSize(width
, height
), GetId()); 
1306     sizeEvent
.SetEventObject(this); 
1308     GetEventHandler()->ProcessEvent(sizeEvent
); 
1311 // For implementation purposes - sometimes decorations make the client area 
1313 wxPoint 
wxWindow::GetClientAreaOrigin() const 
1315     return wxPoint(0, 0); 
1318 // Makes an adjustment to the window position (for example, a frame that has 
1319 // a toolbar that it manages itself). 
1320 void wxWindow::AdjustForParentClientOrigin(int& x
, int& y
, int sizeFlags
) 
1322     if (((sizeFlags 
& wxSIZE_NO_ADJUSTMENTS
) == 0) && GetParent()) 
1324         wxPoint 
pt(GetParent()->GetClientAreaOrigin()); 
1325         x 
+= pt
.x
; y 
+= pt
.y
; 
1329 void wxWindow::SetSizeHints(int minW
, int minH
, int maxW
, int maxH
, int incW
, int incH
) 
1336     wxFrame 
*frame 
= wxDynamicCast(this, wxFrame
); 
1339         // TODO what about dialogs? 
1343     Widget widget 
= (Widget
) frame
->GetShellWidget(); 
1346         XtVaSetValues(widget
, XmNminWidth
, minW
, NULL
); 
1348         XtVaSetValues(widget
, XmNminHeight
, minH
, NULL
); 
1350         XtVaSetValues(widget
, XmNmaxWidth
, maxW
, NULL
); 
1352         XtVaSetValues(widget
, XmNmaxHeight
, maxH
, NULL
); 
1354         XtVaSetValues(widget
, XmNwidthInc
, incW
, NULL
); 
1356         XtVaSetValues(widget
, XmNheightInc
, incH
, NULL
); 
1359 // --------------------------------------------------------------------------- 
1361 // --------------------------------------------------------------------------- 
1363 int wxWindow::GetCharHeight() const 
1365     wxCHECK_MSG( m_font
.Ok(), 0, "valid window font needed" ); 
1367     WXFontStructPtr pFontStruct 
= m_font
.GetFontStruct(1.0, GetXDisplay()); 
1369     int direction
, ascent
, descent
; 
1370     XCharStruct overall
; 
1371     XTextExtents ((XFontStruct
*) pFontStruct
, "x", 1, &direction
, &ascent
, 
1372         &descent
, &overall
); 
1374     //  return (overall.ascent + overall.descent); 
1375     return (ascent 
+ descent
); 
1378 int wxWindow::GetCharWidth() const 
1380     wxCHECK_MSG( m_font
.Ok(), 0, "valid window font needed" ); 
1382     WXFontStructPtr pFontStruct 
= m_font
.GetFontStruct(1.0, GetXDisplay()); 
1384     int direction
, ascent
, descent
; 
1385     XCharStruct overall
; 
1386     XTextExtents ((XFontStruct
*) pFontStruct
, "x", 1, &direction
, &ascent
, 
1387         &descent
, &overall
); 
1389     return overall
.width
; 
1392 void wxWindow::GetTextExtent(const wxString
& string
, 
1394                              int *descent
, int *externalLeading
, 
1395                              const wxFont 
*theFont
) const 
1397     wxFont 
*fontToUse 
= (wxFont 
*)theFont
; 
1399         fontToUse 
= (wxFont 
*) & m_font
; 
1401     wxCHECK_RET( fontToUse
->Ok(), "valid window font needed" ); 
1403     WXFontStructPtr pFontStruct 
= theFont
->GetFontStruct(1.0, GetXDisplay()); 
1405     int direction
, ascent
, descent2
; 
1406     XCharStruct overall
; 
1407     int slen 
= string
.Len(); 
1411         XTextExtents16((XFontStruct
*) pFontStruct
, (XChar2b 
*) (char*) (const char*) string
, slen
, &direction
, 
1412         &ascent
, &descent2
, &overall
); 
1415     XTextExtents((XFontStruct
*) pFontStruct
, string
, slen
, 
1416                  &direction
, &ascent
, &descent2
, &overall
); 
1419         *x 
= (overall
.width
); 
1421         *y 
= (ascent 
+ descent2
); 
1423         *descent 
= descent2
; 
1424     if (externalLeading
) 
1425         *externalLeading 
= 0; 
1429 // ---------------------------------------------------------------------------- 
1431 // ---------------------------------------------------------------------------- 
1433 void wxWindow::Refresh(bool eraseBack
, const wxRect 
*rect
) 
1435     m_needsRefresh 
= TRUE
; 
1436     Display 
*display 
= XtDisplay((Widget
) GetMainWidget()); 
1437     Window thisWindow 
= XtWindow((Widget
) GetMainWidget()); 
1439     XExposeEvent dummyEvent
; 
1441     GetSize(&width
, &height
); 
1443     dummyEvent
.type 
= Expose
; 
1444     dummyEvent
.display 
= display
; 
1445     dummyEvent
.send_event 
= True
; 
1446     dummyEvent
.window 
= thisWindow
; 
1449         dummyEvent
.x 
= rect
->x
; 
1450         dummyEvent
.y 
= rect
->y
; 
1451         dummyEvent
.width 
= rect
->width
; 
1452         dummyEvent
.height 
= rect
->height
; 
1458         dummyEvent
.width 
= width
; 
1459         dummyEvent
.height 
= height
; 
1461     dummyEvent
.count 
= 0; 
1465         wxClientDC 
dc(this); 
1466         wxBrush 
backgroundBrush(GetBackgroundColour(), wxSOLID
); 
1467         dc
.SetBackground(backgroundBrush
); 
1474     XSendEvent(display
, thisWindow
, False
, ExposureMask
, (XEvent 
*)&dummyEvent
); 
1477 void wxWindow::Clear() 
1479     wxClientDC 
dc(this); 
1480     wxBrush 
brush(GetBackgroundColour(), wxSOLID
); 
1481     dc
.SetBackground(brush
); 
1485 void wxWindow::ClearUpdateRects() 
1487     wxRectList::Node
* node 
= m_updateRects
.GetFirst(); 
1490         wxRect
* rect 
= node
->GetData(); 
1492         node 
= node
->GetNext(); 
1495     m_updateRects
.Clear(); 
1498 void wxWindow::DoPaint() 
1500     //TODO : make a temporary gc so we can do the XCopyArea below 
1501     if (m_backingPixmap 
&& !m_needsRefresh
) 
1505       GC tempGC 
= (GC
) dc
.GetBackingGC(); 
1507       Widget widget 
= (Widget
) GetMainWidget(); 
1512       // We have to test whether it's a wxScrolledWindow (hack!) because 
1513       // otherwise we don't know how many pixels have been scrolled. We might 
1514       // solve this in the future by defining virtual wxWindow functions to get 
1515       // the scroll position in pixels. Or, each kind of scrolled window has to 
1516       // implement backing stores itself, using generic wxWindows code. 
1517       wxScrolledWindow
* scrolledWindow 
= wxDynamicCast(this, wxScrolledWindow
); 
1518       if ( scrolledWindow 
) 
1521           scrolledWindow
->CalcScrolledPosition(0, 0, &x
, &y
); 
1527       // TODO: This could be optimized further by only copying the areas in the 
1528       //       current update region. 
1530       // Only blit the part visible in the client area. The backing pixmap 
1531       // always starts at 0, 0 but we may be looking at only a portion of it. 
1532       wxSize clientArea 
= GetClientSize(); 
1533       int toBlitX 
= m_pixmapWidth 
- scrollPosX
; 
1534       int toBlitY 
= m_pixmapHeight 
- scrollPosY
; 
1536       // Copy whichever is samller, the amount of pixmap we have to copy, 
1537       // or the size of the client area. 
1538       toBlitX 
= wxMin(toBlitX
, clientArea
.x
); 
1539       toBlitY 
= wxMin(toBlitY
, clientArea
.y
); 
1541       // Make sure we're not negative 
1542       toBlitX 
= wxMax(0, toBlitX
); 
1543       toBlitY 
= wxMax(0, toBlitY
); 
1548        (Pixmap
) m_backingPixmap
, 
1551        scrollPosX
, scrollPosY
, // Start at the scroll position 
1552        toBlitX
, toBlitY
,       // How much of the pixmap to copy 
1558         // Set an erase event first 
1559         wxEraseEvent 
eraseEvent(GetId()); 
1560         eraseEvent
.SetEventObject(this); 
1561         GetEventHandler()->ProcessEvent(eraseEvent
); 
1563         wxPaintEvent 
event(GetId()); 
1564         event
.SetEventObject(this); 
1565         GetEventHandler()->ProcessEvent(event
); 
1567         m_needsRefresh 
= FALSE
; 
1571 // ---------------------------------------------------------------------------- 
1573 // ---------------------------------------------------------------------------- 
1575 // Responds to colour changes: passes event on to children. 
1576 void wxWindow::OnSysColourChanged(wxSysColourChangedEvent
& event
) 
1578     wxWindowList::Node 
*node 
= GetChildren().GetFirst(); 
1581         // Only propagate to non-top-level windows 
1582         wxWindow 
*win 
= node
->GetData(); 
1583         if ( win
->GetParent() ) 
1585             wxSysColourChangedEvent event2
; 
1586             event
.m_eventObject 
= win
; 
1587             win
->GetEventHandler()->ProcessEvent(event2
); 
1590         node 
= node
->GetNext(); 
1594 void wxWindow::OnIdle(wxIdleEvent
& event
) 
1596     // This calls the UI-update mechanism (querying windows for 
1597     // menu/toolbar/control state information) 
1601 // ---------------------------------------------------------------------------- 
1603 // ---------------------------------------------------------------------------- 
1605 bool wxWindow::ProcessAccelerator(wxKeyEvent
& event
) 
1607     if (!m_acceleratorTable
.Ok()) 
1610     int count 
= m_acceleratorTable
.GetCount(); 
1611     wxAcceleratorEntry
* entries 
= m_acceleratorTable
.GetEntries(); 
1613     for (i 
= 0; i 
< count
; i
++) 
1615         wxAcceleratorEntry
* entry 
= & (entries
[i
]); 
1616         if (entry
->MatchesEvent(event
)) 
1618             // Bingo, we have a match. Now find a control that matches the entry 
1621             // Need to go up to the top of the window hierarchy, since it might 
1622             // be e.g. a menu item 
1623             wxWindow
* parent 
= this; 
1624             while ( parent 
&& !parent
->IsTopLevel() ) 
1625                 parent 
= parent
->GetParent(); 
1630             wxFrame
* frame 
= wxDynamicCast(parent
, wxFrame
); 
1633                 // Try for a menu command 
1634                 if (frame
->GetMenuBar()) 
1636                     wxMenuItem
* item 
= frame
->GetMenuBar()->FindItemForId(entry
->GetCommand()); 
1639                         wxCommandEvent 
commandEvent(wxEVT_COMMAND_MENU_SELECTED
, entry
->GetCommand()); 
1640                         commandEvent
.SetEventObject(frame
); 
1642                         // If ProcessEvent returns TRUE (it was handled), then 
1643                         // the calling code will skip the event handling. 
1644                         return frame
->GetEventHandler()->ProcessEvent(commandEvent
); 
1649             // Find a child matching the command id 
1650             wxWindow
* child 
= parent
->FindWindow(entry
->GetCommand()); 
1656             // Now we process those kinds of windows that we can. 
1657             // For now, only buttons. 
1658             if ( wxDynamicCast(child
, wxButton
) ) 
1660                 wxCommandEvent 
commandEvent (wxEVT_COMMAND_BUTTON_CLICKED
, child
->GetId()); 
1661                 commandEvent
.SetEventObject(child
); 
1662                 return child
->GetEventHandler()->ProcessEvent(commandEvent
); 
1669     // We didn't match the key event against an accelerator. 
1673 // ============================================================================ 
1674 // Motif-specific stuff from here on 
1675 // ============================================================================ 
1677 // ---------------------------------------------------------------------------- 
1678 // function which maintain the global hash table mapping Widgets to wxWindows 
1679 // ---------------------------------------------------------------------------- 
1681 bool wxAddWindowToTable(Widget w
, wxWindow 
*win
) 
1683     wxWindow 
*oldItem 
= NULL
; 
1684     if ((oldItem 
= (wxWindow 
*)wxWidgetHashTable
->Get ((long) w
))) 
1686         wxLogDebug("Widget table clash: new widget is %ld, %s", 
1687                    (long)w
, win
->GetClassInfo()->GetClassName()); 
1691     wxWidgetHashTable
->Put((long) w
, win
); 
1693     wxLogDebug("Widget 0x%08x <-> window %p (%s)", 
1694                w
, win
, win
->GetClassInfo()->GetClassName()); 
1699 wxWindow 
*wxGetWindowFromTable(Widget w
) 
1701     return (wxWindow 
*)wxWidgetHashTable
->Get((long) w
); 
1704 void wxDeleteWindowFromTable(Widget w
) 
1706     wxWidgetHashTable
->Delete((long)w
); 
1709 // ---------------------------------------------------------------------------- 
1710 // add/remove window from the table 
1711 // ---------------------------------------------------------------------------- 
1713 // Add to hash table, add event handler 
1714 bool wxWindow::AttachWidget (wxWindow
* parent
, WXWidget mainWidget
, 
1715                              WXWidget formWidget
, int x
, int y
, int width
, int height
) 
1717     wxAddWindowToTable((Widget
) mainWidget
, this); 
1718     if (CanAddEventHandler()) 
1720         XtAddEventHandler((Widget
) mainWidget
, 
1721             ButtonPressMask 
| ButtonReleaseMask 
| PointerMotionMask
, // | KeyPressMask, 
1723             wxPanelItemEventHandler
, 
1730         XtOverrideTranslations ((Widget
) mainWidget
, 
1731             ptr 
= XtParseTranslationTable ("<Configure>: resize()")); 
1732         XtFree ((char *) ptr
); 
1735     // Some widgets have a parent form widget, e.g. wxRadioBox 
1738         if (!wxAddWindowToTable((Widget
) formWidget
, this)) 
1742         XtOverrideTranslations ((Widget
) formWidget
, 
1743             ptr 
= XtParseTranslationTable ("<Configure>: resize()")); 
1744         XtFree ((char *) ptr
); 
1751     SetSize (x
, y
, width
, height
); 
1756 // Remove event handler, remove from hash table 
1757 bool wxWindow::DetachWidget(WXWidget widget
) 
1759     if (CanAddEventHandler()) 
1761         XtRemoveEventHandler((Widget
) widget
, 
1762             ButtonPressMask 
| ButtonReleaseMask 
| PointerMotionMask
, // | KeyPressMask, 
1764             wxPanelItemEventHandler
, 
1768     wxDeleteWindowFromTable((Widget
) widget
); 
1772 // ---------------------------------------------------------------------------- 
1773 // Motif-specific accessors 
1774 // ---------------------------------------------------------------------------- 
1776 // Get the underlying X window 
1777 WXWindow 
wxWindow::GetXWindow() const 
1779     Widget wMain 
= (Widget
)GetMainWidget(); 
1781         return (WXWindow
) XtWindow(wMain
); 
1783         return (WXWindow
) 0; 
1786 // Get the underlying X display 
1787 WXDisplay 
*wxWindow::GetXDisplay() const 
1789     Widget wMain 
= (Widget
)GetMainWidget(); 
1791         return (WXDisplay
*) XtDisplay(wMain
); 
1793         return (WXDisplay
*) NULL
; 
1796 WXWidget 
wxWindow::GetMainWidget() const 
1799         return m_drawingArea
; 
1801         return m_mainWidget
; 
1804 WXWidget 
wxWindow::GetClientWidget() const 
1806     if (m_drawingArea 
!= (WXWidget
) 0) 
1807         return m_drawingArea
; 
1809         return GetMainWidget(); 
1812 WXWidget 
wxWindow::GetTopWidget() const 
1814     return GetMainWidget(); 
1817 WXWidget 
wxWindow::GetLabelWidget() const 
1819     return GetMainWidget(); 
1822 // ---------------------------------------------------------------------------- 
1824 // ---------------------------------------------------------------------------- 
1826 // All widgets should have this as their resize proc. 
1827 // OnSize sent to wxWindow via client data. 
1828 void wxWidgetResizeProc(Widget w
, XConfigureEvent 
*event
, String args
[], int *num_args
) 
1830     wxWindow 
*win 
= wxGetWindowFromTable(w
); 
1834     if (win
->PreResize()) 
1837         win
->GetSize(&width
, &height
); 
1838         wxSizeEvent 
sizeEvent(wxSize(width
, height
), win
->GetId()); 
1839         sizeEvent
.SetEventObject(win
); 
1840         win
->GetEventHandler()->ProcessEvent(sizeEvent
); 
1844 static void wxCanvasRepaintProc(Widget drawingArea
, 
1845                                 XtPointer clientData
, 
1846                                 XmDrawingAreaCallbackStruct 
* cbs
) 
1848     if (!wxGetWindowFromTable(drawingArea
)) 
1851     XEvent 
* event 
= cbs
->event
; 
1852     wxWindow 
* win 
= (wxWindow 
*) clientData
; 
1854     switch (event
->type
) 
1858             win
->AddUpdateRect(event
->xexpose
.x
, event
->xexpose
.y
, 
1859                                event
->xexpose
.width
, event
->xexpose
.height
); 
1861             if (event 
-> xexpose
.count 
== 0) 
1864                 win
->ClearUpdateRects(); 
1871 // Unable to deal with Enter/Leave without a separate EventHandler (Motif 1.1.4) 
1872 static void wxCanvasEnterLeave(Widget drawingArea
, 
1873                                XtPointer clientData
, 
1874                                XCrossingEvent 
* event
) 
1876     XmDrawingAreaCallbackStruct cbs
; 
1879     ((XCrossingEvent 
&) ev
) = *event
; 
1881     cbs
.reason 
= XmCR_INPUT
; 
1884     wxCanvasInputEvent(drawingArea
, (XtPointer
) NULL
, &cbs
); 
1887 // Fix to make it work under Motif 1.0 (!) 
1888 static void wxCanvasMotionEvent (Widget drawingArea
, XButtonEvent 
* event
) 
1890 #if XmVersion <= 1000 
1891     XmDrawingAreaCallbackStruct cbs
; 
1894     ev 
= *((XEvent 
*) event
); 
1895     cbs
.reason 
= XmCR_INPUT
; 
1898     wxCanvasInputEvent (drawingArea
, (XtPointer
) NULL
, &cbs
); 
1899 #endif // XmVersion <= 1000 
1902 static void wxCanvasInputEvent(Widget drawingArea
, 
1904                                XmDrawingAreaCallbackStruct 
* cbs
) 
1906     wxWindow 
*canvas 
= wxGetWindowFromTable(drawingArea
); 
1912     if (cbs
->reason 
!= XmCR_INPUT
) 
1915     local_event 
= *(cbs
->event
);    // We must keep a copy! 
1917     switch (local_event
.xany
.type
) 
1925             // FIXME: most of this mouse event code is more or less 
1926             // duplicated in wxTranslateMouseEvent 
1928             wxEventType eventType 
= wxEVT_NULL
; 
1930             if (local_event
.xany
.type 
== EnterNotify
) 
1932                 //if (local_event.xcrossing.mode!=NotifyNormal) 
1933                 //  return ; // Ignore grab events 
1934                 eventType 
= wxEVT_ENTER_WINDOW
; 
1935                 //            canvas->GetEventHandler()->OnSetFocus(); 
1937             else if (local_event
.xany
.type 
== LeaveNotify
) 
1939                 //if (local_event.xcrossingr.mode!=NotifyNormal) 
1940                 //  return ; // Ignore grab events 
1941                 eventType 
= wxEVT_LEAVE_WINDOW
; 
1942                 //            canvas->GetEventHandler()->OnKillFocus(); 
1944             else if (local_event
.xany
.type 
== MotionNotify
) 
1946                 eventType 
= wxEVT_MOTION
; 
1947                 if (local_event
.xmotion
.is_hint 
== NotifyHint
) 
1950                     Display 
*dpy 
= XtDisplay (drawingArea
); 
1952                     XQueryPointer (dpy
, XtWindow (drawingArea
), 
1954                         &local_event
.xmotion
.x_root
, 
1955                         &local_event
.xmotion
.y_root
, 
1956                         &local_event
.xmotion
.x
, 
1957                         &local_event
.xmotion
.y
, 
1958                         &local_event
.xmotion
.state
); 
1965             else if (local_event
.xany
.type 
== ButtonPress
) 
1967                 if (local_event
.xbutton
.button 
== Button1
) 
1969                     eventType 
= wxEVT_LEFT_DOWN
; 
1970                     canvas
->SetButton1(TRUE
); 
1972                 else if (local_event
.xbutton
.button 
== Button2
) 
1974                     eventType 
= wxEVT_MIDDLE_DOWN
; 
1975                     canvas
->SetButton2(TRUE
); 
1977                 else if (local_event
.xbutton
.button 
== Button3
) 
1979                     eventType 
= wxEVT_RIGHT_DOWN
; 
1980                     canvas
->SetButton3(TRUE
); 
1983             else if (local_event
.xany
.type 
== ButtonRelease
) 
1985                 if (local_event
.xbutton
.button 
== Button1
) 
1987                     eventType 
= wxEVT_LEFT_UP
; 
1988                     canvas
->SetButton1(FALSE
); 
1990                 else if (local_event
.xbutton
.button 
== Button2
) 
1992                     eventType 
= wxEVT_MIDDLE_UP
; 
1993                     canvas
->SetButton2(FALSE
); 
1995                 else if (local_event
.xbutton
.button 
== Button3
) 
1997                     eventType 
= wxEVT_RIGHT_UP
; 
1998                     canvas
->SetButton3(FALSE
); 
2002             wxMouseEvent 
wxevent (eventType
); 
2004             wxevent
.m_leftDown 
= ((eventType 
== wxEVT_LEFT_DOWN
) 
2005                 || (event_left_is_down (&local_event
) 
2006                 && (eventType 
!= wxEVT_LEFT_UP
))); 
2007             wxevent
.m_middleDown 
= ((eventType 
== wxEVT_MIDDLE_DOWN
) 
2008                 || (event_middle_is_down (&local_event
) 
2009                 && (eventType 
!= wxEVT_MIDDLE_UP
))); 
2010             wxevent
.m_rightDown 
= ((eventType 
== wxEVT_RIGHT_DOWN
) 
2011                 || (event_right_is_down (&local_event
) 
2012                 && (eventType 
!= wxEVT_RIGHT_UP
))); 
2014             wxevent
.m_shiftDown 
= local_event
.xbutton
.state 
& ShiftMask
; 
2015             wxevent
.m_controlDown 
= local_event
.xbutton
.state 
& ControlMask
; 
2016             wxevent
.m_altDown 
= local_event
.xbutton
.state 
& Mod3Mask
; 
2017             wxevent
.m_metaDown 
= local_event
.xbutton
.state 
& Mod1Mask
; 
2018             wxevent
.SetTimestamp(local_event
.xbutton
.time
); 
2020             // Now check if we need to translate this event into a double click 
2021             if (TRUE
) // canvas->doubleClickAllowed) 
2023                 if (wxevent
.ButtonDown()) 
2025                     long dclickTime 
= XtGetMultiClickTime((Display
*) wxGetDisplay()); 
2027                     // get button and time-stamp 
2029                     if (wxevent
.LeftDown()) 
2031                     else if (wxevent
.MiddleDown()) 
2033                     else if (wxevent
.RightDown()) 
2035                     long ts 
= wxevent
.GetTimestamp(); 
2037                     // check, if single or double click 
2038                     int buttonLast 
= canvas
->GetLastClickedButton(); 
2039                     long lastTS 
= canvas
->GetLastClickTime(); 
2040                     if ( buttonLast 
&& buttonLast 
== button 
&& (ts 
- lastTS
) < dclickTime 
) 
2043                         canvas
->SetLastClick(0, ts
); 
2044                         switch ( eventType 
) 
2046                         case wxEVT_LEFT_DOWN
: 
2047                             wxevent
.SetEventType(wxEVT_LEFT_DCLICK
); 
2049                         case wxEVT_MIDDLE_DOWN
: 
2050                             wxevent
.SetEventType(wxEVT_MIDDLE_DCLICK
); 
2052                         case wxEVT_RIGHT_DOWN
: 
2053                             wxevent
.SetEventType(wxEVT_RIGHT_DCLICK
); 
2063                         // not fast enough or different button 
2064                         canvas
->SetLastClick(button
, ts
); 
2069             wxevent
.SetId(canvas
->GetId()); 
2070             wxevent
.SetEventObject(canvas
); 
2071             wxevent
.m_x 
= local_event
.xbutton
.x
; 
2072             wxevent
.m_y 
= local_event
.xbutton
.y
; 
2073             canvas
->GetEventHandler()->ProcessEvent (wxevent
); 
2075             if (eventType 
== wxEVT_ENTER_WINDOW 
|| 
2076                     eventType 
== wxEVT_LEAVE_WINDOW 
|| 
2077                     eventType 
== wxEVT_MOTION
 
2087             XComposeStatus compose
; 
2088             (void) XLookupString ((XKeyEvent 
*) & local_event
, wxBuffer
, 20, &keySym
, &compose
); 
2091             (void) XLookupString ((XKeyEvent 
*) & local_event
, wxBuffer
, 20, &keySym
, NULL
); 
2092             int id 
= wxCharCodeXToWX (keySym
); 
2094             wxEventType eventType 
= wxEVT_CHAR
; 
2096             wxKeyEvent 
event (eventType
); 
2098             if (local_event
.xkey
.state 
& ShiftMask
) 
2099                 event
.m_shiftDown 
= TRUE
; 
2100             if (local_event
.xkey
.state 
& ControlMask
) 
2101                 event
.m_controlDown 
= TRUE
; 
2102             if (local_event
.xkey
.state 
& Mod3Mask
) 
2103                 event
.m_altDown 
= TRUE
; 
2104             if (local_event
.xkey
.state 
& Mod1Mask
) 
2105                 event
.m_metaDown 
= TRUE
; 
2106             event
.SetEventObject(canvas
); 
2107             event
.m_keyCode 
= id
; 
2108             event
.SetTimestamp(local_event
.xkey
.time
); 
2112                 // Implement wxFrame::OnCharHook by checking ancestor. 
2113                 wxWindow 
*parent 
= canvas
->GetParent(); 
2114                 while (parent 
&& !parent
->IsKindOf(CLASSINFO(wxFrame
))) 
2115                     parent 
= parent
->GetParent(); 
2119                     event
.SetEventType(wxEVT_CHAR_HOOK
); 
2120                     if (parent
->GetEventHandler()->ProcessEvent(event
)) 
2124                 // For simplicity, OnKeyDown is the same as OnChar 
2125                 // TODO: filter modifier key presses from OnChar 
2126                 event
.SetEventType(wxEVT_KEY_DOWN
); 
2128                 // Only process OnChar if OnKeyDown didn't swallow it 
2129                 if (!canvas
->GetEventHandler()->ProcessEvent (event
)) 
2131                   event
.SetEventType(wxEVT_CHAR
); 
2132                   canvas
->GetEventHandler()->ProcessEvent (event
); 
2140             (void) XLookupString ((XKeyEvent 
*) & local_event
, wxBuffer
, 20, &keySym
, NULL
); 
2141             int id 
= wxCharCodeXToWX (keySym
); 
2143             wxKeyEvent 
event (wxEVT_KEY_UP
); 
2145             if (local_event
.xkey
.state 
& ShiftMask
) 
2146                 event
.m_shiftDown 
= TRUE
; 
2147             if (local_event
.xkey
.state 
& ControlMask
) 
2148                 event
.m_controlDown 
= TRUE
; 
2149             if (local_event
.xkey
.state 
& Mod3Mask
) 
2150                 event
.m_altDown 
= TRUE
; 
2151             if (local_event
.xkey
.state 
& Mod1Mask
) 
2152                 event
.m_metaDown 
= TRUE
; 
2153             event
.SetEventObject(canvas
); 
2154             event
.m_keyCode 
= id
; 
2155             event
.SetTimestamp(local_event
.xkey
.time
); 
2159                 canvas
->GetEventHandler()->ProcessEvent (event
); 
2165             if (local_event
.xfocus
.detail 
!= NotifyPointer
) 
2167                 wxFocusEvent 
event(wxEVT_SET_FOCUS
, canvas
->GetId()); 
2168                 event
.SetEventObject(canvas
); 
2169                 canvas
->GetEventHandler()->ProcessEvent(event
); 
2175             if (local_event
.xfocus
.detail 
!= NotifyPointer
) 
2177                 wxFocusEvent 
event(wxEVT_KILL_FOCUS
, canvas
->GetId()); 
2178                 event
.SetEventObject(canvas
); 
2179                 canvas
->GetEventHandler()->ProcessEvent(event
); 
2188 static void wxPanelItemEventHandler(Widget    wid
, 
2189                                     XtPointer client_data
, 
2191                                     Boolean  
*continueToDispatch
) 
2193     // Widget can be a label or the actual widget. 
2195     wxWindow 
*window 
= wxGetWindowFromTable(wid
); 
2198         wxMouseEvent 
wxevent(0); 
2199         if (wxTranslateMouseEvent(wxevent
, window
, wid
, event
)) 
2201             window
->GetEventHandler()->ProcessEvent(wxevent
); 
2205     // TODO: probably the key to allowing default behaviour to happen. Say we 
2206     // set a m_doDefault flag to FALSE at the start of this function. Then in 
2207     // e.g. wxWindow::OnMouseEvent we can call Default() which sets this flag to 
2208     // TRUE, indicating that default processing can happen. Thus, behaviour can 
2209     // appear to be overridden just by adding an event handler and not calling 
2210     // wxWindow::OnWhatever. ALSO, maybe we can use this instead of the current 
2211     // way of handling drawing area events, to simplify things. 
2212     *continueToDispatch 
= True
; 
2215 static void wxScrollBarCallback(Widget scrollbar
, 
2216                                 XtPointer clientData
, 
2217                                 XmScrollBarCallbackStruct 
*cbs
) 
2219     wxWindow 
*win 
= wxGetWindowFromTable(scrollbar
); 
2220     int orientation 
= (int) clientData
; 
2222     wxEventType eventType 
= wxEVT_NULL
; 
2223     switch (cbs
->reason
) 
2225     case XmCR_INCREMENT
: 
2227             eventType 
= wxEVT_SCROLLWIN_LINEDOWN
; 
2230     case XmCR_DECREMENT
: 
2232             eventType 
= wxEVT_SCROLLWIN_LINEUP
; 
2237             eventType 
= wxEVT_SCROLLWIN_THUMBTRACK
; 
2240     case XmCR_VALUE_CHANGED
: 
2242             // TODO: Should this be intercepted too, or will it cause 
2243             // duplicate events? 
2244             eventType 
= wxEVT_SCROLLWIN_THUMBTRACK
; 
2247     case XmCR_PAGE_INCREMENT
: 
2249             eventType 
= wxEVT_SCROLLWIN_PAGEDOWN
; 
2252     case XmCR_PAGE_DECREMENT
: 
2254             eventType 
= wxEVT_SCROLLWIN_PAGEUP
; 
2259             eventType 
= wxEVT_SCROLLWIN_TOP
; 
2262     case XmCR_TO_BOTTOM
: 
2264             eventType 
= wxEVT_SCROLLWIN_BOTTOM
; 
2269             // Should never get here 
2270             wxFAIL_MSG("Unknown scroll event."); 
2275     wxScrollWinEvent 
event(eventType
, 
2277                            ((orientation 
== XmHORIZONTAL
) ? 
2278                             wxHORIZONTAL 
: wxVERTICAL
)); 
2279     event
.SetEventObject( win 
); 
2280     win
->GetEventHandler()->ProcessEvent(event
); 
2283 // For repainting arbitrary windows 
2284 void wxUniversalRepaintProc(Widget w
, XtPointer 
WXUNUSED(c_data
), XEvent 
*event
, char *) 
2289     wxWindow
* win 
= wxGetWindowFromTable(w
); 
2293     switch(event 
-> type
) 
2297             window 
= (Window
) win 
-> GetXWindow(); 
2298             display 
= (Display 
*) win 
-> GetXDisplay(); 
2300             if (event 
-> xexpose
.count 
== 0) 
2304                 win
->ClearUpdateRects(); 
2308                 win
->AddUpdateRect(event
->xexpose
.x
, event
->xexpose
.y
, 
2309                                    event
->xexpose
.width
, event
->xexpose
.height
); 
2317 // ---------------------------------------------------------------------------- 
2318 // CanvaseXXXSize() functions 
2319 // ---------------------------------------------------------------------------- 
2321 // SetSize, but as per old wxCanvas (with drawing widget etc.) 
2322 void wxWindow::CanvasSetSize (int x
, int y
, int w
, int h
, int sizeFlags
) 
2324     // A bit of optimization to help sort out the flickers. 
2325     int oldX
, oldY
, oldW
, oldH
; 
2326     GetSize(& oldW
, & oldH
); 
2327     GetPosition(& oldX
, & oldY
); 
2329     bool useOldPos 
= FALSE
; 
2330     bool useOldSize 
= FALSE
; 
2332     if ((x 
== -1) && (x 
== -1) && ((sizeFlags 
& wxSIZE_ALLOW_MINUS_ONE
) == 0)) 
2334     else if (x 
== oldX 
&& y 
== oldY
) 
2337     if ((w 
== -1) && (h 
== -1)) 
2339     else if (w 
== oldW 
&& h 
== oldH
) 
2342     if (!wxNoOptimize::CanOptimize()) 
2344         useOldSize 
= FALSE
; useOldPos 
= FALSE
; 
2347     if (useOldPos 
&& useOldSize
) 
2350     Widget drawingArea 
= (Widget
) m_drawingArea
; 
2351     bool managed 
= XtIsManaged(m_borderWidget 
? (Widget
) m_borderWidget 
: (Widget
) m_scrolledWindow
); 
2354         XtUnmanageChild (m_borderWidget 
? (Widget
) m_borderWidget 
: (Widget
) m_scrolledWindow
); 
2355     XtVaSetValues(drawingArea
, XmNresizePolicy
, XmRESIZE_ANY
, NULL
); 
2357     int xx 
= x
; int yy 
= y
; 
2358     AdjustForParentClientOrigin(xx
, yy
, sizeFlags
); 
2362         if (x 
> -1 || (sizeFlags 
& wxSIZE_ALLOW_MINUS_ONE
)) 
2364             XtVaSetValues (m_borderWidget 
? (Widget
) m_borderWidget 
: (Widget
) m_scrolledWindow
, 
2368         if (y 
> -1 || (sizeFlags 
& wxSIZE_ALLOW_MINUS_ONE
)) 
2370             XtVaSetValues (m_borderWidget 
? (Widget
) m_borderWidget 
: (Widget
) m_scrolledWindow
, 
2382                 XtVaSetValues ((Widget
) m_borderWidget
, XmNwidth
, w
, NULL
); 
2383                 short thick
, margin
; 
2384                 XtVaGetValues ((Widget
) m_borderWidget
, 
2385                     XmNshadowThickness
, &thick
, 
2386                     XmNmarginWidth
, &margin
, 
2388                 w 
-= 2 * (thick 
+ margin
); 
2391             XtVaSetValues ((Widget
) m_scrolledWindow
, XmNwidth
, w
, NULL
); 
2395             XtVaGetValues ((Widget
) m_scrolledWindow
, 
2396                 XmNspacing
, &spacing
, 
2397                 XmNverticalScrollBar
, &sbar
, 
2401                 XtVaGetValues (sbar
, XmNwidth
, &wsbar
, NULL
); 
2405             w 
-= (spacing 
+ wsbar
); 
2408             XtVaSetValues(drawingArea
, XmNwidth
, w
, NULL
); 
2415                 XtVaSetValues ((Widget
) m_borderWidget
, XmNheight
, h
, NULL
); 
2416                 short thick
, margin
; 
2417                 XtVaGetValues ((Widget
) m_borderWidget
, 
2418                     XmNshadowThickness
, &thick
, 
2419                     XmNmarginHeight
, &margin
, 
2421                 h 
-= 2 * (thick 
+ margin
); 
2424             XtVaSetValues ((Widget
) m_scrolledWindow
, XmNheight
, h
, NULL
); 
2428             XtVaGetValues ((Widget
) m_scrolledWindow
, 
2429                 XmNspacing
, &spacing
, 
2430                 XmNhorizontalScrollBar
, &sbar
, 
2434                 XtVaGetValues (sbar
, XmNheight
, &wsbar
, NULL
); 
2438             h 
-= (spacing 
+ wsbar
); 
2441             XtVaSetValues(drawingArea
, XmNheight
, h
, NULL
); 
2447         XtManageChild (m_borderWidget 
? (Widget
) m_borderWidget 
: (Widget
) m_scrolledWindow
); 
2448     XtVaSetValues(drawingArea
, XmNresizePolicy
, XmRESIZE_NONE
, NULL
); 
2452     GetClientSize (&ww
, &hh
); 
2453     wxSizeEvent 
sizeEvent(wxSize(ww
, hh
), GetId()); 
2454     sizeEvent
.SetEventObject(this); 
2456     GetEventHandler()->ProcessEvent(sizeEvent
); 
2460 void wxWindow::CanvasSetClientSize (int w
, int h
) 
2462     Widget drawingArea 
= (Widget
) m_drawingArea
; 
2464     XtVaSetValues(drawingArea
, XmNresizePolicy
, XmRESIZE_ANY
, NULL
); 
2467         XtVaSetValues(drawingArea
, XmNwidth
, w
, NULL
); 
2469         XtVaSetValues(drawingArea
, XmNheight
, h
, NULL
); 
2472     // TODO: is this necessary? 
2473     allowRepainting 
= FALSE
; 
2475     XSync (XtDisplay (drawingArea
), FALSE
); 
2477     while (XtAppPending (wxTheApp
->appContext
)) 
2479         XFlush (XtDisplay (drawingArea
)); 
2480         XtAppNextEvent (wxTheApp
->appContext
, &event
); 
2481         XtDispatchEvent (&event
); 
2485     XtVaSetValues(drawingArea
, XmNresizePolicy
, XmRESIZE_NONE
, NULL
); 
2488     allowRepainting 
= TRUE
; 
2491     wxSizeEvent 
sizeEvent(wxSize(w
, h
), GetId()); 
2492     sizeEvent
.SetEventObject(this); 
2494     GetEventHandler()->ProcessEvent(sizeEvent
); 
2498 void wxWindow::CanvasGetClientSize (int *w
, int *h
) const 
2500     // Must return the same thing that was set via SetClientSize 
2502     XtVaGetValues ((Widget
) m_drawingArea
, XmNwidth
, &xx
, XmNheight
, &yy
, NULL
); 
2507 void wxWindow::CanvasGetSize (int *w
, int *h
) const 
2510     if ((Widget
) m_borderWidget
) 
2511         XtVaGetValues ((Widget
) m_borderWidget
, XmNwidth
, &xx
, XmNheight
, &yy
, NULL
); 
2512     else if ((Widget
) m_scrolledWindow
) 
2513         XtVaGetValues ((Widget
) m_scrolledWindow
, XmNwidth
, &xx
, XmNheight
, &yy
, NULL
); 
2515         XtVaGetValues ((Widget
) m_drawingArea
, XmNwidth
, &xx
, XmNheight
, &yy
, NULL
); 
2521 void wxWindow::CanvasGetPosition (int *x
, int *y
) const 
2524     XtVaGetValues (m_borderWidget 
? (Widget
) m_borderWidget 
: (Widget
) m_scrolledWindow
, XmNx
, &xx
, XmNy
, &yy
, NULL
); 
2526     // We may be faking the client origin. 
2527     // So a window that's really at (0, 30) may appear 
2528     // (to wxWin apps) to be at (0, 0). 
2531         wxPoint 
pt(GetParent()->GetClientAreaOrigin()); 
2540 // ---------------------------------------------------------------------------- 
2541 // TranslateXXXEvent() functions 
2542 // ---------------------------------------------------------------------------- 
2544 bool wxTranslateMouseEvent(wxMouseEvent
& wxevent
, wxWindow 
*win
, Widget widget
, XEvent 
*xevent
) 
2546     switch (xevent
->xany
.type
) 
2548         case EnterNotify
:  // never received here - yes ? MB 
2549         case LeaveNotify
:  // never received here - yes ? MB 
2554             wxEventType eventType 
= wxEVT_NULL
; 
2556             // FIXME: this is never true I think - MB 
2558             if (xevent
->xany
.type 
== LeaveNotify
) 
2560                 win
->SetButton1(FALSE
); 
2561                 win
->SetButton2(FALSE
); 
2562                 win
->SetButton3(FALSE
); 
2565             else if (xevent
->xany
.type 
== MotionNotify
) 
2567                 eventType 
= wxEVT_MOTION
; 
2569             else if (xevent
->xany
.type 
== ButtonPress
) 
2571                 wxevent
.SetTimestamp(xevent
->xbutton
.time
); 
2573                 if (xevent
->xbutton
.button 
== Button1
) 
2575                     eventType 
= wxEVT_LEFT_DOWN
; 
2576                     win
->SetButton1(TRUE
); 
2579                 else if (xevent
->xbutton
.button 
== Button2
) 
2581                     eventType 
= wxEVT_MIDDLE_DOWN
; 
2582                     win
->SetButton2(TRUE
); 
2585                 else if (xevent
->xbutton
.button 
== Button3
) 
2587                     eventType 
= wxEVT_RIGHT_DOWN
; 
2588                     win
->SetButton3(TRUE
); 
2592                 // check for a double click 
2594                 long dclickTime 
= XtGetMultiClickTime((Display
*) wxGetDisplay()); 
2595                 long ts 
= wxevent
.GetTimestamp(); 
2597                 int buttonLast 
= win
->GetLastClickedButton(); 
2598                 long lastTS 
= win
->GetLastClickTime(); 
2599                 if ( buttonLast 
&& buttonLast 
== button 
&& (ts 
- lastTS
) < dclickTime 
) 
2602                     win
->SetLastClick(0, ts
); 
2603                     switch ( eventType 
) 
2605                         case wxEVT_LEFT_DOWN
: 
2606                             eventType 
= wxEVT_LEFT_DCLICK
; 
2608                         case wxEVT_MIDDLE_DOWN
: 
2609                             eventType 
= wxEVT_MIDDLE_DCLICK
; 
2611                         case wxEVT_RIGHT_DOWN
: 
2612                             eventType 
= wxEVT_RIGHT_DCLICK
; 
2622                     // not fast enough or different button 
2623                     win
->SetLastClick(button
, ts
); 
2626             else if (xevent
->xany
.type 
== ButtonRelease
) 
2628                 if (xevent
->xbutton
.button 
== Button1
) 
2630                     eventType 
= wxEVT_LEFT_UP
; 
2631                     win
->SetButton1(FALSE
); 
2633                 else if (xevent
->xbutton
.button 
== Button2
) 
2635                     eventType 
= wxEVT_MIDDLE_UP
; 
2636                     win
->SetButton2(FALSE
); 
2638                 else if (xevent
->xbutton
.button 
== Button3
) 
2640                     eventType 
= wxEVT_RIGHT_UP
; 
2641                     win
->SetButton3(FALSE
); 
2650             wxevent
.SetEventType(eventType
); 
2653             XtVaGetValues(widget
, XmNx
, &x1
, XmNy
, &y1
, NULL
); 
2656             win
->GetPosition(&x2
, &y2
); 
2658             // The button x/y must be translated to wxWindows 
2659             // window space - the widget might be a label or button, 
2663             if (widget 
!= (Widget
)win
->GetMainWidget()) 
2669             wxevent
.m_x 
= xevent
->xbutton
.x 
+ dx
; 
2670             wxevent
.m_y 
= xevent
->xbutton
.y 
+ dy
; 
2672             wxevent
.m_leftDown 
= ((eventType 
== wxEVT_LEFT_DOWN
) 
2673                 || (event_left_is_down (xevent
) 
2674                 && (eventType 
!= wxEVT_LEFT_UP
))); 
2675             wxevent
.m_middleDown 
= ((eventType 
== wxEVT_MIDDLE_DOWN
) 
2676                 || (event_middle_is_down (xevent
) 
2677                 && (eventType 
!= wxEVT_MIDDLE_UP
))); 
2678             wxevent
.m_rightDown 
= ((eventType 
== wxEVT_RIGHT_DOWN
) 
2679                 || (event_right_is_down (xevent
) 
2680                 && (eventType 
!= wxEVT_RIGHT_UP
))); 
2682             wxevent
.m_shiftDown 
= xevent
->xbutton
.state 
& ShiftMask
; 
2683             wxevent
.m_controlDown 
= xevent
->xbutton
.state 
& ControlMask
; 
2684             wxevent
.m_altDown 
= xevent
->xbutton
.state 
& Mod3Mask
; 
2685             wxevent
.m_metaDown 
= xevent
->xbutton
.state 
& Mod1Mask
; 
2687             wxevent
.SetId(win
->GetId()); 
2688             wxevent
.SetEventObject(win
); 
2696 bool wxTranslateKeyEvent(wxKeyEvent
& wxevent
, wxWindow 
*win
, Widget widget
, XEvent 
*xevent
) 
2698     switch (xevent
->xany
.type
) 
2707             XComposeStatus compose
; 
2708             (void) XLookupString ((XKeyEvent 
*) xevent
, buf
, 20, &keySym
, &compose
); 
2710             (void) XLookupString ((XKeyEvent 
*) xevent
, buf
, 20, &keySym
, NULL
); 
2711             int id 
= wxCharCodeXToWX (keySym
); 
2713             if (xevent
->xkey
.state 
& ShiftMask
) 
2714                 wxevent
.m_shiftDown 
= TRUE
; 
2715             if (xevent
->xkey
.state 
& ControlMask
) 
2716                 wxevent
.m_controlDown 
= TRUE
; 
2717             if (xevent
->xkey
.state 
& Mod3Mask
) 
2718                 wxevent
.m_altDown 
= TRUE
; 
2719             if (xevent
->xkey
.state 
& Mod1Mask
) 
2720                 wxevent
.m_metaDown 
= TRUE
; 
2721             wxevent
.SetEventObject(win
); 
2722             wxevent
.m_keyCode 
= id
; 
2723             wxevent
.SetTimestamp(xevent
->xkey
.time
); 
2725             wxevent
.m_x 
= xevent
->xbutton
.x
; 
2726             wxevent
.m_y 
= xevent
->xbutton
.y
; 
2740 // ---------------------------------------------------------------------------- 
2742 // ---------------------------------------------------------------------------- 
2744 #define YAllocColor XAllocColor 
2745 XColor g_itemColors
[5]; 
2746 int wxComputeColours (Display 
*display
, wxColour 
* back
, wxColour 
* fore
) 
2749     static XmColorProc colorProc
; 
2751     result 
= wxNO_COLORS
; 
2755         g_itemColors
[0].red 
= (((long) back
->Red ()) << 8); 
2756         g_itemColors
[0].green 
= (((long) back
->Green ()) << 8); 
2757         g_itemColors
[0].blue 
= (((long) back
->Blue ()) << 8); 
2758         g_itemColors
[0].flags 
= DoRed 
| DoGreen 
| DoBlue
; 
2759         if (colorProc 
== (XmColorProc
) NULL
) 
2761             // Get a ptr to the actual function 
2762             colorProc 
= XmSetColorCalculation ((XmColorProc
) NULL
); 
2763             // And set it back to motif. 
2764             XmSetColorCalculation (colorProc
); 
2766         (*colorProc
) (&g_itemColors
[wxBACK_INDEX
], 
2767             &g_itemColors
[wxFORE_INDEX
], 
2768             &g_itemColors
[wxSELE_INDEX
], 
2769             &g_itemColors
[wxTOPS_INDEX
], 
2770             &g_itemColors
[wxBOTS_INDEX
]); 
2771         result 
= wxBACK_COLORS
; 
2775         g_itemColors
[wxFORE_INDEX
].red 
= (((long) fore
->Red ()) << 8); 
2776         g_itemColors
[wxFORE_INDEX
].green 
= (((long) fore
->Green ()) << 8); 
2777         g_itemColors
[wxFORE_INDEX
].blue 
= (((long) fore
->Blue ()) << 8); 
2778         g_itemColors
[wxFORE_INDEX
].flags 
= DoRed 
| DoGreen 
| DoBlue
; 
2779         if (result 
== wxNO_COLORS
) 
2780             result 
= wxFORE_COLORS
; 
2783     Display 
*dpy 
= display
; 
2784     Colormap cmap 
= (Colormap
) wxTheApp
->GetMainColormap((WXDisplay
*) dpy
); 
2788         /* 5 Colours to allocate */ 
2789         for (int i 
= 0; i 
< 5; i
++) 
2790             if (!YAllocColor (dpy
, cmap
, &g_itemColors
[i
])) 
2791                 result 
= wxNO_COLORS
; 
2795         /* Only 1 colour to allocate */ 
2796         if (!YAllocColor (dpy
, cmap
, &g_itemColors
[wxFORE_INDEX
])) 
2797             result 
= wxNO_COLORS
; 
2804 // Changes the foreground and background colours to be derived from the current 
2805 // background colour. To change the foreground colour, you must call 
2806 // SetForegroundColour explicitly. 
2807 void wxWindow::ChangeBackgroundColour() 
2809     WXWidget mainWidget 
= GetMainWidget(); 
2811         DoChangeBackgroundColour(mainWidget
, m_backgroundColour
); 
2813     // This not necessary 
2816     if (m_scrolledWindow 
&& (GetMainWidget() != m_scrolledWindow
)) 
2818         DoChangeBackgroundColour(m_scrolledWindow
, m_backgroundColour
); 
2819         // Have to set the scrollbar colours back since 
2820         // the scrolled window seemed to change them 
2821         wxColour backgroundColour 
= wxSystemSettings::GetSystemColour(wxSYS_COLOUR_3DFACE
); 
2824             DoChangeBackgroundColour(m_hScrollBar
, backgroundColour
); 
2826             DoChangeBackgroundColour(m_vScrollBar
, backgroundColour
); 
2831 void wxWindow::ChangeForegroundColour() 
2833     WXWidget mainWidget 
= GetMainWidget(); 
2835         DoChangeForegroundColour(mainWidget
, m_foregroundColour
); 
2836     if ( m_scrolledWindow 
&& mainWidget 
!= m_scrolledWindow 
) 
2837         DoChangeForegroundColour(m_scrolledWindow
, m_foregroundColour
); 
2840 // Change a widget's foreground and background colours. 
2841 void wxWindow::DoChangeForegroundColour(WXWidget widget
, wxColour
& foregroundColour
) 
2843     // When should we specify the foreground, if it's calculated 
2844     // by wxComputeColours? 
2845     // Solution: say we start with the default (computed) foreground colour. 
2846     // If we call SetForegroundColour explicitly for a control or window, 
2847     // then the foreground is changed. 
2848     // Therefore SetBackgroundColour computes the foreground colour, and 
2849     // SetForegroundColour changes the foreground colour. The ordering is 
2852     Widget w 
= (Widget
)widget
; 
2855                   XmNforeground
, foregroundColour
.AllocColour(XtDisplay(w
)), 
2860 void wxWindow::DoChangeBackgroundColour(WXWidget widget
, wxColour
& backgroundColour
, bool changeArmColour
) 
2862     wxComputeColours (XtDisplay((Widget
) widget
), & backgroundColour
, 
2865     XtVaSetValues ((Widget
) widget
, 
2866         XmNbackground
, g_itemColors
[wxBACK_INDEX
].pixel
, 
2867         XmNtopShadowColor
, g_itemColors
[wxTOPS_INDEX
].pixel
, 
2868         XmNbottomShadowColor
, g_itemColors
[wxBOTS_INDEX
].pixel
, 
2869         XmNforeground
, g_itemColors
[wxFORE_INDEX
].pixel
, 
2872     if (changeArmColour
) 
2873         XtVaSetValues ((Widget
) widget
, 
2874         XmNarmColor
, g_itemColors
[wxSELE_INDEX
].pixel
, 
2878 bool wxWindow::SetBackgroundColour(const wxColour
& col
) 
2880     if ( !wxWindowBase::SetBackgroundColour(col
) ) 
2883     ChangeBackgroundColour(); 
2888 bool wxWindow::SetForegroundColour(const wxColour
& col
) 
2890     if ( !wxWindowBase::SetForegroundColour(col
) ) 
2893     ChangeForegroundColour(); 
2898 void wxWindow::ChangeFont(bool keepOriginalSize
) 
2900     // Note that this causes the widget to be resized back 
2901     // to its original size! We therefore have to set the size 
2902     // back again. TODO: a better way in Motif? 
2903     Widget w 
= (Widget
) GetLabelWidget(); // Usually the main widget 
2904     if (w 
&& m_font
.Ok()) 
2906         int width
, height
, width1
, height1
; 
2907         GetSize(& width
, & height
); 
2909         // lesstif 0.87 hangs here 
2910 #ifndef LESSTIF_VERSION 
2912             XmNfontList
, (XmFontList
) m_font
.GetFontList(1.0, XtDisplay(w
)), 
2916         GetSize(& width1
, & height1
); 
2917         if (keepOriginalSize 
&& (width 
!= width1 
|| height 
!= height1
)) 
2919             SetSize(-1, -1, width
, height
); 
2924 // ---------------------------------------------------------------------------- 
2926 // ---------------------------------------------------------------------------- 
2928 wxWindow 
*wxGetActiveWindow() 
2934 // ---------------------------------------------------------------------------- 
2935 // wxNoOptimize: switch off size optimization 
2936 // ---------------------------------------------------------------------------- 
2938 int wxNoOptimize::ms_count 
= 0;