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" 
  42 #if  wxUSE_DRAG_AND_DROP 
  46 // DoSetSizeIntr and DoMoveWindowIntr 
  48 // under Motif composite controls (such as wxCalendarCtrl or generic wxSpinCtrl 
  49 // did not work and/or segfaulted because 
  50 // 1) wxWindow::Create calls SetSize, 
  51 //    which results in a call to DoSetSize much earlier than in the other ports 
  52 // 2) if wxWindow::Create is called (wxControl::Create calls it) 
  53 //    then DoSetSize is never called, causing layout problems in composite 
  57 // 1) don't call SetSize, DoSetSize, DoMoveWindow, DoGetPosition, 
  58 //    DoSetPosition directly or indirectly from wxWindow::Create 
  59 // 2) call DoMoveWindow from DoSetSize, allowing controls to override it 
  62     #pragma message disable nosimpint 
  66 #include <Xm/DrawingA.h> 
  67 #include <Xm/ScrolledW.h> 
  68 #include <Xm/ScrollBar.h> 
  71 #include <Xm/RowColumn.h>           // for XmMenuPosition 
  73     #pragma message enable nosimpint 
  76 #include "wx/motif/private.h" 
  77 #include "wx/motif/dcclient.h" 
  81 // ---------------------------------------------------------------------------- 
  82 // global variables for this module 
  83 // ---------------------------------------------------------------------------- 
  85 extern wxHashTable 
*wxWidgetHashTable
; 
  86 static wxWindow
