1 /////////////////////////////////////////////////////////////////////////////
4 // Author: Julian Smart
8 // Copyright: (c) Julian Smart
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
12 // ============================================================================
14 // ============================================================================
16 // ----------------------------------------------------------------------------
18 // ----------------------------------------------------------------------------
21 #pragma implementation "window.h"
27 #include "wx/dcclient.h"
31 #include "wx/layout.h"
32 #include "wx/dialog.h"
33 #include "wx/listbox.h"
34 #include "wx/button.h"
35 #include "wx/settings.h"
36 #include "wx/msgdlg.h"
38 #include "wx/scrolwin.h"
39 #include "wx/module.h"
40 #include "wx/menuitem.h"
43 #include "wx/listimpl.cpp"
45 #if wxUSE_DRAG_AND_DROP
51 #include <Xm/DrawingA.h>
52 #include <Xm/ScrolledW.h>
53 #include <Xm/ScrollBar.h>
57 #include "wx/motif/private.h"
61 // ----------------------------------------------------------------------------
63 // ----------------------------------------------------------------------------
65 static const int SCROLL_MARGIN
= 4;
67 // ----------------------------------------------------------------------------
68 // global variables for this module
69 // ----------------------------------------------------------------------------
71 extern wxHashTable
*wxWidgetHashTable
;
73 // ----------------------------------------------------------------------------
75 // ----------------------------------------------------------------------------
77 static void wxCanvasRepaintProc(Widget
, XtPointer
, XmDrawingAreaCallbackStruct
* cbs
);
78 static void wxCanvasInputEvent(Widget drawingArea
, XtPointer data
, XmDrawingAreaCallbackStruct
* cbs
);
79 static void wxCanvasMotionEvent(Widget
, XButtonEvent
* event
);
80 static void wxCanvasEnterLeave(Widget drawingArea
, XtPointer clientData
, XCrossingEvent
* event
);
81 static void wxScrollBarCallback(Widget widget
, XtPointer clientData
,
82 XmScaleCallbackStruct
*cbs
);
83 static void wxPanelItemEventHandler(Widget wid
,
84 XtPointer client_data
,
86 Boolean
*continueToDispatch
);
91 // Helper function for 16-bit fonts
92 static int str16len(const char *s
)
96 while (s
[0] && s
[1]) {
106 // ----------------------------------------------------------------------------
108 // ----------------------------------------------------------------------------
110 #define event_left_is_down(x) ((x)->xbutton.state & Button1Mask)
111 #define event_middle_is_down(x) ((x)->xbutton.state & Button2Mask)
112 #define event_right_is_down(x) ((x)->xbutton.state & Button3Mask)
114 // ----------------------------------------------------------------------------
116 // ----------------------------------------------------------------------------
118 #if !USE_SHARED_LIBRARY
119 IMPLEMENT_DYNAMIC_CLASS(wxWindow
, wxEvtHandler
)
121 BEGIN_EVENT_TABLE(wxWindow
, wxEvtHandler
)
122 EVT_SYS_COLOUR_CHANGED(wxWindow::OnSysColourChanged
)
123 EVT_IDLE(wxWindow::OnIdle
)
125 #endif // USE_SHARED_LIBRARY
127 // ============================================================================
129 // ============================================================================
131 // ----------------------------------------------------------------------------
133 // ----------------------------------------------------------------------------
135 WX_DEFINE_LIST(wxRectList
);
137 // ----------------------------------------------------------------------------
139 // ----------------------------------------------------------------------------
141 void wxWindow::UnmanageAndDestroy(WXWidget widget
)
143 Widget w
= (Widget
)widget
;
151 bool wxWindow::MapOrUnmap(WXWidget widget
, bool map
)
153 Widget w
= (Widget
)widget
;
165 // ----------------------------------------------------------------------------
167 // ----------------------------------------------------------------------------
169 void wxWindow::Init()
171 // generic initializations first
175 m_needsRefresh
= TRUE
;
176 m_mainWidget
= (WXWidget
) 0;
180 m_button3Pressed
= FALSE
;
182 m_winCaptured
= FALSE
;
190 m_drawingArea
= (WXWidget
) 0;
198 m_backingPixmap
= (WXPixmap
) 0;
207 m_canAddEventHandler
= FALSE
;
210 // real construction (Init() must have been called before!)
211 bool wxWindow::Create(wxWindow
*parent
, wxWindowID id
,
215 const wxString
& name
)
217 wxCHECK_MSG( parent
, FALSE
, "can't create wxWindow without parent" );
219 CreateBase(parent
, id
, pos
, size
, style
, name
);
221 parent
->AddChild(this);
223 m_backgroundColour
= wxSystemSettings::GetSystemColour(wxSYS_COLOUR_3DFACE
);
224 m_foregroundColour
= *wxBLACK
;
226 //// TODO: we should probably optimize by only creating a
227 //// a drawing area if we have one or more scrollbars (wxVSCROLL/wxHSCROLL).
228 //// But for now, let's simplify things by always creating the
229 //// drawing area, since otherwise the translations are different.
231 // New translations for getting mouse motion feedback
232 static const String translations
=
233 "<Btn1Motion>: wxCanvasMotionEvent() DrawingAreaInput() ManagerGadgetButtonMotion()\n\
234 <Btn2Motion>: wxCanvasMotionEvent() DrawingAreaInput() ManagerGadgetButtonMotion()\n\
235 <Btn3Motion>: wxCanvasMotionEvent() DrawingAreaInput() ManagerGadgetButtonMotion()\n\
236 <BtnMotion>: wxCanvasMotionEvent() DrawingAreaInput() ManagerGadgetButtonMotion()\n\
237 <Btn1Down>: DrawingAreaInput() ManagerGadgetArm()\n\
238 <Btn2Down>: DrawingAreaInput() ManagerGadgetArm()\n\
239 <Btn3Down>: DrawingAreaInput() ManagerGadgetArm()\n\
240 <Btn1Up>: DrawingAreaInput() ManagerGadgetActivate()\n\
241 <Btn2Up>: DrawingAreaInput() ManagerGadgetActivate()\n\
242 <Btn3Up>: DrawingAreaInput() ManagerGadgetActivate()\n\
243 <Motion>: wxCanvasMotionEvent() DrawingAreaInput()\n\
244 <EnterWindow>: wxCanvasMotionEvent() DrawingAreaInput()\n\
245 <LeaveWindow>: wxCanvasMotionEvent() DrawingAreaInput()\n\
246 <Key>: DrawingAreaInput()";
248 XtActionsRec actions
[1];
249 actions
[0].string
= "wxCanvasMotionEvent";
250 actions
[0].proc
= (XtActionProc
) wxCanvasMotionEvent
;
251 XtAppAddActions ((XtAppContext
) wxTheApp
->GetAppContext(), actions
, 1);
253 Widget parentWidget
= (Widget
) parent
->GetClientWidget();
254 if (style
& wxBORDER
)
256 m_borderWidget
= (WXWidget
)XtVaCreateManagedWidget
259 xmFrameWidgetClass
, parentWidget
,
260 XmNshadowType
, XmSHADOW_IN
,
265 m_scrolledWindow
= (WXWidget
)XtVaCreateManagedWidget
268 xmScrolledWindowWidgetClass
,
269 m_borderWidget
? (Widget
) m_borderWidget
271 XmNresizePolicy
, XmRESIZE_NONE
,
273 XmNscrollingPolicy
, XmAPPLICATION_DEFINED
,
274 //XmNscrollBarDisplayPolicy, XmAS_NEEDED,
278 XtTranslations ptr
= XtParseTranslationTable(translations
);
279 m_drawingArea
= (WXWidget
)XtVaCreateWidget
282 xmDrawingAreaWidgetClass
, (Widget
) m_scrolledWindow
,
283 XmNunitType
, XmPIXELS
,
284 // XmNresizePolicy, XmRESIZE_ANY,
285 XmNresizePolicy
, XmRESIZE_NONE
,
288 XmNtranslations
, ptr
,
291 XtFree((char *) ptr
);
294 if (GetWindowStyleFlag() & wxOVERRIDE_KEY_TRANSLATIONS
)
296 ptr
= XtParseTranslationTable ("<Key>: DrawingAreaInput()");
297 XtOverrideTranslations ((Widget
) m_drawingArea
, ptr
);
298 XtFree ((char *) ptr
);
302 wxAddWindowToTable((Widget
) m_drawingArea
, this);
303 wxAddWindowToTable((Widget
) m_scrolledWindow
, this);
305 // This order is very important in Motif 1.2.1
306 XtRealizeWidget ((Widget
) m_scrolledWindow
);
307 XtRealizeWidget ((Widget
) m_drawingArea
);
308 XtManageChild ((Widget
) m_drawingArea
);
310 ptr
= XtParseTranslationTable("<Configure>: resize()");
311 XtOverrideTranslations((Widget
) m_drawingArea
, ptr
);
312 XtFree ((char *) ptr
);
314 XtAddCallback ((Widget
) m_drawingArea
, XmNexposeCallback
, (XtCallbackProc
) wxCanvasRepaintProc
, (XtPointer
) this);
315 XtAddCallback ((Widget
) m_drawingArea
, XmNinputCallback
, (XtCallbackProc
) wxCanvasInputEvent
, (XtPointer
) this);
319 display
= XtDisplay (scrolledWindow
);
320 xwindow
= XtWindow (drawingArea
);
324 (Widget
)m_drawingArea
,
325 PointerMotionHintMask
| EnterWindowMask
|
326 LeaveWindowMask
| FocusChangeMask
,
328 (XtEventHandler
) wxCanvasEnterLeave
,
332 // Scrolled widget needs to have its colour changed or we get a little blue
333 // square where the scrollbars abutt
334 wxColour backgroundColour
= wxSystemSettings::GetSystemColour(wxSYS_COLOUR_3DFACE
);
335 DoChangeBackgroundColour(m_scrolledWindow
, backgroundColour
, TRUE
);
336 DoChangeBackgroundColour(m_drawingArea
, backgroundColour
, TRUE
);
338 XmScrolledWindowSetAreas(
339 (Widget
)m_scrolledWindow
,
340 (Widget
) 0, (Widget
) 0,
341 (Widget
) m_drawingArea
);
345 XtRealizeWidget ((Widget
) m_hScrollBar
);
347 XtRealizeWidget ((Widget
) m_vScrollBar
);
350 // Without this, the cursor may not be restored properly (e.g. in splitter
352 SetCursor(*wxSTANDARD_CURSOR
);
353 SetFont(wxSystemSettings::GetSystemFont(wxSYS_DEFAULT_GUI_FONT
));
354 SetSize(pos
.x
, pos
.y
, size
.x
, size
.y
);
360 wxWindow::~wxWindow()
362 // Motif-specific actions first
363 WXWidget wMain
= GetMainWidget();
366 // Removes event handlers
372 // If m_drawingArea, we're a fully-fledged window with drawing area,
373 // scrollbars etc. (what wxCanvas used to be)
376 // Destroy children before destroying self
380 XFreePixmap (XtDisplay ((Widget
) GetMainWidget()), (Pixmap
) m_backingPixmap
);
382 Widget w
= (Widget
) m_drawingArea
;
383 wxDeleteWindowFromTable(w
);
390 m_mainWidget
= (WXWidget
) 0;
392 // Only if we're _really_ a canvas (not a dialog box/panel)
393 if (m_scrolledWindow
)
395 wxDeleteWindowFromTable((Widget
) m_scrolledWindow
);
398 UnmanageAndDestroy(m_hScrollBar
);
399 UnmanageAndDestroy(m_vScrollBar
);
400 UnmanageAndDestroy(m_scrolledWindow
);
404 XtDestroyWidget ((Widget
) m_borderWidget
);
405 m_borderWidget
= (WXWidget
) 0;
409 // Destroy the window
412 // If this line (XtDestroyWidget) causes a crash, you may comment it out.
413 // Child widgets will get destroyed automatically when a frame
414 // or dialog is destroyed, but before that you may get some memory
415 // leaks and potential layout problems if you delete and then add
417 XtDestroyWidget((Widget
) GetMainWidget());
418 SetMainWidget((WXWidget
) NULL
);
422 // ----------------------------------------------------------------------------
423 // scrollbar management
424 // ----------------------------------------------------------------------------
427 void wxWindow::CreateScrollbar(wxOrientation orientation
)
429 wxCHECK_RET( m_drawingArea
, "this window can't have scrollbars" );
431 XtVaSetValues((Widget
) m_scrolledWindow
, XmNresizePolicy
, XmRESIZE_NONE
, NULL
);
433 // Add scrollbars if required
434 if (orientation
== wxHORIZONTAL
)
436 Widget hScrollBar
= XtVaCreateManagedWidget ("hsb",
437 xmScrollBarWidgetClass
, (Widget
) m_scrolledWindow
,
438 XmNorientation
, XmHORIZONTAL
,
440 // XtAddCallback (hScrollBar, XmNvalueChangedCallback, (XtCallbackProc) wxScrollBarCallback, (XtPointer) XmHORIZONTAL);
441 XtAddCallback (hScrollBar
, XmNdragCallback
, (XtCallbackProc
) wxScrollBarCallback
, (XtPointer
) XmHORIZONTAL
);
442 XtAddCallback (hScrollBar
, XmNincrementCallback
, (XtCallbackProc
) wxScrollBarCallback
, (XtPointer
) XmHORIZONTAL
);
443 XtAddCallback (hScrollBar
, XmNdecrementCallback
, (XtCallbackProc
) wxScrollBarCallback
, (XtPointer
) XmHORIZONTAL
);
444 XtAddCallback (hScrollBar
, XmNpageIncrementCallback
, (XtCallbackProc
) wxScrollBarCallback
, (XtPointer
) XmHORIZONTAL
);
445 XtAddCallback (hScrollBar
, XmNpageDecrementCallback
, (XtCallbackProc
) wxScrollBarCallback
, (XtPointer
) XmHORIZONTAL
);
446 XtAddCallback (hScrollBar
, XmNtoTopCallback
, (XtCallbackProc
) wxScrollBarCallback
, (XtPointer
) XmHORIZONTAL
);
447 XtAddCallback (hScrollBar
, XmNtoBottomCallback
, (XtCallbackProc
) wxScrollBarCallback
, (XtPointer
) XmHORIZONTAL
);
449 XtVaSetValues (hScrollBar
,
454 m_hScrollBar
= (WXWidget
) hScrollBar
;
456 wxColour backgroundColour
= wxSystemSettings::GetSystemColour(wxSYS_COLOUR_3DFACE
);
457 DoChangeBackgroundColour(m_hScrollBar
, backgroundColour
, TRUE
);
459 XtRealizeWidget(hScrollBar
);
461 XtVaSetValues((Widget
) m_scrolledWindow
,
462 XmNhorizontalScrollBar
, (Widget
) m_hScrollBar
,
468 if (orientation
== wxVERTICAL
)
470 Widget vScrollBar
= XtVaCreateManagedWidget ("vsb",
471 xmScrollBarWidgetClass
, (Widget
) m_scrolledWindow
,
472 XmNorientation
, XmVERTICAL
,
474 // XtAddCallback (vScrollBar, XmNvalueChangedCallback, (XtCallbackProc) wxScrollBarCallback, (XtPointer) XmVERTICAL);
475 XtAddCallback (vScrollBar
, XmNdragCallback
, (XtCallbackProc
) wxScrollBarCallback
, (XtPointer
) XmVERTICAL
);
476 XtAddCallback (vScrollBar
, XmNincrementCallback
, (XtCallbackProc
) wxScrollBarCallback
, (XtPointer
) XmVERTICAL
);
477 XtAddCallback (vScrollBar
, XmNdecrementCallback
, (XtCallbackProc
) wxScrollBarCallback
, (XtPointer
) XmVERTICAL
);
478 XtAddCallback (vScrollBar
, XmNpageIncrementCallback
, (XtCallbackProc
) wxScrollBarCallback
, (XtPointer
) XmVERTICAL
);
479 XtAddCallback (vScrollBar
, XmNpageDecrementCallback
, (XtCallbackProc
) wxScrollBarCallback
, (XtPointer
) XmVERTICAL
);
480 XtAddCallback (vScrollBar
, XmNtoTopCallback
, (XtCallbackProc
) wxScrollBarCallback
, (XtPointer
) XmVERTICAL
);
481 XtAddCallback (vScrollBar
, XmNtoBottomCallback
, (XtCallbackProc
) wxScrollBarCallback
, (XtPointer
) XmVERTICAL
);
483 XtVaSetValues (vScrollBar
,
488 m_vScrollBar
= (WXWidget
) vScrollBar
;
489 wxColour backgroundColour
= wxSystemSettings::GetSystemColour(wxSYS_COLOUR_3DFACE
);
490 DoChangeBackgroundColour(m_vScrollBar
, backgroundColour
, TRUE
);
492 XtRealizeWidget(vScrollBar
);
494 XtVaSetValues((Widget
) m_scrolledWindow
,
495 XmNverticalScrollBar
, (Widget
) m_vScrollBar
,
501 XtVaSetValues((Widget
) m_scrolledWindow
, XmNresizePolicy
, XmRESIZE_ANY
, NULL
);
504 void wxWindow::DestroyScrollbar(wxOrientation orientation
)
506 wxCHECK_RET( m_drawingArea
, "this window can't have scrollbars" );
508 XtVaSetValues((Widget
) m_scrolledWindow
, XmNresizePolicy
, XmRESIZE_NONE
, NULL
);
509 // Add scrollbars if required
510 if (orientation
== wxHORIZONTAL
)
514 XtDestroyWidget((Widget
) m_hScrollBar
);
516 m_hScrollBar
= (WXWidget
) 0;
519 XtVaSetValues((Widget
) m_scrolledWindow
,
520 XmNhorizontalScrollBar
, (Widget
) 0,
525 if (orientation
== wxVERTICAL
)
529 XtDestroyWidget((Widget
) m_vScrollBar
);
531 m_vScrollBar
= (WXWidget
) 0;
534 XtVaSetValues((Widget
) m_scrolledWindow
,
535 XmNverticalScrollBar
, (Widget
) 0,
539 XtVaSetValues((Widget
) m_scrolledWindow
, XmNresizePolicy
, XmRESIZE_ANY
, NULL
);
542 // ---------------------------------------------------------------------------
544 // ---------------------------------------------------------------------------
546 void wxWindow::SetFocus()
548 Widget wMain
= (Widget
) GetMainWidget();
549 XmProcessTraversal(wMain
, XmTRAVERSE_CURRENT
);
550 XmProcessTraversal((Widget
) GetMainWidget(), XmTRAVERSE_CURRENT
);
553 // Get the window with the focus
554 wxWindow
*wxWindowBase::FindFocus()
557 // (1) Can there be multiple focussed widgets in an application?
558 // In which case we need to find the top-level window that's
560 // (2) The widget with the focus may not be in the widget table
561 // depending on which widgets I put in the table
562 wxWindow
*winFocus
= (wxWindow
*)NULL
;
563 for ( wxWindowList::Node
*node
= wxTopLevelWindows
.GetFirst();
565 node
= node
->GetNext() )
567 wxWindow
*win
= node
->GetData();
569 Widget w
= XmGetFocusWidget ((Widget
) win
->GetTopWidget());
571 if (w
!= (Widget
) NULL
)
573 winFocus
= wxGetWindowFromTable(w
);
582 bool wxWindow::Enable(bool enable
)
584 if ( !wxWindowBase::Enable(enable
) )
587 Widget wMain
= (Widget
)GetMainWidget();
590 XtSetSensitive(wMain
, enable
);
591 XmUpdateDisplay(wMain
);
597 bool wxWindow::Show(bool show
)
599 if ( !wxWindowBase::Show(show
) )
602 if (m_borderWidget
|| m_scrolledWindow
)
604 MapOrUnmap(m_drawingArea
, show
);
605 MapOrUnmap(m_borderWidget
? m_borderWidget
: m_scrolledWindow
, show
);
609 if ( !MapOrUnmap(GetTopWidget(), show
) )
610 MapOrUnmap(GetMainWidget(), show
);
614 Window xwin
= (Window
) GetXWindow();
615 Display
*xdisp
= (Display
*) GetXDisplay();
617 XMapWindow(xdisp
, xwin
);
619 XUnmapWindow(xdisp
, xwin
);
625 // Raise the window to the top of the Z order
626 void wxWindow::Raise()
628 Widget wTop
= (Widget
) GetTopWidget();
629 Window window
= XtWindow(wTop
);
630 XRaiseWindow(XtDisplay(wTop
), window
);
633 // Lower the window to the bottom of the Z order
634 void wxWindow::Lower()
636 Widget wTop
= (Widget
) GetTopWidget();
637 Window window
= XtWindow(wTop
);
638 XLowerWindow(XtDisplay(wTop
), window
);
641 void wxWindow::SetTitle(const wxString
& title
)
643 XtVaSetValues((Widget
)GetMainWidget(), XmNtitle
, title
.c_str(), NULL
);
646 wxString
wxWindow::GetTitle() const
649 XtVaGetValues((Widget
)GetMainWidget(), XmNtitle
, &title
, NULL
);
651 return wxString(title
);
654 void wxWindow::CaptureMouse()
659 Widget wMain
= (Widget
)GetMainWidget();
661 XtAddGrab(wMain
, TRUE
, FALSE
);
663 m_winCaptured
= TRUE
;
666 void wxWindow::ReleaseMouse()
668 if ( !m_winCaptured
)
671 Widget wMain
= (Widget
)GetMainWidget();
675 m_winCaptured
= FALSE
;
678 bool wxWindow::SetFont(const wxFont
& font
)
680 if ( !wxWindowBase::SetFont(font
) )
691 bool wxWindow::SetCursor(const wxCursor
& cursor
)
693 if ( !wxWindowBase::SetCursor(cursor
) )
699 wxASSERT_MSG( m_cursor
.Ok(),
700 _T("cursor must be valid after call to the base version"));
702 WXDisplay
*dpy
= GetXDisplay();
703 WXCursor x_cursor
= m_cursor
.GetXCursor(dpy
);
705 Widget w
= (Widget
) GetMainWidget();
706 Window win
= XtWindow(w
);
707 XDefineCursor((Display
*) dpy
, win
, (Cursor
) x_cursor
);
712 // Coordinates relative to the window
713 void wxWindow::WarpPointer (int x
, int y
)
715 Widget wClient
= (Widget
)GetClientWidget();
717 XWarpPointer(XtDisplay(wClient
), None
, XtWindow(wClient
), 0, 0, 0, 0, x
, y
);
720 // ---------------------------------------------------------------------------
722 // ---------------------------------------------------------------------------
724 int wxWindow::GetScrollPos(int orient
) const
726 if (orient
== wxHORIZONTAL
)
732 Widget scrollBar
= (Widget
) ((orient
== wxHORIZONTAL
) ? m_hScrollBar
: m_vScrollBar
);
736 XtVaGetValues(scrollBar
, XmNvalue
, &pos
, NULL
);
744 // This now returns the whole range, not just the number of positions that we
746 int wxWindow::GetScrollRange(int orient
) const
748 Widget scrollBar
= (Widget
)GetScrollbar((wxOrientation
)orient
);
749 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" );
762 XtVaGetValues(scrollBar
, XmNsliderSize
, &thumb
, NULL
);
766 void wxWindow::SetScrollPos(int orient
, int pos
, bool WXUNUSED(refresh
))
768 Widget scrollBar
= (Widget
)GetScrollbar((wxOrientation
)orient
);
772 XtVaSetValues (scrollBar
, XmNvalue
, pos
, NULL
);
775 SetInternalScrollPos((wxOrientation
)orient
, pos
);
778 // New function that will replace some of the above.
779 void wxWindow::SetScrollbar(int orient
, int pos
, int thumbVisible
,
780 int range
, bool WXUNUSED(refresh
))
783 GetSize(& oldW
, & oldH
);
787 if (thumbVisible
== 0)
790 if (thumbVisible
> range
)
791 thumbVisible
= range
;
793 // Save the old state to see if it changed
794 WXWidget oldScrollBar
= GetScrollbar((wxOrientation
)orient
);
796 if (orient
== wxHORIZONTAL
)
798 if (thumbVisible
== range
)
801 DestroyScrollbar(wxHORIZONTAL
);
806 CreateScrollbar(wxHORIZONTAL
);
809 if (orient
== wxVERTICAL
)
811 if (thumbVisible
== range
)
814 DestroyScrollbar(wxVERTICAL
);
819 CreateScrollbar(wxVERTICAL
);
822 WXWidget newScrollBar
= GetScrollbar((wxOrientation
)orient
);
824 if (oldScrollBar
!= newScrollBar
)
826 // This is important! Without it, scrollbars misbehave badly.
827 XtUnrealizeWidget((Widget
) m_scrolledWindow
);
828 XmScrolledWindowSetAreas ((Widget
) m_scrolledWindow
, (Widget
) m_hScrollBar
, (Widget
) m_vScrollBar
, (Widget
) m_drawingArea
);
829 XtRealizeWidget((Widget
) m_scrolledWindow
);
830 XtManageChild((Widget
) m_scrolledWindow
);
835 XtVaSetValues((Widget
) newScrollBar
,
839 XmNsliderSize
, thumbVisible
,
843 SetInternalScrollPos((wxOrientation
)orient
, pos
);
846 GetSize(& newW
, & newH
);
848 // Adjusting scrollbars can resize the canvas accidentally
849 if (newW
!= oldW
|| newH
!= oldH
)
850 SetSize(-1, -1, oldW
, oldH
);
853 // Does a physical scroll
854 void wxWindow::ScrollWindow(int dx
, int dy
, const wxRect
*rect
)
859 // Use specified rectangle
860 x
= rect
->x
; y
= rect
->y
; w
= rect
->width
; h
= rect
->height
;
864 // Use whole client area
866 GetClientSize(& w
, & h
);
869 int x1
= (dx
>= 0) ? x
: x
- dx
;
870 int y1
= (dy
>= 0) ? y
: y
- dy
;
871 int w1
= w
- abs(dx
);
872 int h1
= h
- abs(dy
);
873 int x2
= (dx
>= 0) ? x
+ dx
: x
;
874 int y2
= (dy
>= 0) ? y
+ dy
: y
;
878 dc
.SetLogicalFunction (wxCOPY
);
880 Widget widget
= (Widget
) GetMainWidget();
881 Window window
= XtWindow(widget
);
882 Display
* display
= XtDisplay(widget
);
884 XCopyArea(display
, window
, window
, (GC
) dc
.GetGC(),
885 x1
, y1
, w1
, h1
, x2
, y2
);
887 dc
.SetAutoSetting(TRUE
);
888 wxBrush
brush(GetBackgroundColour(), wxSOLID
);
889 dc
.SetBrush(brush
); // FIXME: needed?
891 // We'll add rectangles to the list of update rectangles according to which
892 // bits we've exposed.
897 wxRect
*rect
= new wxRect
;
903 XFillRectangle(display
, window
,
904 (GC
) dc
.GetGC(), rect
->x
, rect
->y
, rect
->width
, rect
->height
);
908 rect
->width
= rect
->width
;
909 rect
->height
= rect
->height
;
911 updateRects
.Append((wxObject
*) rect
);
915 wxRect
*rect
= new wxRect
;
917 rect
->x
= x
+ w
+ dx
;
922 XFillRectangle(display
, window
,
923 (GC
) dc
.GetGC(), rect
->x
, rect
->y
, rect
->width
,
928 rect
->width
= rect
->width
;
929 rect
->height
= rect
->height
;
931 updateRects
.Append((wxObject
*) rect
);
935 wxRect
*rect
= new wxRect
;
942 XFillRectangle(display
, window
,
943 (GC
) dc
.GetGC(), rect
->x
, rect
->y
, rect
->width
, rect
->height
);
947 rect
->width
= rect
->width
;
948 rect
->height
= rect
->height
;
950 updateRects
.Append((wxObject
*) rect
);
954 wxRect
*rect
= new wxRect
;
957 rect
->y
= y
+ h
+ dy
;
961 XFillRectangle(display
, window
,
962 (GC
) dc
.GetGC(), rect
->x
, rect
->y
, rect
->width
, rect
->height
);
966 rect
->width
= rect
->width
;
967 rect
->height
= rect
->height
;
969 updateRects
.Append((wxObject
*) rect
);
971 dc
.SetBrush(wxNullBrush
);
973 // Now send expose events
975 wxNode
* node
= updateRects
.First();
978 wxRect
* rect
= (wxRect
*) node
->Data();
982 event
.display
= display
;
983 event
.send_event
= True
;
984 event
.window
= window
;
988 event
.width
= rect
->width
;
989 event
.height
= rect
->height
;
993 XSendEvent(display
, window
, False
, ExposureMask
, (XEvent
*)&event
);
999 // Delete the update rects
1000 node
= updateRects
.First();
1003 wxRect
* rect
= (wxRect
*) node
->Data();
1005 node
= node
->Next();
1008 XmUpdateDisplay((Widget
) GetMainWidget());
1011 // ---------------------------------------------------------------------------
1013 // ---------------------------------------------------------------------------
1015 #if wxUSE_DRAG_AND_DROP
1017 void wxWindow::SetDropTarget(wxDropTarget
* WXUNUSED(pDropTarget
))
1024 // Old style file-manager drag&drop
1025 void wxWindow::DragAcceptFiles(bool WXUNUSED(accept
))
1030 // ----------------------------------------------------------------------------
1032 // ----------------------------------------------------------------------------
1036 void wxWindow::DoSetToolTip(wxToolTip
* WXUNUSED(tooltip
))
1041 #endif // wxUSE_TOOLTIPS
1043 // ---------------------------------------------------------------------------
1044 // moving and resizing
1045 // ---------------------------------------------------------------------------
1047 bool wxWindow::PreResize()
1053 void wxWindow::DoGetSize(int *x
, int *y
) const
1057 CanvasGetSize(x
, y
);
1061 Widget widget
= (Widget
) GetTopWidget();
1063 XtVaGetValues(widget
, XmNwidth
, &xx
, XmNheight
, &yy
, NULL
);
1067 void wxWindow::DoGetPosition(int *x
, int *y
) const
1071 CanvasGetPosition(x
, y
);
1074 Widget widget
= (Widget
) GetTopWidget();
1076 XtVaGetValues(widget
, XmNx
, &xx
, XmNy
, &yy
, NULL
);
1078 // We may be faking the client origin. So a window that's really at (0, 30)
1079 // may appear (to wxWin apps) to be at (0, 0).
1082 wxPoint
pt(GetParent()->GetClientAreaOrigin());
1090 void wxWindow::DoScreenToClient(int *x
, int *y
) const
1092 Widget widget
= (Widget
) GetClientWidget();
1093 Display
*display
= XtDisplay((Widget
) GetMainWidget());
1094 Window rootWindow
= RootWindowOfScreen(XtScreen(widget
));
1095 Window thisWindow
= XtWindow(widget
);
1100 XTranslateCoordinates(display
, rootWindow
, thisWindow
, xx
, yy
, x
, y
, &childWindow
);
1103 void wxWindow::DoClientToScreen(int *x
, int *y
) const
1105 Widget widget
= (Widget
) GetClientWidget();
1106 Display
*display
= XtDisplay(widget
);
1107 Window rootWindow
= RootWindowOfScreen(XtScreen(widget
));
1108 Window thisWindow
= XtWindow(widget
);
1113 XTranslateCoordinates(display
, thisWindow
, rootWindow
, xx
, yy
, x
, y
, &childWindow
);
1117 // Get size *available for subwindows* i.e. excluding menu bar etc.
1118 void wxWindow::DoGetClientSize(int *x
, int *y
) const
1120 Widget widget
= (Widget
) GetClientWidget();
1122 XtVaGetValues(widget
, XmNwidth
, &xx
, XmNheight
, &yy
, NULL
);
1126 void wxWindow::DoSetSize(int x
, int y
, int width
, int height
, int sizeFlags
)
1128 // A bit of optimization to help sort out the flickers.
1129 int oldX
, oldY
, oldW
, oldH
;
1130 GetSize(& oldW
, & oldH
);
1131 GetPosition(& oldX
, & oldY
);
1133 bool useOldPos
= FALSE
;
1134 bool useOldSize
= FALSE
;
1136 if ((x
== -1) && (x
== -1) && ((sizeFlags
& wxSIZE_ALLOW_MINUS_ONE
) == 0))
1138 else if (x
== oldX
&& y
== oldY
)
1141 if ((width
== -1) && (height
== -1))
1143 else if (width
== oldW
&& height
== oldH
)
1146 if (!wxNoOptimize::CanOptimize())
1148 useOldSize
= FALSE
; useOldPos
= FALSE
;
1151 if (useOldPos
&& useOldSize
)
1156 CanvasSetSize(x
, y
, width
, height
, sizeFlags
);
1159 Widget widget
= (Widget
) GetTopWidget();
1163 bool managed
= XtIsManaged( widget
);
1165 XtUnmanageChild(widget
);
1167 int xx
= x
; int yy
= y
;
1168 AdjustForParentClientOrigin(xx
, yy
, sizeFlags
);
1172 if (x
> -1 || (sizeFlags
& wxSIZE_ALLOW_MINUS_ONE
))
1173 XtVaSetValues(widget
, XmNx
, xx
, NULL
);
1174 if (y
> -1 || (sizeFlags
& wxSIZE_ALLOW_MINUS_ONE
))
1175 XtVaSetValues(widget
, XmNy
, yy
, NULL
);
1180 XtVaSetValues(widget
, XmNwidth
, width
, NULL
);
1182 XtVaSetValues(widget
, XmNheight
, height
, NULL
);
1186 XtManageChild(widget
);
1188 // How about this bit. Maybe we don't need to generate size events
1189 // all the time -- they'll be generated when the window is sized anyway.
1191 wxSizeEvent
sizeEvent(wxSize(width
, height
), GetId());
1192 sizeEvent
.SetEventObject(this);
1194 GetEventHandler()->ProcessEvent(sizeEvent
);
1198 void wxWindow::DoSetClientSize(int width
, int height
)
1202 CanvasSetClientSize(width
, height
);
1206 Widget widget
= (Widget
) GetTopWidget();
1209 XtVaSetValues(widget
, XmNwidth
, width
, NULL
);
1211 XtVaSetValues(widget
, XmNheight
, height
, NULL
);
1213 wxSizeEvent
sizeEvent(wxSize(width
, height
), GetId());
1214 sizeEvent
.SetEventObject(this);
1216 GetEventHandler()->ProcessEvent(sizeEvent
);
1219 // For implementation purposes - sometimes decorations make the client area
1221 wxPoint
wxWindow::GetClientAreaOrigin() const
1223 return wxPoint(0, 0);
1226 // Makes an adjustment to the window position (for example, a frame that has
1227 // a toolbar that it manages itself).
1228 void wxWindow::AdjustForParentClientOrigin(int& x
, int& y
, int sizeFlags
)
1230 if (((sizeFlags
& wxSIZE_NO_ADJUSTMENTS
) == 0) && GetParent())
1232 wxPoint
pt(GetParent()->GetClientAreaOrigin());
1233 x
+= pt
.x
; y
+= pt
.y
;
1237 void wxWindow::SetSizeHints(int minW
, int minH
, int maxW
, int maxH
, int incW
, int incH
)
1244 wxFrame
*frame
= wxDynamicCast(this, wxFrame
);
1247 // TODO what about dialogs?
1251 Widget widget
= (Widget
) frame
->GetShellWidget();
1254 XtVaSetValues(widget
, XmNminWidth
, minW
, NULL
);
1256 XtVaSetValues(widget
, XmNminHeight
, minH
, NULL
);
1258 XtVaSetValues(widget
, XmNmaxWidth
, maxW
, NULL
);
1260 XtVaSetValues(widget
, XmNmaxHeight
, maxH
, NULL
);
1262 XtVaSetValues(widget
, XmNwidthInc
, incW
, NULL
);
1264 XtVaSetValues(widget
, XmNheightInc
, incH
, NULL
);
1267 // ---------------------------------------------------------------------------
1269 // ---------------------------------------------------------------------------
1271 int wxWindow::GetCharHeight() const
1273 wxCHECK_MSG( m_font
.Ok(), 0, "valid window font needed" );
1275 WXFontStructPtr pFontStruct
= m_font
.GetFontStruct(1.0, GetXDisplay());
1277 int direction
, ascent
, descent
;
1278 XCharStruct overall
;
1279 XTextExtents ((XFontStruct
*) pFontStruct
, "x", 1, &direction
, &ascent
,
1280 &descent
, &overall
);
1282 // return (overall.ascent + overall.descent);
1283 return (ascent
+ descent
);
1286 int wxWindow::GetCharWidth() const
1288 wxCHECK_MSG( m_font
.Ok(), 0, "valid window font needed" );
1290 WXFontStructPtr pFontStruct
= m_font
.GetFontStruct(1.0, GetXDisplay());
1292 int direction
, ascent
, descent
;
1293 XCharStruct overall
;
1294 XTextExtents ((XFontStruct
*) pFontStruct
, "x", 1, &direction
, &ascent
,
1295 &descent
, &overall
);
1297 return overall
.width
;
1300 void wxWindow::GetTextExtent(const wxString
& string
,
1302 int *descent
, int *externalLeading
,
1303 const wxFont
*theFont
) const
1305 wxFont
*fontToUse
= (wxFont
*)theFont
;
1307 fontToUse
= (wxFont
*) & m_font
;
1309 wxCHECK_RET( fontToUse
->Ok(), "valid window font needed" );
1311 WXFontStructPtr pFontStruct
= theFont
->GetFontStruct(1.0, GetXDisplay());
1313 int direction
, ascent
, descent2
;
1314 XCharStruct overall
;
1319 XTextExtents16((XFontStruct
*) pFontStruct
, (XChar2b
*) (char*) (const char*) string
, slen
, &direction
,
1320 &ascent
, &descent2
, &overall
);
1323 XTextExtents((XFontStruct
*) pFontStruct
, string
, slen
,
1324 &direction
, &ascent
, &descent2
, &overall
);
1327 *x
= (overall
.width
);
1329 *y
= (ascent
+ descent2
);
1331 *descent
= descent2
;
1332 if (externalLeading
)
1333 *externalLeading
= 0;
1336 // ----------------------------------------------------------------------------
1338 // ----------------------------------------------------------------------------
1340 void wxWindow::Refresh(bool eraseBack
, const wxRect
*rect
)
1342 m_needsRefresh
= TRUE
;
1343 Display
*display
= XtDisplay((Widget
) GetMainWidget());
1344 Window thisWindow
= XtWindow((Widget
) GetMainWidget());
1346 XExposeEvent dummyEvent
;
1348 GetSize(&width
, &height
);
1350 dummyEvent
.type
= Expose
;
1351 dummyEvent
.display
= display
;
1352 dummyEvent
.send_event
= True
;
1353 dummyEvent
.window
= thisWindow
;
1356 dummyEvent
.x
= rect
->x
;
1357 dummyEvent
.y
= rect
->y
;
1358 dummyEvent
.width
= rect
->width
;
1359 dummyEvent
.height
= rect
->height
;
1365 dummyEvent
.width
= width
;
1366 dummyEvent
.height
= height
;
1368 dummyEvent
.count
= 0;
1372 wxClientDC
dc(this);
1373 wxBrush
backgroundBrush(GetBackgroundColour(), wxSOLID
);
1374 dc
.SetBackground(backgroundBrush
);
1381 XSendEvent(display
, thisWindow
, False
, ExposureMask
, (XEvent
*)&dummyEvent
);
1384 void wxWindow::Clear()
1386 wxClientDC
dc(this);
1387 wxBrush
brush(GetBackgroundColour(), wxSOLID
);
1388 dc
.SetBackground(brush
);
1392 void wxWindow::ClearUpdateRects()
1394 wxRectList::Node
* node
= m_updateRects
.GetFirst();
1397 wxRect
* rect
= node
->GetData();
1399 node
= node
->GetNext();
1402 m_updateRects
.Clear();
1405 void wxWindow::DoPaint()
1407 //TODO : make a temporary gc so we can do the XCopyArea below
1408 if (m_backingPixmap
&& !m_needsRefresh
)
1412 GC tempGC
= (GC
) dc
.GetBackingGC();
1414 Widget widget
= (Widget
) GetMainWidget();
1419 // We have to test whether it's a wxScrolledWindow (hack!) because
1420 // otherwise we don't know how many pixels have been scrolled. We might
1421 // solve this in the future by defining virtual wxWindow functions to get
1422 // the scroll position in pixels. Or, each kind of scrolled window has to
1423 // implement backing stores itself, using generic wxWindows code.
1424 wxScrolledWindow
* scrolledWindow
= wxDynamicCast(this, wxScrolledWindow
);
1425 if ( scrolledWindow
)
1428 scrolledWindow
->CalcScrolledPosition(0, 0, &x
, &y
);
1434 // TODO: This could be optimized further by only copying the areas in the
1435 // current update region.
1437 // Only blit the part visible in the client area. The backing pixmap
1438 // always starts at 0, 0 but we may be looking at only a portion of it.
1439 wxSize clientArea
= GetClientSize();
1440 int toBlitX
= m_pixmapWidth
- scrollPosX
;
1441 int toBlitY
= m_pixmapHeight
- scrollPosY
;
1443 // Copy whichever is samller, the amount of pixmap we have to copy,
1444 // or the size of the client area.
1445 toBlitX
= wxMin(toBlitX
, clientArea
.x
);
1446 toBlitY
= wxMin(toBlitY
, clientArea
.y
);
1448 // Make sure we're not negative
1449 toBlitX
= wxMax(0, toBlitX
);
1450 toBlitY
= wxMax(0, toBlitY
);
1455 (Pixmap
) m_backingPixmap
,
1458 scrollPosX
, scrollPosY
, // Start at the scroll position
1459 toBlitX
, toBlitY
, // How much of the pixmap to copy
1465 // Set an erase event first
1466 wxEraseEvent
eraseEvent(GetId());
1467 eraseEvent
.SetEventObject(this);
1468 GetEventHandler()->ProcessEvent(eraseEvent
);
1470 wxPaintEvent
event(GetId());
1471 event
.SetEventObject(this);
1472 GetEventHandler()->ProcessEvent(event
);
1474 m_needsRefresh
= FALSE
;
1478 // ----------------------------------------------------------------------------
1480 // ----------------------------------------------------------------------------
1482 // Responds to colour changes: passes event on to children.
1483 void wxWindow::OnSysColourChanged(wxSysColourChangedEvent
& event
)
1485 wxWindowList::Node
*node
= GetChildren().GetFirst();
1488 // Only propagate to non-top-level windows
1489 wxWindow
*win
= node
->GetData();
1490 if ( win
->GetParent() )
1492 wxSysColourChangedEvent event2
;
1493 event
.m_eventObject
= win
;
1494 win
->GetEventHandler()->ProcessEvent(event2
);
1497 node
= node
->GetNext();
1501 void wxWindow::OnIdle(wxIdleEvent
& event
)
1503 // This calls the UI-update mechanism (querying windows for
1504 // menu/toolbar/control state information)
1508 // ----------------------------------------------------------------------------
1510 // ----------------------------------------------------------------------------
1512 bool wxWindow::ProcessAccelerator(wxKeyEvent
& event
)
1514 if (!m_acceleratorTable
.Ok())
1517 int count
= m_acceleratorTable
.GetCount();
1518 wxAcceleratorEntry
* entries
= m_acceleratorTable
.GetEntries();
1520 for (i
= 0; i
< count
; i
++)
1522 wxAcceleratorEntry
* entry
= & (entries
[i
]);
1523 if (entry
->MatchesEvent(event
))
1525 // Bingo, we have a match. Now find a control that matches the entry
1528 // Need to go up to the top of the window hierarchy, since it might
1529 // be e.g. a menu item
1530 wxWindow
* parent
= this;
1531 while ( parent
&& !parent
->IsTopLevel() )
1532 parent
= parent
->GetParent();
1537 wxFrame
* frame
= wxDynamicCast(parent
, wxFrame
);
1540 // Try for a menu command
1541 if (frame
->GetMenuBar())
1543 wxMenuItem
* item
= frame
->GetMenuBar()->FindItemForId(entry
->GetCommand());
1546 wxCommandEvent
commandEvent(wxEVT_COMMAND_MENU_SELECTED
, entry
->GetCommand());
1547 commandEvent
.SetEventObject(frame
);
1549 // If ProcessEvent returns TRUE (it was handled), then
1550 // the calling code will skip the event handling.
1551 return frame
->GetEventHandler()->ProcessEvent(commandEvent
);
1556 // Find a child matching the command id
1557 wxWindow
* child
= parent
->FindWindow(entry
->GetCommand());
1563 // Now we process those kinds of windows that we can.
1564 // For now, only buttons.
1565 if ( wxDynamicCast(child
, wxButton
) )
1567 wxCommandEvent
commandEvent (wxEVT_COMMAND_BUTTON_CLICKED
, child
->GetId());
1568 commandEvent
.SetEventObject(child
);
1569 return child
->GetEventHandler()->ProcessEvent(commandEvent
);
1576 // We didn't match the key event against an accelerator.
1580 // ============================================================================
1581 // Motif-specific stuff from here on
1582 // ============================================================================
1584 // ----------------------------------------------------------------------------
1585 // function which maintain the global hash table mapping Widgets to wxWindows
1586 // ----------------------------------------------------------------------------
1588 bool wxAddWindowToTable(Widget w
, wxWindow
*win
)
1590 wxWindow
*oldItem
= NULL
;
1591 if ((oldItem
= (wxWindow
*)wxWidgetHashTable
->Get ((long) w
)))
1593 wxLogDebug("Widget table clash: new widget is %ld, %s",
1594 (long)w
, win
->GetClassInfo()->GetClassName());
1598 wxWidgetHashTable
->Put((long) w
, win
);
1603 wxWindow
*wxGetWindowFromTable(Widget w
)
1605 return (wxWindow
*)wxWidgetHashTable
->Get((long) w
);
1608 void wxDeleteWindowFromTable(Widget w
)
1610 wxWidgetHashTable
->Delete((long)w
);
1613 // ----------------------------------------------------------------------------
1614 // add/remove window from the table
1615 // ----------------------------------------------------------------------------
1617 // Add to hash table, add event handler
1618 bool wxWindow::AttachWidget (wxWindow
* parent
, WXWidget mainWidget
,
1619 WXWidget formWidget
, int x
, int y
, int width
, int height
)
1621 wxAddWindowToTable((Widget
) mainWidget
, this);
1622 if (CanAddEventHandler())
1624 XtAddEventHandler((Widget
) mainWidget
,
1625 ButtonPressMask
| ButtonReleaseMask
| PointerMotionMask
, // | KeyPressMask,
1627 wxPanelItemEventHandler
,
1634 XtOverrideTranslations ((Widget
) mainWidget
,
1635 ptr
= XtParseTranslationTable ("<Configure>: resize()"));
1636 XtFree ((char *) ptr
);
1639 // Some widgets have a parent form widget, e.g. wxRadioBox
1642 if (!wxAddWindowToTable((Widget
) formWidget
, this))
1646 XtOverrideTranslations ((Widget
) formWidget
,
1647 ptr
= XtParseTranslationTable ("<Configure>: resize()"));
1648 XtFree ((char *) ptr
);
1655 SetSize (x
, y
, width
, height
);
1660 // Remove event handler, remove from hash table
1661 bool wxWindow::DetachWidget(WXWidget widget
)
1663 if (CanAddEventHandler())
1665 XtRemoveEventHandler((Widget
) widget
,
1666 ButtonPressMask
| ButtonReleaseMask
| PointerMotionMask
, // | KeyPressMask,
1668 wxPanelItemEventHandler
,
1672 wxDeleteWindowFromTable((Widget
) widget
);
1676 // ----------------------------------------------------------------------------
1677 // Motif-specific accessors
1678 // ----------------------------------------------------------------------------
1680 // Get the underlying X window
1681 WXWindow
wxWindow::GetXWindow() const
1683 Widget wMain
= (Widget
)GetMainWidget();
1685 return (WXWindow
) XtWindow(wMain
);
1687 return (WXWindow
) 0;
1690 // Get the underlying X display
1691 WXDisplay
*wxWindow::GetXDisplay() const
1693 Widget wMain
= (Widget
)GetMainWidget();
1695 return (WXDisplay
*) XtDisplay(wMain
);
1697 return (WXDisplay
*) NULL
;
1700 WXWidget
wxWindow::GetMainWidget() const
1703 return m_drawingArea
;
1705 return m_mainWidget
;
1708 WXWidget
wxWindow::GetClientWidget() const
1710 if (m_drawingArea
!= (WXWidget
) 0)
1711 return m_drawingArea
;
1713 return GetMainWidget();
1716 WXWidget
wxWindow::GetTopWidget() const
1718 return GetMainWidget();
1721 WXWidget
wxWindow::GetLabelWidget() const
1723 return GetMainWidget();
1726 // ----------------------------------------------------------------------------
1728 // ----------------------------------------------------------------------------
1730 // All widgets should have this as their resize proc.
1731 // OnSize sent to wxWindow via client data.
1732 void wxWidgetResizeProc(Widget w
, XConfigureEvent
*event
, String args
[], int *num_args
)
1734 wxWindow
*win
= wxGetWindowFromTable(w
);
1738 if (win
->PreResize())
1741 win
->GetSize(&width
, &height
);
1742 wxSizeEvent
sizeEvent(wxSize(width
, height
), win
->GetId());
1743 sizeEvent
.SetEventObject(win
);
1744 win
->GetEventHandler()->ProcessEvent(sizeEvent
);
1748 static void wxCanvasRepaintProc(Widget drawingArea
,
1749 XtPointer clientData
,
1750 XmDrawingAreaCallbackStruct
* cbs
)
1752 if (!wxGetWindowFromTable(drawingArea
))
1755 XEvent
* event
= cbs
->event
;
1756 wxWindow
* win
= (wxWindow
*) clientData
;
1758 switch (event
->type
)
1762 if (event
-> xexpose
.count
== 0)
1765 wxPaintEvent
event(win
->GetId());
1766 event
.SetEventObject(win
);
1767 win
->GetEventHandler()->ProcessEvent(event
);
1771 win
->ClearUpdateRects();
1775 win
->AddUpdateRect(event
->xexpose
.x
, event
->xexpose
.y
,
1776 event
->xexpose
.width
, event
->xexpose
.height
);
1783 // Unable to deal with Enter/Leave without a separate EventHandler (Motif 1.1.4)
1784 static void wxCanvasEnterLeave(Widget drawingArea
,
1785 XtPointer clientData
,
1786 XCrossingEvent
* event
)
1788 XmDrawingAreaCallbackStruct cbs
;
1791 ((XCrossingEvent
&) ev
) = *event
;
1793 cbs
.reason
= XmCR_INPUT
;
1796 wxCanvasInputEvent(drawingArea
, (XtPointer
) NULL
, &cbs
);
1799 // Fix to make it work under Motif 1.0 (!)
1800 static void wxCanvasMotionEvent (Widget drawingArea
, XButtonEvent
* event
)
1802 #if XmVersion <= 1000
1803 XmDrawingAreaCallbackStruct cbs
;
1806 ev
= *((XEvent
*) event
);
1807 cbs
.reason
= XmCR_INPUT
;
1810 wxCanvasInputEvent (drawingArea
, (XtPointer
) NULL
, &cbs
);
1811 #endif // XmVersion <= 1000
1814 static void wxCanvasInputEvent(Widget drawingArea
,
1816 XmDrawingAreaCallbackStruct
* cbs
)
1818 wxWindow
*canvas
= wxGetWindowFromTable(drawingArea
);
1824 if (cbs
->reason
!= XmCR_INPUT
)
1827 local_event
= *(cbs
->event
); // We must keep a copy!
1829 switch (local_event
.xany
.type
)
1837 wxEventType eventType
= wxEVT_NULL
;
1839 if (local_event
.xany
.type
== EnterNotify
)
1841 //if (local_event.xcrossing.mode!=NotifyNormal)
1842 // return ; // Ignore grab events
1843 eventType
= wxEVT_ENTER_WINDOW
;
1844 // canvas->GetEventHandler()->OnSetFocus();
1846 else if (local_event
.xany
.type
== LeaveNotify
)
1848 //if (local_event.xcrossing.mode!=NotifyNormal)
1849 // return ; // Ignore grab events
1850 eventType
= wxEVT_LEAVE_WINDOW
;
1851 // canvas->GetEventHandler()->OnKillFocus();
1853 else if (local_event
.xany
.type
== MotionNotify
)
1855 eventType
= wxEVT_MOTION
;
1856 if (local_event
.xmotion
.is_hint
== NotifyHint
)
1859 Display
*dpy
= XtDisplay (drawingArea
);
1861 XQueryPointer (dpy
, XtWindow (drawingArea
),
1863 &local_event
.xmotion
.x_root
,
1864 &local_event
.xmotion
.y_root
,
1865 &local_event
.xmotion
.x
,
1866 &local_event
.xmotion
.y
,
1867 &local_event
.xmotion
.state
);
1874 else if (local_event
.xany
.type
== ButtonPress
)
1876 if (local_event
.xbutton
.button
== Button1
)
1878 eventType
= wxEVT_LEFT_DOWN
;
1879 canvas
->SetButton1(TRUE
);
1881 else if (local_event
.xbutton
.button
== Button2
)
1883 eventType
= wxEVT_MIDDLE_DOWN
;
1884 canvas
->SetButton2(TRUE
);
1886 else if (local_event
.xbutton
.button
== Button3
)
1888 eventType
= wxEVT_RIGHT_DOWN
;
1889 canvas
->SetButton3(TRUE
);
1892 else if (local_event
.xany
.type
== ButtonRelease
)
1894 if (local_event
.xbutton
.button
== Button1
)
1896 eventType
= wxEVT_LEFT_UP
;
1897 canvas
->SetButton1(FALSE
);
1899 else if (local_event
.xbutton
.button
== Button2
)
1901 eventType
= wxEVT_MIDDLE_UP
;
1902 canvas
->SetButton2(FALSE
);
1904 else if (local_event
.xbutton
.button
== Button3
)
1906 eventType
= wxEVT_RIGHT_UP
;
1907 canvas
->SetButton3(FALSE
);
1911 wxMouseEvent
wxevent (eventType
);
1913 wxevent
.m_leftDown
= ((eventType
== wxEVT_LEFT_DOWN
)
1914 || (event_left_is_down (&local_event
)
1915 && (eventType
!= wxEVT_LEFT_UP
)));
1916 wxevent
.m_middleDown
= ((eventType
== wxEVT_MIDDLE_DOWN
)
1917 || (event_middle_is_down (&local_event
)
1918 && (eventType
!= wxEVT_MIDDLE_UP
)));
1919 wxevent
.m_rightDown
= ((eventType
== wxEVT_RIGHT_DOWN
)
1920 || (event_right_is_down (&local_event
)
1921 && (eventType
!= wxEVT_RIGHT_UP
)));
1923 wxevent
.m_shiftDown
= local_event
.xbutton
.state
& ShiftMask
;
1924 wxevent
.m_controlDown
= local_event
.xbutton
.state
& ControlMask
;
1925 wxevent
.m_altDown
= local_event
.xbutton
.state
& Mod3Mask
;
1926 wxevent
.m_metaDown
= local_event
.xbutton
.state
& Mod1Mask
;
1927 wxevent
.SetTimestamp(local_event
.xbutton
.time
);
1929 // Now check if we need to translate this event into a double click
1930 if (TRUE
) // canvas->doubleClickAllowed)
1932 if (wxevent
.ButtonDown())
1934 long dclickTime
= XtGetMultiClickTime((Display
*) wxGetDisplay());
1936 // get button and time-stamp
1938 if (wxevent
.LeftDown())
1940 else if (wxevent
.MiddleDown())
1942 else if (wxevent
.RightDown())
1944 long ts
= wxevent
.GetTimestamp();
1946 // check, if single or double click
1947 int buttonLast
= canvas
->GetLastClickedButton();
1948 long lastTS
= canvas
->GetLastClickTime();
1949 if ( buttonLast
&& buttonLast
== button
&& (ts
- lastTS
) < dclickTime
)
1952 canvas
->SetLastClick(0, ts
);
1953 switch ( eventType
)
1955 case wxEVT_LEFT_DOWN
:
1956 wxevent
.SetEventType(wxEVT_LEFT_DCLICK
);
1958 case wxEVT_MIDDLE_DOWN
:
1959 wxevent
.SetEventType(wxEVT_MIDDLE_DCLICK
);
1961 case wxEVT_RIGHT_DOWN
:
1962 wxevent
.SetEventType(wxEVT_RIGHT_DCLICK
);
1972 // not fast enough or different button
1973 canvas
->SetLastClick(button
, ts
);
1978 wxevent
.SetId(canvas
->GetId());
1979 wxevent
.SetEventObject(canvas
);
1980 wxevent
.m_x
= local_event
.xbutton
.x
;
1981 wxevent
.m_y
= local_event
.xbutton
.y
;
1982 canvas
->GetEventHandler()->ProcessEvent (wxevent
);
1984 if (eventType
== wxEVT_ENTER_WINDOW
||
1985 eventType
== wxEVT_LEAVE_WINDOW
||
1986 eventType
== wxEVT_MOTION
1996 XComposeStatus compose
;
1997 (void) XLookupString ((XKeyEvent
*) & local_event
, wxBuffer
, 20, &keySym
, &compose
);
2000 (void) XLookupString ((XKeyEvent
*) & local_event
, wxBuffer
, 20, &keySym
, NULL
);
2001 int id
= wxCharCodeXToWX (keySym
);
2003 wxEventType eventType
= wxEVT_CHAR
;
2005 wxKeyEvent
event (eventType
);
2007 if (local_event
.xkey
.state
& ShiftMask
)
2008 event
.m_shiftDown
= TRUE
;
2009 if (local_event
.xkey
.state
& ControlMask
)
2010 event
.m_controlDown
= TRUE
;
2011 if (local_event
.xkey
.state
& Mod3Mask
)
2012 event
.m_altDown
= TRUE
;
2013 if (local_event
.xkey
.state
& Mod1Mask
)
2014 event
.m_metaDown
= TRUE
;
2015 event
.SetEventObject(canvas
);
2016 event
.m_keyCode
= id
;
2017 event
.SetTimestamp(local_event
.xkey
.time
);
2021 // Implement wxFrame::OnCharHook by checking ancestor.
2022 wxWindow
*parent
= canvas
->GetParent();
2023 while (parent
&& !parent
->IsKindOf(CLASSINFO(wxFrame
)))
2024 parent
= parent
->GetParent();
2028 event
.SetEventType(wxEVT_CHAR_HOOK
);
2029 if (parent
->GetEventHandler()->ProcessEvent(event
))
2033 // For simplicity, OnKeyDown is the same as OnChar
2034 // TODO: filter modifier key presses from OnChar
2035 event
.SetEventType(wxEVT_KEY_DOWN
);
2037 // Only process OnChar if OnKeyDown didn't swallow it
2038 if (!canvas
->GetEventHandler()->ProcessEvent (event
))
2040 event
.SetEventType(wxEVT_CHAR
);
2041 canvas
->GetEventHandler()->ProcessEvent (event
);
2049 (void) XLookupString ((XKeyEvent
*) & local_event
, wxBuffer
, 20, &keySym
, NULL
);
2050 int id
= wxCharCodeXToWX (keySym
);
2052 wxKeyEvent
event (wxEVT_KEY_UP
);
2054 if (local_event
.xkey
.state
& ShiftMask
)
2055 event
.m_shiftDown
= TRUE
;
2056 if (local_event
.xkey
.state
& ControlMask
)
2057 event
.m_controlDown
= TRUE
;
2058 if (local_event
.xkey
.state
& Mod3Mask
)
2059 event
.m_altDown
= TRUE
;
2060 if (local_event
.xkey
.state
& Mod1Mask
)
2061 event
.m_metaDown
= TRUE
;
2062 event
.SetEventObject(canvas
);
2063 event
.m_keyCode
= id
;
2064 event
.SetTimestamp(local_event
.xkey
.time
);
2068 canvas
->GetEventHandler()->ProcessEvent (event
);
2074 if (local_event
.xfocus
.detail
!= NotifyPointer
)
2076 wxFocusEvent
event(wxEVT_SET_FOCUS
, canvas
->GetId());
2077 event
.SetEventObject(canvas
);
2078 canvas
->GetEventHandler()->ProcessEvent(event
);
2084 if (local_event
.xfocus
.detail
!= NotifyPointer
)
2086 wxFocusEvent
event(wxEVT_KILL_FOCUS
, canvas
->GetId());
2087 event
.SetEventObject(canvas
);
2088 canvas
->GetEventHandler()->ProcessEvent(event
);
2097 static void wxPanelItemEventHandler(Widget wid
,
2098 XtPointer client_data
,
2100 Boolean
*continueToDispatch
)
2102 // Widget can be a label or the actual widget.
2104 wxWindow
*window
= wxGetWindowFromTable(wid
);
2107 wxMouseEvent
wxevent(0);
2108 if (wxTranslateMouseEvent(wxevent
, window
, wid
, event
))
2110 window
->GetEventHandler()->ProcessEvent(wxevent
);
2114 // TODO: probably the key to allowing default behaviour to happen. Say we
2115 // set a m_doDefault flag to FALSE at the start of this function. Then in
2116 // e.g. wxWindow::OnMouseEvent we can call Default() which sets this flag to
2117 // TRUE, indicating that default processing can happen. Thus, behaviour can
2118 // appear to be overridden just by adding an event handler and not calling
2119 // wxWindow::OnWhatever. ALSO, maybe we can use this instead of the current
2120 // way of handling drawing area events, to simplify things.
2121 *continueToDispatch
= True
;
2124 static void wxScrollBarCallback(Widget scrollbar
,
2125 XtPointer clientData
,
2126 XmScaleCallbackStruct
*cbs
)
2128 wxWindow
*win
= wxGetWindowFromTable(scrollbar
);
2129 int orientation
= (int) clientData
;
2131 wxEventType eventType
= wxEVT_NULL
;
2132 switch (cbs
->reason
)
2134 case XmCR_INCREMENT
:
2136 eventType
= wxEVT_SCROLL_LINEDOWN
;
2139 case XmCR_DECREMENT
:
2141 eventType
= wxEVT_SCROLL_LINEUP
;
2146 eventType
= wxEVT_SCROLL_THUMBTRACK
;
2149 case XmCR_VALUE_CHANGED
:
2151 // TODO: Should this be intercepted too, or will it cause
2152 // duplicate events?
2153 eventType
= wxEVT_SCROLL_THUMBTRACK
;
2156 case XmCR_PAGE_INCREMENT
:
2158 eventType
= wxEVT_SCROLL_PAGEDOWN
;
2161 case XmCR_PAGE_DECREMENT
:
2163 eventType
= wxEVT_SCROLL_PAGEUP
;
2168 eventType
= wxEVT_SCROLL_TOP
;
2171 case XmCR_TO_BOTTOM
:
2173 eventType
= wxEVT_SCROLL_BOTTOM
;
2178 // Should never get here
2179 wxFAIL_MSG("Unknown scroll event.");
2184 wxScrollEvent
event(eventType
, win
->GetId());
2185 event
.SetEventObject(win
);
2186 event
.SetPosition(cbs
->value
);
2187 event
.SetOrientation( (orientation
== XmHORIZONTAL
) ? wxHORIZONTAL
: wxVERTICAL
);
2189 win
->GetEventHandler()->ProcessEvent(event
);
2192 // For repainting arbitrary windows
2193 void wxUniversalRepaintProc(Widget w
, XtPointer
WXUNUSED(c_data
), XEvent
*event
, char *)
2198 wxWindow
* win
= wxGetWindowFromTable(w
);
2202 switch(event
-> type
)
2206 window
= (Window
) win
-> GetXWindow();
2207 display
= (Display
*) win
-> GetXDisplay();
2209 if (event
-> xexpose
.count
== 0)
2213 win
->ClearUpdateRects();
2217 win
->AddUpdateRect(event
->xexpose
.x
, event
->xexpose
.y
,
2218 event
->xexpose
.width
, event
->xexpose
.height
);
2226 // ----------------------------------------------------------------------------
2227 // CanvaseXXXSize() functions
2228 // ----------------------------------------------------------------------------
2230 // SetSize, but as per old wxCanvas (with drawing widget etc.)
2231 void wxWindow::CanvasSetSize (int x
, int y
, int w
, int h
, int sizeFlags
)
2233 // A bit of optimization to help sort out the flickers.
2234 int oldX
, oldY
, oldW
, oldH
;
2235 GetSize(& oldW
, & oldH
);
2236 GetPosition(& oldX
, & oldY
);
2238 bool useOldPos
= FALSE
;
2239 bool useOldSize
= FALSE
;
2241 if ((x
== -1) && (x
== -1) && ((sizeFlags
& wxSIZE_ALLOW_MINUS_ONE
) == 0))
2243 else if (x
== oldX
&& y
== oldY
)
2246 if ((w
== -1) && (h
== -1))
2248 else if (w
== oldW
&& h
== oldH
)
2251 if (!wxNoOptimize::CanOptimize())
2253 useOldSize
= FALSE
; useOldPos
= FALSE
;
2256 if (useOldPos
&& useOldSize
)
2259 Widget drawingArea
= (Widget
) m_drawingArea
;
2260 bool managed
= XtIsManaged(m_borderWidget
? (Widget
) m_borderWidget
: (Widget
) m_scrolledWindow
);
2263 XtUnmanageChild (m_borderWidget
? (Widget
) m_borderWidget
: (Widget
) m_scrolledWindow
);
2264 XtVaSetValues(drawingArea
, XmNresizePolicy
, XmRESIZE_ANY
, NULL
);
2266 int xx
= x
; int yy
= y
;
2267 AdjustForParentClientOrigin(xx
, yy
, sizeFlags
);
2271 if (x
> -1 || (sizeFlags
& wxSIZE_ALLOW_MINUS_ONE
))
2273 XtVaSetValues (m_borderWidget
? (Widget
) m_borderWidget
: (Widget
) m_scrolledWindow
,
2277 if (y
> -1 || (sizeFlags
& wxSIZE_ALLOW_MINUS_ONE
))
2279 XtVaSetValues (m_borderWidget
? (Widget
) m_borderWidget
: (Widget
) m_scrolledWindow
,
2291 XtVaSetValues ((Widget
) m_borderWidget
, XmNwidth
, w
, NULL
);
2292 short thick
, margin
;
2293 XtVaGetValues ((Widget
) m_borderWidget
,
2294 XmNshadowThickness
, &thick
,
2295 XmNmarginWidth
, &margin
,
2297 w
-= 2 * (thick
+ margin
);
2300 XtVaSetValues ((Widget
) m_scrolledWindow
, XmNwidth
, w
, NULL
);
2304 XtVaGetValues ((Widget
) m_scrolledWindow
,
2305 XmNspacing
, &spacing
,
2306 XmNverticalScrollBar
, &sbar
,
2310 XtVaGetValues (sbar
, XmNwidth
, &wsbar
, NULL
);
2314 w
-= (spacing
+ wsbar
);
2317 XtVaSetValues(drawingArea
, XmNwidth
, w
, NULL
);
2324 XtVaSetValues ((Widget
) m_borderWidget
, XmNheight
, h
, NULL
);
2325 short thick
, margin
;
2326 XtVaGetValues ((Widget
) m_borderWidget
,
2327 XmNshadowThickness
, &thick
,
2328 XmNmarginHeight
, &margin
,
2330 h
-= 2 * (thick
+ margin
);
2333 XtVaSetValues ((Widget
) m_scrolledWindow
, XmNheight
, h
, NULL
);
2337 XtVaGetValues ((Widget
) m_scrolledWindow
,
2338 XmNspacing
, &spacing
,
2339 XmNhorizontalScrollBar
, &sbar
,
2343 XtVaGetValues (sbar
, XmNheight
, &wsbar
, NULL
);
2347 h
-= (spacing
+ wsbar
);
2350 XtVaSetValues(drawingArea
, XmNheight
, h
, NULL
);
2356 XtManageChild (m_borderWidget
? (Widget
) m_borderWidget
: (Widget
) m_scrolledWindow
);
2357 XtVaSetValues(drawingArea
, XmNresizePolicy
, XmRESIZE_NONE
, NULL
);
2361 GetClientSize (&ww
, &hh
);
2362 wxSizeEvent
sizeEvent(wxSize(ww
, hh
), GetId());
2363 sizeEvent
.SetEventObject(this);
2365 GetEventHandler()->ProcessEvent(sizeEvent
);
2369 void wxWindow::CanvasSetClientSize (int w
, int h
)
2371 Widget drawingArea
= (Widget
) m_drawingArea
;
2373 XtVaSetValues(drawingArea
, XmNresizePolicy
, XmRESIZE_ANY
, NULL
);
2376 XtVaSetValues(drawingArea
, XmNwidth
, w
, NULL
);
2378 XtVaSetValues(drawingArea
, XmNheight
, h
, NULL
);
2381 // TODO: is this necessary?
2382 allowRepainting
= FALSE
;
2384 XSync (XtDisplay (drawingArea
), FALSE
);
2386 while (XtAppPending (wxTheApp
->appContext
))
2388 XFlush (XtDisplay (drawingArea
));
2389 XtAppNextEvent (wxTheApp
->appContext
, &event
);
2390 XtDispatchEvent (&event
);
2394 XtVaSetValues(drawingArea
, XmNresizePolicy
, XmRESIZE_NONE
, NULL
);
2397 allowRepainting
= TRUE
;
2400 wxSizeEvent
sizeEvent(wxSize(w
, h
), GetId());
2401 sizeEvent
.SetEventObject(this);
2403 GetEventHandler()->ProcessEvent(sizeEvent
);
2407 void wxWindow::CanvasGetClientSize (int *w
, int *h
) const
2409 // Must return the same thing that was set via SetClientSize
2411 XtVaGetValues ((Widget
) m_drawingArea
, XmNwidth
, &xx
, XmNheight
, &yy
, NULL
);
2416 void wxWindow::CanvasGetSize (int *w
, int *h
) const
2419 if ((Widget
) m_borderWidget
)
2420 XtVaGetValues ((Widget
) m_borderWidget
, XmNwidth
, &xx
, XmNheight
, &yy
, NULL
);
2421 else if ((Widget
) m_scrolledWindow
)
2422 XtVaGetValues ((Widget
) m_scrolledWindow
, XmNwidth
, &xx
, XmNheight
, &yy
, NULL
);
2424 XtVaGetValues ((Widget
) m_drawingArea
, XmNwidth
, &xx
, XmNheight
, &yy
, NULL
);
2430 void wxWindow::CanvasGetPosition (int *x
, int *y
) const
2433 XtVaGetValues (m_borderWidget
? (Widget
) m_borderWidget
: (Widget
) m_scrolledWindow
, XmNx
, &xx
, XmNy
, &yy
, NULL
);
2435 // We may be faking the client origin.
2436 // So a window that's really at (0, 30) may appear
2437 // (to wxWin apps) to be at (0, 0).
2440 wxPoint
pt(GetParent()->GetClientAreaOrigin());
2449 // ----------------------------------------------------------------------------
2450 // TranslateXXXEvent() functions
2451 // ----------------------------------------------------------------------------
2453 bool wxTranslateMouseEvent(wxMouseEvent
& wxevent
, wxWindow
*win
, Widget widget
, XEvent
*xevent
)
2455 switch (xevent
->xany
.type
)
2463 wxEventType eventType
= wxEVT_NULL
;
2465 if (xevent
->xany
.type
== LeaveNotify
)
2467 win
->SetButton1(FALSE
);
2468 win
->SetButton2(FALSE
);
2469 win
->SetButton3(FALSE
);
2472 else if (xevent
->xany
.type
== MotionNotify
)
2474 eventType
= wxEVT_MOTION
;
2476 else if (xevent
->xany
.type
== ButtonPress
)
2478 if (xevent
->xbutton
.button
== Button1
)
2480 eventType
= wxEVT_LEFT_DOWN
;
2481 win
->SetButton1(TRUE
);
2483 else if (xevent
->xbutton
.button
== Button2
)
2485 eventType
= wxEVT_MIDDLE_DOWN
;
2486 win
->SetButton2(TRUE
);
2488 else if (xevent
->xbutton
.button
== Button3
)
2490 eventType
= wxEVT_RIGHT_DOWN
;
2491 win
->SetButton3(TRUE
);
2494 else if (xevent
->xany
.type
== ButtonRelease
)
2496 if (xevent
->xbutton
.button
== Button1
)
2498 eventType
= wxEVT_LEFT_UP
;
2499 win
->SetButton1(FALSE
);
2501 else if (xevent
->xbutton
.button
== Button2
)
2503 eventType
= wxEVT_MIDDLE_UP
;
2504 win
->SetButton2(FALSE
);
2506 else if (xevent
->xbutton
.button
== Button3
)
2508 eventType
= wxEVT_RIGHT_UP
;
2509 win
->SetButton3(FALSE
);
2518 wxevent
.SetEventType(eventType
);
2521 XtVaGetValues(widget
, XmNx
, &x1
, XmNy
, &y1
, NULL
);
2524 win
->GetPosition(&x2
, &y2
);
2526 // The button x/y must be translated to wxWindows
2527 // window space - the widget might be a label or button,
2531 if (widget
!= (Widget
)win
->GetMainWidget())
2537 wxevent
.m_x
= xevent
->xbutton
.x
+ dx
;
2538 wxevent
.m_y
= xevent
->xbutton
.y
+ dy
;
2540 wxevent
.m_leftDown
= ((eventType
== wxEVT_LEFT_DOWN
)
2541 || (event_left_is_down (xevent
)
2542 && (eventType
!= wxEVT_LEFT_UP
)));
2543 wxevent
.m_middleDown
= ((eventType
== wxEVT_MIDDLE_DOWN
)
2544 || (event_middle_is_down (xevent
)
2545 && (eventType
!= wxEVT_MIDDLE_UP
)));
2546 wxevent
.m_rightDown
= ((eventType
== wxEVT_RIGHT_DOWN
)
2547 || (event_right_is_down (xevent
)
2548 && (eventType
!= wxEVT_RIGHT_UP
)));
2550 wxevent
.m_shiftDown
= xevent
->xbutton
.state
& ShiftMask
;
2551 wxevent
.m_controlDown
= xevent
->xbutton
.state
& ControlMask
;
2558 bool wxTranslateKeyEvent(wxKeyEvent
& wxevent
, wxWindow
*win
, Widget widget
, XEvent
*xevent
)
2560 switch (xevent
->xany
.type
)
2568 XComposeStatus compose
;
2569 (void) XLookupString ((XKeyEvent
*) xevent
, buf
, 20, &keySym
, &compose
);
2571 (void) XLookupString ((XKeyEvent
*) xevent
, buf
, 20, &keySym
, NULL
);
2572 int id
= wxCharCodeXToWX (keySym
);
2574 if (xevent
->xkey
.state
& ShiftMask
)
2575 wxevent
.m_shiftDown
= TRUE
;
2576 if (xevent
->xkey
.state
& ControlMask
)
2577 wxevent
.m_controlDown
= TRUE
;
2578 if (xevent
->xkey
.state
& Mod3Mask
)
2579 wxevent
.m_altDown
= TRUE
;
2580 if (xevent
->xkey
.state
& Mod1Mask
)
2581 wxevent
.m_metaDown
= TRUE
;
2582 wxevent
.SetEventObject(win
);
2583 wxevent
.m_keyCode
= id
;
2584 wxevent
.SetTimestamp(xevent
->xkey
.time
);
2586 wxevent
.m_x
= xevent
->xbutton
.x
;
2587 wxevent
.m_y
= xevent
->xbutton
.y
;
2601 // ----------------------------------------------------------------------------
2603 // ----------------------------------------------------------------------------
2605 #define YAllocColor XAllocColor
2606 XColor g_itemColors
[5];
2607 int wxComputeColours (Display
*display
, wxColour
* back
, wxColour
* fore
)
2610 static XmColorProc colorProc
;
2612 result
= wxNO_COLORS
;
2616 g_itemColors
[0].red
= (((long) back
->Red ()) << 8);
2617 g_itemColors
[0].green
= (((long) back
->Green ()) << 8);
2618 g_itemColors
[0].blue
= (((long) back
->Blue ()) << 8);
2619 g_itemColors
[0].flags
= DoRed
| DoGreen
| DoBlue
;
2620 if (colorProc
== (XmColorProc
) NULL
)
2622 // Get a ptr to the actual function
2623 colorProc
= XmSetColorCalculation ((XmColorProc
) NULL
);
2624 // And set it back to motif.
2625 XmSetColorCalculation (colorProc
);
2627 (*colorProc
) (&g_itemColors
[wxBACK_INDEX
],
2628 &g_itemColors
[wxFORE_INDEX
],
2629 &g_itemColors
[wxSELE_INDEX
],
2630 &g_itemColors
[wxTOPS_INDEX
],
2631 &g_itemColors
[wxBOTS_INDEX
]);
2632 result
= wxBACK_COLORS
;
2636 g_itemColors
[wxFORE_INDEX
].red
= (((long) fore
->Red ()) << 8);
2637 g_itemColors
[wxFORE_INDEX
].green
= (((long) fore
->Green ()) << 8);
2638 g_itemColors
[wxFORE_INDEX
].blue
= (((long) fore
->Blue ()) << 8);
2639 g_itemColors
[wxFORE_INDEX
].flags
= DoRed
| DoGreen
| DoBlue
;
2640 if (result
== wxNO_COLORS
)
2641 result
= wxFORE_COLORS
;
2644 Display
*dpy
= display
;
2645 Colormap cmap
= (Colormap
) wxTheApp
->GetMainColormap((WXDisplay
*) dpy
);
2649 /* 5 Colours to allocate */
2650 for (int i
= 0; i
< 5; i
++)
2651 if (!YAllocColor (dpy
, cmap
, &g_itemColors
[i
]))
2652 result
= wxNO_COLORS
;
2656 /* Only 1 colour to allocate */
2657 if (!YAllocColor (dpy
, cmap
, &g_itemColors
[wxFORE_INDEX
]))
2658 result
= wxNO_COLORS
;
2665 // Changes the foreground and background colours to be derived from the current
2666 // background colour. To change the foreground colour, you must call
2667 // SetForegroundColour explicitly.
2668 void wxWindow::ChangeBackgroundColour()
2670 WXWidget mainWidget
= GetMainWidget();
2672 DoChangeBackgroundColour(mainWidget
, m_backgroundColour
);
2674 // This not necessary
2677 if (m_scrolledWindow
&& (GetMainWidget() != m_scrolledWindow
))
2679 DoChangeBackgroundColour(m_scrolledWindow
, m_backgroundColour
);
2680 // Have to set the scrollbar colours back since
2681 // the scrolled window seemed to change them
2682 wxColour backgroundColour
= wxSystemSettings::GetSystemColour(wxSYS_COLOUR_3DFACE
);
2685 DoChangeBackgroundColour(m_hScrollBar
, backgroundColour
);
2687 DoChangeBackgroundColour(m_vScrollBar
, backgroundColour
);
2692 void wxWindow::ChangeForegroundColour()
2694 WXWidget mainWidget
= GetMainWidget();
2696 DoChangeForegroundColour(mainWidget
, m_foregroundColour
);
2697 if ( m_scrolledWindow
&& mainWidget
!= m_scrolledWindow
)
2698 DoChangeForegroundColour(m_scrolledWindow
, m_foregroundColour
);
2701 // Change a widget's foreground and background colours.
2702 void wxWindow::DoChangeForegroundColour(WXWidget widget
, wxColour
& foregroundColour
)
2704 // When should we specify the foreground, if it's calculated
2705 // by wxComputeColours?
2706 // Solution: say we start with the default (computed) foreground colour.
2707 // If we call SetForegroundColour explicitly for a control or window,
2708 // then the foreground is changed.
2709 // Therefore SetBackgroundColour computes the foreground colour, and
2710 // SetForegroundColour changes the foreground colour. The ordering is
2713 Widget w
= (Widget
)widget
;
2716 XmNforeground
, foregroundColour
.AllocColour(XtDisplay(w
)),
2721 void wxWindow::DoChangeBackgroundColour(WXWidget widget
, wxColour
& backgroundColour
, bool changeArmColour
)
2723 wxComputeColours (XtDisplay((Widget
) widget
), & backgroundColour
,
2726 XtVaSetValues ((Widget
) widget
,
2727 XmNbackground
, g_itemColors
[wxBACK_INDEX
].pixel
,
2728 XmNtopShadowColor
, g_itemColors
[wxTOPS_INDEX
].pixel
,
2729 XmNbottomShadowColor
, g_itemColors
[wxBOTS_INDEX
].pixel
,
2730 XmNforeground
, g_itemColors
[wxFORE_INDEX
].pixel
,
2733 if (changeArmColour
)
2734 XtVaSetValues ((Widget
) widget
,
2735 XmNarmColor
, g_itemColors
[wxSELE_INDEX
].pixel
,
2739 bool wxWindow::SetBackgroundColour(const wxColour
& col
)
2741 if ( !wxWindowBase::SetBackgroundColour(col
) )
2744 ChangeBackgroundColour();
2749 bool wxWindow::SetForegroundColour(const wxColour
& col
)
2751 if ( !wxWindowBase::SetForegroundColour(col
) )
2754 ChangeForegroundColour();
2759 void wxWindow::ChangeFont(bool keepOriginalSize
)
2761 // Note that this causes the widget to be resized back
2762 // to its original size! We therefore have to set the size
2763 // back again. TODO: a better way in Motif?
2764 Widget w
= (Widget
) GetLabelWidget(); // Usually the main widget
2765 if (w
&& m_font
.Ok())
2767 int width
, height
, width1
, height1
;
2768 GetSize(& width
, & height
);
2770 // lesstif 0.87 hangs here
2771 #ifndef LESSTIF_VERSION
2773 XmNfontList
, (XmFontList
) m_font
.GetFontList(1.0, XtDisplay(w
)),
2777 GetSize(& width1
, & height1
);
2778 if (keepOriginalSize
&& (width
!= width1
|| height
!= height1
))
2780 SetSize(-1, -1, width
, height
);
2785 // ----------------------------------------------------------------------------
2787 // ----------------------------------------------------------------------------
2789 wxWindow
*wxGetActiveWindow()
2795 // ----------------------------------------------------------------------------
2796 // wxNoOptimize: switch off size optimization
2797 // ----------------------------------------------------------------------------
2799 int wxNoOptimize::ms_count
= 0;