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"
40 #include "wx/menuitem.h"
43 #if wxUSE_DRAG_AND_DROP
49 #include <Xm/DrawingA.h>
50 #include <Xm/ScrolledW.h>
51 #include <Xm/ScrollBar.h>
55 #include "wx/motif/private.h"
59 // ----------------------------------------------------------------------------
61 // ----------------------------------------------------------------------------
63 static const int SCROLL_MARGIN
= 4;
65 // ----------------------------------------------------------------------------
66 // global variables for this module
67 // ----------------------------------------------------------------------------
69 static wxHashTable
*gs_wxWidgetHashTable
;
71 // ----------------------------------------------------------------------------
73 // ----------------------------------------------------------------------------
75 static void wxCanvasRepaintProc(Widget
, XtPointer
, XmDrawingAreaCallbackStruct
* cbs
);
76 static void wxCanvasInputEvent(Widget drawingArea
, XtPointer data
, XmDrawingAreaCallbackStruct
* cbs
);
77 static void wxCanvasMotionEvent(Widget
, XButtonEvent
* event
);
78 static void wxCanvasEnterLeave(Widget drawingArea
, XtPointer clientData
, XCrossingEvent
* event
);
79 static void wxScrollBarCallback(Widget widget
, XtPointer clientData
,
80 XmScaleCallbackStruct
*cbs
);
81 static void wxPanelItemEventHandler(Widget wid
,
82 XtPointer client_data
,
84 Boolean
*continueToDispatch
);
89 // Helper function for 16-bit fonts
90 static int str16len(const char *s
)
94 while (s
[0] && s
[1]) {
104 // ----------------------------------------------------------------------------
106 // ----------------------------------------------------------------------------
108 #define event_left_is_down(x) ((x)->xbutton.state & Button1Mask)
109 #define event_middle_is_down(x) ((x)->xbutton.state & Button2Mask)
110 #define event_right_is_down(x) ((x)->xbutton.state & Button3Mask)
112 // ----------------------------------------------------------------------------
114 // ----------------------------------------------------------------------------
116 #if !USE_SHARED_LIBRARY
117 IMPLEMENT_DYNAMIC_CLASS(wxWindow
, wxEvtHandler
)
119 BEGIN_EVENT_TABLE(wxWindow
, wxEvtHandler
)
120 EVT_SYS_COLOUR_CHANGED(wxWindow::OnSysColourChanged
)
121 EVT_IDLE(wxWindow::OnIdle
)
123 #endif // USE_SHARED_LIBRARY
125 // ============================================================================
127 // ============================================================================
129 // ----------------------------------------------------------------------------
131 // ----------------------------------------------------------------------------
133 void wxWindow::UnmanageAndDestroy(WXWidget widget
)
135 Widget w
= (Widget
)widget
;
143 bool wxWindow::MapOrUnmap(WXWidget widget
, bool map
)
145 Widget w
= (Widget
)widget
;
157 // ----------------------------------------------------------------------------
159 // ----------------------------------------------------------------------------
161 void wxWindow::Init()
163 // generic initializations first
167 m_needsRefresh
= TRUE
;
168 m_mainWidget
= (WXWidget
) 0;
172 m_button3Pressed
= FALSE
;
174 m_winCaptured
= FALSE
;
182 m_drawingArea
= (WXWidget
) 0;
190 m_backingPixmap
= (WXPixmap
) 0;
199 m_canAddEventHandler
= FALSE
;
202 // real construction (Init() must have been called before!)
203 bool wxWindow::Create(wxWindow
*parent
, wxWindowID id
,
207 const wxString
& name
)
209 wxCHECK_MSG( parent
, FALSE
, "can't create wxWindow without parent" );
211 CreateBase(parent
, id
, pos
, size
, style
, name
);
213 parent
->AddChild(this);
215 m_backgroundColour
= wxSystemSettings::GetSystemColour(wxSYS_COLOUR_3DFACE
);
216 m_foregroundColour
= *wxBLACK
;
218 //// TODO: we should probably optimize by only creating a
219 //// a drawing area if we have one or more scrollbars (wxVSCROLL/wxHSCROLL).
220 //// But for now, let's simplify things by always creating the
221 //// drawing area, since otherwise the translations are different.
223 // New translations for getting mouse motion feedback
224 static const String translations
=
225 "<Btn1Motion>: wxCanvasMotionEvent() DrawingAreaInput() ManagerGadgetButtonMotion()\n\
226 <Btn2Motion>: wxCanvasMotionEvent() DrawingAreaInput() ManagerGadgetButtonMotion()\n\
227 <Btn3Motion>: wxCanvasMotionEvent() DrawingAreaInput() ManagerGadgetButtonMotion()\n\
228 <BtnMotion>: wxCanvasMotionEvent() DrawingAreaInput() ManagerGadgetButtonMotion()\n\
229 <Btn1Down>: DrawingAreaInput() ManagerGadgetArm()\n\
230 <Btn2Down>: DrawingAreaInput() ManagerGadgetArm()\n\
231 <Btn3Down>: DrawingAreaInput() ManagerGadgetArm()\n\
232 <Btn1Up>: DrawingAreaInput() ManagerGadgetActivate()\n\
233 <Btn2Up>: DrawingAreaInput() ManagerGadgetActivate()\n\
234 <Btn3Up>: DrawingAreaInput() ManagerGadgetActivate()\n\
235 <Motion>: wxCanvasMotionEvent() DrawingAreaInput()\n\
236 <EnterWindow>: wxCanvasMotionEvent() DrawingAreaInput()\n\
237 <LeaveWindow>: wxCanvasMotionEvent() DrawingAreaInput()\n\
238 <Key>: DrawingAreaInput()";
240 XtActionsRec actions
[1];
241 actions
[0].string
= "wxCanvasMotionEvent";
242 actions
[0].proc
= (XtActionProc
) wxCanvasMotionEvent
;
243 XtAppAddActions ((XtAppContext
) wxTheApp
->GetAppContext(), actions
, 1);
245 Widget parentWidget
= (Widget
) parent
->GetClientWidget();
246 if (style
& wxBORDER
)
248 m_borderWidget
= (WXWidget
)XtVaCreateManagedWidget
251 xmFrameWidgetClass
, parentWidget
,
252 XmNshadowType
, XmSHADOW_IN
,
257 m_scrolledWindow
= (WXWidget
)XtVaCreateManagedWidget
260 xmScrolledWindowWidgetClass
,
261 m_borderWidget
? (Widget
) m_borderWidget
263 XmNresizePolicy
, XmRESIZE_NONE
,
265 XmNscrollingPolicy
, XmAPPLICATION_DEFINED
,
266 //XmNscrollBarDisplayPolicy, XmAS_NEEDED,
270 XtTranslations ptr
= XtParseTranslationTable(translations
);
271 m_drawingArea
= (WXWidget
)XtVaCreateWidget
274 xmDrawingAreaWidgetClass
, (Widget
) m_scrolledWindow
,
275 XmNunitType
, XmPIXELS
,
276 // XmNresizePolicy, XmRESIZE_ANY,
277 XmNresizePolicy
, XmRESIZE_NONE
,
280 XmNtranslations
, ptr
,
283 XtFree((char *) ptr
);
286 if (GetWindowStyleFlag() & wxOVERRIDE_KEY_TRANSLATIONS
)
288 ptr
= XtParseTranslationTable ("<Key>: DrawingAreaInput()");
289 XtOverrideTranslations ((Widget
) m_drawingArea
, ptr
);
290 XtFree ((char *) ptr
);
294 wxAddWindowToTable((Widget
) m_drawingArea
, this);
295 wxAddWindowToTable((Widget
) m_scrolledWindow
, this);
297 // This order is very important in Motif 1.2.1
298 XtRealizeWidget ((Widget
) m_scrolledWindow
);
299 XtRealizeWidget ((Widget
) m_drawingArea
);
300 XtManageChild ((Widget
) m_drawingArea
);
302 ptr
= XtParseTranslationTable("<Configure>: resize()");
303 XtOverrideTranslations((Widget
) m_drawingArea
, ptr
);
304 XtFree ((char *) ptr
);
306 XtAddCallback ((Widget
) m_drawingArea
, XmNexposeCallback
, (XtCallbackProc
) wxCanvasRepaintProc
, (XtPointer
) this);
307 XtAddCallback ((Widget
) m_drawingArea
, XmNinputCallback
, (XtCallbackProc
) wxCanvasInputEvent
, (XtPointer
) this);
311 display
= XtDisplay (scrolledWindow
);
312 xwindow
= XtWindow (drawingArea
);
316 (Widget
)m_drawingArea
,
317 PointerMotionHintMask
| EnterWindowMask
|
318 LeaveWindowMask
| FocusChangeMask
,
320 (XtEventHandler
) wxCanvasEnterLeave
,
324 // Scrolled widget needs to have its colour changed or we get a little blue
325 // square where the scrollbars abutt
326 wxColour backgroundColour
= wxSystemSettings::GetSystemColour(wxSYS_COLOUR_3DFACE
);
327 DoChangeBackgroundColour(m_scrolledWindow
, backgroundColour
, TRUE
);
328 DoChangeBackgroundColour(m_drawingArea
, backgroundColour
, TRUE
);
330 XmScrolledWindowSetAreas(
331 (Widget
)m_scrolledWindow
,
332 (Widget
) 0, (Widget
) 0,
333 (Widget
) m_drawingArea
);
337 XtRealizeWidget ((Widget
) m_hScrollBar
);
339 XtRealizeWidget ((Widget
) m_vScrollBar
);
342 // Without this, the cursor may not be restored properly (e.g. in splitter
344 SetCursor(*wxSTANDARD_CURSOR
);
345 SetFont(wxSystemSettings::GetSystemFont(wxSYS_DEFAULT_GUI_FONT
));
346 SetSize(pos
.x
, pos
.y
, size
.x
, size
.y
);
352 wxWindow::~wxWindow()
354 // Motif-specific actions first
355 WXWidget wMain
= GetMainWidget();
358 // Removes event handlers
364 // If m_drawingArea, we're a fully-fledged window with drawing area,
365 // scrollbars etc. (what wxCanvas used to be)
368 // Destroy children before destroying self
372 XFreePixmap (XtDisplay ((Widget
) GetMainWidget()), (Pixmap
) m_backingPixmap
);
374 Widget w
= (Widget
) m_drawingArea
;
375 wxDeleteWindowFromTable(w
);
382 m_mainWidget
= (WXWidget
) 0;
384 // Only if we're _really_ a canvas (not a dialog box/panel)
385 if (m_scrolledWindow
)
387 wxDeleteWindowFromTable((Widget
) m_scrolledWindow
);
390 UnmanageAndDestroy(m_hScrollBar
);
391 UnmanageAndDestroy(m_vScrollBar
);
392 UnmanageAndDestroy(m_scrolledWindow
);
396 XtDestroyWidget ((Widget
) m_borderWidget
);
397 m_borderWidget
= (WXWidget
) 0;
401 // Destroy the window
404 // If this line (XtDestroyWidget) causes a crash, you may comment it out.
405 // Child widgets will get destroyed automatically when a frame
406 // or dialog is destroyed, but before that you may get some memory
407 // leaks and potential layout problems if you delete and then add
409 XtDestroyWidget((Widget
) GetMainWidget());
410 SetMainWidget((WXWidget
) NULL
);
414 // ----------------------------------------------------------------------------
415 // scrollbar management
416 // ----------------------------------------------------------------------------
419 void wxWindow::CreateScrollbar(int orientation
)
421 wxCHECK_RET( m_drawingArea
, "this window can't have scrollbars" );
423 XtVaSetValues((Widget
) m_scrolledWindow
, XmNresizePolicy
, XmRESIZE_NONE
, NULL
);
425 // Add scrollbars if required
426 if (orientation
== wxHORIZONTAL
)
428 Widget hScrollBar
= XtVaCreateManagedWidget ("hsb",
429 xmScrollBarWidgetClass
, (Widget
) m_scrolledWindow
,
430 XmNorientation
, XmHORIZONTAL
,
432 // XtAddCallback (hScrollBar, XmNvalueChangedCallback, (XtCallbackProc) wxScrollBarCallback, (XtPointer) XmHORIZONTAL);
433 XtAddCallback (hScrollBar
, XmNdragCallback
, (XtCallbackProc
) wxScrollBarCallback
, (XtPointer
) XmHORIZONTAL
);
434 XtAddCallback (hScrollBar
, XmNincrementCallback
, (XtCallbackProc
) wxScrollBarCallback
, (XtPointer
) XmHORIZONTAL
);
435 XtAddCallback (hScrollBar
, XmNdecrementCallback
, (XtCallbackProc
) wxScrollBarCallback
, (XtPointer
) XmHORIZONTAL
);
436 XtAddCallback (hScrollBar
, XmNpageIncrementCallback
, (XtCallbackProc
) wxScrollBarCallback
, (XtPointer
) XmHORIZONTAL
);
437 XtAddCallback (hScrollBar
, XmNpageDecrementCallback
, (XtCallbackProc
) wxScrollBarCallback
, (XtPointer
) XmHORIZONTAL
);
438 XtAddCallback (hScrollBar
, XmNtoTopCallback
, (XtCallbackProc
) wxScrollBarCallback
, (XtPointer
) XmHORIZONTAL
);
439 XtAddCallback (hScrollBar
, XmNtoBottomCallback
, (XtCallbackProc
) wxScrollBarCallback
, (XtPointer
) XmHORIZONTAL
);
441 XtVaSetValues (hScrollBar
,
446 m_hScrollBar
= (WXWidget
) hScrollBar
;
448 wxColour backgroundColour
= wxSystemSettings::GetSystemColour(wxSYS_COLOUR_3DFACE
);
449 DoChangeBackgroundColour(m_hScrollBar
, backgroundColour
, TRUE
);
451 XtRealizeWidget(hScrollBar
);
453 XtVaSetValues((Widget
) m_scrolledWindow
,
454 XmNhorizontalScrollBar
, (Widget
) m_hScrollBar
,
460 if (orientation
== wxVERTICAL
)
462 Widget vScrollBar
= XtVaCreateManagedWidget ("vsb",
463 xmScrollBarWidgetClass
, (Widget
) m_scrolledWindow
,
464 XmNorientation
, XmVERTICAL
,
466 // XtAddCallback (vScrollBar, XmNvalueChangedCallback, (XtCallbackProc) wxScrollBarCallback, (XtPointer) XmVERTICAL);
467 XtAddCallback (vScrollBar
, XmNdragCallback
, (XtCallbackProc
) wxScrollBarCallback
, (XtPointer
) XmVERTICAL
);
468 XtAddCallback (vScrollBar
, XmNincrementCallback
, (XtCallbackProc
) wxScrollBarCallback
, (XtPointer
) XmVERTICAL
);
469 XtAddCallback (vScrollBar
, XmNdecrementCallback
, (XtCallbackProc
) wxScrollBarCallback
, (XtPointer
) XmVERTICAL
);
470 XtAddCallback (vScrollBar
, XmNpageIncrementCallback
, (XtCallbackProc
) wxScrollBarCallback
, (XtPointer
) XmVERTICAL
);
471 XtAddCallback (vScrollBar
, XmNpageDecrementCallback
, (XtCallbackProc
) wxScrollBarCallback
, (XtPointer
) XmVERTICAL
);
472 XtAddCallback (vScrollBar
, XmNtoTopCallback
, (XtCallbackProc
) wxScrollBarCallback
, (XtPointer
) XmVERTICAL
);
473 XtAddCallback (vScrollBar
, XmNtoBottomCallback
, (XtCallbackProc
) wxScrollBarCallback
, (XtPointer
) XmVERTICAL
);
475 XtVaSetValues (vScrollBar
,
480 m_vScrollBar
= (WXWidget
) vScrollBar
;
481 wxColour backgroundColour
= wxSystemSettings::GetSystemColour(wxSYS_COLOUR_3DFACE
);
482 DoChangeBackgroundColour(m_vScrollBar
, backgroundColour
, TRUE
);
484 XtRealizeWidget(vScrollBar
);
486 XtVaSetValues((Widget
) m_scrolledWindow
,
487 XmNverticalScrollBar
, (Widget
) m_vScrollBar
,
493 XtVaSetValues((Widget
) m_scrolledWindow
, XmNresizePolicy
, XmRESIZE_ANY
, NULL
);
496 void wxWindow::DestroyScrollbar(int orientation
)
498 wxCHECK_RET( m_drawingArea
, "this window can't have scrollbars" );
500 XtVaSetValues((Widget
) m_scrolledWindow
, XmNresizePolicy
, XmRESIZE_NONE
, NULL
);
501 // Add scrollbars if required
502 if (orientation
== wxHORIZONTAL
)
506 XtDestroyWidget((Widget
) m_hScrollBar
);
508 m_hScrollBar
= (WXWidget
) 0;
511 XtVaSetValues((Widget
) m_scrolledWindow
,
512 XmNhorizontalScrollBar
, (Widget
) 0,
517 if (orientation
== wxVERTICAL
)
521 XtDestroyWidget((Widget
) m_vScrollBar
);
523 m_vScrollBar
= (WXWidget
) 0;
526 XtVaSetValues((Widget
) m_scrolledWindow
,
527 XmNverticalScrollBar
, (Widget
) 0,
531 XtVaSetValues((Widget
) m_scrolledWindow
, XmNresizePolicy
, XmRESIZE_ANY
, NULL
);
534 // ---------------------------------------------------------------------------
536 // ---------------------------------------------------------------------------
538 void wxWindow::SetFocus()
540 Widget wMain
= (Widget
) GetMainWidget();
541 XmProcessTraversal(wMain
, XmTRAVERSE_CURRENT
);
542 XmProcessTraversal((Widget
) GetMainWidget(), XmTRAVERSE_CURRENT
);
545 // Get the window with the focus
546 wxWindow
*wxWindow::FindFocus()
549 // (1) Can there be multiple focussed widgets in an application?
550 // In which case we need to find the top-level window that's
552 // (2) The widget with the focus may not be in the widget table
553 // depending on which widgets I put in the table
554 wxWindow
*winFocus
= (wxWindow
*)NULL
;
555 for ( wxWindowList::Node
*node
= wxTopLevelWindows
.GetFirst();
557 node
= node
->GetNext() )
559 wxWindow
*win
= node
->GetData();
561 Widget w
= XmGetFocusWidget ((Widget
) win
->GetTopWidget());
563 if (w
!= (Widget
) NULL
)
565 winFocus
= wxGetWindowFromTable(w
);
574 void wxWindow::Enable(bool enable
)
576 if ( !wxWindowBase::Enable(enable
) )
579 Widget wMain
= GetMainWidget();
582 XtSetSensitive(wMain
, enable
);
583 XmUpdateDisplay(wMain
);
589 bool wxWindow::Show(bool show
)
591 if ( !wxWindowBase::Show(show
) )
594 if (m_borderWidget
|| m_scrolledWindow
)
596 MapOrUnmap(m_drawingArea
, show
);
597 MapOrUnmap(m_borderWidget
? m_borderWidget
: m_scrolledWindow
, show
);
601 if ( !MapOrUnmap(GetTopWidget(), show
) )
602 MapOrUnmap(GetMainWidget(), show
);
606 Window xwin
= (Window
) GetXWindow();
607 Display
*xdisp
= (Display
*) GetXDisplay();
609 XMapWindow(xdisp
, xwin
);
611 XUnmapWindow(xdisp
, xwin
);
617 // Raise the window to the top of the Z order
618 void wxWindow::Raise()
620 Widget wTop
= (Widget
) GetTopWidget();
621 Window window
= XtWindow(wTop
);
622 XRaiseWindow(XtDisplay(wTop
), window
);
625 // Lower the window to the bottom of the Z order
626 void wxWindow::Lower()
628 Widget wTop
= (Widget
) GetTopWidget();
629 Window window
= XtWindow(wTop
);
630 XLowerWindow(XtDisplay(wTop
), window
);
633 void wxWindow::SetTitle( const wxString
& title
)
635 SetWindowText(GetHwnd(), title
.c_str());
638 wxString
wxWindow::GetTitle() const
640 return wxGetWindowText(GetHWND());
643 void wxWindow::CaptureMouse()
648 Widget wMain
= GetMainWidget();
650 XtAddGrab(wMain
, TRUE
, FALSE
);
652 m_winCaptured
= TRUE
;
655 void wxWindow::ReleaseMouse()
657 if ( !m_winCaptured
)
660 Widget wMain
= GetMainWidget();
664 m_winCaptured
= FALSE
;
667 bool wxWindow::SetFont(const wxFont
& font
)
669 if ( !wxWindowBase::SetFont(font
) )
680 bool wxWindow::SetCursor(const wxCursor
& cursor
)
682 if ( !wxWindowBase::SetCursor(cursor
) )
688 wxASSERT_MSG( m_cursor
.Ok(),
689 _T("cursor must be valid after call to the base version"));
691 WXDisplay
*dpy
= GetXDisplay();
692 WXCursor x_cursor
= m_cursor
.GetXCursor(dpy
);
694 Widget w
= (Widget
) GetMainWidget();
695 Window win
= XtWindow(w
);
696 XDefineCursor((Display
*) dpy
, win
, (Cursor
) x_cursor
);
699 // Coordinates relative to the window
700 void wxWindow::WarpPointer (int x
, int y
)
702 Widget wClient
= (Widget
)GetClientWidget();
704 XWarpPointer(XtDisplay(wClient
), None
, XtWindow(wClient
), 0, 0, 0, 0, x
, y
);
707 // ---------------------------------------------------------------------------
709 // ---------------------------------------------------------------------------
711 int wxWindow::GetScrollPos(int orient
) const
713 if (orient
== wxHORIZONTAL
)
719 Widget scrollBar
= (Widget
) ((orient
== wxHORIZONTAL
) ? m_hScrollBar
: m_vScrollBar
);
723 XtVaGetValues(scrollBar
, XmNvalue
, &pos
, NULL
);
731 // This now returns the whole range, not just the number of positions that we
733 int wxWindow::GetScrollRange(int orient
) const
735 Widget scrollBar
= (Widget
)GetScrollbar(orient
);
736 wxCHECK_MSG( scrollBar
, 0, "no such scrollbar" );
739 XtVaGetValues(scrollBar
, XmNmaximum
, &range
, NULL
);
743 int wxWindow::GetScrollThumb(int orient
) const
745 Widget scrollBar
= (Widget
)GetScrollbar(orient
);
746 wxCHECK_MSG( scrollBar
, 0, "no such scrollbar" );
749 XtVaGetValues(scrollBar
, XmNsliderSize
, &thumb
, NULL
);
753 void wxWindow::SetScrollPos(int orient
, int pos
, bool WXUNUSED(refresh
))
755 Widget scrollBar
= (Widget
)GetScrollbar(orient
);
759 XtVaSetValues (scrollBar
, XmNvalue
, pos
, NULL
);
762 SetInternalScrollPos(orient
, pos
);
765 // New function that will replace some of the above.
766 void wxWindow::SetScrollbar(int orient
, int pos
, int thumbVisible
,
767 int range
, bool WXUNUSED(refresh
))
770 GetSize(& oldW
, & oldH
);
774 if (thumbVisible
== 0)
777 if (thumbVisible
> range
)
778 thumbVisible
= range
;
780 // Save the old state to see if it changed
781 WXWidget oldScrollBar
= GetScrollbar(orient
);
783 if (orient
== wxHORIZONTAL
)
785 if (thumbVisible
== range
)
788 DestroyScrollbar(wxHORIZONTAL
);
793 CreateScrollbar(wxHORIZONTAL
);
796 if (orient
== wxVERTICAL
)
798 if (thumbVisible
== range
)
801 DestroyScrollbar(wxVERTICAL
);
806 CreateScrollbar(wxVERTICAL
);
809 WXWidget newScrollBar
= GetScrollbar(orient
);
811 if (oldScrollBar
!= newScrollBar
)
813 // This is important! Without it, scrollbars misbehave badly.
814 XtUnrealizeWidget((Widget
) m_scrolledWindow
);
815 XmScrolledWindowSetAreas ((Widget
) m_scrolledWindow
, (Widget
) m_hScrollBar
, (Widget
) m_vScrollBar
, (Widget
) m_drawingArea
);
816 XtRealizeWidget((Widget
) m_scrolledWindow
);
817 XtManageChild((Widget
) m_scrolledWindow
);
822 XtVaSetValues((Widget
) newScrollBar
,
826 XmNsliderSize
, thumbVisible
,
830 SetInternalScrollPos(orient
, pos
);
833 GetSize(& newW
, & newH
);
835 // Adjusting scrollbars can resize the canvas accidentally
836 if (newW
!= oldW
|| newH
!= oldH
)
837 SetSize(-1, -1, oldW
, oldH
);
840 // Does a physical scroll
841 void wxWindow::ScrollWindow(int dx
, int dy
, const wxRect
*rect
)
846 // Use specified rectangle
847 x
= rect
->x
; y
= rect
->y
; w
= rect
->width
; h
= rect
->height
;
851 // Use whole client area
853 GetClientSize(& w
, & h
);
856 int x1
= (dx
>= 0) ? x
: x
- dx
;
857 int y1
= (dy
>= 0) ? y
: y
- dy
;
858 int w1
= w
- abs(dx
);
859 int h1
= h
- abs(dy
);
860 int x2
= (dx
>= 0) ? x
+ dx
: x
;
861 int y2
= (dy
>= 0) ? y
+ dy
: y
;
865 dc
.SetLogicalFunction (wxCOPY
);
867 Widget widget
= (Widget
) GetMainWidget();
868 Window window
= XtWindow(widget
);
869 Display
* display
= XtDisplay(widget
);
871 XCopyArea(display
, window
, window
, (GC
) dc
.GetGC(),
872 x1
, y1
, w1
, h1
, x2
, y2
);
874 dc
.SetAutoSetting(TRUE
);
875 wxBrush
brush(GetBackgroundColour(), wxSOLID
);
876 dc
.SetBrush(brush
); // FIXME: needed?
878 // We'll add rectangles to the list of update rectangles according to which
879 // bits we've exposed.
884 wxRect
*rect
= new wxRect
;
890 XFillRectangle(display
, window
,
891 (GC
) dc
.GetGC(), rect
->x
, rect
->y
, rect
->width
, rect
->height
);
895 rect
->width
= rect
->width
;
896 rect
->height
= rect
->height
;
898 updateRects
.Append((wxObject
*) rect
);
902 wxRect
*rect
= new wxRect
;
904 rect
->x
= x
+ w
+ dx
;
909 XFillRectangle(display
, window
,
910 (GC
) dc
.GetGC(), rect
->x
, rect
->y
, rect
->width
,
915 rect
->width
= rect
->width
;
916 rect
->height
= rect
->height
;
918 updateRects
.Append((wxObject
*) rect
);
922 wxRect
*rect
= new wxRect
;
929 XFillRectangle(display
, window
,
930 (GC
) dc
.GetGC(), rect
->x
, rect
->y
, rect
->width
, rect
->height
);
934 rect
->width
= rect
->width
;
935 rect
->height
= rect
->height
;
937 updateRects
.Append((wxObject
*) rect
);
941 wxRect
*rect
= new wxRect
;
944 rect
->y
= y
+ h
+ dy
;
948 XFillRectangle(display
, window
,
949 (GC
) dc
.GetGC(), rect
->x
, rect
->y
, rect
->width
, rect
->height
);
953 rect
->width
= rect
->width
;
954 rect
->height
= rect
->height
;
956 updateRects
.Append((wxObject
*) rect
);
958 dc
.SetBrush(wxNullBrush
);
960 // Now send expose events
962 wxNode
* node
= updateRects
.First();
965 wxRect
* rect
= (wxRect
*) node
->Data();
969 event
.display
= display
;
970 event
.send_event
= True
;
971 event
.window
= window
;
975 event
.width
= rect
->width
;
976 event
.height
= rect
->height
;
980 XSendEvent(display
, window
, False
, ExposureMask
, (XEvent
*)&event
);
986 // Delete the update rects
987 node
= updateRects
.First();
990 wxRect
* rect
= (wxRect
*) node
->Data();
995 XmUpdateDisplay((Widget
) GetMainWidget());
998 // ---------------------------------------------------------------------------
1000 // ---------------------------------------------------------------------------
1002 #if wxUSE_DRAG_AND_DROP
1004 void wxWindow::SetDropTarget(wxDropTarget
* WXUNUSED(pDropTarget
))
1011 // Old style file-manager drag&drop
1012 void wxWindow::DragAcceptFiles(bool WXUNUSED(accept
))
1017 // ----------------------------------------------------------------------------
1019 // ----------------------------------------------------------------------------
1023 void wxWindow::DoSetToolTip(wxToolTip
* WXUNUSED(tooltip
))
1028 #endif // wxUSE_TOOLTIPS
1030 // ---------------------------------------------------------------------------
1031 // moving and resizing
1032 // ---------------------------------------------------------------------------
1034 bool wxWindow::PreResize()
1040 void wxWindow::GetSize(int *x
, int *y
) const
1044 CanvasGetSize(x
, y
);
1048 Widget widget
= (Widget
) GetTopWidget();
1050 XtVaGetValues(widget
, XmNwidth
, &xx
, XmNheight
, &yy
, NULL
);
1054 void wxWindow::GetPosition(int *x
, int *y
) const
1058 CanvasGetPosition(x
, y
);
1061 Widget widget
= (Widget
) GetTopWidget();
1063 XtVaGetValues(widget
, XmNx
, &xx
, XmNy
, &yy
, NULL
);
1065 // We may be faking the client origin. So a window that's really at (0, 30)
1066 // may appear (to wxWin apps) to be at (0, 0).
1069 wxPoint
pt(GetParent()->GetClientAreaOrigin());
1077 void wxWindow::ScreenToClient(int *x
, int *y
) const
1079 Widget widget
= (Widget
) GetClientWidget();
1080 Display
*display
= XtDisplay((Widget
) GetMainWidget());
1081 Window rootWindow
= RootWindowOfScreen(XtScreen(widget
));
1082 Window thisWindow
= XtWindow(widget
);
1087 XTranslateCoordinates(display
, rootWindow
, thisWindow
, xx
, yy
, x
, y
, &childWindow
);
1090 void wxWindow::ClientToScreen(int *x
, int *y
) const
1092 Widget widget
= (Widget
) GetClientWidget();
1093 Display
*display
= XtDisplay(widget
);
1094 Window rootWindow
= RootWindowOfScreen(XtScreen(widget
));
1095 Window thisWindow
= XtWindow(widget
);
1100 XTranslateCoordinates(display
, thisWindow
, rootWindow
, xx
, yy
, x
, y
, &childWindow
);
1104 // Get size *available for subwindows* i.e. excluding menu bar etc.
1105 void wxWindow::GetClientSize(int *x
, int *y
) const
1107 Widget widget
= (Widget
) GetClientWidget();
1109 XtVaGetValues(widget
, XmNwidth
, &xx
, XmNheight
, &yy
, NULL
);
1113 void wxWindow::DoSetSize(int x
, int y
, int width
, int height
, int sizeFlags
)
1115 // A bit of optimization to help sort out the flickers.
1116 int oldX
, oldY
, oldW
, oldH
;
1117 GetSize(& oldW
, & oldH
);
1118 GetPosition(& oldX
, & oldY
);
1120 bool useOldPos
= FALSE
;
1121 bool useOldSize
= FALSE
;
1123 if ((x
== -1) && (x
== -1) && ((sizeFlags
& wxSIZE_ALLOW_MINUS_ONE
) == 0))
1125 else if (x
== oldX
&& y
== oldY
)
1128 if ((width
== -1) && (height
== -1))
1130 else if (width
== oldW
&& height
== oldH
)
1133 if (!wxNoOptimize::CanOptimize())
1135 useOldSize
= FALSE
; useOldPos
= FALSE
;
1138 if (useOldPos
&& useOldSize
)
1143 CanvasSetSize(x
, y
, width
, height
, sizeFlags
);
1146 Widget widget
= (Widget
) GetTopWidget();
1150 bool managed
= XtIsManaged( widget
);
1152 XtUnmanageChild(widget
);
1154 int xx
= x
; int yy
= y
;
1155 AdjustForParentClientOrigin(xx
, yy
, sizeFlags
);
1159 if (x
> -1 || (sizeFlags
& wxSIZE_ALLOW_MINUS_ONE
))
1160 XtVaSetValues(widget
, XmNx
, xx
, NULL
);
1161 if (y
> -1 || (sizeFlags
& wxSIZE_ALLOW_MINUS_ONE
))
1162 XtVaSetValues(widget
, XmNy
, yy
, NULL
);
1167 XtVaSetValues(widget
, XmNwidth
, width
, NULL
);
1169 XtVaSetValues(widget
, XmNheight
, height
, NULL
);
1173 XtManageChild(widget
);
1175 // How about this bit. Maybe we don't need to generate size events
1176 // all the time -- they'll be generated when the window is sized anyway.
1178 wxSizeEvent
sizeEvent(wxSize(width
, height
), GetId());
1179 sizeEvent
.SetEventObject(this);
1181 GetEventHandler()->ProcessEvent(sizeEvent
);
1185 void wxWindow::DoSetClientSize(int width
, int height
)
1189 CanvasSetClientSize(width
, height
);
1193 Widget widget
= (Widget
) GetTopWidget();
1196 XtVaSetValues(widget
, XmNwidth
, width
, NULL
);
1198 XtVaSetValues(widget
, XmNheight
, height
, NULL
);
1200 wxSizeEvent
sizeEvent(wxSize(width
, height
), GetId());
1201 sizeEvent
.SetEventObject(this);
1203 GetEventHandler()->ProcessEvent(sizeEvent
);
1206 // For implementation purposes - sometimes decorations make the client area
1208 wxPoint
wxWindow::GetClientAreaOrigin() const
1210 return wxPoint(0, 0);
1213 // Makes an adjustment to the window position (for example, a frame that has
1214 // a toolbar that it manages itself).
1215 void wxWindow::AdjustForParentClientOrigin(int& x
, int& y
, int sizeFlags
)
1217 if (((sizeFlags
& wxSIZE_NO_ADJUSTMENTS
) == 0) && GetParent())
1219 wxPoint
pt(GetParent()->GetClientAreaOrigin());
1220 x
+= pt
.x
; y
+= pt
.y
;
1224 void wxWindow::SetSizeHints(int minW
, int minH
, int maxW
, int maxH
, int incW
, int incH
)
1231 wxFrame
*frame
= wxDynamicCast(this, wxFrame
);
1234 // TODO what about dialogs?
1238 Widget widget
= (Widget
) frame
->GetShellWidget();
1241 XtVaSetValues(widget
, XmNminWidth
, minW
, NULL
);
1243 XtVaSetValues(widget
, XmNminHeight
, minH
, NULL
);
1245 XtVaSetValues(widget
, XmNmaxWidth
, maxW
, NULL
);
1247 XtVaSetValues(widget
, XmNmaxHeight
, maxH
, NULL
);
1249 XtVaSetValues(widget
, XmNwidthInc
, incW
, NULL
);
1251 XtVaSetValues(widget
, XmNheightInc
, incH
, NULL
);
1254 // ---------------------------------------------------------------------------
1256 // ---------------------------------------------------------------------------
1258 int wxWindow::GetCharHeight() const
1260 wxCHECK_MSG( m_windowFont
.Ok(), 0, "valid window font needed" );
1262 WXFontStructPtr pFontStruct
= m_windowFont
.GetFontStruct(1.0, GetXDisplay());
1264 int direction
, ascent
, descent
;
1265 XCharStruct overall
;
1266 XTextExtents ((XFontStruct
*) pFontStruct
, "x", 1, &direction
, &ascent
,
1267 &descent
, &overall
);
1269 // return (overall.ascent + overall.descent);
1270 return (ascent
+ descent
);
1273 int wxWindow::GetCharWidth() const
1275 wxCHECK_MSG( m_windowFont
.Ok(), 0, "valid window font needed" );
1277 WXFontStructPtr pFontStruct
= m_windowFont
.GetFontStruct(1.0, GetXDisplay());
1279 int direction
, ascent
, descent
;
1280 XCharStruct overall
;
1281 XTextExtents ((XFontStruct
*) pFontStruct
, "x", 1, &direction
, &ascent
,
1282 &descent
, &overall
);
1284 return overall
.width
;
1287 void wxWindow::GetTextExtent(const wxString
& string
,
1289 int *descent
, int *externalLeading
,
1290 const wxFont
*theFont
) const
1292 wxFont
*fontToUse
= (wxFont
*)theFont
;
1294 fontToUse
= (wxFont
*) & m_windowFont
;
1296 wxCHECK_RET( fontToUse
.Ok(), "valid window font needed" );
1298 WXFontStructPtr pFontStruct
= theFont
->GetFontStruct(1.0, GetXDisplay());
1300 int direction
, ascent
, descent2
;
1301 XCharStruct overall
;
1306 XTextExtents16((XFontStruct
*) pFontStruct
, (XChar2b
*) (char*) (const char*) string
, slen
, &direction
,
1307 &ascent
, &descent2
, &overall
);
1310 XTextExtents((XFontStruct
*) pFontStruct
, string
, slen
,
1311 &direction
, &ascent
, &descent2
, &overall
);
1314 *x
= (overall
.width
);
1316 *y
= (ascent
+ descent2
);
1318 *descent
= descent2
;
1319 if (externalLeading
)
1320 *externalLeading
= 0;
1323 // ----------------------------------------------------------------------------
1325 // ----------------------------------------------------------------------------
1327 void wxWindow::Refresh(bool eraseBack
, const wxRect
*rect
)
1329 m_needsRefresh
= TRUE
;
1330 Display
*display
= XtDisplay((Widget
) GetMainWidget());
1331 Window thisWindow
= XtWindow((Widget
) GetMainWidget());
1333 XExposeEvent dummyEvent
;
1335 GetSize(&width
, &height
);
1337 dummyEvent
.type
= Expose
;
1338 dummyEvent
.display
= display
;
1339 dummyEvent
.send_event
= True
;
1340 dummyEvent
.window
= thisWindow
;
1343 dummyEvent
.x
= rect
->x
;
1344 dummyEvent
.y
= rect
->y
;
1345 dummyEvent
.width
= rect
->width
;
1346 dummyEvent
.height
= rect
->height
;
1352 dummyEvent
.width
= width
;
1353 dummyEvent
.height
= height
;
1355 dummyEvent
.count
= 0;
1359 wxClientDC
dc(this);
1360 wxBrush
backgroundBrush(GetBackgroundColour(), wxSOLID
);
1361 dc
.SetBackground(backgroundBrush
);
1368 XSendEvent(display
, thisWindow
, False
, ExposureMask
, (XEvent
*)&dummyEvent
);
1371 void wxWindow::Clear()
1373 wxClientDC
dc(this);
1374 wxBrush
brush(GetBackgroundColour(), wxSOLID
);
1375 dc
.SetBackground(brush
);
1379 void wxWindow::ClearUpdateRects()
1381 wxNode
* node
= m_updateRects
.First();
1384 wxRect
* rect
= (wxRect
*) node
->Data();
1386 node
= node
->Next();
1388 m_updateRects
.Clear();
1391 void wxWindow::DoPaint()
1393 //TODO : make a temporary gc so we can do the XCopyArea below
1394 if (m_backingPixmap
&& !m_needsRefresh
)
1398 GC tempGC
= (GC
) dc
.GetBackingGC();
1400 Widget widget
= (Widget
) GetMainWidget();
1405 // We have to test whether it's a wxScrolledWindow (hack!) because
1406 // otherwise we don't know how many pixels have been scrolled. We might
1407 // solve this in the future by defining virtual wxWindow functions to get
1408 // the scroll position in pixels. Or, each kind of scrolled window has to
1409 // implement backing stores itself, using generic wxWindows code.
1410 wxScrolledWindow
* scrolledWindow
= wxDynamicCast(this, wxScrolledWindow
);
1411 if ( scrolledWindow
)
1414 scrolledWindow
->CalcScrolledPosition(0, 0, &x
, &y
);
1420 // TODO: This could be optimized further by only copying the areas in the
1421 // current update region.
1423 // Only blit the part visible in the client area. The backing pixmap
1424 // always starts at 0, 0 but we may be looking at only a portion of it.
1425 wxSize clientArea
= GetClientSize();
1426 int toBlitX
= m_pixmapWidth
- scrollPosX
;
1427 int toBlitY
= m_pixmapHeight
- scrollPosY
;
1429 // Copy whichever is samller, the amount of pixmap we have to copy,
1430 // or the size of the client area.
1431 toBlitX
= wxMin(toBlitX
, clientArea
.x
);
1432 toBlitY
= wxMin(toBlitY
, clientArea
.y
);
1434 // Make sure we're not negative
1435 toBlitX
= wxMax(0, toBlitX
);
1436 toBlitY
= wxMax(0, toBlitY
);
1441 (Pixmap
) m_backingPixmap
,
1444 scrollPosX
, scrollPosY
, // Start at the scroll position
1445 toBlitX
, toBlitY
, // How much of the pixmap to copy
1451 // Set an erase event first
1452 wxEraseEvent
eraseEvent(GetId());
1453 eraseEvent
.SetEventObject(this);
1454 GetEventHandler()->ProcessEvent(eraseEvent
);
1456 wxPaintEvent
event(GetId());
1457 event
.SetEventObject(this);
1458 GetEventHandler()->ProcessEvent(event
);
1460 m_needsRefresh
= FALSE
;
1464 // ----------------------------------------------------------------------------
1466 // ----------------------------------------------------------------------------
1468 // Responds to colour changes: passes event on to children.
1469 void wxWindow::OnSysColourChanged(wxSysColourChangedEvent
& event
)
1471 wxWindowList::Node
*node
= GetChildren().GetFirst();
1474 // Only propagate to non-top-level windows
1475 wxWindow
*win
= node
->GetData();
1476 if ( win
->GetParent() )
1478 wxSysColourChangedEvent event2
;
1479 event
.m_eventObject
= win
;
1480 win
->GetEventHandler()->ProcessEvent(event2
);
1483 node
= node
->GetNext();
1487 void wxWindow::OnIdle(wxIdleEvent
& event
)
1489 // This calls the UI-update mechanism (querying windows for
1490 // menu/toolbar/control state information)
1494 // ----------------------------------------------------------------------------
1496 // ----------------------------------------------------------------------------
1498 bool wxWindow::ProcessAccelerator(wxKeyEvent
& event
)
1500 if (!m_acceleratorTable
.Ok())
1503 int count
= m_acceleratorTable
.GetCount();
1504 wxAcceleratorEntry
* entries
= m_acceleratorTable
.GetEntries();
1506 for (i
= 0; i
< count
; i
++)
1508 wxAcceleratorEntry
* entry
= & (entries
[i
]);
1509 if (entry
->MatchesEvent(event
))
1511 // Bingo, we have a match. Now find a control that matches the entry
1514 // Need to go up to the top of the window hierarchy, since it might
1515 // be e.g. a menu item
1516 wxWindow
* parent
= this;
1517 while ( parent
&& !parent
->IsTopLevel() )
1518 parent
= parent
->GetParent();
1523 wxFrame
* frame
= wxDynamicCast(parent
, wxFrame
);
1526 // Try for a menu command
1527 if (frame
->GetMenuBar())
1529 wxMenuItem
* item
= frame
->GetMenuBar()->FindItemForId(entry
->GetCommand());
1532 wxCommandEvent
commandEvent(wxEVT_COMMAND_MENU_SELECTED
, entry
->GetCommand());
1533 commandEvent
.SetEventObject(frame
);
1535 // If ProcessEvent returns TRUE (it was handled), then
1536 // the calling code will skip the event handling.
1537 return frame
->GetEventHandler()->ProcessEvent(commandEvent
);
1542 // Find a child matching the command id
1543 wxWindow
* child
= parent
->FindWindow(entry
->GetCommand());
1549 // Now we process those kinds of windows that we can.
1550 // For now, only buttons.
1551 if ( wxDynamicCast(child
, wxButton
) )
1553 wxCommandEvent
commandEvent (wxEVT_COMMAND_BUTTON_CLICKED
, child
->GetId());
1554 commandEvent
.SetEventObject(child
);
1555 return child
->GetEventHandler()->ProcessEvent(commandEvent
);
1562 // We didn't match the key event against an accelerator.
1566 // ============================================================================
1567 // Motif-specific stuff from here on
1568 // ============================================================================
1570 // ----------------------------------------------------------------------------
1571 // function which maintain the global hash table mapping Widgets to wxWindows
1572 // ----------------------------------------------------------------------------
1574 bool wxAddWindowToTable(Widget w
, wxWindow
*win
)
1576 wxWindow
*oldItem
= NULL
;
1577 if ((oldItem
= (wxWindow
*)gs_wxWidgetHashTable
->Get ((long) w
)))
1579 wxLogDebug("Widget table clash: new widget is %ld, %s",
1580 (long)w
, win
->GetClassInfo()->GetClassName());
1584 gs_wxWidgetHashTable
->Put((long) w
, win
);
1589 wxWindow
*wxGetWindowFromTable(Widget w
)
1591 return (wxWindow
*)gs_wxWidgetHashTable
->Get((long) w
);
1594 void wxDeleteWindowFromTable(Widget w
)
1596 gs_wxWidgetHashTable
->Delete((long)w
);
1599 // ----------------------------------------------------------------------------
1600 // add/remove window from the table
1601 // ----------------------------------------------------------------------------
1603 // Add to hash table, add event handler
1604 bool wxWindow::AttachWidget (wxWindow
* parent
, WXWidget mainWidget
,
1605 WXWidget formWidget
, int x
, int y
, int width
, int height
)
1607 wxAddWindowToTable((Widget
) mainWidget
, this);
1608 if (CanAddEventHandler())
1610 XtAddEventHandler((Widget
) mainWidget
,
1611 ButtonPressMask
| ButtonReleaseMask
| PointerMotionMask
, // | KeyPressMask,
1613 wxPanelItemEventHandler
,
1620 XtOverrideTranslations ((Widget
) mainWidget
,
1621 ptr
= XtParseTranslationTable ("<Configure>: resize()"));
1622 XtFree ((char *) ptr
);
1625 // Some widgets have a parent form widget, e.g. wxRadioBox
1628 if (!wxAddWindowToTable((Widget
) formWidget
, this))
1632 XtOverrideTranslations ((Widget
) formWidget
,
1633 ptr
= XtParseTranslationTable ("<Configure>: resize()"));
1634 XtFree ((char *) ptr
);
1641 SetSize (x
, y
, width
, height
);
1646 // Remove event handler, remove from hash table
1647 bool wxWindow::DetachWidget(WXWidget widget
)
1649 if (CanAddEventHandler())
1651 XtRemoveEventHandler((Widget
) widget
,
1652 ButtonPressMask
| ButtonReleaseMask
| PointerMotionMask
, // | KeyPressMask,
1654 wxPanelItemEventHandler
,
1658 wxDeleteWindowFromTable((Widget
) widget
);
1662 // ----------------------------------------------------------------------------
1663 // Motif-specific accessors
1664 // ----------------------------------------------------------------------------
1666 // Get the underlying X window
1667 WXWindow
wxWindow::GetXWindow() const
1669 Widget wMain
= GetMainWidget();
1671 return (WXWindow
) XtWindow(wMain
);
1673 return (WXWindow
) 0;
1676 // Get the underlying X display
1677 WXDisplay
*wxWindow::GetXDisplay() const
1679 Widget wMain
= GetMainWidget();
1681 return (WXDisplay
*) XtDisplay(wMain
);
1683 return (WXDisplay
*) NULL
;
1686 WXWidget
wxWindow::GetMainWidget() const
1689 return m_drawingArea
;
1691 return m_mainWidget
;
1694 WXWidget
wxWindow::GetClientWidget() const
1696 if (m_drawingArea
!= (WXWidget
) 0)
1697 return m_drawingArea
;
1699 return GetMainWidget();
1702 WXWidget
wxWindow::GetTopWidget() const
1704 return GetMainWidget();
1707 WXWidget
wxWindow::GetLabelWidget() const
1709 return GetMainWidget();
1712 // ----------------------------------------------------------------------------
1714 // ----------------------------------------------------------------------------
1716 // All widgets should have this as their resize proc.
1717 // OnSize sent to wxWindow via client data.
1718 void wxWidgetResizeProc(Widget w
, XConfigureEvent
*event
, String args
[], int *num_args
)
1720 wxWindow
*win
= wxGetWindowFromTable(w
);
1724 if (win
->PreResize())
1727 win
->GetSize(&width
, &height
);
1728 wxSizeEvent
sizeEvent(wxSize(width
, height
), win
->GetId());
1729 sizeEvent
.SetEventObject(win
);
1730 win
->GetEventHandler()->ProcessEvent(sizeEvent
);
1734 static void wxCanvasRepaintProc(Widget drawingArea
,
1735 XtPointer clientData
,
1736 XmDrawingAreaCallbackStruct
* cbs
)
1738 if (!wxGetWindowFromTable(drawingArea
))
1741 XEvent
* event
= cbs
->event
;
1742 wxWindow
* win
= (wxWindow
*) clientData
;
1743 Display
* display
= (Display
*) win
->GetXDisplay();
1745 switch (event
->type
)
1749 wxRect
* rect
= new wxRect(event
->xexpose
.x
, event
->xexpose
.y
,
1750 event
->xexpose
.width
, event
->xexpose
.height
);
1752 win
->m_updateRects
.Append((wxObject
*) rect
);
1754 if (event
-> xexpose
.count
== 0)
1757 wxPaintEvent
event(win
->GetId());
1758 event
.SetEventObject(win
);
1759 win
->GetEventHandler()->ProcessEvent(event
);
1763 win
->ClearUpdateRects();
1770 // Unable to deal with Enter/Leave without a separate EventHandler (Motif 1.1.4)
1771 static void wxCanvasEnterLeave(Widget drawingArea
,
1772 XtPointer clientData
,
1773 XCrossingEvent
* event
)
1775 XmDrawingAreaCallbackStruct cbs
;
1778 ((XCrossingEvent
&) ev
) = *event
;
1780 cbs
.reason
= XmCR_INPUT
;
1783 wxCanvasInputEvent(drawingArea
, (XtPointer
) NULL
, &cbs
);
1786 // Fix to make it work under Motif 1.0 (!)
1787 static void wxCanvasMotionEvent (Widget drawingArea
, XButtonEvent
* event
)
1789 #if XmVersion <= 1000
1790 XmDrawingAreaCallbackStruct cbs
;
1793 ev
= *((XEvent
*) event
);
1794 cbs
.reason
= XmCR_INPUT
;
1797 wxCanvasInputEvent (drawingArea
, (XtPointer
) NULL
, &cbs
);
1798 #endif // XmVersion <= 1000
1801 static void wxCanvasInputEvent(Widget drawingArea
,
1803 XmDrawingAreaCallbackStruct
* cbs
)
1805 wxWindow
*canvas
= wxGetWindowFromTable(drawingArea
);
1811 if (cbs
->reason
!= XmCR_INPUT
)
1814 local_event
= *(cbs
->event
); // We must keep a copy!
1816 switch (local_event
.xany
.type
)
1824 wxEventType eventType
= wxEVT_NULL
;
1826 if (local_event
.xany
.type
== EnterNotify
)
1828 //if (local_event.xcrossing.mode!=NotifyNormal)
1829 // return ; // Ignore grab events
1830 eventType
= wxEVT_ENTER_WINDOW
;
1831 // canvas->GetEventHandler()->OnSetFocus();
1833 else if (local_event
.xany
.type
== LeaveNotify
)
1835 //if (local_event.xcrossing.mode!=NotifyNormal)
1836 // return ; // Ignore grab events
1837 eventType
= wxEVT_LEAVE_WINDOW
;
1838 // canvas->GetEventHandler()->OnKillFocus();
1840 else if (local_event
.xany
.type
== MotionNotify
)
1842 eventType
= wxEVT_MOTION
;
1843 if (local_event
.xmotion
.is_hint
== NotifyHint
)
1846 Display
*dpy
= XtDisplay (drawingArea
);
1848 XQueryPointer (dpy
, XtWindow (drawingArea
),
1850 &local_event
.xmotion
.x_root
,
1851 &local_event
.xmotion
.y_root
,
1852 &local_event
.xmotion
.x
,
1853 &local_event
.xmotion
.y
,
1854 &local_event
.xmotion
.state
);
1861 else if (local_event
.xany
.type
== ButtonPress
)
1863 if (local_event
.xbutton
.button
== Button1
)
1865 eventType
= wxEVT_LEFT_DOWN
;
1866 canvas
->m_button1Pressed
= TRUE
;
1868 else if (local_event
.xbutton
.button
== Button2
)
1870 eventType
= wxEVT_MIDDLE_DOWN
;
1871 canvas
->m_button2Pressed
= TRUE
;
1873 else if (local_event
.xbutton
.button
== Button3
)
1875 eventType
= wxEVT_RIGHT_DOWN
;
1876 canvas
->m_button3Pressed
= TRUE
;
1879 else if (local_event
.xany
.type
== ButtonRelease
)
1881 if (local_event
.xbutton
.button
== Button1
)
1883 eventType
= wxEVT_LEFT_UP
;
1884 canvas
->m_button1Pressed
= FALSE
;
1886 else if (local_event
.xbutton
.button
== Button2
)
1888 eventType
= wxEVT_MIDDLE_UP
;
1889 canvas
->m_button2Pressed
= FALSE
;
1891 else if (local_event
.xbutton
.button
== Button3
)
1893 eventType
= wxEVT_RIGHT_UP
;
1894 canvas
->m_button3Pressed
= FALSE
;
1898 wxMouseEvent
wxevent (eventType
);
1899 wxevent
.m_eventHandle
= (char *) &local_event
;
1901 wxevent
.m_leftDown
= ((eventType
== wxEVT_LEFT_DOWN
)
1902 || (event_left_is_down (&local_event
)
1903 && (eventType
!= wxEVT_LEFT_UP
)));
1904 wxevent
.m_middleDown
= ((eventType
== wxEVT_MIDDLE_DOWN
)
1905 || (event_middle_is_down (&local_event
)
1906 && (eventType
!= wxEVT_MIDDLE_UP
)));
1907 wxevent
.m_rightDown
= ((eventType
== wxEVT_RIGHT_DOWN
)
1908 || (event_right_is_down (&local_event
)
1909 && (eventType
!= wxEVT_RIGHT_UP
)));
1911 wxevent
.m_shiftDown
= local_event
.xbutton
.state
& ShiftMask
;
1912 wxevent
.m_controlDown
= local_event
.xbutton
.state
& ControlMask
;
1913 wxevent
.m_altDown
= local_event
.xbutton
.state
& Mod3Mask
;
1914 wxevent
.m_metaDown
= local_event
.xbutton
.state
& Mod1Mask
;
1915 wxevent
.SetTimestamp(local_event
.xbutton
.time
);
1917 // Now check if we need to translate this event into a double click
1918 if (TRUE
) // canvas->doubleClickAllowed)
1920 if (wxevent
.ButtonDown())
1922 long dclickTime
= XtGetMultiClickTime((Display
*) wxGetDisplay());
1924 // get button and time-stamp
1926 if (wxevent
.LeftDown()) button
= 1;
1927 else if (wxevent
.MiddleDown()) button
= 2;
1928 else if (wxevent
.RightDown()) button
= 3;
1929 long ts
= wxevent
.GetTimestamp();
1930 // check, if single or double click
1931 if (canvas
->m_lastButton
&& canvas
->m_lastButton
==button
&& (ts
- canvas
->m_lastTS
) < dclickTime
)
1934 canvas
->m_lastButton
= 0;
1935 switch ( eventType
)
1937 case wxEVT_LEFT_DOWN
:
1938 wxevent
.SetEventType(wxEVT_LEFT_DCLICK
);
1940 case wxEVT_MIDDLE_DOWN
:
1941 wxevent
.SetEventType(wxEVT_MIDDLE_DCLICK
);
1943 case wxEVT_RIGHT_DOWN
:
1944 wxevent
.SetEventType(wxEVT_RIGHT_DCLICK
);
1954 // not fast enough or different button
1955 canvas
->m_lastTS
= ts
;
1956 canvas
->m_lastButton
= button
;
1961 wxevent
.SetId(canvas
->GetId());
1962 wxevent
.SetEventObject(canvas
);
1963 wxevent
.m_x
= local_event
.xbutton
.x
;
1964 wxevent
.m_y
= local_event
.xbutton
.y
;
1965 canvas
->GetEventHandler()->ProcessEvent (wxevent
);
1967 if (eventType
== wxEVT_ENTER_WINDOW
||
1968 eventType
== wxEVT_LEAVE_WINDOW
||
1969 eventType
== wxEVT_MOTION
1979 XComposeStatus compose
;
1980 (void) XLookupString ((XKeyEvent
*) & local_event
, wxBuffer
, 20, &keySym
, &compose
);
1983 (void) XLookupString ((XKeyEvent
*) & local_event
, wxBuffer
, 20, &keySym
, NULL
);
1984 int id
= wxCharCodeXToWX (keySym
);
1986 wxEventType eventType
= wxEVT_CHAR
;
1988 wxKeyEvent
event (eventType
);
1990 if (local_event
.xkey
.state
& ShiftMask
)
1991 event
.m_shiftDown
= TRUE
;
1992 if (local_event
.xkey
.state
& ControlMask
)
1993 event
.m_controlDown
= TRUE
;
1994 if (local_event
.xkey
.state
& Mod3Mask
)
1995 event
.m_altDown
= TRUE
;
1996 if (local_event
.xkey
.state
& Mod1Mask
)
1997 event
.m_metaDown
= TRUE
;
1998 event
.SetEventObject(canvas
);
1999 event
.m_keyCode
= id
;
2000 event
.SetTimestamp(local_event
.xkey
.time
);
2004 // Implement wxFrame::OnCharHook by checking ancestor.
2005 wxWindow
*parent
= canvas
->GetParent();
2006 while (parent
&& !parent
->IsKindOf(CLASSINFO(wxFrame
)))
2007 parent
= parent
->GetParent();
2011 event
.SetEventType(wxEVT_CHAR_HOOK
);
2012 if (parent
->GetEventHandler()->ProcessEvent(event
))
2016 // For simplicity, OnKeyDown is the same as OnChar
2017 // TODO: filter modifier key presses from OnChar
2018 event
.SetEventType(wxEVT_KEY_DOWN
);
2020 // Only process OnChar if OnKeyDown didn't swallow it
2021 if (!canvas
->GetEventHandler()->ProcessEvent (event
))
2023 event
.SetEventType(wxEVT_CHAR
);
2024 canvas
->GetEventHandler()->ProcessEvent (event
);
2032 (void) XLookupString ((XKeyEvent
*) & local_event
, wxBuffer
, 20, &keySym
, NULL
);
2033 int id
= wxCharCodeXToWX (keySym
);
2035 wxKeyEvent
event (wxEVT_KEY_UP
);
2037 if (local_event
.xkey
.state
& ShiftMask
)
2038 event
.m_shiftDown
= TRUE
;
2039 if (local_event
.xkey
.state
& ControlMask
)
2040 event
.m_controlDown
= TRUE
;
2041 if (local_event
.xkey
.state
& Mod3Mask
)
2042 event
.m_altDown
= TRUE
;
2043 if (local_event
.xkey
.state
& Mod1Mask
)
2044 event
.m_metaDown
= TRUE
;
2045 event
.SetEventObject(canvas
);
2046 event
.m_keyCode
= id
;
2047 event
.SetTimestamp(local_event
.xkey
.time
);
2051 canvas
->GetEventHandler()->ProcessEvent (event
);
2057 if (local_event
.xfocus
.detail
!= NotifyPointer
)
2059 wxFocusEvent
event(wxEVT_SET_FOCUS
, canvas
->GetId());
2060 event
.SetEventObject(canvas
);
2061 canvas
->GetEventHandler()->ProcessEvent(event
);
2067 if (local_event
.xfocus
.detail
!= NotifyPointer
)
2069 wxFocusEvent
event(wxEVT_KILL_FOCUS
, canvas
->GetId());
2070 event
.SetEventObject(canvas
);
2071 canvas
->GetEventHandler()->ProcessEvent(event
);
2080 static void wxPanelItemEventHandler(Widget wid
,
2081 XtPointer client_data
,
2083 Boolean
*continueToDispatch
)
2085 // Widget can be a label or the actual widget.
2087 wxWindow
*window
= wxGetWindowFromTable(drawingArea
);
2090 wxMouseEvent
wxevent(0);
2091 if (wxTranslateMouseEvent(wxevent
, window
, wid
, event
))
2093 window
->GetEventHandler()->ProcessEvent(wxevent
);
2097 // TODO: probably the key to allowing default behaviour to happen. Say we
2098 // set a m_doDefault flag to FALSE at the start of this function. Then in
2099 // e.g. wxWindow::OnMouseEvent we can call Default() which sets this flag to
2100 // TRUE, indicating that default processing can happen. Thus, behaviour can
2101 // appear to be overridden just by adding an event handler and not calling
2102 // wxWindow::OnWhatever. ALSO, maybe we can use this instead of the current
2103 // way of handling drawing area events, to simplify things.
2104 *continueToDispatch
= True
;
2107 static void wxScrollBarCallback(Widget scrollbar
,
2108 XtPointer clientData
,
2109 XmScaleCallbackStruct
*cbs
)
2111 Widget scrolledWindow
= XtParent (scrollbar
);
2112 wxWindow
*win
= wxGetWindowFromTable(scrollbar
);
2113 int orientation
= (int) clientData
;
2115 wxEventType eventType
= wxEVT_NULL
;
2116 switch (cbs
->reason
)
2118 case XmCR_INCREMENT
:
2120 eventType
= wxEVT_SCROLL_LINEDOWN
;
2123 case XmCR_DECREMENT
:
2125 eventType
= wxEVT_SCROLL_LINEUP
;
2130 eventType
= wxEVT_SCROLL_THUMBTRACK
;
2133 case XmCR_VALUE_CHANGED
:
2135 // TODO: Should this be intercepted too, or will it cause
2136 // duplicate events?
2137 eventType
= wxEVT_SCROLL_THUMBTRACK
;
2140 case XmCR_PAGE_INCREMENT
:
2142 eventType
= wxEVT_SCROLL_PAGEDOWN
;
2145 case XmCR_PAGE_DECREMENT
:
2147 eventType
= wxEVT_SCROLL_PAGEUP
;
2152 eventType
= wxEVT_SCROLL_TOP
;
2155 case XmCR_TO_BOTTOM
:
2157 eventType
= wxEVT_SCROLL_BOTTOM
;
2162 // Should never get here
2163 wxFAIL_MSG("Unknown scroll event.");
2168 wxScrollEvent
event(eventType
, win
->GetId());
2169 event
.SetEventObject(win
);
2170 event
.SetPosition(cbs
->value
);
2171 event
.SetOrientation( (orientation
== XmHORIZONTAL
) ? wxHORIZONTAL
: wxVERTICAL
);
2173 win
->GetEventHandler()->ProcessEvent(event
);
2176 // For repainting arbitrary windows
2177 void wxUniversalRepaintProc(Widget w
, XtPointer
WXUNUSED(c_data
), XEvent
*event
, char *)
2182 wxWindow
* win
= wxGetWindowFromTable(w
);
2186 switch(event
-> type
)
2190 window
= (Window
) win
-> GetXWindow();
2191 display
= (Display
*) win
-> GetXDisplay();
2193 wxRect
* rect
= new wxRect(event
->xexpose
.x
, event
->xexpose
.y
,
2194 event
->xexpose
.width
, event
->xexpose
.height
);
2195 win
->m_updateRects
.Append((wxObject
*) rect
);
2197 if (event
-> xexpose
.count
== 0)
2201 win
->ClearUpdateRects();
2208 // ----------------------------------------------------------------------------
2209 // CanvaseXXXSize() functions
2210 // ----------------------------------------------------------------------------
2212 // SetSize, but as per old wxCanvas (with drawing widget etc.)
2213 void wxWindow::CanvasSetSize (int x
, int y
, int w
, int h
, int sizeFlags
)
2215 // A bit of optimization to help sort out the flickers.
2216 int oldX
, oldY
, oldW
, oldH
;
2217 GetSize(& oldW
, & oldH
);
2218 GetPosition(& oldX
, & oldY
);
2220 bool useOldPos
= FALSE
;
2221 bool useOldSize
= FALSE
;
2223 if ((x
== -1) && (x
== -1) && ((sizeFlags
& wxSIZE_ALLOW_MINUS_ONE
) == 0))
2225 else if (x
== oldX
&& y
== oldY
)
2228 if ((w
== -1) && (h
== -1))
2230 else if (w
== oldW
&& h
== oldH
)
2233 if (!wxNoOptimize::CanOptimize())
2235 useOldSize
= FALSE
; useOldPos
= FALSE
;
2238 if (useOldPos
&& useOldSize
)
2241 Widget drawingArea
= (Widget
) m_drawingArea
;
2242 bool managed
= XtIsManaged(m_borderWidget
? (Widget
) m_borderWidget
: (Widget
) m_scrolledWindow
);
2245 XtUnmanageChild (m_borderWidget
? (Widget
) m_borderWidget
: (Widget
) m_scrolledWindow
);
2246 XtVaSetValues((Widget
) m_drawingArea
, XmNresizePolicy
, XmRESIZE_ANY
, NULL
);
2248 int xx
= x
; int yy
= y
;
2249 AdjustForParentClientOrigin(xx
, yy
, sizeFlags
);
2253 if (x
> -1 || (sizeFlags
& wxSIZE_ALLOW_MINUS_ONE
))
2255 XtVaSetValues (m_borderWidget
? (Widget
) m_borderWidget
: (Widget
) m_scrolledWindow
,
2259 if (y
> -1 || (sizeFlags
& wxSIZE_ALLOW_MINUS_ONE
))
2261 XtVaSetValues (m_borderWidget
? (Widget
) m_borderWidget
: (Widget
) m_scrolledWindow
,
2273 XtVaSetValues ((Widget
) m_borderWidget
, XmNwidth
, w
, NULL
);
2274 short thick
, margin
;
2275 XtVaGetValues ((Widget
) m_borderWidget
,
2276 XmNshadowThickness
, &thick
,
2277 XmNmarginWidth
, &margin
,
2279 w
-= 2 * (thick
+ margin
);
2282 XtVaSetValues ((Widget
) m_scrolledWindow
, XmNwidth
, w
, NULL
);
2286 XtVaGetValues ((Widget
) m_scrolledWindow
,
2287 XmNspacing
, &spacing
,
2288 XmNverticalScrollBar
, &sbar
,
2292 XtVaGetValues (sbar
, XmNwidth
, &wsbar
, NULL
);
2296 w
-= (spacing
+ wsbar
);
2298 // XtVaSetValues ((Widget) m_drawingArea, XmNwidth, w, NULL);
2304 XtVaSetValues ((Widget
) m_borderWidget
, XmNheight
, h
, NULL
);
2305 short thick
, margin
;
2306 XtVaGetValues ((Widget
) m_borderWidget
,
2307 XmNshadowThickness
, &thick
,
2308 XmNmarginHeight
, &margin
,
2310 h
-= 2 * (thick
+ margin
);
2313 XtVaSetValues ((Widget
) m_scrolledWindow
, XmNheight
, h
, NULL
);
2317 XtVaGetValues ((Widget
) m_scrolledWindow
,
2318 XmNspacing
, &spacing
,
2319 XmNhorizontalScrollBar
, &sbar
,
2323 XtVaGetValues (sbar
, XmNheight
, &wsbar
, NULL
);
2327 h
-= (spacing
+ wsbar
);
2329 // XtVaSetValues ((Widget) m_drawingArea, XmNheight, h, NULL);
2335 XtManageChild (m_borderWidget
? (Widget
) m_borderWidget
: (Widget
) m_scrolledWindow
);
2336 XtVaSetValues((Widget
) m_drawingArea
, XmNresizePolicy
, XmRESIZE_NONE
, NULL
);
2340 GetClientSize (&ww
, &hh
);
2341 wxSizeEvent
sizeEvent(wxSize(ww
, hh
), GetId());
2342 sizeEvent
.SetEventObject(this);
2344 GetEventHandler()->ProcessEvent(sizeEvent
);
2348 void wxWindow::CanvasSetClientSize (int w
, int h
)
2350 Widget drawingArea
= (Widget
) m_drawingArea
;
2352 XtVaSetValues((Widget
) m_drawingArea
, XmNresizePolicy
, XmRESIZE_ANY
, NULL
);
2355 XtVaSetValues ((Widget
) m_drawingArea
, XmNwidth
, w
, NULL
);
2357 XtVaSetValues ((Widget
) m_drawingArea
, XmNheight
, h
, NULL
);
2360 // TODO: is this necessary?
2361 allowRepainting
= FALSE
;
2363 XSync (XtDisplay (drawingArea
), FALSE
);
2365 while (XtAppPending (wxTheApp
->appContext
))
2367 XFlush (XtDisplay (drawingArea
));
2368 XtAppNextEvent (wxTheApp
->appContext
, &event
);
2369 XtDispatchEvent (&event
);
2373 XtVaSetValues((Widget
) m_drawingArea
, XmNresizePolicy
, XmRESIZE_NONE
, NULL
);
2376 allowRepainting
= TRUE
;
2379 wxSizeEvent
sizeEvent(wxSize(w
, h
), GetId());
2380 sizeEvent
.SetEventObject(this);
2382 GetEventHandler()->ProcessEvent(sizeEvent
);
2386 void wxWindow::CanvasGetClientSize (int *w
, int *h
) const
2388 // Must return the same thing that was set via SetClientSize
2390 XtVaGetValues ((Widget
) m_drawingArea
, XmNwidth
, &xx
, XmNheight
, &yy
, NULL
);
2395 void wxWindow::CanvasGetSize (int *w
, int *h
) const
2398 if ((Widget
) m_borderWidget
)
2399 XtVaGetValues ((Widget
) m_borderWidget
, XmNwidth
, &xx
, XmNheight
, &yy
, NULL
);
2400 else if ((Widget
) m_scrolledWindow
)
2401 XtVaGetValues ((Widget
) m_scrolledWindow
, XmNwidth
, &xx
, XmNheight
, &yy
, NULL
);
2403 XtVaGetValues ((Widget
) m_drawingArea
, XmNwidth
, &xx
, XmNheight
, &yy
, NULL
);
2409 void wxWindow::CanvasGetPosition (int *x
, int *y
) const
2412 XtVaGetValues (m_borderWidget
? (Widget
) m_borderWidget
: (Widget
) m_scrolledWindow
, XmNx
, &xx
, XmNy
, &yy
, NULL
);
2414 // We may be faking the client origin.
2415 // So a window that's really at (0, 30) may appear
2416 // (to wxWin apps) to be at (0, 0).
2419 wxPoint
pt(GetParent()->GetClientAreaOrigin());
2428 // ----------------------------------------------------------------------------
2429 // TranslateXXXEvent() functions
2430 // ----------------------------------------------------------------------------
2432 bool wxTranslateMouseEvent(wxMouseEvent
& wxevent
, wxWindow
*win
, Widget widget
, XEvent
*xevent
)
2434 switch (xevent
->xany
.type
)
2442 wxEventType eventType
= wxEVT_NULL
;
2444 if (xevent
->xany
.type
== LeaveNotify
)
2446 win
->m_button1Pressed
= FALSE
;
2447 win
->m_button2Pressed
= FALSE
;
2448 win
->m_button3Pressed
= FALSE
;
2451 else if (xevent
->xany
.type
== MotionNotify
)
2453 eventType
= wxEVT_MOTION
;
2455 else if (xevent
->xany
.type
== ButtonPress
)
2457 if (xevent
->xbutton
.button
== Button1
)
2459 eventType
= wxEVT_LEFT_DOWN
;
2460 win
->m_button1Pressed
= TRUE
;
2462 else if (xevent
->xbutton
.button
== Button2
)
2464 eventType
= wxEVT_MIDDLE_DOWN
;
2465 win
->m_button2Pressed
= TRUE
;
2467 else if (xevent
->xbutton
.button
== Button3
)
2469 eventType
= wxEVT_RIGHT_DOWN
;
2470 win
->m_button3Pressed
= TRUE
;
2473 else if (xevent
->xany
.type
== ButtonRelease
)
2475 if (xevent
->xbutton
.button
== Button1
)
2477 eventType
= wxEVT_LEFT_UP
;
2478 win
->m_button1Pressed
= FALSE
;
2480 else if (xevent
->xbutton
.button
== Button2
)
2482 eventType
= wxEVT_MIDDLE_UP
;
2483 win
->m_button2Pressed
= FALSE
;
2485 else if (xevent
->xbutton
.button
== Button3
)
2487 eventType
= wxEVT_RIGHT_UP
;
2488 win
->m_button3Pressed
= FALSE
;
2494 wxevent
.m_eventHandle
= (char *)xevent
;
2495 wxevent
.SetEventType(eventType
);
2498 XtVaGetValues(widget
, XmNx
, &x1
, XmNy
, &y1
, NULL
);
2501 win
->GetPosition(&x2
, &y2
);
2503 // The button x/y must be translated to wxWindows
2504 // window space - the widget might be a label or button,
2508 if (widget
!= (Widget
)win
->GetMainWidget())
2514 wxevent
.m_x
= xevent
->xbutton
.x
+ dx
;
2515 wxevent
.m_y
= xevent
->xbutton
.y
+ dy
;
2517 wxevent
.m_leftDown
= ((eventType
== wxEVT_LEFT_DOWN
)
2518 || (event_left_is_down (xevent
)
2519 && (eventType
!= wxEVT_LEFT_UP
)));
2520 wxevent
.m_middleDown
= ((eventType
== wxEVT_MIDDLE_DOWN
)
2521 || (event_middle_is_down (xevent
)
2522 && (eventType
!= wxEVT_MIDDLE_UP
)));
2523 wxevent
.m_rightDown
= ((eventType
== wxEVT_RIGHT_DOWN
)
2524 || (event_right_is_down (xevent
)
2525 && (eventType
!= wxEVT_RIGHT_UP
)));
2527 wxevent
.m_shiftDown
= xevent
->xbutton
.state
& ShiftMask
;
2528 wxevent
.m_controlDown
= xevent
->xbutton
.state
& ControlMask
;
2535 bool wxTranslateKeyEvent(wxKeyEvent
& wxevent
, wxWindow
*win
, Widget widget
, XEvent
*xevent
)
2537 switch (xevent
->xany
.type
)
2545 XComposeStatus compose
;
2546 (void) XLookupString ((XKeyEvent
*) xevent
, buf
, 20, &keySym
, &compose
);
2548 (void) XLookupString ((XKeyEvent
*) xevent
, buf
, 20, &keySym
, NULL
);
2549 int id
= wxCharCodeXToWX (keySym
);
2551 if (xevent
->xkey
.state
& ShiftMask
)
2552 wxevent
.m_shiftDown
= TRUE
;
2553 if (xevent
->xkey
.state
& ControlMask
)
2554 wxevent
.m_controlDown
= TRUE
;
2555 if (xevent
->xkey
.state
& Mod3Mask
)
2556 wxevent
.m_altDown
= TRUE
;
2557 if (xevent
->xkey
.state
& Mod1Mask
)
2558 wxevent
.m_metaDown
= TRUE
;
2559 wxevent
.SetEventObject(win
);
2560 wxevent
.m_keyCode
= id
;
2561 wxevent
.SetTimestamp(xevent
->xkey
.time
);
2563 wxevent
.m_x
= xevent
->xbutton
.x
;
2564 wxevent
.m_y
= xevent
->xbutton
.y
;
2578 // ----------------------------------------------------------------------------
2580 // ----------------------------------------------------------------------------
2582 #define YAllocColor XAllocColor
2583 XColor g_itemColors
[5];
2584 int wxComputeColours (Display
*display
, wxColour
* back
, wxColour
* fore
)
2587 static XmColorProc colorProc
;
2589 result
= wxNO_COLORS
;
2593 g_itemColors
[0].red
= (((long) back
->Red ()) << 8);
2594 g_itemColors
[0].green
= (((long) back
->Green ()) << 8);
2595 g_itemColors
[0].blue
= (((long) back
->Blue ()) << 8);
2596 g_itemColors
[0].flags
= DoRed
| DoGreen
| DoBlue
;
2597 if (colorProc
== (XmColorProc
) NULL
)
2599 // Get a ptr to the actual function
2600 colorProc
= XmSetColorCalculation ((XmColorProc
) NULL
);
2601 // And set it back to motif.
2602 XmSetColorCalculation (colorProc
);
2604 (*colorProc
) (&g_itemColors
[wxBACK_INDEX
],
2605 &g_itemColors
[wxFORE_INDEX
],
2606 &g_itemColors
[wxSELE_INDEX
],
2607 &g_itemColors
[wxTOPS_INDEX
],
2608 &g_itemColors
[wxBOTS_INDEX
]);
2609 result
= wxBACK_COLORS
;
2613 g_itemColors
[wxFORE_INDEX
].red
= (((long) fore
->Red ()) << 8);
2614 g_itemColors
[wxFORE_INDEX
].green
= (((long) fore
->Green ()) << 8);
2615 g_itemColors
[wxFORE_INDEX
].blue
= (((long) fore
->Blue ()) << 8);
2616 g_itemColors
[wxFORE_INDEX
].flags
= DoRed
| DoGreen
| DoBlue
;
2617 if (result
== wxNO_COLORS
)
2618 result
= wxFORE_COLORS
;
2621 Display
*dpy
= display
;
2622 Colormap cmap
= (Colormap
) wxTheApp
->GetMainColormap((WXDisplay
*) dpy
);
2626 /* 5 Colours to allocate */
2627 for (int i
= 0; i
< 5; i
++)
2628 if (!YAllocColor (dpy
, cmap
, &g_itemColors
[i
]))
2629 result
= wxNO_COLORS
;
2633 /* Only 1 colour to allocate */
2634 if (!YAllocColor (dpy
, cmap
, &g_itemColors
[wxFORE_INDEX
]))
2635 result
= wxNO_COLORS
;
2642 // Changes the foreground and background colours to be derived from the current
2643 // background colour. To change the foreground colour, you must call
2644 // SetForegroundColour explicitly.
2645 void wxWindow::ChangeBackgroundColour()
2647 WXWidget mainWidget
= GetMainWidget();
2649 DoChangeBackgroundColour(mainWidget
, m_backgroundColour
);
2651 // This not necessary
2654 if (m_scrolledWindow
&& (GetMainWidget() != m_scrolledWindow
))
2656 DoChangeBackgroundColour(m_scrolledWindow
, m_backgroundColour
);
2657 // Have to set the scrollbar colours back since
2658 // the scrolled window seemed to change them
2659 wxColour backgroundColour
= wxSystemSettings::GetSystemColour(wxSYS_COLOUR_3DFACE
);
2662 DoChangeBackgroundColour(m_hScrollBar
, backgroundColour
);
2664 DoChangeBackgroundColour(m_vScrollBar
, backgroundColour
);
2669 void wxWindow::ChangeForegroundColour()
2671 WXWidget mainWidget
= GetMainWidget();
2673 DoChangeForegroundColour(mainWidget
, m_foregroundColour
);
2674 if ( m_scrolledWindow
&& mainWidget
!= m_scrolledWindow
)
2675 DoChangeForegroundColour(m_scrolledWindow
, m_foregroundColour
);
2678 // Change a widget's foreground and background colours.
2679 void wxWindow::DoChangeForegroundColour(WXWidget widget
, wxColour
& foregroundColour
)
2681 // When should we specify the foreground, if it's calculated
2682 // by wxComputeColours?
2683 // Solution: say we start with the default (computed) foreground colour.
2684 // If we call SetForegroundColour explicitly for a control or window,
2685 // then the foreground is changed.
2686 // Therefore SetBackgroundColour computes the foreground colour, and
2687 // SetForegroundColour changes the foreground colour. The ordering is
2690 Widget w
= (Widget
)widget
;
2693 XmNforeground
, foregroundColour
.AllocColour(XtDisplay(w
)),
2698 void wxWindow::DoChangeBackgroundColour(WXWidget widget
, wxColour
& backgroundColour
, bool changeArmColour
)
2700 wxComputeColours (XtDisplay((Widget
) widget
), & backgroundColour
,
2703 XtVaSetValues ((Widget
) widget
,
2704 XmNbackground
, g_itemColors
[wxBACK_INDEX
].pixel
,
2705 XmNtopShadowColor
, g_itemColors
[wxTOPS_INDEX
].pixel
,
2706 XmNbottomShadowColor
, g_itemColors
[wxBOTS_INDEX
].pixel
,
2707 XmNforeground
, g_itemColors
[wxFORE_INDEX
].pixel
,
2710 if (changeArmColour
)
2711 XtVaSetValues ((Widget
) widget
,
2712 XmNarmColor
, g_itemColors
[wxSELE_INDEX
].pixel
,
2716 void wxWindow::SetBackgroundColour(const wxColour
& col
)
2718 m_backgroundColour
= col
;
2719 ChangeBackgroundColour();
2722 void wxWindow::SetForegroundColour(const wxColour
& col
)
2724 m_foregroundColour
= col
;
2725 ChangeForegroundColour();
2728 void wxWindow::ChangeFont(bool keepOriginalSize
)
2730 // Note that this causes the widget to be resized back
2731 // to its original size! We therefore have to set the size
2732 // back again. TODO: a better way in Motif?
2733 Widget w
= (Widget
) GetLabelWidget(); // Usually the main widget
2734 if (w
&& m_windowFont
.Ok())
2736 int width
, height
, width1
, height1
;
2737 GetSize(& width
, & height
);
2739 // lesstif 0.87 hangs here
2740 #ifndef LESSTIF_VERSION
2742 XmNfontList
, (XmFontList
) m_windowFont
.GetFontList(1.0, XtDisplay(w
)),
2746 GetSize(& width1
, & height1
);
2747 if (keepOriginalSize
&& (width
!= width1
|| height
!= height1
))
2749 SetSize(-1, -1, width
, height
);
2754 // ----------------------------------------------------------------------------
2756 // ----------------------------------------------------------------------------
2758 wxWindow
*wxGetActiveWindow()
2764 // ----------------------------------------------------------------------------
2765 // wxNoOptimize: switch off size optimization
2766 // ----------------------------------------------------------------------------
2768 int wxNoOptimize::m_count
= 0;
2770 wxNoOptimize::wxNoOptimize()
2775 wxNoOptimize::~wxNoOptimize()
2780 bool wxNoOptimize::CanOptimize()
2782 return (m_count
== 0);