* g_captureWindow 
= NULL
; 
  89 // ---------------------------------------------------------------------------- 
  91 // ---------------------------------------------------------------------------- 
  93 static void wxCanvasRepaintProc(Widget
, XtPointer
, XmDrawingAreaCallbackStruct 
* cbs
); 
  94 static void wxCanvasInputEvent(Widget drawingArea
, XtPointer data
, XmDrawingAreaCallbackStruct 
* cbs
); 
  95 static void wxCanvasMotionEvent(Widget
, XButtonEvent 
* event
); 
  96 static void wxCanvasEnterLeave(Widget drawingArea
, XtPointer clientData
, XCrossingEvent 
* event
); 
  97 static void wxScrollBarCallback(Widget widget
, XtPointer clientData
, 
  98                                 XmScrollBarCallbackStruct 
*cbs
); 
  99 static void wxPanelItemEventHandler(Widget    wid
, 
 100                                     XtPointer client_data
, 
 102                                     Boolean  
*continueToDispatch
); 
 107 // Helper function for 16-bit fonts 
 108 static int str16len(const char *s
) 
 112     while (s
[0] && s
[1]) { 
 122 // ---------------------------------------------------------------------------- 
 124 // ---------------------------------------------------------------------------- 
 126 #define event_left_is_down(x) ((x)->xbutton.state & Button1Mask) 
 127 #define event_middle_is_down(x) ((x)->xbutton.state & Button2Mask) 
 128 #define event_right_is_down(x) ((x)->xbutton.state & Button3Mask) 
 130 // ---------------------------------------------------------------------------- 
 132 // ---------------------------------------------------------------------------- 
 134     IMPLEMENT_DYNAMIC_CLASS(wxWindow
, wxWindowBase
) 
 136     BEGIN_EVENT_TABLE(wxWindow
, wxWindowBase
) 
 137         EVT_SYS_COLOUR_CHANGED(wxWindow::OnSysColourChanged
) 
 140 // ============================================================================ 
 142 // ============================================================================ 
 144 // ---------------------------------------------------------------------------- 
 146 // ---------------------------------------------------------------------------- 
 148 void wxWindow::UnmanageAndDestroy(WXWidget widget
) 
 150     Widget w 
= (Widget
)widget
; 
 158 bool wxWindow::MapOrUnmap(WXWidget widget
, bool domap
) 
 160     Widget w 
= (Widget
)widget
; 
 164     //   Rationale: a lot of common operations (including but not 
 165     // limited to moving, resizing and appending items to a listbox) 
 166     // unmamange the widget, do their work, then manage it again. 
 167     // This means that, for example adding an item to a listbox will show it, 
 168     // or that most controls are shown every time they are moved or resized! 
 169     XtSetMappedWhenManaged( w
, domap 
); 
 171     // if the widget is not unmanaged, it still intercepts 
 172     // mouse events, even if it is not mapped (and hence invisible) 
 187 // ---------------------------------------------------------------------------- 
 189 // ---------------------------------------------------------------------------- 
 191 void wxWindow::Init() 
 194     m_needsRefresh 
= true; 
 195     m_mainWidget 
= (WXWidget
) 0; 
 197     m_winCaptured 
= false; 
 205     m_drawingArea 
= (WXWidget
) 0; 
 210     m_backingPixmap 
= (WXPixmap
) 0; 
 221 // real construction (Init() must have been called before!) 
 222 bool wxWindow::Create(wxWindow 
*parent
, wxWindowID id
, 
 226                       const wxString
& name
) 
 228     // Get default border 
 229     wxBorder border 
= GetBorder(style
); 
 230     style 
&= ~wxBORDER_MASK
; 
 233     wxCHECK_MSG( parent
, false, "can't create wxWindow without parent" ); 
 235     CreateBase(parent
, id
, pos
, size
, style
, wxDefaultValidator
, name
); 
 237     parent
->AddChild(this); 
 240     //// TODO: we should probably optimize by only creating a 
 241     //// a drawing area if we have one or more scrollbars (wxVSCROLL/wxHSCROLL). 
 242     //// But for now, let's simplify things by always creating the 
 243     //// drawing area, since otherwise the translations are different. 
 245     // New translations for getting mouse motion feedback 
 246     static const String translations 
= wxMOTIF_STR( 
 247 "<Btn1Motion>: wxCanvasMotionEvent() DrawingAreaInput() ManagerGadgetButtonMotion()\n\ 
 248 <Btn2Motion>: wxCanvasMotionEvent() DrawingAreaInput() ManagerGadgetButtonMotion()\n\ 
 249 <Btn3Motion>: wxCanvasMotionEvent() DrawingAreaInput() ManagerGadgetButtonMotion()\n\ 
 250 <BtnMotion>: wxCanvasMotionEvent() DrawingAreaInput() ManagerGadgetButtonMotion()\n\ 
 251 <Btn1Down>: DrawingAreaInput() ManagerGadgetArm()\n\ 
 252 <Btn2Down>: DrawingAreaInput() ManagerGadgetArm()\n\ 
 253 <Btn3Down>: DrawingAreaInput() ManagerGadgetArm()\n\ 
 254 <Btn1Up>: DrawingAreaInput() ManagerGadgetActivate()\n\ 
 255 <Btn2Up>: DrawingAreaInput() ManagerGadgetActivate()\n\ 
 256 <Btn3Up>: DrawingAreaInput() ManagerGadgetActivate()\n\ 
 257 <Motion>: wxCanvasMotionEvent() DrawingAreaInput()\n\ 
 258 <EnterWindow>: wxCanvasMotionEvent() DrawingAreaInput()\n\ 
 259 <LeaveWindow>: wxCanvasMotionEvent() DrawingAreaInput()\n\ 
 260 <Key>: DrawingAreaInput()"); 
 262     XtActionsRec actions
[1]; 
 263     actions
[0].string 
= wxMOTIF_STR("wxCanvasMotionEvent"); 
 264     actions
[0].proc 
= (XtActionProc
) wxCanvasMotionEvent
; 
 265     XtAppAddActions ((XtAppContext
) wxTheApp
->GetAppContext(), actions
, 1); 
 267     Widget parentWidget 
= (Widget
) parent
->GetClientWidget(); 
 268     m_borderWidget 
= wxCreateBorderWidget( (WXWidget
)parentWidget
, style 
); 
 270     m_scrolledWindow 
= (WXWidget
)XtVaCreateManagedWidget
 
 273                                   xmScrolledWindowWidgetClass
, 
 274                                   m_borderWidget 
? (Widget
) m_borderWidget
 
 276                                   XmNresizePolicy
, XmRESIZE_NONE
, 
 278                                   XmNscrollingPolicy
, XmAPPLICATION_DEFINED
, 
 279                                   //XmNscrollBarDisplayPolicy, XmAS_NEEDED, 
 283     XtTranslations ptr 
= XtParseTranslationTable(translations
); 
 284     m_drawingArea 
= (WXWidget
)XtVaCreateWidget
 
 287                                xmDrawingAreaWidgetClass
, (Widget
) m_scrolledWindow
, 
 288                                XmNunitType
, XmPIXELS
, 
 289                                // XmNresizePolicy, XmRESIZE_ANY, 
 290                                XmNresizePolicy
, XmRESIZE_NONE
, 
 293                                XmNtranslations
, ptr
, 
 296     XtFree((char *) ptr
); 
 299     if (GetWindowStyleFlag() & wxOVERRIDE_KEY_TRANSLATIONS
) 
 301         ptr 
= XtParseTranslationTable ("<Key>: DrawingAreaInput()"); 
 302         XtOverrideTranslations ((Widget
) m_drawingArea
, ptr
); 
 303         XtFree ((char *) ptr
); 
 307     wxAddWindowToTable((Widget
) m_drawingArea
, this); 
 308     wxAddWindowToTable((Widget
) m_scrolledWindow
, this); 
 310     // This order is very important in Motif 1.2.1 
 311     XtRealizeWidget ((Widget
) m_scrolledWindow
); 
 312     XtRealizeWidget ((Widget
) m_drawingArea
); 
 313     XtManageChild ((Widget
) m_drawingArea
); 
 315     ptr 
= XtParseTranslationTable("<Configure>: resize()"); 
 316     XtOverrideTranslations((Widget
) m_drawingArea
, ptr
); 
 317     XtFree ((char *) ptr
); 
 319     XtAddCallback ((Widget
) m_drawingArea
, XmNexposeCallback
, (XtCallbackProc
) wxCanvasRepaintProc
, (XtPointer
) this); 
 320     XtAddCallback ((Widget
) m_drawingArea
, XmNinputCallback
, (XtCallbackProc
) wxCanvasInputEvent
, (XtPointer
) this); 
 323                       (Widget
)m_drawingArea
, 
 324                        PointerMotionHintMask 
| EnterWindowMask 
| 
 325                        LeaveWindowMask 
| FocusChangeMask
, 
 327                        (XtEventHandler
) wxCanvasEnterLeave
, 
 331     XmScrolledWindowSetAreas( 
 332                              (Widget
)m_scrolledWindow
, 
 333                              (Widget
) 0, (Widget
) 0, 
 334                              (Widget
) m_drawingArea
); 
 338     // Without this, the cursor may not be restored properly (e.g. in splitter 
 340     SetCursor(*wxSTANDARD_CURSOR
); 
 341     DoSetSizeIntr(pos
.x
, pos
.y
, size
.x
,size
.y
, wxSIZE_AUTO
, true); 
 346 wxWindow::~wxWindow() 
 348     if (g_captureWindow 
== this) 
 349         g_captureWindow 
= NULL
; 
 351     m_isBeingDeleted 
= true; 
 353     // Motif-specific actions first 
 354     WXWidget wMain 
= GetMainWidget(); 
 357         // Removes event handlers 
 361     // If m_drawingArea, we're a fully-fledged window with drawing area, 
 362     // scrollbars etc. (what wxCanvas used to be) 
 365         // Destroy children before destroying self 
 369             XFreePixmap (XtDisplay ((Widget
) GetMainWidget()), (Pixmap
) m_backingPixmap
); 
 371         Widget w 
= (Widget
) m_drawingArea
; 
 372         wxDeleteWindowFromTable(w
); 
 377             m_drawingArea 
= (WXWidget
) 0; 
 380         // Only if we're _really_ a canvas (not a dialog box/panel) 
 381         if (m_scrolledWindow
) 
 383             wxDeleteWindowFromTable((Widget
) m_scrolledWindow
); 
 388             wxDeleteWindowFromTable((Widget
) m_hScrollBar
); 
 389             XtUnmanageChild((Widget
) m_hScrollBar
); 
 393             wxDeleteWindowFromTable((Widget
) m_vScrollBar
); 
 394             XtUnmanageChild((Widget
) m_vScrollBar
); 
 398             XtDestroyWidget((Widget
) m_hScrollBar
); 
 400             XtDestroyWidget((Widget
) m_vScrollBar
); 
 402         UnmanageAndDestroy(m_scrolledWindow
); 
 406             XtDestroyWidget ((Widget
) m_borderWidget
); 
 407             m_borderWidget 
= (WXWidget
) 0; 
 410     else // Why wasn't this here before? JACS 8/3/2000 
 414     // Destroy the window 
 417         // If this line (XtDestroyWidget) causes a crash, you may comment it out. 
 418         // Child widgets will get destroyed automatically when a frame 
 419         // or dialog is destroyed, but before that you may get some memory 
 420         // leaks and potential layout problems if you delete and then add 
 423         // GRG, Feb/2000: commented this out when adding support for 
 424         //   wxSCROLL[WIN]_THUMBRELEASE events. Also it was reported 
 425         //   that this call crashed wxMotif under OS/2, so it seems 
 426         //   that leaving it out is the right thing to do. 
 427         // SN, Feb/2000: newgrid/griddemo shows why it is needed :-( 
 428         XtDestroyWidget((Widget
) GetMainWidget()); 
 429         SetMainWidget((WXWidget
) NULL
); 
 433 // ---------------------------------------------------------------------------- 
 434 // scrollbar management 
 435 // ---------------------------------------------------------------------------- 
 437 WXWidget 
wxWindow::DoCreateScrollBar(WXWidget parent
, 
 438                                      wxOrientation orientation
, 
 441     int orient 
= ( orientation 
& wxHORIZONTAL 
) ? XmHORIZONTAL 
: XmVERTICAL
; 
 443         XtVaCreateManagedWidget( "scrollBarWidget", 
 444                                  xmScrollBarWidgetClass
, (Widget
)parent
, 
 445                                  XmNorientation
, orient
, 
 450     XtPointer o 
= (XtPointer
)orientation
; 
 451     XtCallbackProc cb 
= (XtCallbackProc
)callback
; 
 453     XtAddCallback( sb
, XmNvalueChangedCallback
, cb
, o 
); 
 454     XtAddCallback( sb
, XmNdragCallback
, cb
, o 
); 
 455     XtAddCallback( sb
, XmNincrementCallback
, cb
, o 
); 
 456     XtAddCallback( sb
, XmNdecrementCallback
, cb
, o 
); 
 457     XtAddCallback( sb
, XmNpageIncrementCallback
, cb
, o 
); 
 458     XtAddCallback( sb
, XmNpageDecrementCallback
, cb
, o 
); 
 459     XtAddCallback( sb
, XmNtoTopCallback
, cb
, o 
); 
 460     XtAddCallback( sb
, XmNtoBottomCallback
, cb
, o 
); 
 466 void wxWindow::CreateScrollbar(wxOrientation orientation
) 
 468     wxCHECK_RET( m_drawingArea
, "this window can't have scrollbars" ); 
 470     XtVaSetValues( (Widget
) m_scrolledWindow
, 
 471                    XmNresizePolicy
, XmRESIZE_NONE
, 
 474     wxColour backgroundColour 
= wxSystemSettings::GetColour(wxSYS_COLOUR_3DFACE
); 
 475     // Add scrollbars if required 
 476     if (orientation 
== wxHORIZONTAL
) 
 478         m_hScrollBar 
= DoCreateScrollBar( m_scrolledWindow
, wxHORIZONTAL
, 
 479                                           (void (*)())wxScrollBarCallback 
); 
 481         wxDoChangeBackgroundColour(m_hScrollBar
, backgroundColour
, true); 
 483         XtRealizeWidget( (Widget
)m_hScrollBar 
); 
 485         XtVaSetValues((Widget
) m_scrolledWindow
, 
 486             XmNhorizontalScrollBar
, (Widget
) m_hScrollBar
, 
 489         wxAddWindowToTable( (Widget
)m_hScrollBar
, this ); 
 491     else if (orientation 
== wxVERTICAL
) 
 493         m_vScrollBar 
= DoCreateScrollBar( m_scrolledWindow
, wxVERTICAL
, 
 494                                           (void (*)())wxScrollBarCallback 
); 
 496         wxDoChangeBackgroundColour(m_vScrollBar
, backgroundColour
, true); 
 498         XtRealizeWidget((Widget
)m_vScrollBar
); 
 500         XtVaSetValues((Widget
) m_scrolledWindow
, 
 501             XmNverticalScrollBar
, (Widget
) m_vScrollBar
, 
 504         wxAddWindowToTable( (Widget
)m_vScrollBar
, this ); 
 507     XtVaSetValues( (Widget
) m_scrolledWindow
, 
 508                    XmNresizePolicy
, XmRESIZE_ANY
, 
 512 void wxWindow::DestroyScrollbar(wxOrientation orientation
) 
 514     wxCHECK_RET( m_drawingArea
, "this window can't have scrollbars" ); 
 516     XtVaSetValues((Widget
) m_scrolledWindow
, 
 517                   XmNresizePolicy
, XmRESIZE_NONE
, 
 519     String stringSB 
= orientation 
== wxHORIZONTAL 
? 
 520         XmNhorizontalScrollBar 
: XmNverticalScrollBar
; 
 521     WXWidget
* widgetSB 
= orientation 
== wxHORIZONTAL 
? 
 522         &m_hScrollBar 
: &m_vScrollBar
; 
 526         wxDeleteWindowFromTable( (Widget
)*widgetSB 
); 
 527         XtDestroyWidget( (Widget
)*widgetSB 
); 
 528         *widgetSB 
= (WXWidget
)NULL
; 
 531     XtVaSetValues( (Widget
)m_scrolledWindow
, 
 532                    stringSB
, (Widget
) 0, 
 535     XtVaSetValues((Widget
) m_scrolledWindow
, 
 536                   XmNresizePolicy
, XmRESIZE_ANY
, 
 540 // --------------------------------------------------------------------------- 
 542 // --------------------------------------------------------------------------- 
 544 void wxWindow::SetFocus() 
 546     Widget wMain 
= (Widget
) GetMainWidget(); 
 547     XmProcessTraversal(wMain
, XmTRAVERSE_CURRENT
); 
 548     XmProcessTraversal((Widget
) GetMainWidget(), XmTRAVERSE_CURRENT
); 
 551 // Get the window with the focus 
 552 wxWindow 
*wxWindowBase::DoFindFocus() 
 555     // (1) Can there be multiple focussed widgets in an application? 
 556     // In which case we need to find the top-level window that's 
 558     // (2) The widget with the focus may not be in the widget table 
 559     // depending on which widgets I put in the table 
 560     wxWindow 
*winFocus 
= (wxWindow 
*)NULL
; 
 561     for ( wxWindowList::compatibility_iterator node 
= wxTopLevelWindows
.GetFirst(); 
 563           node 
= node
->GetNext() ) 
 565         wxWindow 
*win 
= node
->GetData(); 
 567         Widget w 
= XmGetFocusWidget ((Widget
) win
->GetTopWidget()); 
 569         if (w 
!= (Widget
) NULL
) 
 571             winFocus 
= wxGetWindowFromTable(w
); 
 580 bool wxWindow::Enable(bool enable
) 
 582     if ( !wxWindowBase::Enable(enable
) ) 
 585     Widget wMain 
= (Widget
)GetMainWidget(); 
 588         XtSetSensitive(wMain
, enable
); 
 589         XmUpdateDisplay(wMain
); 
 595 bool wxWindow::Show(bool show
) 
 597     if ( !wxWindowBase::Show(show
) ) 
 600     if (m_borderWidget 
|| m_scrolledWindow
) 
 602         MapOrUnmap(m_borderWidget 
? m_borderWidget 
: m_scrolledWindow
, show
); 
 603         // MapOrUnmap(m_drawingArea, show); 
 607         if ( !MapOrUnmap(GetTopWidget(), show
) ) 
 608             MapOrUnmap(GetMainWidget(), show
); 
 614 // Raise the window to the top of the Z order 
 615 void wxWindow::Raise() 
 617     Widget wTop 
= (Widget
) GetTopWidget(); 
 618     Window window 
= XtWindow(wTop
); 
 619     XRaiseWindow(XtDisplay(wTop
), window
); 
 622 // Lower the window to the bottom of the Z order 
 623 void wxWindow::Lower() 
 625     Widget wTop 
= (Widget
) GetTopWidget(); 
 626     Window window 
= XtWindow(wTop
); 
 627     XLowerWindow(XtDisplay(wTop
), window
); 
 630 void wxWindow::SetLabel(const wxString
& label
) 
 632     XtVaSetValues((Widget
)GetMainWidget(), XmNtitle
, 
 633                   (const char*)label
.mb_str(), NULL
); 
 636 wxString 
wxWindow::GetLabel() const 
 639     XtVaGetValues((Widget
)GetMainWidget(), XmNtitle
, &label
, NULL
); 
 641     return wxString(label
); 
 644 void wxWindow::DoCaptureMouse() 
 646     g_captureWindow 
= this; 
 650     Widget wMain 
= (Widget
)GetMainWidget(); 
 652         XtAddGrab(wMain
, True
, False
); 
 654     m_winCaptured 
= true; 
 657 void wxWindow::DoReleaseMouse() 
 659     g_captureWindow 
= NULL
; 
 660     if ( !m_winCaptured 
) 
 663     Widget wMain 
= (Widget
)GetMainWidget(); 
 667     m_winCaptured 
= false; 
 670 bool wxWindow::SetFont(const wxFont
& font
) 
 672     if ( !wxWindowBase::SetFont(font
) ) 
 683 bool wxWindow::SetCursor(const wxCursor
& cursor
) 
 685     if ( !wxWindowBase::SetCursor(cursor
) ) 
 691     //    wxASSERT_MSG( m_cursor.Ok(), 
 692     //                  wxT("cursor must be valid after call to the base version")); 
 693     const wxCursor
* cursor2 
= NULL
; 
 695         cursor2 
= & m_cursor
; 
 697         cursor2 
= wxSTANDARD_CURSOR
; 
 699     WXDisplay 
*dpy 
= GetXDisplay(); 
 700     WXCursor x_cursor 
= cursor2
->GetXCursor(dpy
); 
 702     Widget w 
= (Widget
) GetMainWidget(); 
 703     Window win 
= XtWindow(w
); 
 704     XDefineCursor((Display
*) dpy
, win
, (Cursor
) x_cursor
); 
 709 // Coordinates relative to the window 
 710 void wxWindow::WarpPointer (int x
, int y
) 
 712     Widget wClient 
= (Widget
)GetClientWidget(); 
 714     XWarpPointer(XtDisplay(wClient
), None
, XtWindow(wClient
), 0, 0, 0, 0, x
, y
); 
 717 // --------------------------------------------------------------------------- 
 719 // --------------------------------------------------------------------------- 
 721 int wxWindow::GetScrollPos(int orient
) const 
 723     if (orient 
== wxHORIZONTAL
) 
 729     Widget scrollBar 
= (Widget
) ((orient 
== wxHORIZONTAL
) ? m_hScrollBar 
: m_vScrollBar
); 
 733         XtVaGetValues(scrollBar
, XmNvalue
, &pos
, NULL
); 
 741 // This now returns the whole range, not just the number of positions that we 
 743 int wxWindow::GetScrollRange(int orient
) const 
 745     Widget scrollBar 
= (Widget
)GetScrollbar((wxOrientation
)orient
); 
 746     // CE scintilla windows don't always have these scrollbars 
 747     // and it tends to pile up a whole bunch of asserts 
 748     //wxCHECK_MSG( scrollBar, 0, "no such scrollbar" ); 
 752         XtVaGetValues(scrollBar
, XmNmaximum
, &range
, NULL
); 
 756 int wxWindow::GetScrollThumb(int orient
) const 
 758     Widget scrollBar 
= (Widget
)GetScrollbar((wxOrientation
)orient
); 
 759     //wxCHECK_MSG( scrollBar, 0, "no such scrollbar" ); 
 763         XtVaGetValues(scrollBar
, XmNsliderSize
, &thumb
, NULL
); 
 767 void wxWindow::SetScrollPos(int orient
, int pos
, bool WXUNUSED(refresh
)) 
 769     Widget scrollBar 
= (Widget
)GetScrollbar((wxOrientation
)orient
); 
 773         XtVaSetValues (scrollBar
, XmNvalue
, pos
, NULL
); 
 776     SetInternalScrollPos((wxOrientation
)orient
, pos
); 
 779 // New function that will replace some of the above. 
 780 void wxWindow::SetScrollbar(int orient
, int pos
, int thumbVisible
, 
 781                             int range
, bool WXUNUSED(refresh
)) 
 784     GetSize(& oldW
, & oldH
); 
 788     if (thumbVisible 
== 0) 
 791     if (thumbVisible 
> range
) 
 792         thumbVisible 
= range
; 
 794     // Save the old state to see if it changed 
 795     WXWidget oldScrollBar 
= GetScrollbar((wxOrientation
)orient
); 
 797     if (orient 
== wxHORIZONTAL
) 
 799         if (thumbVisible 
== range
) 
 802                 DestroyScrollbar(wxHORIZONTAL
); 
 807                 CreateScrollbar(wxHORIZONTAL
); 
 810     if (orient 
== wxVERTICAL
) 
 812         if (thumbVisible 
== range
) 
 815                 DestroyScrollbar(wxVERTICAL
); 
 820                 CreateScrollbar(wxVERTICAL
); 
 823     WXWidget newScrollBar 
=  GetScrollbar((wxOrientation
)orient
); 
 825     if (oldScrollBar 
!= newScrollBar
) 
 827         // This is important! Without it, scrollbars misbehave badly. 
 828         XtUnrealizeWidget((Widget
) m_scrolledWindow
); 
 829         XmScrolledWindowSetAreas ((Widget
) m_scrolledWindow
, (Widget
) m_hScrollBar
, (Widget
) m_vScrollBar
, (Widget
) m_drawingArea
); 
 830         XtRealizeWidget((Widget
) m_scrolledWindow
); 
 831         XtManageChild((Widget
) m_scrolledWindow
); 
 836         XtVaSetValues((Widget
) newScrollBar
, 
 840         XmNsliderSize
, thumbVisible
, 
 844     SetInternalScrollPos((wxOrientation
)orient
, pos
); 
 847     GetSize(& newW
, & newH
); 
 849     // Adjusting scrollbars can resize the canvas accidentally 
 850     if (newW 
!= oldW 
|| newH 
!= oldH
) 
 851         SetSize(wxDefaultCoord
, wxDefaultCoord
, oldW
, oldH
); 
 854 // Does a physical scroll 
 855 void wxWindow::ScrollWindow(int dx
, int dy
, const wxRect 
*rect
) 
 860         // Use specified rectangle 
 861         x 
= rect
->x
; y 
= rect
->y
; w 
= rect
->width
; h 
= rect
->height
; 
 865         // Use whole client area 
 867         GetClientSize(& w
, & h
); 
 870     int x1 
= (dx 
>= 0) ? x 
: x 
- dx
; 
 871     int y1 
= (dy 
>= 0) ? y 
: y 
- dy
; 
 872     int w1 
= w 
- abs(dx
); 
 873     int h1 
= h 
- abs(dy
); 
 874     int x2 
= (dx 
>= 0) ? x 
+ dx 
: x
; 
 875     int y2 
= (dy 
>= 0) ? y 
+ dy 
: y
; 
 878     wxClientDCImpl 
* const 
 879         dcimpl 
= static_cast<wxClientDCImpl 
*>(dc
.GetImpl()); 
 880     GC 
const gc 
= (GC
) dcimpl
->GetGC(); 
 882     dc
.SetLogicalFunction (wxCOPY
); 
 884     Widget widget 
= (Widget
) GetMainWidget(); 
 885     Window window 
= XtWindow(widget
); 
 886     Display
* display 
= XtDisplay(widget
); 
 888     XCopyArea(display
, window
, window
, gc
, x1
, y1
, w1
, h1
, x2
, y2
); 
 890     dcimpl
->SetAutoSetting(true); 
 891     wxBrush 
brush(GetBackgroundColour(), wxSOLID
); 
 892     dc
.SetBrush(brush
); // FIXME: needed? 
 894     wxWindowList::compatibility_iterator cnode 
= m_children
.GetFirst(); 
 897         wxWindow 
*child 
= cnode
->GetData(); 
 900         child
->GetSize( &sx
, &sy 
); 
 901         wxPoint 
pos( child
->GetPosition() ); 
 902         child
->SetSize( pos
.x 
+ dx
, pos
.y 
+ dy
, sx
, sy
, wxSIZE_ALLOW_MINUS_ONE 
); 
 903         cnode 
= cnode
->GetNext(); 
 906     // We'll add rectangles to the list of update rectangles according to which 
 907     // bits we've exposed. 
 912         wxRect 
*rect 
= new wxRect
; 
 918         XFillRectangle(display
, window
, gc
, rect
->x
, rect
->y
, rect
->width
, rect
->height
); 
 922         rect
->width 
= rect
->width
; 
 923         rect
->height 
= rect
->height
; 
 925         updateRects
.Append((wxObject
*) rect
); 
 929         wxRect 
*rect 
= new wxRect
; 
 931         rect
->x 
= x 
+ w 
+ dx
; 
 936         XFillRectangle(display
, window
, gc
, rect
->x
, rect
->y
, rect
->width
, rect
->height
); 
 940         rect
->width 
= rect
->width
; 
 941         rect
->height 
= rect
->height
; 
 943         updateRects
.Append((wxObject
*) rect
); 
 947         wxRect 
*rect 
= new wxRect
; 
 954         XFillRectangle(display
, window
, gc
, rect
->x
, rect
->y
, rect
->width
, rect
->height
); 
 958         rect
->width 
= rect
->width
; 
 959         rect
->height 
= rect
->height
; 
 961         updateRects
.Append((wxObject
*) rect
); 
 965         wxRect 
*rect 
= new wxRect
; 
 968         rect
->y 
= y 
+ h 
+ dy
; 
 972         XFillRectangle(display
, window
, gc
, rect
->x
, rect
->y
, rect
->width
, rect
->height
); 
 976         rect
->width 
= rect
->width
; 
 977         rect
->height 
= rect
->height
; 
 979         updateRects
.Append((wxObject
*) rect
); 
 981     dc
.SetBrush(wxNullBrush
); 
 983     // Now send expose events 
 985     wxList::compatibility_iterator  node 
= updateRects
.GetFirst(); 
 988         wxRect
* rect 
= (wxRect
*) node
->GetData(); 
 992         event
.display 
= display
; 
 993         event
.send_event 
= True
; 
 994         event
.window 
= window
; 
 998         event
.width 
= rect
->width
; 
 999         event
.height 
= rect
->height
; 
1003         XSendEvent(display
, window
, False
, ExposureMask
, (XEvent 
*)&event
); 
1005         node 
= node
->GetNext(); 
1009     // Delete the update rects 
1010     node 
= updateRects
.GetFirst(); 
1013         wxRect
* rect 
= (wxRect
*) node
->GetData(); 
1015         node 
= node
->GetNext(); 
1018     XmUpdateDisplay((Widget
) GetMainWidget()); 
1021 // --------------------------------------------------------------------------- 
1023 // --------------------------------------------------------------------------- 
1025 #if wxUSE_DRAG_AND_DROP 
1027 void wxWindow::SetDropTarget(wxDropTarget 
* WXUNUSED(pDropTarget
)) 
1034 // Old style file-manager drag&drop 
1035 void wxWindow::DragAcceptFiles(bool WXUNUSED(accept
)) 
1040 // ---------------------------------------------------------------------------- 
1042 // ---------------------------------------------------------------------------- 
1046 void wxWindow::DoSetToolTip(wxToolTip 
* WXUNUSED(tooltip
)) 
1051 #endif // wxUSE_TOOLTIPS 
1053 // ---------------------------------------------------------------------------- 
1055 // ---------------------------------------------------------------------------- 
1059 bool wxWindow::DoPopupMenu(wxMenu 
*menu
, int x
, int y
) 
1061     if ( x 
== wxDefaultCoord 
&& y 
== wxDefaultCoord 
) 
1063         wxPoint mouse 
= ScreenToClient(wxGetMousePosition()); 
1064         x 
= mouse
.x
; y 
= mouse
.y
; 
1067     Widget widget 
= (Widget
) GetMainWidget(); 
1069     /* The menuId field seems to be usused, so we'll use it to 
1070     indicate whether a menu is popped up or not: 
1071     0: Not currently created as a popup 
1072     -1: Created as a popup, but not active 
1076     if (menu
->GetParent() && (menu
->GetId() != -1)) 
1079     if (menu
->GetMainWidget()) 
1081         menu
->DestroyMenu(true); 
1084     menu
->SetId(1); /* Mark as popped-up */ 
1085     menu
->CreateMenu(NULL
, widget
, menu
, 0); 
1086     menu
->SetInvokingWindow(this); 
1090     //  menu->SetParent(parent); 
1091     //  parent->children->Append(menu);  // Store menu for later deletion 
1093     Widget menuWidget 
= (Widget
) menu
->GetMainWidget(); 
1101     if (this->IsKindOf(CLASSINFO(wxCanvas))) 
1103     wxCanvas *canvas = (wxCanvas *) this; 
1104     deviceX = canvas->GetDC ()->LogicalToDeviceX (x); 
1105     deviceY = canvas->GetDC ()->LogicalToDeviceY (y); 
1109     Display 
*display 
= XtDisplay (widget
); 
1110     Window rootWindow 
= RootWindowOfScreen (XtScreen((Widget
)widget
)); 
1111     Window thisWindow 
= XtWindow (widget
); 
1113     XTranslateCoordinates (display
, thisWindow
, rootWindow
, (int) deviceX
, (int) deviceY
, 
1114         &rootX
, &rootY
, &childWindow
); 
1116     XButtonPressedEvent event
; 
1117     event
.type 
= ButtonPress
; 
1123     event
.x_root 
= rootX
; 
1124     event
.y_root 
= rootY
; 
1126     XmMenuPosition (menuWidget
, &event
); 
1127     XtManageChild (menuWidget
); 
1129     // The ID of a pop-up menu is 1 when active, and is set to 0 by the 
1130     // idle-time destroy routine. 
1131     // Waiting until this ID changes causes this function to block until 
1132     // the menu has been dismissed and the widgets cleaned up. 
1133     // In other words, once this routine returns, it is safe to delete 
1135     // Ian Brown <ian.brown@printsoft.de> 
1137     wxEventLoop evtLoop
; 
1139     while (menu
->GetId() == 1) 
1141         wxDoEventLoopIteration( evtLoop 
); 
1149 // --------------------------------------------------------------------------- 
1150 // moving and resizing 
1151 // --------------------------------------------------------------------------- 
1153 bool wxWindow::PreResize() 
1159 void wxWindow::DoGetSize(int *x
, int *y
) const 
1161     Widget widget 
= (Widget
)( !m_drawingArea 
? GetTopWidget() : 
1162                               ( m_borderWidget 
? m_borderWidget 
: 
1163                                 m_scrolledWindow 
? m_scrolledWindow 
: 
1168         XtVaGetValues( widget
, 
1172     if(x
) *x 
= widget 
? xx 
: -1; 
1173     if(y
) *y 
= widget 
? yy 
: -1; 
1176 void wxWindow::DoGetPosition(int *x
, int *y
) const 
1178     Widget widget 
= (Widget
) 
1180           ( m_borderWidget 
? m_borderWidget 
: m_scrolledWindow 
) : 
1184     XtVaGetValues(widget
, XmNx
, &xx
, XmNy
, &yy
, NULL
); 
1186     // We may be faking the client origin. So a window that's really at (0, 30) 
1187     // may appear (to wxWin apps) to be at (0, 0). 
1190         wxPoint 
pt(GetParent()->GetClientAreaOrigin()); 
1191         xx 
= (Position
)(xx 
- pt
.x
); 
1192         yy 
= (Position
)(yy 
- pt
.y
); 
1199 void wxWindow::DoScreenToClient(int *x
, int *y
) const 
1201     Widget widget 
= (Widget
) GetClientWidget(); 
1202     Display 
*display 
= XtDisplay((Widget
) GetMainWidget()); 
1203     Window rootWindow 
= RootWindowOfScreen(XtScreen(widget
)); 
1204     Window thisWindow 
= XtWindow(widget
); 
1207     int xx 
= x 
? *x 
: 0; 
1208     int yy 
= y 
? *y 
: 0; 
1209     XTranslateCoordinates(display
, rootWindow
, thisWindow
, 
1210                           xx
, yy
, x 
? x 
: &xx
, y 
? y 
: &yy
, 
1214 void wxWindow::DoClientToScreen(int *x
, int *y
) const 
1216     Widget widget 
= (Widget
) GetClientWidget(); 
1217     Display 
*display 
= XtDisplay(widget
); 
1218     Window rootWindow 
= RootWindowOfScreen(XtScreen(widget
)); 
1219     Window thisWindow 
= XtWindow(widget
); 
1222     int xx 
= x 
? *x 
: 0; 
1223     int yy 
= y 
? *y 
: 0; 
1224     XTranslateCoordinates(display
, thisWindow
, rootWindow
, 
1225                           xx
, yy
, x 
? x 
: &xx
, y 
? y 
: &yy
, 
1230 // Get size *available for subwindows* i.e. excluding menu bar etc. 
1231 void wxWindow::DoGetClientSize(int *x
, int *y
) const 
1233     Widget widget 
= (Widget
) GetClientWidget(); 
1235     XtVaGetValues(widget
, XmNwidth
, &xx
, XmNheight
, &yy
, NULL
); 
1236     if(x
) *x 
= xx
; if(y
) *y 
= yy
; 
1239 void wxWindow::DoSetSize(int x
, int y
, int width
, int height
, int sizeFlags
) 
1241     DoSetSizeIntr(x
, y
, width
, height
, sizeFlags
, false); 
1244 void wxWindow::DoSetSizeIntr(int x
, int y
, int width
, int height
, 
1245                              int sizeFlags
, bool fromCtor
) 
1247     // A bit of optimization to help sort out the flickers. 
1248     int oldX 
= -1, oldY 
= -1, oldW 
= -1, oldH 
= -1; 
1252         GetSize(& oldW
, & oldH
); 
1253         GetPosition(& oldX
, & oldY
); 
1261     if ( !(sizeFlags 
& wxSIZE_ALLOW_MINUS_ONE
) ) 
1269     wxSize 
size(wxDefaultSize
); 
1272         if ( ( sizeFlags 
& wxSIZE_AUTO_WIDTH 
) && !fromCtor 
) 
1274             size 
= DoGetBestSize(); 
1285         if( ( sizeFlags 
& wxSIZE_AUTO_HEIGHT 
) && !fromCtor 
) 
1287             if( size
.x 
== -1 ) size 
= DoGetBestSize(); 
1296     if ( x 
!= oldX 
|| y 
!= oldY 
|| width 
!= oldW 
|| height 
!= oldH
 
1297          || !wxNoOptimize::CanOptimize() ) 
1310                 flags 
|= wxMOVE_WIDTH
; 
1313                 flags 
|= wxMOVE_HEIGHT
; 
1315             int xx 
= x
; int yy 
= y
; 
1316             AdjustForParentClientOrigin(xx
, yy
, sizeFlags
); 
1318                 DoMoveWindow( xx
, yy
, width
, height 
); 
1320                 DoMoveWindowIntr( xx
, yy
, width
, height
, flags 
); 
1325         Widget widget 
= (Widget
) GetTopWidget(); 
1329         bool managed 
= XtIsManaged( widget 
); 
1331             XtUnmanageChild(widget
); 
1335         AdjustForParentClientOrigin(xx
, yy
, sizeFlags
); 
1337         DoMoveWindow(xx
, yy
, width
, height
); 
1340             XtManageChild(widget
); 
1344 void wxWindow::DoSetClientSize(int width
, int height
) 
1348         Widget drawingArea 
= (Widget
) m_drawingArea
; 
1350         XtVaSetValues(drawingArea
, XmNresizePolicy
, XmRESIZE_ANY
, NULL
); 
1353             XtVaSetValues(drawingArea
, XmNwidth
, width
, NULL
); 
1355             XtVaSetValues(drawingArea
, XmNheight
, height
, NULL
); 
1357         XtVaSetValues(drawingArea
, XmNresizePolicy
, XmRESIZE_NONE
, NULL
); 
1361     Widget widget 
= (Widget
) GetTopWidget(); 
1364         XtVaSetValues(widget
, XmNwidth
, width
, NULL
); 
1366         XtVaSetValues(widget
, XmNheight
, height
, NULL
); 
1369 void wxWindow::DoMoveWindowIntr(int xx
, int yy
, int w
, int h
, 
1374         Widget drawingArea 
= (Widget
) m_drawingArea
; 
1375         Widget borderOrScrolled 
= m_borderWidget 
? 
1376             (Widget
) m_borderWidget 
: 
1377             (Widget
) m_scrolledWindow
; 
1379         bool managed 
= XtIsManaged(borderOrScrolled
); 
1381             XtUnmanageChild (borderOrScrolled
); 
1382         XtVaSetValues(drawingArea
, XmNresizePolicy
, XmRESIZE_ANY
, NULL
); 
1384         if (flags 
& wxMOVE_X
) 
1385             XtVaSetValues (borderOrScrolled
, 
1388         if (flags 
& wxMOVE_Y
) 
1389             XtVaSetValues (borderOrScrolled
, 
1393         if (flags 
& wxMOVE_WIDTH
) 
1397                 XtVaSetValues ((Widget
) m_borderWidget
, XmNwidth
, w
, NULL
); 
1398                 short thick
, margin
; 
1399                 XtVaGetValues ((Widget
) m_borderWidget
, 
1400                                XmNshadowThickness
, &thick
, 
1401                                XmNmarginWidth
, &margin
, 
1403                 w 
-= 2 * (thick 
+ margin
); 
1407             XtVaSetValues ((Widget
) m_scrolledWindow
, XmNwidth
, w
, NULL
); 
1410         if (flags 
& wxMOVE_HEIGHT
) 
1414                 XtVaSetValues ((Widget
) m_borderWidget
, XmNheight
, h
, NULL
); 
1415                 short thick
, margin
; 
1416                 XtVaGetValues ((Widget
) m_borderWidget
, 
1417                                XmNshadowThickness
, &thick
, 
1418                                XmNmarginHeight
, &margin
, 
1420                 h 
-= 2 * (thick 
+ margin
); 
1424             XtVaSetValues ((Widget
) m_scrolledWindow
, XmNheight
, h
, NULL
); 
1428             XtManageChild (borderOrScrolled
); 
1429         XtVaSetValues(drawingArea
, XmNresizePolicy
, XmRESIZE_NONE
, NULL
); 
1436         XtVaSetValues((Widget
)GetTopWidget(), 
1445 void wxWindow::DoMoveWindow(int x
, int y
, int width
, int height
) 
1447     DoMoveWindowIntr (x
, y
, width
, height
, 
1448                       wxMOVE_X
|wxMOVE_Y
|wxMOVE_WIDTH
|wxMOVE_HEIGHT
); 
1451 // --------------------------------------------------------------------------- 
1453 // --------------------------------------------------------------------------- 
1455 int wxWindow::GetCharHeight() const 
1460         wxGetTextExtent (GetXDisplay(), m_font
, 1.0, 
1461                          "x", NULL
, &height
, NULL
, NULL
); 
1463         wxGetTextExtent (this, "x", NULL
, &height
, NULL
, NULL
); 
1468 int wxWindow::GetCharWidth() const 
1473         wxGetTextExtent (GetXDisplay(), m_font
, 1.0, 
1474                          "x", &width
, NULL
, NULL
, NULL
); 
1476         wxGetTextExtent (this, "x", &width
, NULL
, NULL
, NULL
); 
1481 void wxWindow::GetTextExtent(const wxString
& string
, 
1483                              int *descent
, int *externalLeading
, 
1484                              const wxFont 
*theFont
) const 
1486     const wxFont 
*fontToUse 
= theFont 
? theFont 
: &m_font
; 
1488     if (externalLeading
) 
1489         *externalLeading 
= 0; 
1490     if (fontToUse
->Ok()) 
1491         wxGetTextExtent (GetXDisplay(), *fontToUse
, 1.0, 
1492                          string
, x
, y
, NULL
, descent
); 
1494         wxGetTextExtent (this, string
, x
, y
, NULL
, descent
); 
1497 // ---------------------------------------------------------------------------- 
1499 // ---------------------------------------------------------------------------- 
1501 void wxWindow::AddUpdateRect(int x
, int y
, int w
, int h
) 
1503     m_updateRegion
.Union( x
, y
, w
, h 
); 
1506 void wxWindow::Refresh(bool eraseBack
, const wxRect 
*rect
) 
1508     Widget widget 
= (Widget
) GetMainWidget(); 
1511     m_needsRefresh 
= true; 
1512     Display 
*display 
= XtDisplay(widget
); 
1513     Window thisWindow 
= XtWindow(widget
); 
1515     XExposeEvent dummyEvent
; 
1517     GetSize(&width
, &height
); 
1519     dummyEvent
.type 
= Expose
; 
1520     dummyEvent
.display 
= display
; 
1521     dummyEvent
.send_event 
= True
; 
1522     dummyEvent
.window 
= thisWindow
; 
1525         dummyEvent
.x 
= rect
->x
; 
1526         dummyEvent
.y 
= rect
->y
; 
1527         dummyEvent
.width 
= rect
->width
; 
1528         dummyEvent
.height 
= rect
->height
; 
1534         dummyEvent
.width 
= width
; 
1535         dummyEvent
.height 
= height
; 
1537     dummyEvent
.count 
= 0; 
1541         wxClientDC 
dc(this); 
1542         wxBrush 
backgroundBrush(GetBackgroundColour(), wxSOLID
); 
1543         dc
.SetBackground(backgroundBrush
); 
1545         wxClientDCImpl 
* const 
1546             dcimpl 
= static_cast<wxClientDCImpl 
*>(dc
.GetImpl()); 
1548             dcimpl
->Clear(*rect
); 
1553     XSendEvent(display
, thisWindow
, False
, ExposureMask
, (XEvent 
*)&dummyEvent
); 
1556 void wxWindow::DoPaint() 
1558     //TODO : make a temporary gc so we can do the XCopyArea below 
1559     if (m_backingPixmap 
&& !m_needsRefresh
) 
1563       wxPaintDCImpl 
* const 
1564           dcimpl 
= static_cast<wxPaintDCImpl 
*>(dc
.GetImpl()); 
1566       GC tempGC 
= (GC
) dcimpl
->GetBackingGC(); 
1568       Widget widget 
= (Widget
) GetMainWidget(); 
1573       // We have to test whether it's a wxScrolledWindow (hack!) because 
1574       // otherwise we don't know how many pixels have been scrolled. We might 
1575       // solve this in the future by defining virtual wxWindow functions to get 
1576       // the scroll position in pixels. Or, each kind of scrolled window has to 
1577       // implement backing stores itself, using generic wxWidgets code. 
1578       wxScrolledWindow
* scrolledWindow 
= wxDynamicCast(this, wxScrolledWindow
); 
1579       if ( scrolledWindow 
) 
1582           scrolledWindow
->CalcScrolledPosition(0, 0, &x
, &y
); 
1588       // TODO: This could be optimized further by only copying the areas in the 
1589       //       current update region. 
1591       // Only blit the part visible in the client area. The backing pixmap 
1592       // always starts at 0, 0 but we may be looking at only a portion of it. 
1593       wxSize clientArea 
= GetClientSize(); 
1594       int toBlitX 
= m_pixmapWidth 
- scrollPosX
; 
1595       int toBlitY 
= m_pixmapHeight 
- scrollPosY
; 
1597       // Copy whichever is samller, the amount of pixmap we have to copy, 
1598       // or the size of the client area. 
1599       toBlitX 
= wxMin(toBlitX
, clientArea
.x
); 
1600       toBlitY 
= wxMin(toBlitY
, clientArea
.y
); 
1602       // Make sure we're not negative 
1603       toBlitX 
= wxMax(0, toBlitX
); 
1604       toBlitY 
= wxMax(0, toBlitY
); 
1609        (Pixmap
) m_backingPixmap
, 
1612        scrollPosX
, scrollPosY
, // Start at the scroll position 
1613        toBlitX
, toBlitY
,       // How much of the pixmap to copy 
1619         wxWindowDC 
dc(this); 
1620         // Set an erase event first 
1621         wxEraseEvent 
eraseEvent(GetId(), &dc
); 
1622         eraseEvent
.SetEventObject(this); 
1623         HandleWindowEvent(eraseEvent
); 
1625         wxPaintEvent 
event(GetId()); 
1626         event
.SetEventObject(this); 
1627         HandleWindowEvent(event
); 
1629         m_needsRefresh 
= false; 
1633 // ---------------------------------------------------------------------------- 
1635 // ---------------------------------------------------------------------------- 
1637 // Responds to colour changes: passes event on to children. 
1638 void wxWindow::OnSysColourChanged(wxSysColourChangedEvent
& event
) 
1640     wxWindowList::compatibility_iterator node 
= GetChildren().GetFirst(); 
1643         // Only propagate to non-top-level windows 
1644         wxWindow 
*win 
= node
->GetData(); 
1645         if ( win
->GetParent() ) 
1647             wxSysColourChangedEvent event2
; 
1648             event
.SetEventObject(win
); 
1649             win
->HandleWindowEvent(event2
); 
1652         node 
= node
->GetNext(); 
1656 void wxWindow::OnInternalIdle() 
1658     // This calls the UI-update mechanism (querying windows for 
1659     // menu/toolbar/control state information) 
1660     if (wxUpdateUIEvent::CanUpdate(this) && IsShownOnScreen()) 
1661         UpdateWindowUI(wxUPDATE_UI_FROMIDLE
); 
1664 // ---------------------------------------------------------------------------- 
1666 // ---------------------------------------------------------------------------- 
1668 bool wxWindow::ProcessAccelerator(wxKeyEvent
& event
) 
1671     if (!m_acceleratorTable
.Ok()) 
1674     int count 
= m_acceleratorTable
.GetCount(); 
1675     wxAcceleratorEntry
* entries 
= m_acceleratorTable
.GetEntries(); 
1677     for (i 
= 0; i 
< count
; i
++) 
1679         wxAcceleratorEntry
* entry 
= & (entries
[i
]); 
1680         if (entry
->MatchesEvent(event
)) 
1682             // Bingo, we have a match. Now find a control that matches the 
1683             // entry command id. 
1685             // Need to go up to the top of the window hierarchy, since it might 
1686             // be e.g. a menu item 
1687             wxWindow
* parent 
= this; 
1688             while ( parent 
&& !parent
->IsTopLevel() ) 
1689                 parent 
= parent
->GetParent(); 
1694             wxFrame
* frame 
= wxDynamicCast(parent
, wxFrame
); 
1698                 // Try for a menu command 
1699                 if (frame
->GetMenuBar()) 
1701                     wxMenuItem
* item 
= frame
->GetMenuBar()->FindItem(entry
->GetCommand()); 
1704                         wxCommandEvent 
commandEvent(wxEVT_COMMAND_MENU_SELECTED
, entry
->GetCommand()); 
1705                         commandEvent
.SetEventObject(frame
); 
1707                         // If ProcessEvent returns true (it was handled), then 
1708                         // the calling code will skip the event handling. 
1709                         return frame
->HandleWindowEvent(commandEvent
); 
1715             // Find a child matching the command id 
1716             wxWindow
* child 
= parent
->FindWindow(entry
->GetCommand()); 
1722             // Now we process those kinds of windows that we can. 
1723             // For now, only buttons. 
1724             if ( wxDynamicCast(child
, wxButton
) ) 
1726                 wxCommandEvent 
commandEvent (wxEVT_COMMAND_BUTTON_CLICKED
, child
->GetId()); 
1727                 commandEvent
.SetEventObject(child
); 
1728                 return child
->HandleWindowEvent(commandEvent
); 
1736     // We didn't match the key event against an accelerator. 
1740 // ============================================================================ 
1741 // Motif-specific stuff from here on 
1742 // ============================================================================ 
1744 // ---------------------------------------------------------------------------- 
1745 // function which maintain the global hash table mapping Widgets to wxWidgets 
1746 // ---------------------------------------------------------------------------- 
1748 bool wxAddWindowToTable(Widget w
, wxWindow 
*win
) 
1750     const long key 
= (long)w
; 
1751     if ( wxWidgetHashTable
->Get(key
)) 
1753         wxLogDebug("Widget table clash: new widget is %ld, %s", 
1754                    key
, win
->GetClassInfo()->GetClassName()); 
1758     wxWidgetHashTable
->Put(key
, win
); 
1760     wxLogTrace("widget", "Widget 0x%p <-> window %p (%s)", 
1761                w
, win
, win
->GetClassInfo()->GetClassName()); 
1766 wxWindow 
*wxGetWindowFromTable(Widget w
) 
1768     return (wxWindow 
*)wxWidgetHashTable
->Get((long) w
); 
1771 void wxDeleteWindowFromTable(Widget w
) 
1773     wxLogTrace("widget", "Widget 0x%p", (WXWidget
)w
); 
1775     wxWidgetHashTable
->Delete((long)w
); 
1778 // ---------------------------------------------------------------------------- 
1779 // add/remove window from the table 
1780 // ---------------------------------------------------------------------------- 
1782 // Add to hash table, add event handler 
1783 bool wxWindow::AttachWidget (wxWindow
* WXUNUSED(parent
), WXWidget mainWidget
, 
1784                              WXWidget formWidget
, int x
, int y
, int width
, int height
) 
1786     wxAddWindowToTable((Widget
) mainWidget
, this); 
1787     XtAddEventHandler( (Widget
) mainWidget
, 
1788                        ButtonPressMask 
| ButtonReleaseMask
 
1789                      | PointerMotionMask
, 
1791                        wxPanelItemEventHandler
, 
1797         XtOverrideTranslations ((Widget
) mainWidget
, 
1798             ptr 
= XtParseTranslationTable ("<Configure>: resize()")); 
1799         XtFree ((char *) ptr
); 
1802     // Some widgets have a parent form widget, e.g. wxRadioBox 
1805         if (!wxAddWindowToTable((Widget
) formWidget
, this)) 
1809         XtOverrideTranslations ((Widget
) formWidget
, 
1810             ptr 
= XtParseTranslationTable ("<Configure>: resize()")); 
1811         XtFree ((char *) ptr
); 
1818     DoSetSize (x
, y
, width
, height
, wxSIZE_USE_EXISTING
); 
1823 // Remove event handler, remove from hash table 
1824 bool wxWindow::DetachWidget(WXWidget widget
) 
1826     XtRemoveEventHandler( (Widget
) widget
, 
1827                           ButtonPressMask 
| ButtonReleaseMask
 
1828                         | PointerMotionMask
, 
1830                           wxPanelItemEventHandler
, 
1833     wxDeleteWindowFromTable((Widget
) widget
); 
1837 // ---------------------------------------------------------------------------- 
1838 // Motif-specific accessors 
1839 // ---------------------------------------------------------------------------- 
1841 WXWindow 
wxWindow::GetClientXWindow() const 
1843     Widget wMain 
= (Widget
)GetClientWidget(); 
1845         return (WXWindow
) XtWindow(wMain
); 
1847         return (WXWindow
) 0; 
1850 // Get the underlying X window 
1851 WXWindow 
wxWindow::GetXWindow() const 
1853     Widget wMain 
= (Widget
)GetMainWidget(); 
1855         return (WXWindow
) XtWindow(wMain
); 
1857         return (WXWindow
) 0; 
1860 // Get the underlying X display 
1861 WXDisplay 
*wxWindow::GetXDisplay() const 
1863     Widget wMain 
= (Widget
)GetMainWidget(); 
1865         return (WXDisplay
*) XtDisplay(wMain
); 
1867         return (WXDisplay
*) NULL
; 
1870 WXWidget 
wxWindow::GetMainWidget() const 
1873         return m_drawingArea
; 
1875         return m_mainWidget
; 
1878 WXWidget 
wxWindow::GetClientWidget() const 
1880     if (m_drawingArea 
!= (WXWidget
) 0) 
1881         return m_drawingArea
; 
1883         return GetMainWidget(); 
1886 WXWidget 
wxWindow::GetTopWidget() const 
1888     return GetMainWidget(); 
1891 WXWidget 
wxWindow::GetLabelWidget() const 
1893     return GetMainWidget(); 
1896 // ---------------------------------------------------------------------------- 
1898 // ---------------------------------------------------------------------------- 
1900 // All widgets should have this as their resize proc. 
1901 // OnSize sent to wxWindow via client data. 
1902 void wxWidgetResizeProc(Widget w
, XConfigureEvent 
*WXUNUSED(event
), 
1903                         String 
WXUNUSED(args
)[], int *WXUNUSED(num_args
)) 
1905     wxWindow 
*win 
= wxGetWindowFromTable(w
); 
1909     if (win
->PreResize()) 
1911         wxSize 
newSize(win
->GetSize()); 
1912         wxSizeEvent 
sizeEvent(newSize
, win
->GetId()); 
1913         sizeEvent
.SetEventObject(win
); 
1914         win
->HandleWindowEvent(sizeEvent
); 
1918 static void wxCanvasRepaintProc(Widget drawingArea
, 
1919                                 XtPointer clientData
, 
1920                                 XmDrawingAreaCallbackStruct 
* cbs
) 
1922     if (!wxGetWindowFromTable(drawingArea
)) 
1925     XEvent 
* event 
= cbs
->event
; 
1926     wxWindow 
* win 
= (wxWindow 
*) clientData
; 
1928     switch (event
->type
) 
1932             win
->AddUpdateRect(event
->xexpose
.x
, event
->xexpose
.y
, 
1933                                event
->xexpose
.width
, event
->xexpose
.height
); 
1935             if (event 
-> xexpose
.count 
== 0) 
1944 // Unable to deal with Enter/Leave without a separate EventHandler (Motif 1.1.4) 
1945 static void wxCanvasEnterLeave(Widget drawingArea
, 
1946                                XtPointer 
WXUNUSED(clientData
), 
1947                                XCrossingEvent 
* event
) 
1949     XmDrawingAreaCallbackStruct cbs
; 
1952     ((XCrossingEvent 
&) ev
) = *event
; 
1954     cbs
.reason 
= XmCR_INPUT
; 
1957     wxCanvasInputEvent(drawingArea
, (XtPointer
) NULL
, &cbs
); 
1960 // Fix to make it work under Motif 1.0 (!) 
1961 static void wxCanvasMotionEvent (Widget 
WXUNUSED(drawingArea
), 
1962                                  XButtonEvent 
*WXUNUSED(event
)) 
1964 #if XmVersion <= 1000 
1965     XmDrawingAreaCallbackStruct cbs
; 
1968     ev 
= *((XEvent 
*) event
); 
1969     cbs
.reason 
= XmCR_INPUT
; 
1972     wxCanvasInputEvent (drawingArea
, (XtPointer
) NULL
, &cbs
); 
1973 #endif // XmVersion <= 1000 
1976 static void wxCanvasInputEvent(Widget drawingArea
, 
1977                                XtPointer 
WXUNUSED(data
), 
1978                                XmDrawingAreaCallbackStruct 
* cbs
) 
1980     wxWindow 
*canvas 
= wxGetWindowFromTable(drawingArea
); 
1981     XEvent
* xevent 
= cbs
->event
; 
1986     if (cbs
->reason 
!= XmCR_INPUT
) 
1989     switch (xevent
->xany
.type
) 
1997             wxMouseEvent 
wxevent(0); 
1998             if (wxTranslateMouseEvent(wxevent
, canvas
, drawingArea
, xevent
)) 
2000                 canvas
->HandleWindowEvent(wxevent
); 
2006             wxKeyEvent 
event (wxEVT_CHAR
); 
2007             if (wxTranslateKeyEvent (event
, canvas
, (Widget
) 0, xevent
)) 
2009                 // Implement wxFrame::OnCharHook by checking ancestor. 
2010                 wxWindow 
*parent 
= canvas
; 
2011                 while (parent 
&& !parent
->IsTopLevel()) 
2012                     parent 
= parent
->GetParent(); 
2016                     event
.SetEventType(wxEVT_CHAR_HOOK
); 
2017                     if (parent
->HandleWindowEvent(event
)) 
2021                 // For simplicity, OnKeyDown is the same as OnChar 
2022                 // TODO: filter modifier key presses from OnChar 
2023                 event
.SetEventType(wxEVT_KEY_DOWN
); 
2025                 // Only process OnChar if OnKeyDown didn't swallow it 
2026                 if (!canvas
->HandleWindowEvent (event
)) 
2028                     event
.SetEventType(wxEVT_CHAR
); 
2029                     canvas
->HandleWindowEvent (event
); 
2036             wxKeyEvent 
event (wxEVT_KEY_UP
); 
2037             if (wxTranslateKeyEvent (event
, canvas
, (Widget
) 0, xevent
)) 
2039                 canvas
->HandleWindowEvent (event
); 
2045             if (xevent
->xfocus
.detail 
!= NotifyPointer
) 
2047                 wxFocusEvent 
event(wxEVT_SET_FOCUS
, canvas
->GetId()); 
2048                 event
.SetEventObject(canvas
); 
2049                 canvas
->HandleWindowEvent(event
); 
2055             if (xevent
->xfocus
.detail 
!= NotifyPointer
) 
2057                 wxFocusEvent 
event(wxEVT_KILL_FOCUS
, canvas
->GetId()); 
2058                 event
.SetEventObject(canvas
); 
2059                 canvas
->HandleWindowEvent(event
); 
2068 static void wxPanelItemEventHandler(Widget    wid
, 
2069                                     XtPointer 
WXUNUSED(client_data
), 
2071                                     Boolean  
*continueToDispatch
) 
2073     // Widget can be a label or the actual widget. 
2075     wxWindow 
*window 
= wxGetWindowFromTable(wid
); 
2078         wxMouseEvent 
wxevent(0); 
2079         if (wxTranslateMouseEvent(wxevent
, window
, wid
, event
)) 
2081             window
->HandleWindowEvent(wxevent
); 
2085     // TODO: probably the key to allowing default behaviour to happen. Say we 
2086     // set a m_doDefault flag to false at the start of this function. Then in 
2087     // e.g. wxWindow::OnMouseEvent we can call Default() which sets this flag to 
2088     // true, indicating that default processing can happen. Thus, behaviour can 
2089     // appear to be overridden just by adding an event handler and not calling 
2090     // wxWindow::OnWhatever. ALSO, maybe we can use this instead of the current 
2091     // way of handling drawing area events, to simplify things. 
2092     *continueToDispatch 
= True
; 
2095 static void wxScrollBarCallback(Widget scrollbar
, 
2096                                 XtPointer clientData
, 
2097                                 XmScrollBarCallbackStruct 
*cbs
) 
2099     wxWindow 
*win 
= wxGetWindowFromTable(scrollbar
); 
2100     wxCHECK_RET( win
, _T("invalid widget in scrollbar callback") ); 
2102     wxOrientation orientation 
= (wxOrientation
)wxPtrToUInt(clientData
); 
2104     wxEventType eventType 
= wxEVT_NULL
; 
2105     switch (cbs
->reason
) 
2107     case XmCR_INCREMENT
: 
2109             eventType 
= wxEVT_SCROLLWIN_LINEDOWN
; 
2112     case XmCR_DECREMENT
: 
2114             eventType 
= wxEVT_SCROLLWIN_LINEUP
; 
2119             eventType 
= wxEVT_SCROLLWIN_THUMBTRACK
; 
2122     case XmCR_VALUE_CHANGED
: 
2124             eventType 
= wxEVT_SCROLLWIN_THUMBRELEASE
; 
2127     case XmCR_PAGE_INCREMENT
: 
2129             eventType 
= wxEVT_SCROLLWIN_PAGEDOWN
; 
2132     case XmCR_PAGE_DECREMENT
: 
2134             eventType 
= wxEVT_SCROLLWIN_PAGEUP
; 
2139             eventType 
= wxEVT_SCROLLWIN_TOP
; 
2142     case XmCR_TO_BOTTOM
: 
2144             eventType 
= wxEVT_SCROLLWIN_BOTTOM
; 
2149             // Should never get here 
2150             wxFAIL_MSG("Unknown scroll event."); 
2155     wxScrollWinEvent 
event(eventType
, 
2158     event
.SetEventObject( win 
); 
2159     win
->HandleWindowEvent(event
); 
2162 // For repainting arbitrary windows 
2163 void wxUniversalRepaintProc(Widget w
, XtPointer 
WXUNUSED(c_data
), XEvent 
*event
, char *) 
2165     wxWindow
* win 
= wxGetWindowFromTable(w
); 
2169     switch ( event
->type 
) 
2173             win
->AddUpdateRect(event
->xexpose
.x
, event
->xexpose
.y
, 
2174                                event
->xexpose
.width
, event
->xexpose
.height
); 
2176             if ( event
->xexpose
.count 
== 0 ) 
2186 // ---------------------------------------------------------------------------- 
2187 // TranslateXXXEvent() functions 
2188 // ---------------------------------------------------------------------------- 
2190 bool wxTranslateMouseEvent(wxMouseEvent
& wxevent
, wxWindow 
*win
, 
2191                            Widget widget
, const XEvent 
*xevent
) 
2193     switch (xevent
->xany
.type
) 
2198             fprintf(stderr
, "Widget 0x%p <-> window %p (%s), %s\n", 
2199                     (WXWidget
)widget
, win
, win
->GetClassInfo()->GetClassName(), 
2200                     (xevent
->xany
.type 
== EnterNotify 
? "ENTER" : "LEAVE")); 
2206             int eventx 
= xevent
->xbutton
.x
, eventy 
= xevent
->xbutton
.y
; 
2208             wxEventType eventType 
= wxEVT_NULL
; 
2210             if (xevent
->xany
.type 
== LeaveNotify
) 
2212                 eventType 
= wxEVT_LEAVE_WINDOW
; 
2214             if (xevent
->xany
.type 
== EnterNotify
) 
2216                 eventType 
= wxEVT_ENTER_WINDOW
; 
2218             else if (xevent
->xany
.type 
== MotionNotify
) 
2220                 eventType 
= wxEVT_MOTION
; 
2222                 if (xevent
->xmotion
.is_hint 
== NotifyHint
) 
2227                     Display 
*dpy 
= XtDisplay (widget
); 
2229                     XQueryPointer (dpy
, XtWindow (widget
), 
2231                         &x_root
, &y_root
, &eventx
, &eventy
, &state
); 
2234             else if (xevent
->xany
.type 
== ButtonPress
) 
2236                 wxevent
.SetTimestamp(xevent
->xbutton
.time
); 
2238                 if (xevent
->xbutton
.button 
== Button1
) 
2240                     eventType 
= wxEVT_LEFT_DOWN
; 
2243                 else if (xevent
->xbutton
.button 
== Button2
) 
2245                     eventType 
= wxEVT_MIDDLE_DOWN
; 
2248                 else if (xevent
->xbutton
.button 
== Button3
) 
2250                     eventType 
= wxEVT_RIGHT_DOWN
; 
2254                 // check for a double click 
2256                 long dclickTime 
= XtGetMultiClickTime(xevent
->xany
.display
); 
2257                 long ts 
= wxevent
.GetTimestamp(); 
2259                 int buttonLast 
= win
->GetLastClickedButton(); 
2260                 long lastTS 
= win
->GetLastClickTime(); 
2261                 if ( buttonLast 
&& buttonLast 
== button 
&& 
2262                      (ts 
- lastTS
) < dclickTime 
) 
2265                     win
->SetLastClick(0, ts
); 
2266                     if ( eventType 
== wxEVT_LEFT_DOWN 
) 
2267                         eventType 
= wxEVT_LEFT_DCLICK
; 
2268                     else if ( eventType 
== wxEVT_MIDDLE_DOWN 
) 
2269                         eventType 
= wxEVT_MIDDLE_DCLICK
; 
2270                     else if ( eventType 
== wxEVT_RIGHT_DOWN 
) 
2271                         eventType 
= wxEVT_RIGHT_DCLICK
; 
2275                     // not fast enough or different button 
2276                     win
->SetLastClick(button
, ts
); 
2279             else if (xevent
->xany
.type 
== ButtonRelease
) 
2281                 if (xevent
->xbutton
.button 
== Button1
) 
2283                     eventType 
= wxEVT_LEFT_UP
; 
2285                 else if (xevent
->xbutton
.button 
== Button2
) 
2287                     eventType 
= wxEVT_MIDDLE_UP
; 
2289                 else if (xevent
->xbutton
.button 
== Button3
) 
2291                     eventType 
= wxEVT_RIGHT_UP
; 
2301             wxevent
.SetEventType(eventType
); 
2304             XtVaGetValues(widget
, XmNx
, &x1
, XmNy
, &y1
, NULL
); 
2307             win
->GetPosition(&x2
, &y2
); 
2309             // The button x/y must be translated to wxWidgets 
2310             // window space - the widget might be a label or button, 
2314             if (widget 
!= (Widget
)win
->GetMainWidget()) 
2320             wxevent
.m_x 
= eventx 
+ dx
; 
2321             wxevent
.m_y 
= eventy 
+ dy
; 
2323             wxevent
.m_leftDown 
= ((eventType 
== wxEVT_LEFT_DOWN
) 
2324                 || (event_left_is_down (xevent
) 
2325                 && (eventType 
!= wxEVT_LEFT_UP
))); 
2326             wxevent
.m_middleDown 
= ((eventType 
== wxEVT_MIDDLE_DOWN
) 
2327                 || (event_middle_is_down (xevent
) 
2328                 && (eventType 
!= wxEVT_MIDDLE_UP
))); 
2329             wxevent
.m_rightDown 
= ((eventType 
== wxEVT_RIGHT_DOWN
) 
2330                 || (event_right_is_down (xevent
) 
2331                 && (eventType 
!= wxEVT_RIGHT_UP
))); 
2333             wxevent
.m_shiftDown 
= (xevent
->xbutton
.state 
& ShiftMask
) == ShiftMask
; 
2334             wxevent
.m_controlDown 
= (xevent
->xbutton
.state 
& ControlMask
) == ControlMask
; 
2335             wxevent
.m_altDown 
= (xevent
->xbutton
.state 
& Mod3Mask
) == Mod3Mask
; 
2336             wxevent
.m_metaDown 
= (xevent
->xbutton
.state 
& Mod1Mask
) == Mod1Mask
; 
2338             wxevent
.SetId(win
->GetId()); 
2339             wxevent
.SetEventObject(win
); 
2347 bool wxTranslateKeyEvent(wxKeyEvent
& wxevent
, wxWindow 
*win
, 
2348                          Widget 
WXUNUSED(widget
), const XEvent 
*xevent
) 
2350     switch (xevent
->xany
.type
) 
2358             (void) XLookupString((XKeyEvent 
*)xevent
, buf
, 20, &keySym
, NULL
); 
2359             int id 
= wxCharCodeXToWX (keySym
); 
2360             // id may be WXK_xxx code - these are outside ASCII range, so we 
2361             // can't just use toupper() on id 
2362             if (id 
>= 'a' && id 
<= 'z') 
2365             if (xevent
->xkey
.state 
& ShiftMask
) 
2366                 wxevent
.m_shiftDown 
= true; 
2367             if (xevent
->xkey
.state 
& ControlMask
) 
2368                 wxevent
.m_controlDown 
= true; 
2369             if (xevent
->xkey
.state 
& Mod3Mask
) 
2370                 wxevent
.m_altDown 
= true; 
2371             if (xevent
->xkey
.state 
& Mod1Mask
) 
2372                 wxevent
.m_metaDown 
= true; 
2373             wxevent
.SetEventObject(win
); 
2374             wxevent
.m_keyCode 
= id
; 
2375             wxevent
.SetTimestamp(xevent
->xkey
.time
); 
2377             wxevent
.m_x 
= xevent
->xbutton
.x
; 
2378             wxevent
.m_y 
= xevent
->xbutton
.y
; 
2391 // ---------------------------------------------------------------------------- 
2393 // ---------------------------------------------------------------------------- 
2395 #define YAllocColor XAllocColor 
2396 XColor g_itemColors
[5]; 
2397 int wxComputeColours (Display 
*display
, const wxColour 
* back
, const wxColour 
* fore
) 
2400     static XmColorProc colorProc
; 
2402     result 
= wxNO_COLORS
; 
2406         g_itemColors
[0].red 
= (unsigned short)(((long) back
->Red ()) << 8); 
2407         g_itemColors
[0].green 
= (unsigned short)(((long) back
->Green ()) << 8); 
2408         g_itemColors
[0].blue 
= (unsigned short)(((long) back
->Blue ()) << 8); 
2409         g_itemColors
[0].flags 
= DoRed 
| DoGreen 
| DoBlue
; 
2410         if (colorProc 
== (XmColorProc
) NULL
) 
2412             // Get a ptr to the actual function 
2413             colorProc 
= XmSetColorCalculation ((XmColorProc
) NULL
); 
2414             // And set it back to motif. 
2415             XmSetColorCalculation (colorProc
); 
2417         (*colorProc
) (&g_itemColors
[wxBACK_INDEX
], 
2418             &g_itemColors
[wxFORE_INDEX
], 
2419             &g_itemColors
[wxSELE_INDEX
], 
2420             &g_itemColors
[wxTOPS_INDEX
], 
2421             &g_itemColors
[wxBOTS_INDEX
]); 
2422         result 
= wxBACK_COLORS
; 
2426         g_itemColors
[wxFORE_INDEX
].red 
= (unsigned short)(((long) fore
->Red ()) << 8); 
2427         g_itemColors
[wxFORE_INDEX
].green 
= (unsigned short)(((long) fore
->Green ()) << 8); 
2428         g_itemColors
[wxFORE_INDEX
].blue 
= (unsigned short)(((long) fore
->Blue ()) << 8); 
2429         g_itemColors
[wxFORE_INDEX
].flags 
= DoRed 
| DoGreen 
| DoBlue
; 
2430         if (result 
== wxNO_COLORS
) 
2431             result 
= wxFORE_COLORS
; 
2434     Display 
*dpy 
= display
; 
2435     Colormap cmap 
= (Colormap
) wxTheApp
->GetMainColormap((WXDisplay
*) dpy
); 
2439         /* 5 Colours to allocate */ 
2440         for (int i 
= 0; i 
< 5; i
++) 
2441             if (!YAllocColor (dpy
, cmap
, &g_itemColors
[i
])) 
2442                 result 
= wxNO_COLORS
; 
2446         /* Only 1 colour to allocate */ 
2447         if (!YAllocColor (dpy
, cmap
, &g_itemColors
[wxFORE_INDEX
])) 
2448             result 
= wxNO_COLORS
; 
2454 // Changes the foreground and background colours to be derived from the current 
2455 // background colour. To change the foreground colour, you must call 
2456 // SetForegroundColour explicitly. 
2457 void wxWindow::ChangeBackgroundColour() 
2459     WXWidget mainWidget 
= GetMainWidget(); 
2461         wxDoChangeBackgroundColour(mainWidget
, m_backgroundColour
); 
2462     if ( m_scrolledWindow 
&& mainWidget 
!= m_scrolledWindow 
) 
2463         wxDoChangeForegroundColour(m_scrolledWindow
, m_backgroundColour
); 
2466 void wxWindow::ChangeForegroundColour() 
2468     WXWidget mainWidget 
= GetMainWidget(); 
2470         wxDoChangeForegroundColour(mainWidget
, m_foregroundColour
); 
2471     if ( m_scrolledWindow 
&& mainWidget 
!= m_scrolledWindow 
) 
2472         wxDoChangeForegroundColour(m_scrolledWindow
, m_foregroundColour
); 
2475 bool wxWindow::SetBackgroundColour(const wxColour
& col
) 
2477     if ( !wxWindowBase::SetBackgroundColour(col
) ) 
2480     ChangeBackgroundColour(); 
2485 bool wxWindow::SetForegroundColour(const wxColour
& col
) 
2487     if ( !wxWindowBase::SetForegroundColour(col
) ) 
2490     ChangeForegroundColour(); 
2495 void wxWindow::ChangeFont(bool keepOriginalSize
) 
2497     // Note that this causes the widget to be resized back 
2498     // to its original size! We therefore have to set the size 
2499     // back again. TODO: a better way in Motif? 
2500     Widget w 
= (Widget
) GetLabelWidget(); // Usually the main widget 
2501     if (w 
&& m_font
.Ok()) 
2503         int width
, height
, width1
, height1
; 
2504         GetSize(& width
, & height
); 
2506         wxDoChangeFont( w
, m_font 
); 
2508         GetSize(& width1
, & height1
); 
2509         if (keepOriginalSize 
&& (width 
!= width1 
|| height 
!= height1
)) 
2511             SetSize(wxDefaultCoord
, wxDefaultCoord
, width
, height
); 
2517 void wxWindow::PostCreation() 
2520     ChangeForegroundColour(); 
2521     ChangeBackgroundColour(); 
2525 void wxWindow::PreCreation() 
2527     InheritAttributes(); 
2530 // ---------------------------------------------------------------------------- 
2532 // ---------------------------------------------------------------------------- 
2534 wxWindow 
*wxGetActiveWindow() 
2537     wxFAIL_MSG("Not implemented"); 
2542 wxWindow 
*wxWindowBase::GetCapture() 
2544     return (wxWindow 
*)g_captureWindow
; 
2548 // Find the wxWindow at the current mouse position, returning the mouse 
2550 wxWindow
* wxFindWindowAtPointer(wxPoint
& pt
) 
2552     pt 
= wxGetMousePosition(); 
2553     return wxFindWindowAtPoint(pt
); 
2556 void wxGetMouseState(int& rootX
, int& rootY
, unsigned& maskReturn
) 
2558     Display 
*display 
= wxGlobalDisplay(); 
2559     Window rootWindow 
= RootWindowOfScreen (DefaultScreenOfDisplay(display
)); 
2560     Window rootReturn
, childReturn
; 
2563     XQueryPointer (display
, 
2567                    &rootX
, &rootY
, &winX
, &winY
, &maskReturn
); 
2570 // Get the current mouse position. 
2571 wxPoint 
wxGetMousePosition() 
2576     wxGetMouseState(x
, y
, mask
); 
2577     return wxPoint(x
, y
); 
2580 wxMouseState 
wxGetMouseState() 
2586     wxGetMouseState(x
, y
, mask
); 
2591     ms
.SetLeftDown(mask 
& Button1Mask
); 
2592     ms
.SetMiddleDown(mask 
& Button2Mask
); 
2593     ms
.SetRightDown(mask 
& Button3Mask
); 
2595     ms
.SetControlDown(mask 
& ControlMask
); 
2596     ms
.SetShiftDown(mask 
& ShiftMask
); 
2597     ms
.SetAltDown(mask 
& Mod3Mask
); 
2598     ms
.SetMetaDown(mask 
& Mod1Mask
); 
2604 #if wxMOTIF_NEW_FONT_HANDLING 
2608 void wxGetTextExtent(const wxWindow
* window
, const wxString
& str
, 
2609                      int* width
, int* height
, int* ascent
, int* descent
) 
2613     XmRendition rendition 
= NULL
; 
2614     XmRenderTable table 
= NULL
; 
2615     Widget w 
= (Widget
) window
->GetLabelWidget(); 
2617     XtVaGetValues( w
, XmNrenderTable
, &table
, NULL 
); 
2619         table 
= XmeGetDefaultRenderTable(w
, XmTEXT_RENDER_TABLE
); 
2621     rendition 
= XmRenderTableGetRendition( table
, "" ); 
2622     XtSetArg( args
[count
], XmNfont
, 0 ); ++count
; 
2623     XtSetArg( args
[count
], XmNfontType
, 0 ); ++count
; 
2624     XmRenditionRetrieve( rendition
, args
, count 
); 
2626     if (args
[1].value 
== XmFONT_IS_FONTSET
) 
2628         XRectangle ink
, logical
; 
2629         WXFontSet fset 
= (WXFontSet
) args
[0].value
; 
2631         XmbTextExtents( (XFontSet
)fset
, str
.c_str(), str
.length(), 
2634         if( width 
) *width 
= logical
.width
; 
2635         if( height 
) *height 
= logical
.height
; 
2636         if( ascent 
) *ascent 
= -logical
.y
; 
2637         if( descent 
) *descent 
= logical
.height 
+ logical
.y
; 
2641         int direction
, ascent2
, descent2
; 
2642         XCharStruct overall
; 
2643         XFontStruct
* fontStruct
; 
2645         XmeRenderTableGetDefaultFont( table
, &fontStruct 
); 
2646         XTextExtents(fontStruct
, (const char*)str
.c_str(), str
.length(), 
2647                      &direction
, &ascent2
, &descent2
, &overall
); 
2649         if ( width 
) *width 
= overall
.width
; 
2650         if ( height 
) *height 
= ascent2 
+ descent2
; 
2651         if ( descent 
) *descent 
= descent2
; 
2652         if ( ascent 
) *ascent 
= ascent2
; 
2656 #else // if !wxMOTIF_NEW_FONT_HANDLING 
2658 void wxGetTextExtent(const wxWindow
* window
, const wxString
& str
, 
2659                      int* width
, int* height
, int* ascent
, int* descent
) 
2661     XmFontList list 
= NULL
; 
2664     Widget w 
= (Widget
) window
->GetLabelWidget(); 
2666     XtVaGetValues( w
, XmNfontList
, &list
, NULL 
); 
2667     XmFontListInitFontContext( &cxt
, list 
); 
2669     XmFontListEntry entry 
= XmFontListNextEntry( cxt 
); 
2670     XmFontListFreeFontContext( cxt 
); 
2671     XtPointer thing 
= XmFontListEntryGetFont( entry
, &type 
); 
2673     if (type 
== XmFONT_IS_FONTSET
) 
2675         XRectangle ink
, logical
; 
2677         XmbTextExtents( (XFontSet
)thing
, str
.c_str(), str
.length(), 
2680         if( width 
) *width 
= logical
.width
; 
2681         if( height 
) *height 
= logical
.height
; 
2682         if( ascent 
) *ascent 
= -logical
.y
; 
2683         if( descent 
) *descent 
= logical
.height 
+ logical
.y
; 
2687         int direction
, ascent2
, descent2
; 
2688         XCharStruct overall
; 
2690         XTextExtents( (XFontStruct
*)thing
, (char*)(const char*)str
.c_str(), str
.length(), 
2691                      &direction
, &ascent2
, &descent2
, &overall
); 
2693         if ( width 
) *width 
= overall
.width
; 
2694         if ( height 
) *height 
= ascent2 
+ descent2
; 
2695         if ( descent 
) *descent 
= descent2
; 
2696         if ( ascent 
) *ascent 
= ascent2
; 
2700 #endif // !wxMOTIF_NEW_FONT_HANDLING 
2702 // ---------------------------------------------------------------------------- 
2703 // wxNoOptimize: switch off size optimization 
2704 // ---------------------------------------------------------------------------- 
2706 int wxNoOptimize::ms_count 
= 0;