1 /////////////////////////////////////////////////////////////////////////////
4 // Author: Julian Smart
8 // Copyright: (c) Julian Smart
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
12 // ============================================================================
14 // ============================================================================
16 // ----------------------------------------------------------------------------
18 // ----------------------------------------------------------------------------
21 #pragma implementation "window.h"
25 #define XtDisplay XTDISPLAY
26 #define XtWindow XTWINDOW
27 #define XtScreen XTSCREEN
33 #include "wx/dcclient.h"
36 #include "wx/layout.h"
37 #include "wx/button.h"
38 #include "wx/settings.h"
40 #include "wx/scrolwin.h"
41 #include "wx/module.h"
42 #include "wx/menuitem.h"
44 #include "wx/evtloop.h"
47 #if wxUSE_DRAG_AND_DROP
51 // DoSetSizeIntr and DoMoveWindowIntr
53 // under Motif composite controls (such as wxCalendarCtrl or generic wxSpinCtrl
54 // did nott work and/or segfaulted because
55 // 1) wxWindow::Create calls SetSize,
56 // which results in a call to DoSetSize much earlier than in the other ports
57 // 2) if wxWindow::Create is called (wxControl::Create calls it)
58 // then DoSetSize is never called, causing layout problems in composite
62 // 1) don't call SetSize, DoSetSize, DoMoveWindow, DoGetPosition,
63 // DoSetPosition directly or indirectly from wxWindow::Create
64 // 2) call DoMoveWindow from DoSetSize, allowing controls to override it
67 #pragma message disable nosimpint
71 #include <Xm/DrawingA.h>
72 #include <Xm/ScrolledW.h>
73 #include <Xm/ScrollBar.h>
76 #include <Xm/RowColumn.h> // for XmMenuPosition
78 #pragma message enable nosimpint
81 #include "wx/motif/private.h"
85 // ----------------------------------------------------------------------------
87 // ----------------------------------------------------------------------------
89 static const int SCROLL_MARGIN
= 4;
91 // ----------------------------------------------------------------------------
92 // global variables for this module
93 // ----------------------------------------------------------------------------
95 extern wxHashTable
*wxWidgetHashTable
;
96 static wxWindow
* g_captureWindow
= NULL
;
99 // ----------------------------------------------------------------------------
101 // ----------------------------------------------------------------------------
103 static void wxCanvasRepaintProc(Widget
, XtPointer
, XmDrawingAreaCallbackStruct
* cbs
);
104 static void wxCanvasInputEvent(Widget drawingArea
, XtPointer data
, XmDrawingAreaCallbackStruct
* cbs
);
105 static void wxCanvasMotionEvent(Widget
, XButtonEvent
* event
);
106 static void wxCanvasEnterLeave(Widget drawingArea
, XtPointer clientData
, XCrossingEvent
* event
);
107 static void wxScrollBarCallback(Widget widget
, XtPointer clientData
,
108 XmScrollBarCallbackStruct
*cbs
);
109 static void wxPanelItemEventHandler(Widget wid
,
110 XtPointer client_data
,
112 Boolean
*continueToDispatch
);
117 // Helper function for 16-bit fonts
118 static int str16len(const char *s
)
122 while (s
[0] && s
[1]) {
132 // ----------------------------------------------------------------------------
134 // ----------------------------------------------------------------------------
136 #define event_left_is_down(x) ((x)->xbutton.state & Button1Mask)
137 #define event_middle_is_down(x) ((x)->xbutton.state & Button2Mask)
138 #define event_right_is_down(x) ((x)->xbutton.state & Button3Mask)
140 // ----------------------------------------------------------------------------
142 // ----------------------------------------------------------------------------
144 IMPLEMENT_DYNAMIC_CLASS(wxWindow
, wxWindowBase
)
146 BEGIN_EVENT_TABLE(wxWindow
, wxWindowBase
)
147 EVT_SYS_COLOUR_CHANGED(wxWindow::OnSysColourChanged
)
148 EVT_IDLE(wxWindow::OnIdle
)
151 // ============================================================================
153 // ============================================================================
155 // ----------------------------------------------------------------------------
157 // ----------------------------------------------------------------------------
159 void wxWindow::UnmanageAndDestroy(WXWidget widget
)
161 Widget w
= (Widget
)widget
;
169 bool wxWindow::MapOrUnmap(WXWidget widget
, bool domap
)
171 Widget w
= (Widget
)widget
;
180 // Rationale: a lot of common operations (including but not
181 // limited to moving, resizing and appending items to a listbox)
182 // unmamange the widget, do their work, then manage it again.
183 // This means that, for example adding an item to a listbox will show it,
184 // or that most controls are shown every time they are moved or resized!
185 XtSetMappedWhenManaged( w
, domap
);
190 // ----------------------------------------------------------------------------
192 // ----------------------------------------------------------------------------
194 void wxWindow::Init()
196 // generic initializations first
200 m_needsRefresh
= TRUE
;
201 m_mainWidget
= (WXWidget
) 0;
205 m_button3Pressed
= FALSE
;
207 m_winCaptured
= FALSE
;
210 m_isBeingDeleted
= FALSE
;
216 m_drawingArea
= (WXWidget
) 0;
224 m_backingPixmap
= (WXPixmap
) 0;
233 m_canAddEventHandler
= FALSE
;
236 // real construction (Init() must have been called before!)
237 bool wxWindow::Create(wxWindow
*parent
, wxWindowID id
,
241 const wxString
& name
)
243 wxCHECK_MSG( parent
, FALSE
, "can't create wxWindow without parent" );
245 CreateBase(parent
, id
, pos
, size
, style
, wxDefaultValidator
, name
);
247 parent
->AddChild(this);
249 m_backgroundColour
= wxSystemSettings::GetColour(wxSYS_COLOUR_3DFACE
);
250 m_foregroundColour
= *wxBLACK
;
252 //// TODO: we should probably optimize by only creating a
253 //// a drawing area if we have one or more scrollbars (wxVSCROLL/wxHSCROLL).
254 //// But for now, let's simplify things by always creating the
255 //// drawing area, since otherwise the translations are different.
257 // New translations for getting mouse motion feedback
258 static const String translations
=
259 "<Btn1Motion>: wxCanvasMotionEvent() DrawingAreaInput() ManagerGadgetButtonMotion()\n\
260 <Btn2Motion>: wxCanvasMotionEvent() DrawingAreaInput() ManagerGadgetButtonMotion()\n\
261 <Btn3Motion>: wxCanvasMotionEvent() DrawingAreaInput() ManagerGadgetButtonMotion()\n\
262 <BtnMotion>: wxCanvasMotionEvent() DrawingAreaInput() ManagerGadgetButtonMotion()\n\
263 <Btn1Down>: DrawingAreaInput() ManagerGadgetArm()\n\
264 <Btn2Down>: DrawingAreaInput() ManagerGadgetArm()\n\
265 <Btn3Down>: DrawingAreaInput() ManagerGadgetArm()\n\
266 <Btn1Up>: DrawingAreaInput() ManagerGadgetActivate()\n\
267 <Btn2Up>: DrawingAreaInput() ManagerGadgetActivate()\n\
268 <Btn3Up>: DrawingAreaInput() ManagerGadgetActivate()\n\
269 <Motion>: wxCanvasMotionEvent() DrawingAreaInput()\n\
270 <EnterWindow>: wxCanvasMotionEvent() DrawingAreaInput()\n\
271 <LeaveWindow>: wxCanvasMotionEvent() DrawingAreaInput()\n\
272 <Key>: DrawingAreaInput()";
274 XtActionsRec actions
[1];
275 actions
[0].string
= "wxCanvasMotionEvent";
276 actions
[0].proc
= (XtActionProc
) wxCanvasMotionEvent
;
277 XtAppAddActions ((XtAppContext
) wxTheApp
->GetAppContext(), actions
, 1);
279 Widget parentWidget
= (Widget
) parent
->GetClientWidget();
281 if (style
& wxSIMPLE_BORDER
)
283 m_borderWidget
= (WXWidget
)XtVaCreateManagedWidget
286 xmFrameWidgetClass
, parentWidget
,
287 XmNshadowType
, XmSHADOW_IN
,
288 XmNshadowThickness
, 1,
291 } else if (style
& wxSUNKEN_BORDER
)
293 m_borderWidget
= (WXWidget
)XtVaCreateManagedWidget
296 xmFrameWidgetClass
, parentWidget
,
297 XmNshadowType
, XmSHADOW_IN
,
300 } else if (style
& wxRAISED_BORDER
)
302 m_borderWidget
= (WXWidget
)XtVaCreateManagedWidget
305 xmFrameWidgetClass
, parentWidget
,
306 XmNshadowType
, XmSHADOW_OUT
,
311 m_scrolledWindow
= (WXWidget
)XtVaCreateManagedWidget
314 xmScrolledWindowWidgetClass
,
315 m_borderWidget
? (Widget
) m_borderWidget
317 XmNresizePolicy
, XmRESIZE_NONE
,
319 XmNscrollingPolicy
, XmAPPLICATION_DEFINED
,
320 //XmNscrollBarDisplayPolicy, XmAS_NEEDED,
324 XtTranslations ptr
= XtParseTranslationTable(translations
);
325 m_drawingArea
= (WXWidget
)XtVaCreateWidget
328 xmDrawingAreaWidgetClass
, (Widget
) m_scrolledWindow
,
329 XmNunitType
, XmPIXELS
,
330 // XmNresizePolicy, XmRESIZE_ANY,
331 XmNresizePolicy
, XmRESIZE_NONE
,
334 XmNtranslations
, ptr
,
337 XtFree((char *) ptr
);
340 if (GetWindowStyleFlag() & wxOVERRIDE_KEY_TRANSLATIONS
)
342 ptr
= XtParseTranslationTable ("<Key>: DrawingAreaInput()");
343 XtOverrideTranslations ((Widget
) m_drawingArea
, ptr
);
344 XtFree ((char *) ptr
);
348 wxAddWindowToTable((Widget
) m_drawingArea
, this);
349 wxAddWindowToTable((Widget
) m_scrolledWindow
, this);
351 // This order is very important in Motif 1.2.1
352 XtRealizeWidget ((Widget
) m_scrolledWindow
);
353 XtRealizeWidget ((Widget
) m_drawingArea
);
354 XtManageChild ((Widget
) m_drawingArea
);
356 ptr
= XtParseTranslationTable("<Configure>: resize()");
357 XtOverrideTranslations((Widget
) m_drawingArea
, ptr
);
358 XtFree ((char *) ptr
);
360 XtAddCallback ((Widget
) m_drawingArea
, XmNexposeCallback
, (XtCallbackProc
) wxCanvasRepaintProc
, (XtPointer
) this);
361 XtAddCallback ((Widget
) m_drawingArea
, XmNinputCallback
, (XtCallbackProc
) wxCanvasInputEvent
, (XtPointer
) this);
365 display
= XtDisplay (scrolledWindow
);
366 xwindow
= XtWindow (drawingArea
);
370 (Widget
)m_drawingArea
,
371 PointerMotionHintMask
| EnterWindowMask
|
372 LeaveWindowMask
| FocusChangeMask
,
374 (XtEventHandler
) wxCanvasEnterLeave
,
378 // Scrolled widget needs to have its colour changed or we get a little blue
379 // square where the scrollbars abutt
380 wxColour backgroundColour
= wxSystemSettings::GetColour(wxSYS_COLOUR_3DFACE
);
381 DoChangeBackgroundColour(m_scrolledWindow
, backgroundColour
, TRUE
);
382 DoChangeBackgroundColour(m_drawingArea
, backgroundColour
, TRUE
);
384 XmScrolledWindowSetAreas(
385 (Widget
)m_scrolledWindow
,
386 (Widget
) 0, (Widget
) 0,
387 (Widget
) m_drawingArea
);
391 XtRealizeWidget ((Widget
) m_hScrollBar
);
393 XtRealizeWidget ((Widget
) m_vScrollBar
);
396 // Without this, the cursor may not be restored properly (e.g. in splitter
398 SetCursor(*wxSTANDARD_CURSOR
);
399 SetFont(wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT
));
400 DoSetSizeIntr(pos
.x
, pos
.y
, size
.x
,size
.y
, wxSIZE_AUTO
, TRUE
);
405 wxWindow::~wxWindow()
407 if (g_captureWindow
== this)
408 g_captureWindow
= NULL
;
410 m_isBeingDeleted
= TRUE
;
412 // Motif-specific actions first
413 WXWidget wMain
= GetMainWidget();
416 // Removes event handlers
423 m_parent
->RemoveChild( this );
425 // If m_drawingArea, we're a fully-fledged window with drawing area,
426 // scrollbars etc. (what wxCanvas used to be)
429 // Destroy children before destroying self
433 XFreePixmap (XtDisplay ((Widget
) GetMainWidget()), (Pixmap
) m_backingPixmap
);
435 Widget w
= (Widget
) m_drawingArea
;
436 wxDeleteWindowFromTable(w
);
441 m_drawingArea
= (WXWidget
) 0;
444 // Only if we're _really_ a canvas (not a dialog box/panel)
445 if (m_scrolledWindow
)
447 wxDeleteWindowFromTable((Widget
) m_scrolledWindow
);
452 wxDeleteWindowFromTable((Widget
) m_hScrollBar
);
453 XtUnmanageChild((Widget
) m_hScrollBar
);
457 wxDeleteWindowFromTable((Widget
) m_vScrollBar
);
458 XtUnmanageChild((Widget
) m_vScrollBar
);
462 XtDestroyWidget((Widget
) m_hScrollBar
);
464 XtDestroyWidget((Widget
) m_vScrollBar
);
466 UnmanageAndDestroy(m_scrolledWindow
);
470 XtDestroyWidget ((Widget
) m_borderWidget
);
471 m_borderWidget
= (WXWidget
) 0;
474 else // Why wasn't this here before? JACS 8/3/2000
478 // Destroy the window
481 // If this line (XtDestroyWidget) causes a crash, you may comment it out.
482 // Child widgets will get destroyed automatically when a frame
483 // or dialog is destroyed, but before that you may get some memory
484 // leaks and potential layout problems if you delete and then add
487 // GRG, Feb/2000: commented this out when adding support for
488 // wxSCROLL[WIN]_THUMBRELEASE events. Also it was reported
489 // that this call crashed wxMotif under OS/2, so it seems
490 // that leaving it out is the right thing to do.
491 // SN, Feb/2000: newgrid/griddemo shows why it is needed :-(
492 XtDestroyWidget((Widget
) GetMainWidget());
493 SetMainWidget((WXWidget
) NULL
);
497 // ----------------------------------------------------------------------------
498 // scrollbar management
499 // ----------------------------------------------------------------------------
502 void wxWindow::CreateScrollbar(wxOrientation orientation
)
504 wxCHECK_RET( m_drawingArea
, "this window can't have scrollbars" );
506 XtVaSetValues((Widget
) m_scrolledWindow
, XmNresizePolicy
, XmRESIZE_NONE
, NULL
);
508 // Add scrollbars if required
509 if (orientation
== wxHORIZONTAL
)
511 Widget hScrollBar
= XtVaCreateManagedWidget ("hsb",
512 xmScrollBarWidgetClass
, (Widget
) m_scrolledWindow
,
513 XmNorientation
, XmHORIZONTAL
,
515 XtAddCallback (hScrollBar
, XmNvalueChangedCallback
, (XtCallbackProc
) wxScrollBarCallback
, (XtPointer
) XmHORIZONTAL
);
516 XtAddCallback (hScrollBar
, XmNdragCallback
, (XtCallbackProc
) wxScrollBarCallback
, (XtPointer
) XmHORIZONTAL
);
517 XtAddCallback (hScrollBar
, XmNincrementCallback
, (XtCallbackProc
) wxScrollBarCallback
, (XtPointer
) XmHORIZONTAL
);
518 XtAddCallback (hScrollBar
, XmNdecrementCallback
, (XtCallbackProc
) wxScrollBarCallback
, (XtPointer
) XmHORIZONTAL
);
519 XtAddCallback (hScrollBar
, XmNpageIncrementCallback
, (XtCallbackProc
) wxScrollBarCallback
, (XtPointer
) XmHORIZONTAL
);
520 XtAddCallback (hScrollBar
, XmNpageDecrementCallback
, (XtCallbackProc
) wxScrollBarCallback
, (XtPointer
) XmHORIZONTAL
);
521 XtAddCallback (hScrollBar
, XmNtoTopCallback
, (XtCallbackProc
) wxScrollBarCallback
, (XtPointer
) XmHORIZONTAL
);
522 XtAddCallback (hScrollBar
, XmNtoBottomCallback
, (XtCallbackProc
) wxScrollBarCallback
, (XtPointer
) XmHORIZONTAL
);
524 XtVaSetValues (hScrollBar
,
529 m_hScrollBar
= (WXWidget
) hScrollBar
;
531 wxColour backgroundColour
= wxSystemSettings::GetColour(wxSYS_COLOUR_3DFACE
);
532 DoChangeBackgroundColour(m_hScrollBar
, backgroundColour
, TRUE
);
534 XtRealizeWidget(hScrollBar
);
536 XtVaSetValues((Widget
) m_scrolledWindow
,
537 XmNhorizontalScrollBar
, (Widget
) m_hScrollBar
,
542 wxAddWindowToTable( hScrollBar
, this );
545 if (orientation
== wxVERTICAL
)
547 Widget vScrollBar
= XtVaCreateManagedWidget ("vsb",
548 xmScrollBarWidgetClass
, (Widget
) m_scrolledWindow
,
549 XmNorientation
, XmVERTICAL
,
551 XtAddCallback (vScrollBar
, XmNvalueChangedCallback
, (XtCallbackProc
) wxScrollBarCallback
, (XtPointer
) XmVERTICAL
);
552 XtAddCallback (vScrollBar
, XmNdragCallback
, (XtCallbackProc
) wxScrollBarCallback
, (XtPointer
) XmVERTICAL
);
553 XtAddCallback (vScrollBar
, XmNincrementCallback
, (XtCallbackProc
) wxScrollBarCallback
, (XtPointer
) XmVERTICAL
);
554 XtAddCallback (vScrollBar
, XmNdecrementCallback
, (XtCallbackProc
) wxScrollBarCallback
, (XtPointer
) XmVERTICAL
);
555 XtAddCallback (vScrollBar
, XmNpageIncrementCallback
, (XtCallbackProc
) wxScrollBarCallback
, (XtPointer
) XmVERTICAL
);
556 XtAddCallback (vScrollBar
, XmNpageDecrementCallback
, (XtCallbackProc
) wxScrollBarCallback
, (XtPointer
) XmVERTICAL
);
557 XtAddCallback (vScrollBar
, XmNtoTopCallback
, (XtCallbackProc
) wxScrollBarCallback
, (XtPointer
) XmVERTICAL
);
558 XtAddCallback (vScrollBar
, XmNtoBottomCallback
, (XtCallbackProc
) wxScrollBarCallback
, (XtPointer
) XmVERTICAL
);
560 XtVaSetValues (vScrollBar
,
565 m_vScrollBar
= (WXWidget
) vScrollBar
;
566 wxColour backgroundColour
= wxSystemSettings::GetColour(wxSYS_COLOUR_3DFACE
);
567 DoChangeBackgroundColour(m_vScrollBar
, backgroundColour
, TRUE
);
569 XtRealizeWidget(vScrollBar
);
571 XtVaSetValues((Widget
) m_scrolledWindow
,
572 XmNverticalScrollBar
, (Widget
) m_vScrollBar
,
577 wxAddWindowToTable( vScrollBar
, this );
580 XtVaSetValues((Widget
) m_scrolledWindow
, XmNresizePolicy
, XmRESIZE_ANY
, NULL
);
583 void wxWindow::DestroyScrollbar(wxOrientation orientation
)
585 wxCHECK_RET( m_drawingArea
, "this window can't have scrollbars" );
587 XtVaSetValues((Widget
) m_scrolledWindow
, XmNresizePolicy
, XmRESIZE_NONE
, NULL
);
588 // Add scrollbars if required
589 if (orientation
== wxHORIZONTAL
)
593 wxDeleteWindowFromTable((Widget
)m_hScrollBar
);
594 XtDestroyWidget((Widget
) m_hScrollBar
);
596 m_hScrollBar
= (WXWidget
) 0;
599 XtVaSetValues((Widget
) m_scrolledWindow
,
600 XmNhorizontalScrollBar
, (Widget
) 0,
605 if (orientation
== wxVERTICAL
)
609 wxDeleteWindowFromTable((Widget
)m_vScrollBar
);
610 XtDestroyWidget((Widget
) m_vScrollBar
);
612 m_vScrollBar
= (WXWidget
) 0;
615 XtVaSetValues((Widget
) m_scrolledWindow
,
616 XmNverticalScrollBar
, (Widget
) 0,
620 XtVaSetValues((Widget
) m_scrolledWindow
, XmNresizePolicy
, XmRESIZE_ANY
, NULL
);
623 // ---------------------------------------------------------------------------
625 // ---------------------------------------------------------------------------
627 void wxWindow::SetFocus()
629 Widget wMain
= (Widget
) GetMainWidget();
630 XmProcessTraversal(wMain
, XmTRAVERSE_CURRENT
);
631 XmProcessTraversal((Widget
) GetMainWidget(), XmTRAVERSE_CURRENT
);
634 // Get the window with the focus
635 wxWindow
*wxWindowBase::FindFocus()
638 // (1) Can there be multiple focussed widgets in an application?
639 // In which case we need to find the top-level window that's
641 // (2) The widget with the focus may not be in the widget table
642 // depending on which widgets I put in the table
643 wxWindow
*winFocus
= (wxWindow
*)NULL
;
644 for ( wxWindowList::Node
*node
= wxTopLevelWindows
.GetFirst();
646 node
= node
->GetNext() )
648 wxWindow
*win
= node
->GetData();
650 Widget w
= XmGetFocusWidget ((Widget
) win
->GetTopWidget());
652 if (w
!= (Widget
) NULL
)
654 winFocus
= wxGetWindowFromTable(w
);
663 bool wxWindow::Enable(bool enable
)
665 if ( !wxWindowBase::Enable(enable
) )
668 Widget wMain
= (Widget
)GetMainWidget();
671 XtSetSensitive(wMain
, enable
);
672 XmUpdateDisplay(wMain
);
678 bool wxWindow::Show(bool show
)
680 if ( !wxWindowBase::Show(show
) )
683 if (m_borderWidget
|| m_scrolledWindow
)
685 MapOrUnmap(m_drawingArea
, show
);
686 MapOrUnmap(m_borderWidget
? m_borderWidget
: m_scrolledWindow
, show
);
690 if ( !MapOrUnmap(GetTopWidget(), show
) )
691 MapOrUnmap(GetMainWidget(), show
);
697 // Raise the window to the top of the Z order
698 void wxWindow::Raise()
700 Widget wTop
= (Widget
) GetTopWidget();
701 Window window
= XtWindow(wTop
);
702 XRaiseWindow(XtDisplay(wTop
), window
);
705 // Lower the window to the bottom of the Z order
706 void wxWindow::Lower()
708 Widget wTop
= (Widget
) GetTopWidget();
709 Window window
= XtWindow(wTop
);
710 XLowerWindow(XtDisplay(wTop
), window
);
713 void wxWindow::SetTitle(const wxString
& title
)
715 XtVaSetValues((Widget
)GetMainWidget(), XmNtitle
, title
.c_str(), NULL
);
718 wxString
wxWindow::GetTitle() const
721 XtVaGetValues((Widget
)GetMainWidget(), XmNtitle
, &title
, NULL
);
723 return wxString(title
);
726 void wxWindow::DoCaptureMouse()
728 g_captureWindow
= this;
732 Widget wMain
= (Widget
)GetMainWidget();
734 XtAddGrab(wMain
, TRUE
, FALSE
);
736 m_winCaptured
= TRUE
;
739 void wxWindow::DoReleaseMouse()
741 g_captureWindow
= NULL
;
742 if ( !m_winCaptured
)
745 Widget wMain
= (Widget
)GetMainWidget();
749 m_winCaptured
= FALSE
;
752 bool wxWindow::SetFont(const wxFont
& font
)
754 if ( !wxWindowBase::SetFont(font
) )
765 bool wxWindow::SetCursor(const wxCursor
& cursor
)
767 if ( !wxWindowBase::SetCursor(cursor
) )
773 // wxASSERT_MSG( m_cursor.Ok(),
774 // wxT("cursor must be valid after call to the base version"));
775 wxCursor
* cursor2
= NULL
;
777 cursor2
= & m_cursor
;
779 cursor2
= wxSTANDARD_CURSOR
;
781 WXDisplay
*dpy
= GetXDisplay();
782 WXCursor x_cursor
= cursor2
->GetXCursor(dpy
);
784 Widget w
= (Widget
) GetMainWidget();
785 Window win
= XtWindow(w
);
786 XDefineCursor((Display
*) dpy
, win
, (Cursor
) x_cursor
);
791 // Coordinates relative to the window
792 void wxWindow::WarpPointer (int x
, int y
)
794 Widget wClient
= (Widget
)GetClientWidget();
796 XWarpPointer(XtDisplay(wClient
), None
, XtWindow(wClient
), 0, 0, 0, 0, x
, y
);
799 // ---------------------------------------------------------------------------
801 // ---------------------------------------------------------------------------
803 int wxWindow::GetScrollPos(int orient
) const
805 if (orient
== wxHORIZONTAL
)
811 Widget scrollBar
= (Widget
) ((orient
== wxHORIZONTAL
) ? m_hScrollBar
: m_vScrollBar
);
815 XtVaGetValues(scrollBar
, XmNvalue
, &pos
, NULL
);
823 // This now returns the whole range, not just the number of positions that we
825 int wxWindow::GetScrollRange(int orient
) const
827 Widget scrollBar
= (Widget
)GetScrollbar((wxOrientation
)orient
);
828 wxCHECK_MSG( scrollBar
, 0, "no such scrollbar" );
832 XtVaGetValues(scrollBar
, XmNmaximum
, &range
, NULL
);
836 int wxWindow::GetScrollThumb(int orient
) const
838 Widget scrollBar
= (Widget
)GetScrollbar((wxOrientation
)orient
);
839 wxCHECK_MSG( scrollBar
, 0, "no such scrollbar" );
842 XtVaGetValues(scrollBar
, XmNsliderSize
, &thumb
, NULL
);
846 void wxWindow::SetScrollPos(int orient
, int pos
, bool WXUNUSED(refresh
))
848 Widget scrollBar
= (Widget
)GetScrollbar((wxOrientation
)orient
);
852 XtVaSetValues (scrollBar
, XmNvalue
, pos
, NULL
);
855 SetInternalScrollPos((wxOrientation
)orient
, pos
);
858 // New function that will replace some of the above.
859 void wxWindow::SetScrollbar(int orient
, int pos
, int thumbVisible
,
860 int range
, bool WXUNUSED(refresh
))
863 GetSize(& oldW
, & oldH
);
867 if (thumbVisible
== 0)
870 if (thumbVisible
> range
)
871 thumbVisible
= range
;
873 // Save the old state to see if it changed
874 WXWidget oldScrollBar
= GetScrollbar((wxOrientation
)orient
);
876 if (orient
== wxHORIZONTAL
)
878 if (thumbVisible
== range
)
881 DestroyScrollbar(wxHORIZONTAL
);
886 CreateScrollbar(wxHORIZONTAL
);
889 if (orient
== wxVERTICAL
)
891 if (thumbVisible
== range
)
894 DestroyScrollbar(wxVERTICAL
);
899 CreateScrollbar(wxVERTICAL
);
902 WXWidget newScrollBar
= GetScrollbar((wxOrientation
)orient
);
904 if (oldScrollBar
!= newScrollBar
)
906 // This is important! Without it, scrollbars misbehave badly.
907 XtUnrealizeWidget((Widget
) m_scrolledWindow
);
908 XmScrolledWindowSetAreas ((Widget
) m_scrolledWindow
, (Widget
) m_hScrollBar
, (Widget
) m_vScrollBar
, (Widget
) m_drawingArea
);
909 XtRealizeWidget((Widget
) m_scrolledWindow
);
910 XtManageChild((Widget
) m_scrolledWindow
);
915 XtVaSetValues((Widget
) newScrollBar
,
919 XmNsliderSize
, thumbVisible
,
923 SetInternalScrollPos((wxOrientation
)orient
, pos
);
926 GetSize(& newW
, & newH
);
928 // Adjusting scrollbars can resize the canvas accidentally
929 if (newW
!= oldW
|| newH
!= oldH
)
930 SetSize(-1, -1, oldW
, oldH
);
933 // Does a physical scroll
934 void wxWindow::ScrollWindow(int dx
, int dy
, const wxRect
*rect
)
939 // Use specified rectangle
940 x
= rect
->x
; y
= rect
->y
; w
= rect
->width
; h
= rect
->height
;
944 // Use whole client area
946 GetClientSize(& w
, & h
);
949 int x1
= (dx
>= 0) ? x
: x
- dx
;
950 int y1
= (dy
>= 0) ? y
: y
- dy
;
951 int w1
= w
- abs(dx
);
952 int h1
= h
- abs(dy
);
953 int x2
= (dx
>= 0) ? x
+ dx
: x
;
954 int y2
= (dy
>= 0) ? y
+ dy
: y
;
958 dc
.SetLogicalFunction (wxCOPY
);
960 Widget widget
= (Widget
) GetMainWidget();
961 Window window
= XtWindow(widget
);
962 Display
* display
= XtDisplay(widget
);
964 XCopyArea(display
, window
, window
, (GC
) dc
.GetGC(),
965 x1
, y1
, w1
, h1
, x2
, y2
);
967 dc
.SetAutoSetting(TRUE
);
968 wxBrush
brush(GetBackgroundColour(), wxSOLID
);
969 dc
.SetBrush(brush
); // FIXME: needed?
971 wxWindowList::Node
*cnode
= m_children
.GetFirst();
974 wxWindow
*child
= cnode
->GetData();
977 child
->GetSize( &sx
, &sy
);
978 wxPoint
pos( child
->GetPosition() );
979 child
->SetSize( pos
.x
+ dx
, pos
.y
+ dy
, sx
, sy
, wxSIZE_ALLOW_MINUS_ONE
);
980 cnode
= cnode
->GetNext();
983 // We'll add rectangles to the list of update rectangles according to which
984 // bits we've exposed.
989 wxRect
*rect
= new wxRect
;
995 XFillRectangle(display
, window
,
996 (GC
) dc
.GetGC(), rect
->x
, rect
->y
, rect
->width
, rect
->height
);
1000 rect
->width
= rect
->width
;
1001 rect
->height
= rect
->height
;
1003 updateRects
.Append((wxObject
*) rect
);
1007 wxRect
*rect
= new wxRect
;
1009 rect
->x
= x
+ w
+ dx
;
1014 XFillRectangle(display
, window
,
1015 (GC
) dc
.GetGC(), rect
->x
, rect
->y
, rect
->width
,
1020 rect
->width
= rect
->width
;
1021 rect
->height
= rect
->height
;
1023 updateRects
.Append((wxObject
*) rect
);
1027 wxRect
*rect
= new wxRect
;
1034 XFillRectangle(display
, window
,
1035 (GC
) dc
.GetGC(), rect
->x
, rect
->y
, rect
->width
, rect
->height
);
1039 rect
->width
= rect
->width
;
1040 rect
->height
= rect
->height
;
1042 updateRects
.Append((wxObject
*) rect
);
1046 wxRect
*rect
= new wxRect
;
1049 rect
->y
= y
+ h
+ dy
;
1053 XFillRectangle(display
, window
,
1054 (GC
) dc
.GetGC(), rect
->x
, rect
->y
, rect
->width
, rect
->height
);
1058 rect
->width
= rect
->width
;
1059 rect
->height
= rect
->height
;
1061 updateRects
.Append((wxObject
*) rect
);
1063 dc
.SetBrush(wxNullBrush
);
1065 // Now send expose events
1067 wxList::Node
* node
= updateRects
.GetFirst();
1070 wxRect
* rect
= (wxRect
*) node
->GetData();
1073 event
.type
= Expose
;
1074 event
.display
= display
;
1075 event
.send_event
= True
;
1076 event
.window
= window
;
1080 event
.width
= rect
->width
;
1081 event
.height
= rect
->height
;
1085 XSendEvent(display
, window
, False
, ExposureMask
, (XEvent
*)&event
);
1087 node
= node
->GetNext();
1091 // Delete the update rects
1092 node
= updateRects
.GetFirst();
1095 wxRect
* rect
= (wxRect
*) node
->GetData();
1097 node
= node
->GetNext();
1100 XmUpdateDisplay((Widget
) GetMainWidget());
1103 // ---------------------------------------------------------------------------
1105 // ---------------------------------------------------------------------------
1107 #if wxUSE_DRAG_AND_DROP
1109 void wxWindow::SetDropTarget(wxDropTarget
* WXUNUSED(pDropTarget
))
1116 // Old style file-manager drag&drop
1117 void wxWindow::DragAcceptFiles(bool WXUNUSED(accept
))
1122 // ----------------------------------------------------------------------------
1124 // ----------------------------------------------------------------------------
1128 void wxWindow::DoSetToolTip(wxToolTip
* WXUNUSED(tooltip
))
1133 #endif // wxUSE_TOOLTIPS
1135 // ----------------------------------------------------------------------------
1137 // ----------------------------------------------------------------------------
1141 bool wxWindow::DoPopupMenu(wxMenu
*menu
, int x
, int y
)
1143 Widget widget
= (Widget
) GetMainWidget();
1145 /* The menuId field seems to be usused, so we'll use it to
1146 indicate whether a menu is popped up or not:
1147 0: Not currently created as a popup
1148 -1: Created as a popup, but not active
1152 if (menu
->GetParent() && (menu
->GetId() != -1))
1155 if (menu
->GetMainWidget())
1157 menu
->DestroyMenu(TRUE
);
1160 menu
->SetId(1); /* Mark as popped-up */
1161 menu
->CreateMenu(NULL
, widget
, menu
);
1162 menu
->SetInvokingWindow(this);
1166 // menu->SetParent(parent);
1167 // parent->children->Append(menu); // Store menu for later deletion
1169 Widget menuWidget
= (Widget
) menu
->GetMainWidget();
1177 if (this->IsKindOf(CLASSINFO(wxCanvas)))
1179 wxCanvas *canvas = (wxCanvas *) this;
1180 deviceX = canvas->GetDC ()->LogicalToDeviceX (x);
1181 deviceY = canvas->GetDC ()->LogicalToDeviceY (y);
1185 Display
*display
= XtDisplay (widget
);
1186 Window rootWindow
= RootWindowOfScreen (XtScreen((Widget
)widget
));
1187 Window thisWindow
= XtWindow (widget
);
1189 XTranslateCoordinates (display
, thisWindow
, rootWindow
, (int) deviceX
, (int) deviceY
,
1190 &rootX
, &rootY
, &childWindow
);
1192 XButtonPressedEvent event
;
1193 event
.type
= ButtonPress
;
1199 event
.x_root
= rootX
;
1200 event
.y_root
= rootY
;
1202 XmMenuPosition (menuWidget
, &event
);
1203 XtManageChild (menuWidget
);
1205 // The ID of a pop-up menu is 1 when active, and is set to 0 by the
1206 // idle-time destroy routine.
1207 // Waiting until this ID changes causes this function to block until
1208 // the menu has been dismissed and the widgets cleaned up.
1209 // In other words, once this routine returns, it is safe to delete
1211 // Ian Brown <ian.brown@printsoft.de>
1213 wxEventLoop evtLoop
;
1215 while (menu
->GetId() == 1)
1217 wxDoEventLoopIteration( evtLoop
);
1225 // ---------------------------------------------------------------------------
1226 // moving and resizing
1227 // ---------------------------------------------------------------------------
1229 bool wxWindow::PreResize()
1235 void wxWindow::DoGetSize(int *x
, int *y
) const
1237 Widget widget
= (Widget
)( !m_drawingArea
? GetTopWidget() :
1238 ( m_borderWidget
? m_borderWidget
:
1239 m_scrolledWindow
? m_scrolledWindow
:
1243 XtVaGetValues( widget
,
1251 void wxWindow::DoGetPosition(int *x
, int *y
) const
1253 Widget widget
= (Widget
)
1255 ( m_borderWidget
? m_borderWidget
: m_scrolledWindow
) :
1259 XtVaGetValues(widget
, XmNx
, &xx
, XmNy
, &yy
, NULL
);
1261 // We may be faking the client origin. So a window that's really at (0, 30)
1262 // may appear (to wxWin apps) to be at (0, 0).
1265 wxPoint
pt(GetParent()->GetClientAreaOrigin());
1274 void wxWindow::DoScreenToClient(int *x
, int *y
) const
1276 Widget widget
= (Widget
) GetClientWidget();
1277 Display
*display
= XtDisplay((Widget
) GetMainWidget());
1278 Window rootWindow
= RootWindowOfScreen(XtScreen(widget
));
1279 Window thisWindow
= XtWindow(widget
);
1284 XTranslateCoordinates(display
, rootWindow
, thisWindow
, xx
, yy
, x
, y
, &childWindow
);
1287 void wxWindow::DoClientToScreen(int *x
, int *y
) const
1289 Widget widget
= (Widget
) GetClientWidget();
1290 Display
*display
= XtDisplay(widget
);
1291 Window rootWindow
= RootWindowOfScreen(XtScreen(widget
));
1292 Window thisWindow
= XtWindow(widget
);
1297 XTranslateCoordinates(display
, thisWindow
, rootWindow
, xx
, yy
, x
, y
, &childWindow
);
1301 // Get size *available for subwindows* i.e. excluding menu bar etc.
1302 void wxWindow::DoGetClientSize(int *x
, int *y
) const
1304 Widget widget
= (Widget
) GetClientWidget();
1306 XtVaGetValues(widget
, XmNwidth
, &xx
, XmNheight
, &yy
, NULL
);
1307 if(x
) *x
= xx
; if(y
) *y
= yy
;
1310 void wxWindow::DoSetSize(int x
, int y
, int width
, int height
, int sizeFlags
)
1312 DoSetSizeIntr(x
, y
, width
, height
, sizeFlags
, FALSE
);
1315 void wxWindow::DoSetSizeIntr(int x
, int y
, int width
, int height
,
1316 int sizeFlags
, bool fromCtor
)
1318 // A bit of optimization to help sort out the flickers.
1319 int oldX
= -1, oldY
= -1, oldW
= -1, oldH
= -1;
1322 GetSize(& oldW
, & oldH
);
1323 GetPosition(& oldX
, & oldY
);
1326 if ( !(sizeFlags
& wxSIZE_ALLOW_MINUS_ONE
) )
1334 wxSize
size(-1, -1);
1337 if ( sizeFlags
& wxSIZE_AUTO_WIDTH
&& !fromCtor
)
1339 size
= DoGetBestSize();
1350 if( sizeFlags
& wxSIZE_AUTO_HEIGHT
&& !fromCtor
)
1352 if( size
.x
== -1 ) size
= DoGetBestSize();
1361 if ( x
!= oldX
|| y
!= oldY
|| width
!= oldW
|| height
!= oldH
1362 || !wxNoOptimize::CanOptimize() )
1368 if (x
> -1 || (sizeFlags
& wxSIZE_ALLOW_MINUS_ONE
))
1371 if (y
> -1 || (sizeFlags
& wxSIZE_ALLOW_MINUS_ONE
))
1375 flags
|= wxMOVE_WIDTH
;
1378 flags
|= wxMOVE_HEIGHT
;
1380 int xx
= x
; int yy
= y
;
1381 AdjustForParentClientOrigin(xx
, yy
, sizeFlags
);
1383 DoMoveWindow( xx
, yy
, width
, height
);
1385 DoMoveWindowIntr( xx
, yy
, width
, height
, flags
);
1390 Widget widget
= (Widget
) GetTopWidget();
1394 bool managed
= XtIsManaged( widget
);
1396 XtUnmanageChild(widget
);
1400 AdjustForParentClientOrigin(xx
, yy
, sizeFlags
);
1402 DoMoveWindow(xx
, yy
, width
, height
);
1405 XtManageChild(widget
);
1409 void wxWindow::DoSetClientSize(int width
, int height
)
1413 Widget drawingArea
= (Widget
) m_drawingArea
;
1415 XtVaSetValues(drawingArea
, XmNresizePolicy
, XmRESIZE_ANY
, NULL
);
1418 XtVaSetValues(drawingArea
, XmNwidth
, width
, NULL
);
1420 XtVaSetValues(drawingArea
, XmNheight
, height
, NULL
);
1422 XtVaSetValues(drawingArea
, XmNresizePolicy
, XmRESIZE_NONE
, NULL
);
1426 Widget widget
= (Widget
) GetTopWidget();
1429 XtVaSetValues(widget
, XmNwidth
, width
, NULL
);
1431 XtVaSetValues(widget
, XmNheight
, height
, NULL
);
1434 // For implementation purposes - sometimes decorations make the client area
1436 wxPoint
wxWindow::GetClientAreaOrigin() const
1438 return wxPoint(0, 0);
1441 void wxWindow::SetSizeHints(int minW
, int minH
, int maxW
, int maxH
, int incW
, int incH
)
1448 wxFrame
*frame
= wxDynamicCast(this, wxFrame
);
1451 // TODO what about dialogs?
1455 Widget widget
= (Widget
) frame
->GetShellWidget();
1458 XtVaSetValues(widget
, XmNminWidth
, minW
, NULL
);
1460 XtVaSetValues(widget
, XmNminHeight
, minH
, NULL
);
1462 XtVaSetValues(widget
, XmNmaxWidth
, maxW
, NULL
);
1464 XtVaSetValues(widget
, XmNmaxHeight
, maxH
, NULL
);
1466 XtVaSetValues(widget
, XmNwidthInc
, incW
, NULL
);
1468 XtVaSetValues(widget
, XmNheightInc
, incH
, NULL
);
1471 void wxWindow::DoMoveWindowIntr(int xx
, int yy
, int w
, int h
,
1476 Widget drawingArea
= (Widget
) m_drawingArea
;
1477 Widget borderOrScrolled
= m_borderWidget
?
1478 (Widget
) m_borderWidget
:
1479 (Widget
) m_scrolledWindow
;
1481 bool managed
= XtIsManaged(borderOrScrolled
);
1484 XtUnmanageChild (borderOrScrolled
);
1485 XtVaSetValues(drawingArea
, XmNresizePolicy
, XmRESIZE_ANY
, NULL
);
1487 if (flags
& wxMOVE_X
)
1488 XtVaSetValues (borderOrScrolled
,
1491 if (flags
& wxMOVE_Y
)
1492 XtVaSetValues (borderOrScrolled
,
1496 if (flags
& wxMOVE_WIDTH
)
1500 XtVaSetValues ((Widget
) m_borderWidget
, XmNwidth
, w
, NULL
);
1501 short thick
, margin
;
1502 XtVaGetValues ((Widget
) m_borderWidget
,
1503 XmNshadowThickness
, &thick
,
1504 XmNmarginWidth
, &margin
,
1506 w
-= 2 * (thick
+ margin
);
1509 XtVaSetValues ((Widget
) m_scrolledWindow
, XmNwidth
, w
, NULL
);
1512 if (flags
& wxMOVE_HEIGHT
)
1516 XtVaSetValues ((Widget
) m_borderWidget
, XmNheight
, h
, NULL
);
1517 short thick
, margin
;
1518 XtVaGetValues ((Widget
) m_borderWidget
,
1519 XmNshadowThickness
, &thick
,
1520 XmNmarginHeight
, &margin
,
1522 h
-= 2 * (thick
+ margin
);
1525 XtVaSetValues ((Widget
) m_scrolledWindow
, XmNheight
, h
, NULL
);
1529 XtManageChild (borderOrScrolled
);
1530 XtVaSetValues(drawingArea
, XmNresizePolicy
, XmRESIZE_NONE
, NULL
);
1537 XtVaSetValues((Widget
)GetTopWidget(),
1546 void wxWindow::DoMoveWindow(int x
, int y
, int width
, int height
)
1548 DoMoveWindowIntr (x
, y
, width
, height
,
1549 wxMOVE_X
|wxMOVE_Y
|wxMOVE_WIDTH
|wxMOVE_HEIGHT
);
1552 // ---------------------------------------------------------------------------
1554 // ---------------------------------------------------------------------------
1556 int wxWindow::GetCharHeight() const
1558 wxCHECK_MSG( m_font
.Ok(), 0, "valid window font needed" );
1560 WXFontStructPtr pFontStruct
= m_font
.GetFontStruct(1.0, GetXDisplay());
1562 int direction
, ascent
, descent
;
1563 XCharStruct overall
;
1564 XTextExtents ((XFontStruct
*) pFontStruct
, "x", 1, &direction
, &ascent
,
1565 &descent
, &overall
);
1567 // return (overall.ascent + overall.descent);
1568 return (ascent
+ descent
);
1571 int wxWindow::GetCharWidth() const
1573 wxCHECK_MSG( m_font
.Ok(), 0, "valid window font needed" );
1575 WXFontStructPtr pFontStruct
= m_font
.GetFontStruct(1.0, GetXDisplay());
1577 int direction
, ascent
, descent
;
1578 XCharStruct overall
;
1579 XTextExtents ((XFontStruct
*) pFontStruct
, "x", 1, &direction
, &ascent
,
1580 &descent
, &overall
);
1582 return overall
.width
;
1585 void wxWindow::GetTextExtent(const wxString
& string
,
1587 int *descent
, int *externalLeading
,
1588 const wxFont
*theFont
) const
1590 wxFont
*fontToUse
= (wxFont
*)theFont
;
1592 fontToUse
= (wxFont
*) & m_font
;
1594 wxCHECK_RET( fontToUse
->Ok(), "valid window font needed" );
1596 WXFontStructPtr pFontStruct
= fontToUse
->GetFontStruct(1.0, GetXDisplay());
1598 int direction
, ascent
, descent2
;
1599 XCharStruct overall
;
1600 int slen
= string
.Len();
1604 XTextExtents16((XFontStruct
*) pFontStruct
, (XChar2b
*) (char*) (const char*) string
, slen
, &direction
,
1605 &ascent
, &descent2
, &overall
);
1608 XTextExtents((XFontStruct
*) pFontStruct
, string
, slen
,
1609 &direction
, &ascent
, &descent2
, &overall
);
1612 *x
= (overall
.width
);
1614 *y
= (ascent
+ descent2
);
1616 *descent
= descent2
;
1617 if (externalLeading
)
1618 *externalLeading
= 0;
1622 // ----------------------------------------------------------------------------
1624 // ----------------------------------------------------------------------------
1626 void wxWindow::Refresh(bool eraseBack
, const wxRect
*rect
)
1628 m_needsRefresh
= TRUE
;
1629 Display
*display
= XtDisplay((Widget
) GetMainWidget());
1630 Window thisWindow
= XtWindow((Widget
) GetMainWidget());
1632 XExposeEvent dummyEvent
;
1634 GetSize(&width
, &height
);
1636 dummyEvent
.type
= Expose
;
1637 dummyEvent
.display
= display
;
1638 dummyEvent
.send_event
= True
;
1639 dummyEvent
.window
= thisWindow
;
1642 dummyEvent
.x
= rect
->x
;
1643 dummyEvent
.y
= rect
->y
;
1644 dummyEvent
.width
= rect
->width
;
1645 dummyEvent
.height
= rect
->height
;
1651 dummyEvent
.width
= width
;
1652 dummyEvent
.height
= height
;
1654 dummyEvent
.count
= 0;
1658 wxClientDC
dc(this);
1659 wxBrush
backgroundBrush(GetBackgroundColour(), wxSOLID
);
1660 dc
.SetBackground(backgroundBrush
);
1667 XSendEvent(display
, thisWindow
, False
, ExposureMask
, (XEvent
*)&dummyEvent
);
1670 void wxWindow::Clear()
1672 wxClientDC
dc(this);
1673 wxBrush
brush(GetBackgroundColour(), wxSOLID
);
1674 dc
.SetBackground(brush
);
1678 void wxWindow::ClearUpdateRects()
1680 wxRectList::Node
* node
= m_updateRects
.GetFirst();
1683 wxRect
* rect
= node
->GetData();
1685 node
= node
->GetNext();
1688 m_updateRects
.Clear();
1691 void wxWindow::DoPaint()
1693 //TODO : make a temporary gc so we can do the XCopyArea below
1694 if (m_backingPixmap
&& !m_needsRefresh
)
1698 GC tempGC
= (GC
) dc
.GetBackingGC();
1700 Widget widget
= (Widget
) GetMainWidget();
1705 // We have to test whether it's a wxScrolledWindow (hack!) because
1706 // otherwise we don't know how many pixels have been scrolled. We might
1707 // solve this in the future by defining virtual wxWindow functions to get
1708 // the scroll position in pixels. Or, each kind of scrolled window has to
1709 // implement backing stores itself, using generic wxWindows code.
1710 wxScrolledWindow
* scrolledWindow
= wxDynamicCast(this, wxScrolledWindow
);
1711 if ( scrolledWindow
)
1714 scrolledWindow
->CalcScrolledPosition(0, 0, &x
, &y
);
1720 // TODO: This could be optimized further by only copying the areas in the
1721 // current update region.
1723 // Only blit the part visible in the client area. The backing pixmap
1724 // always starts at 0, 0 but we may be looking at only a portion of it.
1725 wxSize clientArea
= GetClientSize();
1726 int toBlitX
= m_pixmapWidth
- scrollPosX
;
1727 int toBlitY
= m_pixmapHeight
- scrollPosY
;
1729 // Copy whichever is samller, the amount of pixmap we have to copy,
1730 // or the size of the client area.
1731 toBlitX
= wxMin(toBlitX
, clientArea
.x
);
1732 toBlitY
= wxMin(toBlitY
, clientArea
.y
);
1734 // Make sure we're not negative
1735 toBlitX
= wxMax(0, toBlitX
);
1736 toBlitY
= wxMax(0, toBlitY
);
1741 (Pixmap
) m_backingPixmap
,
1744 scrollPosX
, scrollPosY
, // Start at the scroll position
1745 toBlitX
, toBlitY
, // How much of the pixmap to copy
1751 wxWindowDC
dc(this);
1752 // Set an erase event first
1753 wxEraseEvent
eraseEvent(GetId(), &dc
);
1754 eraseEvent
.SetEventObject(this);
1755 GetEventHandler()->ProcessEvent(eraseEvent
);
1757 wxPaintEvent
event(GetId());
1758 event
.SetEventObject(this);
1759 GetEventHandler()->ProcessEvent(event
);
1761 m_needsRefresh
= FALSE
;
1765 // ----------------------------------------------------------------------------
1767 // ----------------------------------------------------------------------------
1769 // Responds to colour changes: passes event on to children.
1770 void wxWindow::OnSysColourChanged(wxSysColourChangedEvent
& event
)
1772 wxWindowList::Node
*node
= GetChildren().GetFirst();
1775 // Only propagate to non-top-level windows
1776 wxWindow
*win
= node
->GetData();
1777 if ( win
->GetParent() )
1779 wxSysColourChangedEvent event2
;
1780 event
.m_eventObject
= win
;
1781 win
->GetEventHandler()->ProcessEvent(event2
);
1784 node
= node
->GetNext();
1788 void wxWindow::OnIdle(wxIdleEvent
& WXUNUSED(event
))
1790 // This calls the UI-update mechanism (querying windows for
1791 // menu/toolbar/control state information)
1795 // ----------------------------------------------------------------------------
1797 // ----------------------------------------------------------------------------
1799 bool wxWindow::ProcessAccelerator(wxKeyEvent
& event
)
1802 if (!m_acceleratorTable
.Ok())
1805 int count
= m_acceleratorTable
.GetCount();
1806 wxAcceleratorEntry
* entries
= m_acceleratorTable
.GetEntries();
1808 for (i
= 0; i
< count
; i
++)
1810 wxAcceleratorEntry
* entry
= & (entries
[i
]);
1811 if (entry
->MatchesEvent(event
))
1813 // Bingo, we have a match. Now find a control that matches the
1814 // entry command id.
1816 // Need to go up to the top of the window hierarchy, since it might
1817 // be e.g. a menu item
1818 wxWindow
* parent
= this;
1819 while ( parent
&& !parent
->IsTopLevel() )
1820 parent
= parent
->GetParent();
1825 wxFrame
* frame
= wxDynamicCast(parent
, wxFrame
);
1829 // Try for a menu command
1830 if (frame
->GetMenuBar())
1832 wxMenuItem
* item
= frame
->GetMenuBar()->FindItem(entry
->GetCommand());
1835 wxCommandEvent
commandEvent(wxEVT_COMMAND_MENU_SELECTED
, entry
->GetCommand());
1836 commandEvent
.SetEventObject(frame
);
1838 // If ProcessEvent returns TRUE (it was handled), then
1839 // the calling code will skip the event handling.
1840 return frame
->GetEventHandler()->ProcessEvent(commandEvent
);
1846 // Find a child matching the command id
1847 wxWindow
* child
= parent
->FindWindow(entry
->GetCommand());
1853 // Now we process those kinds of windows that we can.
1854 // For now, only buttons.
1855 if ( wxDynamicCast(child
, wxButton
) )
1857 wxCommandEvent
commandEvent (wxEVT_COMMAND_BUTTON_CLICKED
, child
->GetId());
1858 commandEvent
.SetEventObject(child
);
1859 return child
->GetEventHandler()->ProcessEvent(commandEvent
);
1867 // We didn't match the key event against an accelerator.
1871 // ============================================================================
1872 // Motif-specific stuff from here on
1873 // ============================================================================
1875 // ----------------------------------------------------------------------------
1876 // function which maintain the global hash table mapping Widgets to wxWindows
1877 // ----------------------------------------------------------------------------
1879 bool wxAddWindowToTable(Widget w
, wxWindow
*win
)
1881 wxWindow
*oldItem
= NULL
;
1882 if ((oldItem
= (wxWindow
*)wxWidgetHashTable
->Get ((long) w
)))
1884 wxLogDebug("Widget table clash: new widget is %ld, %s",
1885 (long)w
, win
->GetClassInfo()->GetClassName());
1889 wxWidgetHashTable
->Put((long) w
, win
);
1891 wxLogTrace("widget", "Widget 0x%p <-> window %p (%s)",
1892 (WXWidget
)w
, win
, win
->GetClassInfo()->GetClassName());
1897 wxWindow
*wxGetWindowFromTable(Widget w
)
1899 return (wxWindow
*)wxWidgetHashTable
->Get((long) w
);
1902 void wxDeleteWindowFromTable(Widget w
)
1904 wxLogTrace("widget", "Widget 0x%p", (WXWidget
)w
);
1906 wxWidgetHashTable
->Delete((long)w
);
1909 // ----------------------------------------------------------------------------
1910 // add/remove window from the table
1911 // ----------------------------------------------------------------------------
1913 // Add to hash table, add event handler
1914 bool wxWindow::AttachWidget (wxWindow
* WXUNUSED(parent
), WXWidget mainWidget
,
1915 WXWidget formWidget
, int x
, int y
, int width
, int height
)
1917 wxAddWindowToTable((Widget
) mainWidget
, this);
1918 if (CanAddEventHandler())
1920 XtAddEventHandler((Widget
) mainWidget
,
1921 ButtonPressMask
| ButtonReleaseMask
| PointerMotionMask
, // | KeyPressMask,
1923 wxPanelItemEventHandler
,
1930 XtOverrideTranslations ((Widget
) mainWidget
,
1931 ptr
= XtParseTranslationTable ("<Configure>: resize()"));
1932 XtFree ((char *) ptr
);
1935 // Some widgets have a parent form widget, e.g. wxRadioBox
1938 if (!wxAddWindowToTable((Widget
) formWidget
, this))
1942 XtOverrideTranslations ((Widget
) formWidget
,
1943 ptr
= XtParseTranslationTable ("<Configure>: resize()"));
1944 XtFree ((char *) ptr
);
1951 SetSize (x
, y
, width
, height
);
1956 // Remove event handler, remove from hash table
1957 bool wxWindow::DetachWidget(WXWidget widget
)
1959 if (CanAddEventHandler())
1961 XtRemoveEventHandler((Widget
) widget
,
1962 ButtonPressMask
| ButtonReleaseMask
| PointerMotionMask
, // | KeyPressMask,
1964 wxPanelItemEventHandler
,
1968 wxDeleteWindowFromTable((Widget
) widget
);
1972 // ----------------------------------------------------------------------------
1973 // Motif-specific accessors
1974 // ----------------------------------------------------------------------------
1976 // Get the underlying X window
1977 WXWindow
wxWindow::GetXWindow() const
1979 Widget wMain
= (Widget
)GetMainWidget();
1981 return (WXWindow
) XtWindow(wMain
);
1983 return (WXWindow
) 0;
1986 // Get the underlying X display
1987 WXDisplay
*wxWindow::GetXDisplay() const
1989 Widget wMain
= (Widget
)GetMainWidget();
1991 return (WXDisplay
*) XtDisplay(wMain
);
1993 return (WXDisplay
*) NULL
;
1996 WXWidget
wxWindow::GetMainWidget() const
1999 return m_drawingArea
;
2001 return m_mainWidget
;
2004 WXWidget
wxWindow::GetClientWidget() const
2006 if (m_drawingArea
!= (WXWidget
) 0)
2007 return m_drawingArea
;
2009 return GetMainWidget();
2012 WXWidget
wxWindow::GetTopWidget() const
2014 return GetMainWidget();
2017 WXWidget
wxWindow::GetLabelWidget() const
2019 return GetMainWidget();
2022 // ----------------------------------------------------------------------------
2024 // ----------------------------------------------------------------------------
2026 // All widgets should have this as their resize proc.
2027 // OnSize sent to wxWindow via client data.
2028 void wxWidgetResizeProc(Widget w
, XConfigureEvent
*WXUNUSED(event
), String
WXUNUSED(args
)[], int *WXUNUSED(num_args
))
2030 wxWindow
*win
= wxGetWindowFromTable(w
);
2034 if (win
->PreResize())
2037 win
->GetSize(&width
, &height
);
2038 wxSizeEvent
sizeEvent(wxSize(width
, height
), win
->GetId());
2039 sizeEvent
.SetEventObject(win
);
2040 win
->GetEventHandler()->ProcessEvent(sizeEvent
);
2044 static void wxCanvasRepaintProc(Widget drawingArea
,
2045 XtPointer clientData
,
2046 XmDrawingAreaCallbackStruct
* cbs
)
2048 if (!wxGetWindowFromTable(drawingArea
))
2051 XEvent
* event
= cbs
->event
;
2052 wxWindow
* win
= (wxWindow
*) clientData
;
2054 switch (event
->type
)
2058 win
->AddUpdateRect(event
->xexpose
.x
, event
->xexpose
.y
,
2059 event
->xexpose
.width
, event
->xexpose
.height
);
2061 if (event
-> xexpose
.count
== 0)
2064 win
->ClearUpdateRects();
2071 // Unable to deal with Enter/Leave without a separate EventHandler (Motif 1.1.4)
2072 static void wxCanvasEnterLeave(Widget drawingArea
,
2073 XtPointer
WXUNUSED(clientData
),
2074 XCrossingEvent
* event
)
2076 XmDrawingAreaCallbackStruct cbs
;
2079 ((XCrossingEvent
&) ev
) = *event
;
2081 cbs
.reason
= XmCR_INPUT
;
2084 wxCanvasInputEvent(drawingArea
, (XtPointer
) NULL
, &cbs
);
2087 // Fix to make it work under Motif 1.0 (!)
2088 static void wxCanvasMotionEvent (Widget
WXUNUSED(drawingArea
),
2089 XButtonEvent
*WXUNUSED(event
))
2091 #if XmVersion <= 1000
2092 XmDrawingAreaCallbackStruct cbs
;
2095 ev
= *((XEvent
*) event
);
2096 cbs
.reason
= XmCR_INPUT
;
2099 wxCanvasInputEvent (drawingArea
, (XtPointer
) NULL
, &cbs
);
2100 #endif // XmVersion <= 1000
2103 static void wxCanvasInputEvent(Widget drawingArea
,
2104 XtPointer
WXUNUSED(data
),
2105 XmDrawingAreaCallbackStruct
* cbs
)
2107 wxWindow
*canvas
= wxGetWindowFromTable(drawingArea
);
2113 if (cbs
->reason
!= XmCR_INPUT
)
2116 local_event
= *(cbs
->event
); // We must keep a copy!
2118 switch (local_event
.xany
.type
)
2126 // FIXME: most of this mouse event code is more or less
2127 // duplicated in wxTranslateMouseEvent
2129 wxEventType eventType
= wxEVT_NULL
;
2131 if (local_event
.xany
.type
== EnterNotify
)
2133 //if (local_event.xcrossing.mode!=NotifyNormal)
2134 // return ; // Ignore grab events
2135 eventType
= wxEVT_ENTER_WINDOW
;
2136 // canvas->GetEventHandler()->OnSetFocus();
2138 else if (local_event
.xany
.type
== LeaveNotify
)
2140 //if (local_event.xcrossingr.mode!=NotifyNormal)
2141 // return ; // Ignore grab events
2142 eventType
= wxEVT_LEAVE_WINDOW
;
2143 // canvas->GetEventHandler()->OnKillFocus();
2145 else if (local_event
.xany
.type
== MotionNotify
)
2147 eventType
= wxEVT_MOTION
;
2150 else if (local_event
.xany
.type
== ButtonPress
)
2152 if (local_event
.xbutton
.button
== Button1
)
2154 eventType
= wxEVT_LEFT_DOWN
;
2155 canvas
->SetButton1(TRUE
);
2157 else if (local_event
.xbutton
.button
== Button2
)
2159 eventType
= wxEVT_MIDDLE_DOWN
;
2160 canvas
->SetButton2(TRUE
);
2162 else if (local_event
.xbutton
.button
== Button3
)
2164 eventType
= wxEVT_RIGHT_DOWN
;
2165 canvas
->SetButton3(TRUE
);
2168 else if (local_event
.xany
.type
== ButtonRelease
)
2170 if (local_event
.xbutton
.button
== Button1
)
2172 eventType
= wxEVT_LEFT_UP
;
2173 canvas
->SetButton1(FALSE
);
2175 else if (local_event
.xbutton
.button
== Button2
)
2177 eventType
= wxEVT_MIDDLE_UP
;
2178 canvas
->SetButton2(FALSE
);
2180 else if (local_event
.xbutton
.button
== Button3
)
2182 eventType
= wxEVT_RIGHT_UP
;
2183 canvas
->SetButton3(FALSE
);
2187 wxMouseEvent
wxevent (eventType
);
2189 wxevent
.m_leftDown
= ((eventType
== wxEVT_LEFT_DOWN
)
2190 || (event_left_is_down (&local_event
)
2191 && (eventType
!= wxEVT_LEFT_UP
)));
2192 wxevent
.m_middleDown
= ((eventType
== wxEVT_MIDDLE_DOWN
)
2193 || (event_middle_is_down (&local_event
)
2194 && (eventType
!= wxEVT_MIDDLE_UP
)));
2195 wxevent
.m_rightDown
= ((eventType
== wxEVT_RIGHT_DOWN
)
2196 || (event_right_is_down (&local_event
)
2197 && (eventType
!= wxEVT_RIGHT_UP
)));
2199 wxevent
.m_shiftDown
= local_event
.xbutton
.state
& ShiftMask
;
2200 wxevent
.m_controlDown
= local_event
.xbutton
.state
& ControlMask
;
2201 wxevent
.m_altDown
= local_event
.xbutton
.state
& Mod3Mask
;
2202 wxevent
.m_metaDown
= local_event
.xbutton
.state
& Mod1Mask
;
2203 wxevent
.SetTimestamp(local_event
.xbutton
.time
);
2205 if ( eventType
== wxEVT_MOTION
)
2207 if (local_event
.xmotion
.is_hint
== NotifyHint
)
2210 Display
*dpy
= XtDisplay (drawingArea
);
2212 XQueryPointer (dpy
, XtWindow (drawingArea
),
2214 &local_event
.xmotion
.x_root
,
2215 &local_event
.xmotion
.y_root
,
2216 &local_event
.xmotion
.x
,
2217 &local_event
.xmotion
.y
,
2218 &local_event
.xmotion
.state
);
2225 // Now check if we need to translate this event into a double click
2226 if (TRUE
) // canvas->doubleClickAllowed)
2228 if (wxevent
.ButtonDown())
2230 long dclickTime
= XtGetMultiClickTime((Display
*) wxGetDisplay());
2232 // get button and time-stamp
2234 if (wxevent
.LeftDown())
2236 else if (wxevent
.MiddleDown())
2238 else if (wxevent
.RightDown())
2240 long ts
= wxevent
.GetTimestamp();
2242 // check, if single or double click
2243 int buttonLast
= canvas
->GetLastClickedButton();
2244 long lastTS
= canvas
->GetLastClickTime();
2245 if ( buttonLast
&& buttonLast
== button
&& (ts
- lastTS
) < dclickTime
)
2248 canvas
->SetLastClick(0, ts
);
2250 wxEventType typeDouble
;
2251 if ( eventType
== wxEVT_LEFT_DOWN
)
2252 typeDouble
= wxEVT_LEFT_DCLICK
;
2253 else if ( eventType
== wxEVT_MIDDLE_DOWN
)
2254 typeDouble
= wxEVT_MIDDLE_DCLICK
;
2255 else if ( eventType
== wxEVT_RIGHT_DOWN
)
2256 typeDouble
= wxEVT_RIGHT_DCLICK
;
2258 typeDouble
= wxEVT_NULL
;
2260 if ( typeDouble
!= wxEVT_NULL
)
2262 wxevent
.SetEventType(typeDouble
);
2267 // not fast enough or different button
2268 canvas
->SetLastClick(button
, ts
);
2273 wxevent
.SetId(canvas
->GetId());
2274 wxevent
.SetEventObject(canvas
);
2275 wxevent
.m_x
= local_event
.xbutton
.x
;
2276 wxevent
.m_y
= local_event
.xbutton
.y
;
2277 canvas
->GetEventHandler()->ProcessEvent (wxevent
);
2279 if (eventType
== wxEVT_ENTER_WINDOW
||
2280 eventType
== wxEVT_LEAVE_WINDOW
||
2281 eventType
== wxEVT_MOTION
2289 wxKeyEvent
event (wxEVT_CHAR
);
2290 if (wxTranslateKeyEvent (event
, canvas
, (Widget
) 0, &local_event
))
2292 // Implement wxFrame::OnCharHook by checking ancestor.
2293 wxWindow
*parent
= canvas
->GetParent();
2294 while (parent
&& !parent
->IsKindOf(CLASSINFO(wxFrame
)))
2295 parent
= parent
->GetParent();
2299 event
.SetEventType(wxEVT_CHAR_HOOK
);
2300 if (parent
->GetEventHandler()->ProcessEvent(event
))
2304 // For simplicity, OnKeyDown is the same as OnChar
2305 // TODO: filter modifier key presses from OnChar
2306 event
.SetEventType(wxEVT_KEY_DOWN
);
2308 // Only process OnChar if OnKeyDown didn't swallow it
2309 if (!canvas
->GetEventHandler()->ProcessEvent (event
))
2311 event
.SetEventType(wxEVT_CHAR
);
2312 canvas
->GetEventHandler()->ProcessEvent (event
);
2319 wxKeyEvent
event (wxEVT_KEY_UP
);
2320 if (wxTranslateKeyEvent (event
, canvas
, (Widget
) 0, &local_event
))
2322 canvas
->GetEventHandler()->ProcessEvent (event
);
2328 if (local_event
.xfocus
.detail
!= NotifyPointer
)
2330 wxFocusEvent
event(wxEVT_SET_FOCUS
, canvas
->GetId());
2331 event
.SetEventObject(canvas
);
2332 canvas
->GetEventHandler()->ProcessEvent(event
);
2338 if (local_event
.xfocus
.detail
!= NotifyPointer
)
2340 wxFocusEvent
event(wxEVT_KILL_FOCUS
, canvas
->GetId());
2341 event
.SetEventObject(canvas
);
2342 canvas
->GetEventHandler()->ProcessEvent(event
);
2351 static void wxPanelItemEventHandler(Widget wid
,
2352 XtPointer
WXUNUSED(client_data
),
2354 Boolean
*continueToDispatch
)
2356 // Widget can be a label or the actual widget.
2358 wxWindow
*window
= wxGetWindowFromTable(wid
);
2361 wxMouseEvent
wxevent(0);
2362 if (wxTranslateMouseEvent(wxevent
, window
, wid
, event
))
2364 window
->GetEventHandler()->ProcessEvent(wxevent
);
2368 // TODO: probably the key to allowing default behaviour to happen. Say we
2369 // set a m_doDefault flag to FALSE at the start of this function. Then in
2370 // e.g. wxWindow::OnMouseEvent we can call Default() which sets this flag to
2371 // TRUE, indicating that default processing can happen. Thus, behaviour can
2372 // appear to be overridden just by adding an event handler and not calling
2373 // wxWindow::OnWhatever. ALSO, maybe we can use this instead of the current
2374 // way of handling drawing area events, to simplify things.
2375 *continueToDispatch
= True
;
2378 static void wxScrollBarCallback(Widget scrollbar
,
2379 XtPointer clientData
,
2380 XmScrollBarCallbackStruct
*cbs
)
2382 wxWindow
*win
= wxGetWindowFromTable(scrollbar
);
2383 int orientation
= (int) clientData
;
2385 wxEventType eventType
= wxEVT_NULL
;
2386 switch (cbs
->reason
)
2388 case XmCR_INCREMENT
:
2390 eventType
= wxEVT_SCROLLWIN_LINEDOWN
;
2393 case XmCR_DECREMENT
:
2395 eventType
= wxEVT_SCROLLWIN_LINEUP
;
2400 eventType
= wxEVT_SCROLLWIN_THUMBTRACK
;
2403 case XmCR_VALUE_CHANGED
:
2405 eventType
= wxEVT_SCROLLWIN_THUMBRELEASE
;
2408 case XmCR_PAGE_INCREMENT
:
2410 eventType
= wxEVT_SCROLLWIN_PAGEDOWN
;
2413 case XmCR_PAGE_DECREMENT
:
2415 eventType
= wxEVT_SCROLLWIN_PAGEUP
;
2420 eventType
= wxEVT_SCROLLWIN_TOP
;
2423 case XmCR_TO_BOTTOM
:
2425 eventType
= wxEVT_SCROLLWIN_BOTTOM
;
2430 // Should never get here
2431 wxFAIL_MSG("Unknown scroll event.");
2436 wxScrollWinEvent
event(eventType
,
2438 ((orientation
== XmHORIZONTAL
) ?
2439 wxHORIZONTAL
: wxVERTICAL
));
2440 event
.SetEventObject( win
);
2441 win
->GetEventHandler()->ProcessEvent(event
);
2444 // For repainting arbitrary windows
2445 void wxUniversalRepaintProc(Widget w
, XtPointer
WXUNUSED(c_data
), XEvent
*event
, char *)
2450 wxWindow
* win
= wxGetWindowFromTable(w
);
2454 switch(event
-> type
)
2458 window
= (Window
) win
-> GetXWindow();
2459 display
= (Display
*) win
-> GetXDisplay();
2461 if (event
-> xexpose
.count
== 0)
2465 win
->ClearUpdateRects();
2469 win
->AddUpdateRect(event
->xexpose
.x
, event
->xexpose
.y
,
2470 event
->xexpose
.width
, event
->xexpose
.height
);
2478 // ----------------------------------------------------------------------------
2479 // TranslateXXXEvent() functions
2480 // ----------------------------------------------------------------------------
2482 bool wxTranslateMouseEvent(wxMouseEvent
& wxevent
, wxWindow
*win
, Widget widget
, XEvent
*xevent
)
2484 switch (xevent
->xany
.type
)
2486 case EnterNotify
: // never received here - yes ? MB
2487 case LeaveNotify
: // never received here - yes ? MB
2492 wxEventType eventType
= wxEVT_NULL
;
2494 // FIXME: this is never true I think - MB
2496 if (xevent
->xany
.type
== LeaveNotify
)
2498 win
->SetButton1(FALSE
);
2499 win
->SetButton2(FALSE
);
2500 win
->SetButton3(FALSE
);
2503 else if (xevent
->xany
.type
== MotionNotify
)
2505 eventType
= wxEVT_MOTION
;
2507 else if (xevent
->xany
.type
== ButtonPress
)
2509 wxevent
.SetTimestamp(xevent
->xbutton
.time
);
2511 if (xevent
->xbutton
.button
== Button1
)
2513 eventType
= wxEVT_LEFT_DOWN
;
2514 win
->SetButton1(TRUE
);
2517 else if (xevent
->xbutton
.button
== Button2
)
2519 eventType
= wxEVT_MIDDLE_DOWN
;
2520 win
->SetButton2(TRUE
);
2523 else if (xevent
->xbutton
.button
== Button3
)
2525 eventType
= wxEVT_RIGHT_DOWN
;
2526 win
->SetButton3(TRUE
);
2530 // check for a double click
2532 long dclickTime
= XtGetMultiClickTime((Display
*) wxGetDisplay());
2533 long ts
= wxevent
.GetTimestamp();
2535 int buttonLast
= win
->GetLastClickedButton();
2536 long lastTS
= win
->GetLastClickTime();
2537 if ( buttonLast
&& buttonLast
== button
&& (ts
- lastTS
) < dclickTime
)
2540 win
->SetLastClick(0, ts
);
2541 if ( eventType
== wxEVT_LEFT_DOWN
)
2542 eventType
= wxEVT_LEFT_DCLICK
;
2543 else if ( eventType
== wxEVT_MIDDLE_DOWN
)
2544 eventType
= wxEVT_MIDDLE_DCLICK
;
2545 else if ( eventType
== wxEVT_RIGHT_DOWN
)
2546 eventType
= wxEVT_RIGHT_DCLICK
;
2550 // not fast enough or different button
2551 win
->SetLastClick(button
, ts
);
2554 else if (xevent
->xany
.type
== ButtonRelease
)
2556 if (xevent
->xbutton
.button
== Button1
)
2558 eventType
= wxEVT_LEFT_UP
;
2559 win
->SetButton1(FALSE
);
2561 else if (xevent
->xbutton
.button
== Button2
)
2563 eventType
= wxEVT_MIDDLE_UP
;
2564 win
->SetButton2(FALSE
);
2566 else if (xevent
->xbutton
.button
== Button3
)
2568 eventType
= wxEVT_RIGHT_UP
;
2569 win
->SetButton3(FALSE
);
2578 wxevent
.SetEventType(eventType
);
2581 XtVaGetValues(widget
, XmNx
, &x1
, XmNy
, &y1
, NULL
);
2584 win
->GetPosition(&x2
, &y2
);
2586 // The button x/y must be translated to wxWindows
2587 // window space - the widget might be a label or button,
2591 if (widget
!= (Widget
)win
->GetMainWidget())
2597 wxevent
.m_x
= xevent
->xbutton
.x
+ dx
;
2598 wxevent
.m_y
= xevent
->xbutton
.y
+ dy
;
2600 wxevent
.m_leftDown
= ((eventType
== wxEVT_LEFT_DOWN
)
2601 || (event_left_is_down (xevent
)
2602 && (eventType
!= wxEVT_LEFT_UP
)));
2603 wxevent
.m_middleDown
= ((eventType
== wxEVT_MIDDLE_DOWN
)
2604 || (event_middle_is_down (xevent
)
2605 && (eventType
!= wxEVT_MIDDLE_UP
)));
2606 wxevent
.m_rightDown
= ((eventType
== wxEVT_RIGHT_DOWN
)
2607 || (event_right_is_down (xevent
)
2608 && (eventType
!= wxEVT_RIGHT_UP
)));
2610 wxevent
.m_shiftDown
= xevent
->xbutton
.state
& ShiftMask
;
2611 wxevent
.m_controlDown
= xevent
->xbutton
.state
& ControlMask
;
2612 wxevent
.m_altDown
= xevent
->xbutton
.state
& Mod3Mask
;
2613 wxevent
.m_metaDown
= xevent
->xbutton
.state
& Mod1Mask
;
2615 wxevent
.SetId(win
->GetId());
2616 wxevent
.SetEventObject(win
);
2624 bool wxTranslateKeyEvent(wxKeyEvent
& wxevent
, wxWindow
*win
,
2625 Widget
WXUNUSED(widget
), XEvent
*xevent
)
2627 switch (xevent
->xany
.type
)
2635 (void) XLookupString((XKeyEvent
*)xevent
, buf
, 20, &keySym
, NULL
);
2636 int id
= wxCharCodeXToWX (keySym
);
2637 // id may be WXK_xxx code - these are outside ASCII range, so we
2638 // can't just use toupper() on id
2639 if (id
>= 'a' && id
<= 'z')
2642 if (xevent
->xkey
.state
& ShiftMask
)
2643 wxevent
.m_shiftDown
= TRUE
;
2644 if (xevent
->xkey
.state
& ControlMask
)
2645 wxevent
.m_controlDown
= TRUE
;
2646 if (xevent
->xkey
.state
& Mod3Mask
)
2647 wxevent
.m_altDown
= TRUE
;
2648 if (xevent
->xkey
.state
& Mod1Mask
)
2649 wxevent
.m_metaDown
= TRUE
;
2650 wxevent
.SetEventObject(win
);
2651 wxevent
.m_keyCode
= id
;
2652 wxevent
.SetTimestamp(xevent
->xkey
.time
);
2654 wxevent
.m_x
= xevent
->xbutton
.x
;
2655 wxevent
.m_y
= xevent
->xbutton
.y
;
2669 // ----------------------------------------------------------------------------
2671 // ----------------------------------------------------------------------------
2673 #define YAllocColor XAllocColor
2674 XColor g_itemColors
[5];
2675 int wxComputeColours (Display
*display
, wxColour
* back
, wxColour
* fore
)
2678 static XmColorProc colorProc
;
2680 result
= wxNO_COLORS
;
2684 g_itemColors
[0].red
= (((long) back
->Red ()) << 8);
2685 g_itemColors
[0].green
= (((long) back
->Green ()) << 8);
2686 g_itemColors
[0].blue
= (((long) back
->Blue ()) << 8);
2687 g_itemColors
[0].flags
= DoRed
| DoGreen
| DoBlue
;
2688 if (colorProc
== (XmColorProc
) NULL
)
2690 // Get a ptr to the actual function
2691 colorProc
= XmSetColorCalculation ((XmColorProc
) NULL
);
2692 // And set it back to motif.
2693 XmSetColorCalculation (colorProc
);
2695 (*colorProc
) (&g_itemColors
[wxBACK_INDEX
],
2696 &g_itemColors
[wxFORE_INDEX
],
2697 &g_itemColors
[wxSELE_INDEX
],
2698 &g_itemColors
[wxTOPS_INDEX
],
2699 &g_itemColors
[wxBOTS_INDEX
]);
2700 result
= wxBACK_COLORS
;
2704 g_itemColors
[wxFORE_INDEX
].red
= (((long) fore
->Red ()) << 8);
2705 g_itemColors
[wxFORE_INDEX
].green
= (((long) fore
->Green ()) << 8);
2706 g_itemColors
[wxFORE_INDEX
].blue
= (((long) fore
->Blue ()) << 8);
2707 g_itemColors
[wxFORE_INDEX
].flags
= DoRed
| DoGreen
| DoBlue
;
2708 if (result
== wxNO_COLORS
)
2709 result
= wxFORE_COLORS
;
2712 Display
*dpy
= display
;
2713 Colormap cmap
= (Colormap
) wxTheApp
->GetMainColormap((WXDisplay
*) dpy
);
2717 /* 5 Colours to allocate */
2718 for (int i
= 0; i
< 5; i
++)
2719 if (!YAllocColor (dpy
, cmap
, &g_itemColors
[i
]))
2720 result
= wxNO_COLORS
;
2724 /* Only 1 colour to allocate */
2725 if (!YAllocColor (dpy
, cmap
, &g_itemColors
[wxFORE_INDEX
]))
2726 result
= wxNO_COLORS
;
2732 // Changes the foreground and background colours to be derived from the current
2733 // background colour. To change the foreground colour, you must call
2734 // SetForegroundColour explicitly.
2735 void wxWindow::ChangeBackgroundColour()
2737 WXWidget mainWidget
= GetMainWidget();
2739 DoChangeBackgroundColour(mainWidget
, m_backgroundColour
);
2742 void wxWindow::ChangeForegroundColour()
2744 WXWidget mainWidget
= GetMainWidget();
2746 DoChangeForegroundColour(mainWidget
, m_foregroundColour
);
2747 if ( m_scrolledWindow
&& mainWidget
!= m_scrolledWindow
)
2748 DoChangeForegroundColour(m_scrolledWindow
, m_foregroundColour
);
2751 // Change a widget's foreground and background colours.
2752 void wxWindow::DoChangeForegroundColour(WXWidget widget
,
2753 wxColour
& foregroundColour
)
2755 wxDoChangeForegroundColour( widget
, foregroundColour
);
2758 void wxWindow::DoChangeBackgroundColour(WXWidget widget
,
2759 wxColour
& backgroundColour
,
2760 bool changeArmColour
)
2762 wxDoChangeBackgroundColour( widget
, backgroundColour
, changeArmColour
);
2765 bool wxWindow::SetBackgroundColour(const wxColour
& col
)
2767 if ( !wxWindowBase::SetBackgroundColour(col
) )
2770 ChangeBackgroundColour();
2775 bool wxWindow::SetForegroundColour(const wxColour
& col
)
2777 if ( !wxWindowBase::SetForegroundColour(col
) )
2780 ChangeForegroundColour();
2785 void wxWindow::ChangeFont(bool keepOriginalSize
)
2787 // Note that this causes the widget to be resized back
2788 // to its original size! We therefore have to set the size
2789 // back again. TODO: a better way in Motif?
2790 Widget w
= (Widget
) GetLabelWidget(); // Usually the main widget
2791 if (w
&& m_font
.Ok())
2793 int width
, height
, width1
, height1
;
2794 GetSize(& width
, & height
);
2796 wxDoChangeFont( GetLabelWidget(), m_font
);
2798 GetSize(& width1
, & height1
);
2799 if (keepOriginalSize
&& (width
!= width1
|| height
!= height1
))
2801 SetSize(-1, -1, width
, height
);
2806 // ----------------------------------------------------------------------------
2808 // ----------------------------------------------------------------------------
2810 wxWindow
*wxGetActiveWindow()
2813 wxFAIL_MSG("Not implemented");
2818 wxWindow
*wxWindowBase::GetCapture()
2820 return (wxWindow
*)g_captureWindow
;
2824 // Find the wxWindow at the current mouse position, returning the mouse
2826 wxWindow
* wxFindWindowAtPointer(wxPoint
& pt
)
2828 return wxFindWindowAtPoint(wxGetMousePosition());
2831 // Get the current mouse position.
2832 wxPoint
wxGetMousePosition()
2834 Display
*display
= (Display
*) wxGetDisplay();
2835 Window rootWindow
= RootWindowOfScreen (DefaultScreenOfDisplay(display
));
2836 Window rootReturn
, childReturn
;
2837 int rootX
, rootY
, winX
, winY
;
2838 unsigned int maskReturn
;
2840 XQueryPointer (display
,
2844 &rootX
, &rootY
, &winX
, &winY
, &maskReturn
);
2845 return wxPoint(rootX
, rootY
);
2849 // ----------------------------------------------------------------------------
2850 // wxNoOptimize: switch off size optimization
2851 // ----------------------------------------------------------------------------
2853 int wxNoOptimize::ms_count
= 0;