1 /////////////////////////////////////////////////////////////////////////////
4 // Author: Julian Smart
8 // Copyright: (c) Julian Smart
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
12 // ============================================================================
14 // ============================================================================
16 // ----------------------------------------------------------------------------
18 // ----------------------------------------------------------------------------
21 #pragma implementation "window.h"
25 #define XtDisplay XTDISPLAY
26 #define XtWindow XTWINDOW
27 #define XtScreen XTSCREEN
33 #include "wx/dcclient.h"
37 #include "wx/layout.h"
38 #include "wx/dialog.h"
39 #include "wx/listbox.h"
40 #include "wx/button.h"
41 #include "wx/settings.h"
42 #include "wx/msgdlg.h"
44 #include "wx/scrolwin.h"
45 #include "wx/module.h"
46 #include "wx/menuitem.h"
48 #include "wx/evtloop.h"
51 #if wxUSE_DRAG_AND_DROP
55 // DoSetSizeIntr and CanvasSetSizeIntr
57 // under Motif composite controls (such as wxCalendarCtrl or generic wxSpinCtrl
58 // don't work and/or segfault because
59 // 1) wxWindow::Create calls SetSize,
60 // which results in a call to DoSetSize much earlier than in the other ports
61 // 2) if wxWindow::Create is called (wxControl::Create calls it)
62 // then DoSetSize is never called, causing layout problems in composite
66 // 1) don't call SetSize, DoSetSize, DoMoveWindow, DoGetPosition,
67 // DoSetPosition directly or indirectly from wxWindow::Create
68 // 2) call DoMoveWindow from DoSetSize, allowing controls to override it,
69 // but make wxWindow::DoMoveWindow a no-op if it is called from
70 // an overridden DoMoveWindow (i.e. wxFoo::DoMoveWindow calls
71 // wxWindow::DoMoveWindow; this is to preserve the behaviour
75 #pragma message disable nosimpint
79 #include <Xm/DrawingA.h>
80 #include <Xm/ScrolledW.h>
81 #include <Xm/ScrollBar.h>
84 #include <Xm/RowColumn.h> // for XmMenuPosition
86 #pragma message enable nosimpint
89 #include "wx/motif/private.h"
93 // ----------------------------------------------------------------------------
95 // ----------------------------------------------------------------------------
97 static const int SCROLL_MARGIN
= 4;
99 // ----------------------------------------------------------------------------
100 // global variables for this module
101 // ----------------------------------------------------------------------------
103 extern wxHashTable
*wxWidgetHashTable
;
104 static wxWindow
* g_captureWindow
= NULL
;
107 // ----------------------------------------------------------------------------
109 // ----------------------------------------------------------------------------
111 static void wxCanvasRepaintProc(Widget
, XtPointer
, XmDrawingAreaCallbackStruct
* cbs
);
112 static void wxCanvasInputEvent(Widget drawingArea
, XtPointer data
, XmDrawingAreaCallbackStruct
* cbs
);
113 static void wxCanvasMotionEvent(Widget
, XButtonEvent
* event
);
114 static void wxCanvasEnterLeave(Widget drawingArea
, XtPointer clientData
, XCrossingEvent
* event
);
115 static void wxScrollBarCallback(Widget widget
, XtPointer clientData
,
116 XmScrollBarCallbackStruct
*cbs
);
117 static void wxPanelItemEventHandler(Widget wid
,
118 XtPointer client_data
,
120 Boolean
*continueToDispatch
);
125 // Helper function for 16-bit fonts
126 static int str16len(const char *s
)
130 while (s
[0] && s
[1]) {
140 // ----------------------------------------------------------------------------
142 // ----------------------------------------------------------------------------
144 #define event_left_is_down(x) ((x)->xbutton.state & Button1Mask)
145 #define event_middle_is_down(x) ((x)->xbutton.state & Button2Mask)
146 #define event_right_is_down(x) ((x)->xbutton.state & Button3Mask)
148 // ----------------------------------------------------------------------------
150 // ----------------------------------------------------------------------------
152 IMPLEMENT_DYNAMIC_CLASS(wxWindow
, wxWindowBase
)
154 BEGIN_EVENT_TABLE(wxWindow
, wxWindowBase
)
155 EVT_SYS_COLOUR_CHANGED(wxWindow::OnSysColourChanged
)
156 EVT_IDLE(wxWindow::OnIdle
)
159 // ============================================================================
161 // ============================================================================
163 // ----------------------------------------------------------------------------
165 // ----------------------------------------------------------------------------
167 void wxWindow::UnmanageAndDestroy(WXWidget widget
)
169 Widget w
= (Widget
)widget
;
177 bool wxWindow::MapOrUnmap(WXWidget widget
, bool domap
)
179 Widget w
= (Widget
)widget
;
188 // Rationale: a lot of common operations (including but not
189 // limited to moving, resizing and appending items to a listbox)
190 // unmamange the widget, do their work, then manage it again.
191 // This means that, for example adding an item to a listbox will show it,
192 // or that most controls are shown every time they are moved or resized!
193 XtSetMappedWhenManaged( w
, domap
);
198 // ----------------------------------------------------------------------------
200 // ----------------------------------------------------------------------------
202 void wxWindow::Init()
204 // generic initializations first
208 m_needsRefresh
= TRUE
;
209 m_mainWidget
= (WXWidget
) 0;
213 m_button3Pressed
= FALSE
;
215 m_winCaptured
= FALSE
;
218 m_isBeingDeleted
= FALSE
;
224 m_drawingArea
= (WXWidget
) 0;
232 m_backingPixmap
= (WXPixmap
) 0;
241 m_canAddEventHandler
= FALSE
;
244 // real construction (Init() must have been called before!)
245 bool wxWindow::Create(wxWindow
*parent
, wxWindowID id
,
249 const wxString
& name
)
251 wxCHECK_MSG( parent
, FALSE
, "can't create wxWindow without parent" );
253 CreateBase(parent
, id
, pos
, size
, style
, wxDefaultValidator
, name
);
255 parent
->AddChild(this);
257 m_backgroundColour
= wxSystemSettings::GetColour(wxSYS_COLOUR_3DFACE
);
258 m_foregroundColour
= *wxBLACK
;
260 //// TODO: we should probably optimize by only creating a
261 //// a drawing area if we have one or more scrollbars (wxVSCROLL/wxHSCROLL).
262 //// But for now, let's simplify things by always creating the
263 //// drawing area, since otherwise the translations are different.
265 // New translations for getting mouse motion feedback
266 static const String translations
=
267 "<Btn1Motion>: wxCanvasMotionEvent() DrawingAreaInput() ManagerGadgetButtonMotion()\n\
268 <Btn2Motion>: wxCanvasMotionEvent() DrawingAreaInput() ManagerGadgetButtonMotion()\n\
269 <Btn3Motion>: wxCanvasMotionEvent() DrawingAreaInput() ManagerGadgetButtonMotion()\n\
270 <BtnMotion>: wxCanvasMotionEvent() DrawingAreaInput() ManagerGadgetButtonMotion()\n\
271 <Btn1Down>: DrawingAreaInput() ManagerGadgetArm()\n\
272 <Btn2Down>: DrawingAreaInput() ManagerGadgetArm()\n\
273 <Btn3Down>: DrawingAreaInput() ManagerGadgetArm()\n\
274 <Btn1Up>: DrawingAreaInput() ManagerGadgetActivate()\n\
275 <Btn2Up>: DrawingAreaInput() ManagerGadgetActivate()\n\
276 <Btn3Up>: DrawingAreaInput() ManagerGadgetActivate()\n\
277 <Motion>: wxCanvasMotionEvent() DrawingAreaInput()\n\
278 <EnterWindow>: wxCanvasMotionEvent() DrawingAreaInput()\n\
279 <LeaveWindow>: wxCanvasMotionEvent() DrawingAreaInput()\n\
280 <Key>: DrawingAreaInput()";
282 XtActionsRec actions
[1];
283 actions
[0].string
= "wxCanvasMotionEvent";
284 actions
[0].proc
= (XtActionProc
) wxCanvasMotionEvent
;
285 XtAppAddActions ((XtAppContext
) wxTheApp
->GetAppContext(), actions
, 1);
287 Widget parentWidget
= (Widget
) parent
->GetClientWidget();
289 if (style
& wxSIMPLE_BORDER
)
291 m_borderWidget
= (WXWidget
)XtVaCreateManagedWidget
294 xmFrameWidgetClass
, parentWidget
,
295 XmNshadowType
, XmSHADOW_IN
,
296 XmNshadowThickness
, 1,
299 } else if (style
& wxSUNKEN_BORDER
)
301 m_borderWidget
= (WXWidget
)XtVaCreateManagedWidget
304 xmFrameWidgetClass
, parentWidget
,
305 XmNshadowType
, XmSHADOW_IN
,
308 } else if (style
& wxRAISED_BORDER
)
310 m_borderWidget
= (WXWidget
)XtVaCreateManagedWidget
313 xmFrameWidgetClass
, parentWidget
,
314 XmNshadowType
, XmSHADOW_OUT
,
319 m_scrolledWindow
= (WXWidget
)XtVaCreateManagedWidget
322 xmScrolledWindowWidgetClass
,
323 m_borderWidget
? (Widget
) m_borderWidget
325 XmNresizePolicy
, XmRESIZE_NONE
,
327 XmNscrollingPolicy
, XmAPPLICATION_DEFINED
,
328 //XmNscrollBarDisplayPolicy, XmAS_NEEDED,
332 XtTranslations ptr
= XtParseTranslationTable(translations
);
333 m_drawingArea
= (WXWidget
)XtVaCreateWidget
336 xmDrawingAreaWidgetClass
, (Widget
) m_scrolledWindow
,
337 XmNunitType
, XmPIXELS
,
338 // XmNresizePolicy, XmRESIZE_ANY,
339 XmNresizePolicy
, XmRESIZE_NONE
,
342 XmNtranslations
, ptr
,
345 XtFree((char *) ptr
);
348 if (GetWindowStyleFlag() & wxOVERRIDE_KEY_TRANSLATIONS
)
350 ptr
= XtParseTranslationTable ("<Key>: DrawingAreaInput()");
351 XtOverrideTranslations ((Widget
) m_drawingArea
, ptr
);
352 XtFree ((char *) ptr
);
356 wxAddWindowToTable((Widget
) m_drawingArea
, this);
357 wxAddWindowToTable((Widget
) m_scrolledWindow
, this);
359 // This order is very important in Motif 1.2.1
360 XtRealizeWidget ((Widget
) m_scrolledWindow
);
361 XtRealizeWidget ((Widget
) m_drawingArea
);
362 XtManageChild ((Widget
) m_drawingArea
);
364 ptr
= XtParseTranslationTable("<Configure>: resize()");
365 XtOverrideTranslations((Widget
) m_drawingArea
, ptr
);
366 XtFree ((char *) ptr
);
368 XtAddCallback ((Widget
) m_drawingArea
, XmNexposeCallback
, (XtCallbackProc
) wxCanvasRepaintProc
, (XtPointer
) this);
369 XtAddCallback ((Widget
) m_drawingArea
, XmNinputCallback
, (XtCallbackProc
) wxCanvasInputEvent
, (XtPointer
) this);
373 display
= XtDisplay (scrolledWindow
);
374 xwindow
= XtWindow (drawingArea
);
378 (Widget
)m_drawingArea
,
379 PointerMotionHintMask
| EnterWindowMask
|
380 LeaveWindowMask
| FocusChangeMask
,
382 (XtEventHandler
) wxCanvasEnterLeave
,
386 // Scrolled widget needs to have its colour changed or we get a little blue
387 // square where the scrollbars abutt
388 wxColour backgroundColour
= wxSystemSettings::GetColour(wxSYS_COLOUR_3DFACE
);
389 DoChangeBackgroundColour(m_scrolledWindow
, backgroundColour
, TRUE
);
390 DoChangeBackgroundColour(m_drawingArea
, backgroundColour
, TRUE
);
392 XmScrolledWindowSetAreas(
393 (Widget
)m_scrolledWindow
,
394 (Widget
) 0, (Widget
) 0,
395 (Widget
) m_drawingArea
);
399 XtRealizeWidget ((Widget
) m_hScrollBar
);
401 XtRealizeWidget ((Widget
) m_vScrollBar
);
404 // Without this, the cursor may not be restored properly (e.g. in splitter
406 SetCursor(*wxSTANDARD_CURSOR
);
407 SetFont(wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT
));
408 DoSetSizeIntr(pos
.x
, pos
.y
, size
.x
,size
.y
, wxSIZE_AUTO
, TRUE
);
413 wxWindow::~wxWindow()
415 if (g_captureWindow
== this)
416 g_captureWindow
= NULL
;
418 m_isBeingDeleted
= TRUE
;
420 // Motif-specific actions first
421 WXWidget wMain
= GetMainWidget();
424 // Removes event handlers
431 m_parent
->RemoveChild( this );
433 // If m_drawingArea, we're a fully-fledged window with drawing area,
434 // scrollbars etc. (what wxCanvas used to be)
437 // Destroy children before destroying self
441 XFreePixmap (XtDisplay ((Widget
) GetMainWidget()), (Pixmap
) m_backingPixmap
);
443 Widget w
= (Widget
) m_drawingArea
;
444 wxDeleteWindowFromTable(w
);
449 m_drawingArea
= (WXWidget
) 0;
452 // Only if we're _really_ a canvas (not a dialog box/panel)
453 if (m_scrolledWindow
)
455 wxDeleteWindowFromTable((Widget
) m_scrolledWindow
);
460 wxDeleteWindowFromTable((Widget
) m_hScrollBar
);
461 XtUnmanageChild((Widget
) m_hScrollBar
);
465 wxDeleteWindowFromTable((Widget
) m_vScrollBar
);
466 XtUnmanageChild((Widget
) m_vScrollBar
);
470 XtDestroyWidget((Widget
) m_hScrollBar
);
472 XtDestroyWidget((Widget
) m_vScrollBar
);
474 UnmanageAndDestroy(m_scrolledWindow
);
478 XtDestroyWidget ((Widget
) m_borderWidget
);
479 m_borderWidget
= (WXWidget
) 0;
482 else // Why wasn't this here before? JACS 8/3/2000
486 // Destroy the window
489 // If this line (XtDestroyWidget) causes a crash, you may comment it out.
490 // Child widgets will get destroyed automatically when a frame
491 // or dialog is destroyed, but before that you may get some memory
492 // leaks and potential layout problems if you delete and then add
495 // GRG, Feb/2000: commented this out when adding support for
496 // wxSCROLL[WIN]_THUMBRELEASE events. Also it was reported
497 // that this call crashed wxMotif under OS/2, so it seems
498 // that leaving it out is the right thing to do.
499 // SN, Feb/2000: newgrid/griddemo shows why it is needed :-(
500 XtDestroyWidget((Widget
) GetMainWidget());
501 SetMainWidget((WXWidget
) NULL
);
505 // ----------------------------------------------------------------------------
506 // scrollbar management
507 // ----------------------------------------------------------------------------
510 void wxWindow::CreateScrollbar(wxOrientation orientation
)
512 wxCHECK_RET( m_drawingArea
, "this window can't have scrollbars" );
514 XtVaSetValues((Widget
) m_scrolledWindow
, XmNresizePolicy
, XmRESIZE_NONE
, NULL
);
516 // Add scrollbars if required
517 if (orientation
== wxHORIZONTAL
)
519 Widget hScrollBar
= XtVaCreateManagedWidget ("hsb",
520 xmScrollBarWidgetClass
, (Widget
) m_scrolledWindow
,
521 XmNorientation
, XmHORIZONTAL
,
523 XtAddCallback (hScrollBar
, XmNvalueChangedCallback
, (XtCallbackProc
) wxScrollBarCallback
, (XtPointer
) XmHORIZONTAL
);
524 XtAddCallback (hScrollBar
, XmNdragCallback
, (XtCallbackProc
) wxScrollBarCallback
, (XtPointer
) XmHORIZONTAL
);
525 XtAddCallback (hScrollBar
, XmNincrementCallback
, (XtCallbackProc
) wxScrollBarCallback
, (XtPointer
) XmHORIZONTAL
);
526 XtAddCallback (hScrollBar
, XmNdecrementCallback
, (XtCallbackProc
) wxScrollBarCallback
, (XtPointer
) XmHORIZONTAL
);
527 XtAddCallback (hScrollBar
, XmNpageIncrementCallback
, (XtCallbackProc
) wxScrollBarCallback
, (XtPointer
) XmHORIZONTAL
);
528 XtAddCallback (hScrollBar
, XmNpageDecrementCallback
, (XtCallbackProc
) wxScrollBarCallback
, (XtPointer
) XmHORIZONTAL
);
529 XtAddCallback (hScrollBar
, XmNtoTopCallback
, (XtCallbackProc
) wxScrollBarCallback
, (XtPointer
) XmHORIZONTAL
);
530 XtAddCallback (hScrollBar
, XmNtoBottomCallback
, (XtCallbackProc
) wxScrollBarCallback
, (XtPointer
) XmHORIZONTAL
);
532 XtVaSetValues (hScrollBar
,
537 m_hScrollBar
= (WXWidget
) hScrollBar
;
539 wxColour backgroundColour
= wxSystemSettings::GetColour(wxSYS_COLOUR_3DFACE
);
540 DoChangeBackgroundColour(m_hScrollBar
, backgroundColour
, TRUE
);
542 XtRealizeWidget(hScrollBar
);
544 XtVaSetValues((Widget
) m_scrolledWindow
,
545 XmNhorizontalScrollBar
, (Widget
) m_hScrollBar
,
550 wxAddWindowToTable( hScrollBar
, this );
553 if (orientation
== wxVERTICAL
)
555 Widget vScrollBar
= XtVaCreateManagedWidget ("vsb",
556 xmScrollBarWidgetClass
, (Widget
) m_scrolledWindow
,
557 XmNorientation
, XmVERTICAL
,
559 XtAddCallback (vScrollBar
, XmNvalueChangedCallback
, (XtCallbackProc
) wxScrollBarCallback
, (XtPointer
) XmVERTICAL
);
560 XtAddCallback (vScrollBar
, XmNdragCallback
, (XtCallbackProc
) wxScrollBarCallback
, (XtPointer
) XmVERTICAL
);
561 XtAddCallback (vScrollBar
, XmNincrementCallback
, (XtCallbackProc
) wxScrollBarCallback
, (XtPointer
) XmVERTICAL
);
562 XtAddCallback (vScrollBar
, XmNdecrementCallback
, (XtCallbackProc
) wxScrollBarCallback
, (XtPointer
) XmVERTICAL
);
563 XtAddCallback (vScrollBar
, XmNpageIncrementCallback
, (XtCallbackProc
) wxScrollBarCallback
, (XtPointer
) XmVERTICAL
);
564 XtAddCallback (vScrollBar
, XmNpageDecrementCallback
, (XtCallbackProc
) wxScrollBarCallback
, (XtPointer
) XmVERTICAL
);
565 XtAddCallback (vScrollBar
, XmNtoTopCallback
, (XtCallbackProc
) wxScrollBarCallback
, (XtPointer
) XmVERTICAL
);
566 XtAddCallback (vScrollBar
, XmNtoBottomCallback
, (XtCallbackProc
) wxScrollBarCallback
, (XtPointer
) XmVERTICAL
);
568 XtVaSetValues (vScrollBar
,
573 m_vScrollBar
= (WXWidget
) vScrollBar
;
574 wxColour backgroundColour
= wxSystemSettings::GetColour(wxSYS_COLOUR_3DFACE
);
575 DoChangeBackgroundColour(m_vScrollBar
, backgroundColour
, TRUE
);
577 XtRealizeWidget(vScrollBar
);
579 XtVaSetValues((Widget
) m_scrolledWindow
,
580 XmNverticalScrollBar
, (Widget
) m_vScrollBar
,
585 wxAddWindowToTable( vScrollBar
, this );
588 XtVaSetValues((Widget
) m_scrolledWindow
, XmNresizePolicy
, XmRESIZE_ANY
, NULL
);
591 void wxWindow::DestroyScrollbar(wxOrientation orientation
)
593 wxCHECK_RET( m_drawingArea
, "this window can't have scrollbars" );
595 XtVaSetValues((Widget
) m_scrolledWindow
, XmNresizePolicy
, XmRESIZE_NONE
, NULL
);
596 // Add scrollbars if required
597 if (orientation
== wxHORIZONTAL
)
601 wxDeleteWindowFromTable((Widget
)m_hScrollBar
);
602 XtDestroyWidget((Widget
) m_hScrollBar
);
604 m_hScrollBar
= (WXWidget
) 0;
607 XtVaSetValues((Widget
) m_scrolledWindow
,
608 XmNhorizontalScrollBar
, (Widget
) 0,
613 if (orientation
== wxVERTICAL
)
617 wxDeleteWindowFromTable((Widget
)m_vScrollBar
);
618 XtDestroyWidget((Widget
) m_vScrollBar
);
620 m_vScrollBar
= (WXWidget
) 0;
623 XtVaSetValues((Widget
) m_scrolledWindow
,
624 XmNverticalScrollBar
, (Widget
) 0,
628 XtVaSetValues((Widget
) m_scrolledWindow
, XmNresizePolicy
, XmRESIZE_ANY
, NULL
);
631 // ---------------------------------------------------------------------------
633 // ---------------------------------------------------------------------------
635 void wxWindow::SetFocus()
637 Widget wMain
= (Widget
) GetMainWidget();
638 XmProcessTraversal(wMain
, XmTRAVERSE_CURRENT
);
639 XmProcessTraversal((Widget
) GetMainWidget(), XmTRAVERSE_CURRENT
);
642 // Get the window with the focus
643 wxWindow
*wxWindowBase::FindFocus()
646 // (1) Can there be multiple focussed widgets in an application?
647 // In which case we need to find the top-level window that's
649 // (2) The widget with the focus may not be in the widget table
650 // depending on which widgets I put in the table
651 wxWindow
*winFocus
= (wxWindow
*)NULL
;
652 for ( wxWindowList::Node
*node
= wxTopLevelWindows
.GetFirst();
654 node
= node
->GetNext() )
656 wxWindow
*win
= node
->GetData();
658 Widget w
= XmGetFocusWidget ((Widget
) win
->GetTopWidget());
660 if (w
!= (Widget
) NULL
)
662 winFocus
= wxGetWindowFromTable(w
);
671 bool wxWindow::Enable(bool enable
)
673 if ( !wxWindowBase::Enable(enable
) )
676 Widget wMain
= (Widget
)GetMainWidget();
679 XtSetSensitive(wMain
, enable
);
680 XmUpdateDisplay(wMain
);
686 bool wxWindow::Show(bool show
)
688 if ( !wxWindowBase::Show(show
) )
691 if (m_borderWidget
|| m_scrolledWindow
)
693 MapOrUnmap(m_drawingArea
, show
);
694 MapOrUnmap(m_borderWidget
? m_borderWidget
: m_scrolledWindow
, show
);
698 if ( !MapOrUnmap(GetTopWidget(), show
) )
699 MapOrUnmap(GetMainWidget(), show
);
703 Window xwin
= (Window
) GetXWindow();
704 Display
*xdisp
= (Display
*) GetXDisplay();
706 XMapWindow(xdisp
, xwin
);
708 XUnmapWindow(xdisp
, xwin
);
714 // Raise the window to the top of the Z order
715 void wxWindow::Raise()
717 Widget wTop
= (Widget
) GetTopWidget();
718 Window window
= XtWindow(wTop
);
719 XRaiseWindow(XtDisplay(wTop
), window
);
722 // Lower the window to the bottom of the Z order
723 void wxWindow::Lower()
725 Widget wTop
= (Widget
) GetTopWidget();
726 Window window
= XtWindow(wTop
);
727 XLowerWindow(XtDisplay(wTop
), window
);
730 void wxWindow::SetTitle(const wxString
& title
)
732 XtVaSetValues((Widget
)GetMainWidget(), XmNtitle
, title
.c_str(), NULL
);
735 wxString
wxWindow::GetTitle() const
738 XtVaGetValues((Widget
)GetMainWidget(), XmNtitle
, &title
, NULL
);
740 return wxString(title
);
743 void wxWindow::DoCaptureMouse()
745 g_captureWindow
= this;
749 Widget wMain
= (Widget
)GetMainWidget();
751 XtAddGrab(wMain
, TRUE
, FALSE
);
753 m_winCaptured
= TRUE
;
756 void wxWindow::DoReleaseMouse()
758 g_captureWindow
= NULL
;
759 if ( !m_winCaptured
)
762 Widget wMain
= (Widget
)GetMainWidget();
766 m_winCaptured
= FALSE
;
769 bool wxWindow::SetFont(const wxFont
& font
)
771 if ( !wxWindowBase::SetFont(font
) )
782 bool wxWindow::SetCursor(const wxCursor
& cursor
)
784 if ( !wxWindowBase::SetCursor(cursor
) )
790 // wxASSERT_MSG( m_cursor.Ok(),
791 // wxT("cursor must be valid after call to the base version"));
792 wxCursor
* cursor2
= NULL
;
794 cursor2
= & m_cursor
;
796 cursor2
= wxSTANDARD_CURSOR
;
798 WXDisplay
*dpy
= GetXDisplay();
799 WXCursor x_cursor
= cursor2
->GetXCursor(dpy
);
801 Widget w
= (Widget
) GetMainWidget();
802 Window win
= XtWindow(w
);
803 XDefineCursor((Display
*) dpy
, win
, (Cursor
) x_cursor
);
808 // Coordinates relative to the window
809 void wxWindow::WarpPointer (int x
, int y
)
811 Widget wClient
= (Widget
)GetClientWidget();
813 XWarpPointer(XtDisplay(wClient
), None
, XtWindow(wClient
), 0, 0, 0, 0, x
, y
);
816 // ---------------------------------------------------------------------------
818 // ---------------------------------------------------------------------------
820 int wxWindow::GetScrollPos(int orient
) const
822 if (orient
== wxHORIZONTAL
)
828 Widget scrollBar
= (Widget
) ((orient
== wxHORIZONTAL
) ? m_hScrollBar
: m_vScrollBar
);
832 XtVaGetValues(scrollBar
, XmNvalue
, &pos
, NULL
);
840 // This now returns the whole range, not just the number of positions that we
842 int wxWindow::GetScrollRange(int orient
) const
844 Widget scrollBar
= (Widget
)GetScrollbar((wxOrientation
)orient
);
845 wxCHECK_MSG( scrollBar
, 0, "no such scrollbar" );
849 XtVaGetValues(scrollBar
, XmNmaximum
, &range
, NULL
);
853 int wxWindow::GetScrollThumb(int orient
) const
855 Widget scrollBar
= (Widget
)GetScrollbar((wxOrientation
)orient
);
856 wxCHECK_MSG( scrollBar
, 0, "no such scrollbar" );
859 XtVaGetValues(scrollBar
, XmNsliderSize
, &thumb
, NULL
);
863 void wxWindow::SetScrollPos(int orient
, int pos
, bool WXUNUSED(refresh
))
865 Widget scrollBar
= (Widget
)GetScrollbar((wxOrientation
)orient
);
869 XtVaSetValues (scrollBar
, XmNvalue
, pos
, NULL
);
872 SetInternalScrollPos((wxOrientation
)orient
, pos
);
875 // New function that will replace some of the above.
876 void wxWindow::SetScrollbar(int orient
, int pos
, int thumbVisible
,
877 int range
, bool WXUNUSED(refresh
))
880 GetSize(& oldW
, & oldH
);
884 if (thumbVisible
== 0)
887 if (thumbVisible
> range
)
888 thumbVisible
= range
;
890 // Save the old state to see if it changed
891 WXWidget oldScrollBar
= GetScrollbar((wxOrientation
)orient
);
893 if (orient
== wxHORIZONTAL
)
895 if (thumbVisible
== range
)
898 DestroyScrollbar(wxHORIZONTAL
);
903 CreateScrollbar(wxHORIZONTAL
);
906 if (orient
== wxVERTICAL
)
908 if (thumbVisible
== range
)
911 DestroyScrollbar(wxVERTICAL
);
916 CreateScrollbar(wxVERTICAL
);
919 WXWidget newScrollBar
= GetScrollbar((wxOrientation
)orient
);
921 if (oldScrollBar
!= newScrollBar
)
923 // This is important! Without it, scrollbars misbehave badly.
924 XtUnrealizeWidget((Widget
) m_scrolledWindow
);
925 XmScrolledWindowSetAreas ((Widget
) m_scrolledWindow
, (Widget
) m_hScrollBar
, (Widget
) m_vScrollBar
, (Widget
) m_drawingArea
);
926 XtRealizeWidget((Widget
) m_scrolledWindow
);
927 XtManageChild((Widget
) m_scrolledWindow
);
932 XtVaSetValues((Widget
) newScrollBar
,
936 XmNsliderSize
, thumbVisible
,
940 SetInternalScrollPos((wxOrientation
)orient
, pos
);
943 GetSize(& newW
, & newH
);
945 // Adjusting scrollbars can resize the canvas accidentally
946 if (newW
!= oldW
|| newH
!= oldH
)
947 SetSize(-1, -1, oldW
, oldH
);
950 // Does a physical scroll
951 void wxWindow::ScrollWindow(int dx
, int dy
, const wxRect
*rect
)
956 // Use specified rectangle
957 x
= rect
->x
; y
= rect
->y
; w
= rect
->width
; h
= rect
->height
;
961 // Use whole client area
963 GetClientSize(& w
, & h
);
966 wxWindowList::Node
*cnode
= m_children
.GetFirst();
969 wxWindow
*child
= cnode
->GetData();
972 child
->GetSize( &sx
, &sy
);
973 wxPoint
pos( child
->GetPosition() );
974 child
->SetSize( pos
.x
+ dx
, pos
.y
+ dy
, sx
, sy
, wxSIZE_ALLOW_MINUS_ONE
);
975 cnode
= cnode
->GetNext();
978 int x1
= (dx
>= 0) ? x
: x
- dx
;
979 int y1
= (dy
>= 0) ? y
: y
- dy
;
980 int w1
= w
- abs(dx
);
981 int h1
= h
- abs(dy
);
982 int x2
= (dx
>= 0) ? x
+ dx
: x
;
983 int y2
= (dy
>= 0) ? y
+ dy
: y
;
987 dc
.SetLogicalFunction (wxCOPY
);
989 Widget widget
= (Widget
) GetMainWidget();
990 Window window
= XtWindow(widget
);
991 Display
* display
= XtDisplay(widget
);
993 XCopyArea(display
, window
, window
, (GC
) dc
.GetGC(),
994 x1
, y1
, w1
, h1
, x2
, y2
);
996 dc
.SetAutoSetting(TRUE
);
997 wxBrush
brush(GetBackgroundColour(), wxSOLID
);
998 dc
.SetBrush(brush
); // FIXME: needed?
1000 // We'll add rectangles to the list of update rectangles according to which
1001 // bits we've exposed.
1006 wxRect
*rect
= new wxRect
;
1012 XFillRectangle(display
, window
,
1013 (GC
) dc
.GetGC(), rect
->x
, rect
->y
, rect
->width
, rect
->height
);
1017 rect
->width
= rect
->width
;
1018 rect
->height
= rect
->height
;
1020 updateRects
.Append((wxObject
*) rect
);
1024 wxRect
*rect
= new wxRect
;
1026 rect
->x
= x
+ w
+ dx
;
1031 XFillRectangle(display
, window
,
1032 (GC
) dc
.GetGC(), rect
->x
, rect
->y
, rect
->width
,
1037 rect
->width
= rect
->width
;
1038 rect
->height
= rect
->height
;
1040 updateRects
.Append((wxObject
*) rect
);
1044 wxRect
*rect
= new wxRect
;
1051 XFillRectangle(display
, window
,
1052 (GC
) dc
.GetGC(), rect
->x
, rect
->y
, rect
->width
, rect
->height
);
1056 rect
->width
= rect
->width
;
1057 rect
->height
= rect
->height
;
1059 updateRects
.Append((wxObject
*) rect
);
1063 wxRect
*rect
= new wxRect
;
1066 rect
->y
= y
+ h
+ dy
;
1070 XFillRectangle(display
, window
,
1071 (GC
) dc
.GetGC(), rect
->x
, rect
->y
, rect
->width
, rect
->height
);
1075 rect
->width
= rect
->width
;
1076 rect
->height
= rect
->height
;
1078 updateRects
.Append((wxObject
*) rect
);
1080 dc
.SetBrush(wxNullBrush
);
1082 // Now send expose events
1084 wxList::Node
* node
= updateRects
.GetFirst();
1087 wxRect
* rect
= (wxRect
*) node
->GetData();
1090 event
.type
= Expose
;
1091 event
.display
= display
;
1092 event
.send_event
= True
;
1093 event
.window
= window
;
1097 event
.width
= rect
->width
;
1098 event
.height
= rect
->height
;
1102 XSendEvent(display
, window
, False
, ExposureMask
, (XEvent
*)&event
);
1104 node
= node
->GetNext();
1108 // Delete the update rects
1109 node
= updateRects
.GetFirst();
1112 wxRect
* rect
= (wxRect
*) node
->GetData();
1114 node
= node
->GetNext();
1117 XmUpdateDisplay((Widget
) GetMainWidget());
1120 // ---------------------------------------------------------------------------
1122 // ---------------------------------------------------------------------------
1124 #if wxUSE_DRAG_AND_DROP
1126 void wxWindow::SetDropTarget(wxDropTarget
* WXUNUSED(pDropTarget
))
1133 // Old style file-manager drag&drop
1134 void wxWindow::DragAcceptFiles(bool WXUNUSED(accept
))
1139 // ----------------------------------------------------------------------------
1141 // ----------------------------------------------------------------------------
1145 void wxWindow::DoSetToolTip(wxToolTip
* WXUNUSED(tooltip
))
1150 #endif // wxUSE_TOOLTIPS
1152 // ----------------------------------------------------------------------------
1154 // ----------------------------------------------------------------------------
1158 bool wxWindow::DoPopupMenu(wxMenu
*menu
, int x
, int y
)
1160 Widget widget
= (Widget
) GetMainWidget();
1162 /* The menuId field seems to be usused, so we'll use it to
1163 indicate whether a menu is popped up or not:
1164 0: Not currently created as a popup
1165 -1: Created as a popup, but not active
1169 if (menu
->GetParent() && (menu
->GetId() != -1))
1172 if (menu
->GetMainWidget())
1174 menu
->DestroyMenu(TRUE
);
1177 menu
->SetId(1); /* Mark as popped-up */
1178 menu
->CreateMenu(NULL
, widget
, menu
);
1179 menu
->SetInvokingWindow(this);
1183 // menu->SetParent(parent);
1184 // parent->children->Append(menu); // Store menu for later deletion
1186 Widget menuWidget
= (Widget
) menu
->GetMainWidget();
1194 if (this->IsKindOf(CLASSINFO(wxCanvas)))
1196 wxCanvas *canvas = (wxCanvas *) this;
1197 deviceX = canvas->GetDC ()->LogicalToDeviceX (x);
1198 deviceY = canvas->GetDC ()->LogicalToDeviceY (y);
1202 Display
*display
= XtDisplay (widget
);
1203 Window rootWindow
= RootWindowOfScreen (XtScreen((Widget
)widget
));
1204 Window thisWindow
= XtWindow (widget
);
1206 XTranslateCoordinates (display
, thisWindow
, rootWindow
, (int) deviceX
, (int) deviceY
,
1207 &rootX
, &rootY
, &childWindow
);
1209 XButtonPressedEvent event
;
1210 event
.type
= ButtonPress
;
1216 event
.x_root
= rootX
;
1217 event
.y_root
= rootY
;
1219 XmMenuPosition (menuWidget
, &event
);
1220 XtManageChild (menuWidget
);
1222 // The ID of a pop-up menu is 1 when active, and is set to 0 by the
1223 // idle-time destroy routine.
1224 // Waiting until this ID changes causes this function to block until
1225 // the menu has been dismissed and the widgets cleaned up.
1226 // In other words, once this routine returns, it is safe to delete
1228 // Ian Brown <ian.brown@printsoft.de>
1230 wxEventLoop evtLoop
;
1232 while (menu
->GetId() == 1)
1234 wxDoEventLoopIteration( evtLoop
);
1242 // ---------------------------------------------------------------------------
1243 // moving and resizing
1244 // ---------------------------------------------------------------------------
1246 bool wxWindow::PreResize()
1252 void wxWindow::DoGetSize(int *x
, int *y
) const
1256 CanvasGetSize(x
, y
);
1260 Widget widget
= (Widget
) GetTopWidget();
1262 XtVaGetValues(widget
, XmNwidth
, &xx
, XmNheight
, &yy
, NULL
);
1263 if(x
) *x
= xx
; if(y
) *y
= yy
;
1266 void wxWindow::DoGetPosition(int *x
, int *y
) const
1270 CanvasGetPosition(x
, y
);
1273 Widget widget
= (Widget
) GetTopWidget();
1275 XtVaGetValues(widget
, XmNx
, &xx
, XmNy
, &yy
, NULL
);
1277 // We may be faking the client origin. So a window that's really at (0, 30)
1278 // may appear (to wxWin apps) to be at (0, 0).
1281 wxPoint
pt(GetParent()->GetClientAreaOrigin());
1286 if(x
) *x
= xx
; if(y
) *y
= yy
;
1289 void wxWindow::DoScreenToClient(int *x
, int *y
) const
1291 Widget widget
= (Widget
) GetClientWidget();
1292 Display
*display
= XtDisplay((Widget
) GetMainWidget());
1293 Window rootWindow
= RootWindowOfScreen(XtScreen(widget
));
1294 Window thisWindow
= XtWindow(widget
);
1299 XTranslateCoordinates(display
, rootWindow
, thisWindow
, xx
, yy
, x
, y
, &childWindow
);
1302 void wxWindow::DoClientToScreen(int *x
, int *y
) const
1304 Widget widget
= (Widget
) GetClientWidget();
1305 Display
*display
= XtDisplay(widget
);
1306 Window rootWindow
= RootWindowOfScreen(XtScreen(widget
));
1307 Window thisWindow
= XtWindow(widget
);
1312 XTranslateCoordinates(display
, thisWindow
, rootWindow
, xx
, yy
, x
, y
, &childWindow
);
1316 // Get size *available for subwindows* i.e. excluding menu bar etc.
1317 void wxWindow::DoGetClientSize(int *x
, int *y
) const
1319 Widget widget
= (Widget
) GetClientWidget();
1321 XtVaGetValues(widget
, XmNwidth
, &xx
, XmNheight
, &yy
, NULL
);
1322 if(x
) *x
= xx
; if(y
) *y
= yy
;
1325 void wxWindow::DoSetSize(int x
, int y
, int width
, int height
, int sizeFlags
)
1327 DoSetSizeIntr(x
, y
, width
, height
, sizeFlags
, FALSE
);
1330 void wxWindow::DoSetSizeIntr(int x
, int y
, int width
, int height
,
1331 int sizeFlags
, bool fromCtor
)
1333 // A bit of optimization to help sort out the flickers.
1334 int oldX
= -1, oldY
= -1, oldW
= -1, oldH
= -1;
1337 GetSize(& oldW
, & oldH
);
1338 GetPosition(& oldX
, & oldY
);
1341 if ( !(sizeFlags
& wxSIZE_ALLOW_MINUS_ONE
) )
1354 bool nothingChanged
= (x
== oldX
) && (y
== oldY
) &&
1355 (width
== oldW
) && (height
== oldH
);
1357 if (!wxNoOptimize::CanOptimize())
1359 nothingChanged
= FALSE
;
1362 if ( !nothingChanged
)
1366 CanvasSetSizeIntr(x
, y
, width
, height
, sizeFlags
, fromCtor
);
1367 if( !fromCtor
) DoMoveWindow(x
, y
, width
, height
);
1371 Widget widget
= (Widget
) GetTopWidget();
1375 bool managed
= XtIsManaged( widget
);
1377 XtUnmanageChild(widget
);
1381 AdjustForParentClientOrigin(xx
, yy
, sizeFlags
);
1383 DoMoveWindow(xx
, yy
, width
, height
);
1386 XtManageChild(widget
);
1390 void wxWindow::DoSetClientSize(int width
, int height
)
1394 CanvasSetClientSize(width
, height
);
1398 Widget widget
= (Widget
) GetTopWidget();
1401 XtVaSetValues(widget
, XmNwidth
, width
, NULL
);
1403 XtVaSetValues(widget
, XmNheight
, height
, NULL
);
1405 wxSizeEvent
sizeEvent(wxSize(width
, height
), GetId());
1406 sizeEvent
.SetEventObject(this);
1408 GetEventHandler()->ProcessEvent(sizeEvent
);
1411 // For implementation purposes - sometimes decorations make the client area
1413 wxPoint
wxWindow::GetClientAreaOrigin() const
1415 return wxPoint(0, 0);
1418 void wxWindow::SetSizeHints(int minW
, int minH
, int maxW
, int maxH
, int incW
, int incH
)
1425 wxFrame
*frame
= wxDynamicCast(this, wxFrame
);
1428 // TODO what about dialogs?
1432 Widget widget
= (Widget
) frame
->GetShellWidget();
1435 XtVaSetValues(widget
, XmNminWidth
, minW
, NULL
);
1437 XtVaSetValues(widget
, XmNminHeight
, minH
, NULL
);
1439 XtVaSetValues(widget
, XmNmaxWidth
, maxW
, NULL
);
1441 XtVaSetValues(widget
, XmNmaxHeight
, maxH
, NULL
);
1443 XtVaSetValues(widget
, XmNwidthInc
, incW
, NULL
);
1445 XtVaSetValues(widget
, XmNheightInc
, incH
, NULL
);
1448 void wxWindow::DoMoveWindow(int x
, int y
, int width
, int height
)
1450 // see the top of the file, near DoSetSizeIntr
1459 XtVaSetValues((Widget
)GetTopWidget(),
1467 // ---------------------------------------------------------------------------
1469 // ---------------------------------------------------------------------------
1471 int wxWindow::GetCharHeight() const
1473 wxCHECK_MSG( m_font
.Ok(), 0, "valid window font needed" );
1475 WXFontStructPtr pFontStruct
= m_font
.GetFontStruct(1.0, GetXDisplay());
1477 int direction
, ascent
, descent
;
1478 XCharStruct overall
;
1479 XTextExtents ((XFontStruct
*) pFontStruct
, "x", 1, &direction
, &ascent
,
1480 &descent
, &overall
);
1482 // return (overall.ascent + overall.descent);
1483 return (ascent
+ descent
);
1486 int wxWindow::GetCharWidth() const
1488 wxCHECK_MSG( m_font
.Ok(), 0, "valid window font needed" );
1490 WXFontStructPtr pFontStruct
= m_font
.GetFontStruct(1.0, GetXDisplay());
1492 int direction
, ascent
, descent
;
1493 XCharStruct overall
;
1494 XTextExtents ((XFontStruct
*) pFontStruct
, "x", 1, &direction
, &ascent
,
1495 &descent
, &overall
);
1497 return overall
.width
;
1500 void wxWindow::GetTextExtent(const wxString
& string
,
1502 int *descent
, int *externalLeading
,
1503 const wxFont
*theFont
) const
1505 wxFont
*fontToUse
= (wxFont
*)theFont
;
1507 fontToUse
= (wxFont
*) & m_font
;
1509 wxCHECK_RET( fontToUse
->Ok(), "valid window font needed" );
1511 WXFontStructPtr pFontStruct
= fontToUse
->GetFontStruct(1.0, GetXDisplay());
1513 int direction
, ascent
, descent2
;
1514 XCharStruct overall
;
1515 int slen
= string
.Len();
1519 XTextExtents16((XFontStruct
*) pFontStruct
, (XChar2b
*) (char*) (const char*) string
, slen
, &direction
,
1520 &ascent
, &descent2
, &overall
);
1523 XTextExtents((XFontStruct
*) pFontStruct
, string
, slen
,
1524 &direction
, &ascent
, &descent2
, &overall
);
1527 *x
= (overall
.width
);
1529 *y
= (ascent
+ descent2
);
1531 *descent
= descent2
;
1532 if (externalLeading
)
1533 *externalLeading
= 0;
1537 // ----------------------------------------------------------------------------
1539 // ----------------------------------------------------------------------------
1541 void wxWindow::Refresh(bool eraseBack
, const wxRect
*rect
)
1543 m_needsRefresh
= TRUE
;
1544 Display
*display
= XtDisplay((Widget
) GetMainWidget());
1545 Window thisWindow
= XtWindow((Widget
) GetMainWidget());
1547 XExposeEvent dummyEvent
;
1549 GetSize(&width
, &height
);
1551 dummyEvent
.type
= Expose
;
1552 dummyEvent
.display
= display
;
1553 dummyEvent
.send_event
= True
;
1554 dummyEvent
.window
= thisWindow
;
1557 dummyEvent
.x
= rect
->x
;
1558 dummyEvent
.y
= rect
->y
;
1559 dummyEvent
.width
= rect
->width
;
1560 dummyEvent
.height
= rect
->height
;
1566 dummyEvent
.width
= width
;
1567 dummyEvent
.height
= height
;
1569 dummyEvent
.count
= 0;
1573 wxClientDC
dc(this);
1574 wxBrush
backgroundBrush(GetBackgroundColour(), wxSOLID
);
1575 dc
.SetBackground(backgroundBrush
);
1582 XSendEvent(display
, thisWindow
, False
, ExposureMask
, (XEvent
*)&dummyEvent
);
1585 void wxWindow::Clear()
1587 wxClientDC
dc(this);
1588 wxBrush
brush(GetBackgroundColour(), wxSOLID
);
1589 dc
.SetBackground(brush
);
1593 void wxWindow::ClearUpdateRects()
1595 wxRectList::Node
* node
= m_updateRects
.GetFirst();
1598 wxRect
* rect
= node
->GetData();
1600 node
= node
->GetNext();
1603 m_updateRects
.Clear();
1606 void wxWindow::DoPaint()
1608 //TODO : make a temporary gc so we can do the XCopyArea below
1609 if (m_backingPixmap
&& !m_needsRefresh
)
1613 GC tempGC
= (GC
) dc
.GetBackingGC();
1615 Widget widget
= (Widget
) GetMainWidget();
1620 // We have to test whether it's a wxScrolledWindow (hack!) because
1621 // otherwise we don't know how many pixels have been scrolled. We might
1622 // solve this in the future by defining virtual wxWindow functions to get
1623 // the scroll position in pixels. Or, each kind of scrolled window has to
1624 // implement backing stores itself, using generic wxWindows code.
1625 wxScrolledWindow
* scrolledWindow
= wxDynamicCast(this, wxScrolledWindow
);
1626 if ( scrolledWindow
)
1629 scrolledWindow
->CalcScrolledPosition(0, 0, &x
, &y
);
1635 // TODO: This could be optimized further by only copying the areas in the
1636 // current update region.
1638 // Only blit the part visible in the client area. The backing pixmap
1639 // always starts at 0, 0 but we may be looking at only a portion of it.
1640 wxSize clientArea
= GetClientSize();
1641 int toBlitX
= m_pixmapWidth
- scrollPosX
;
1642 int toBlitY
= m_pixmapHeight
- scrollPosY
;
1644 // Copy whichever is samller, the amount of pixmap we have to copy,
1645 // or the size of the client area.
1646 toBlitX
= wxMin(toBlitX
, clientArea
.x
);
1647 toBlitY
= wxMin(toBlitY
, clientArea
.y
);
1649 // Make sure we're not negative
1650 toBlitX
= wxMax(0, toBlitX
);
1651 toBlitY
= wxMax(0, toBlitY
);
1656 (Pixmap
) m_backingPixmap
,
1659 scrollPosX
, scrollPosY
, // Start at the scroll position
1660 toBlitX
, toBlitY
, // How much of the pixmap to copy
1666 // Set an erase event first
1667 wxEraseEvent
eraseEvent(GetId());
1668 eraseEvent
.SetEventObject(this);
1669 GetEventHandler()->ProcessEvent(eraseEvent
);
1671 wxPaintEvent
event(GetId());
1672 event
.SetEventObject(this);
1673 GetEventHandler()->ProcessEvent(event
);
1675 m_needsRefresh
= FALSE
;
1679 // ----------------------------------------------------------------------------
1681 // ----------------------------------------------------------------------------
1683 // Responds to colour changes: passes event on to children.
1684 void wxWindow::OnSysColourChanged(wxSysColourChangedEvent
& event
)
1686 wxWindowList::Node
*node
= GetChildren().GetFirst();
1689 // Only propagate to non-top-level windows
1690 wxWindow
*win
= node
->GetData();
1691 if ( win
->GetParent() )
1693 wxSysColourChangedEvent event2
;
1694 event
.m_eventObject
= win
;
1695 win
->GetEventHandler()->ProcessEvent(event2
);
1698 node
= node
->GetNext();
1702 void wxWindow::OnIdle(wxIdleEvent
& WXUNUSED(event
))
1704 // This calls the UI-update mechanism (querying windows for
1705 // menu/toolbar/control state information)
1709 // ----------------------------------------------------------------------------
1711 // ----------------------------------------------------------------------------
1713 bool wxWindow::ProcessAccelerator(wxKeyEvent
& event
)
1716 if (!m_acceleratorTable
.Ok())
1719 int count
= m_acceleratorTable
.GetCount();
1720 wxAcceleratorEntry
* entries
= m_acceleratorTable
.GetEntries();
1722 for (i
= 0; i
< count
; i
++)
1724 wxAcceleratorEntry
* entry
= & (entries
[i
]);
1725 if (entry
->MatchesEvent(event
))
1727 // Bingo, we have a match. Now find a control that matches the
1728 // entry command id.
1730 // Need to go up to the top of the window hierarchy, since it might
1731 // be e.g. a menu item
1732 wxWindow
* parent
= this;
1733 while ( parent
&& !parent
->IsTopLevel() )
1734 parent
= parent
->GetParent();
1739 wxFrame
* frame
= wxDynamicCast(parent
, wxFrame
);
1743 // Try for a menu command
1744 if (frame
->GetMenuBar())
1746 wxMenuItem
* item
= frame
->GetMenuBar()->FindItem(entry
->GetCommand());
1749 wxCommandEvent
commandEvent(wxEVT_COMMAND_MENU_SELECTED
, entry
->GetCommand());
1750 commandEvent
.SetEventObject(frame
);
1752 // If ProcessEvent returns TRUE (it was handled), then
1753 // the calling code will skip the event handling.
1754 return frame
->GetEventHandler()->ProcessEvent(commandEvent
);
1760 // Find a child matching the command id
1761 wxWindow
* child
= parent
->FindWindow(entry
->GetCommand());
1767 // Now we process those kinds of windows that we can.
1768 // For now, only buttons.
1769 if ( wxDynamicCast(child
, wxButton
) )
1771 wxCommandEvent
commandEvent (wxEVT_COMMAND_BUTTON_CLICKED
, child
->GetId());
1772 commandEvent
.SetEventObject(child
);
1773 return child
->GetEventHandler()->ProcessEvent(commandEvent
);
1781 // We didn't match the key event against an accelerator.
1785 // ============================================================================
1786 // Motif-specific stuff from here on
1787 // ============================================================================
1789 // ----------------------------------------------------------------------------
1790 // function which maintain the global hash table mapping Widgets to wxWindows
1791 // ----------------------------------------------------------------------------
1793 bool wxAddWindowToTable(Widget w
, wxWindow
*win
)
1795 wxWindow
*oldItem
= NULL
;
1796 if ((oldItem
= (wxWindow
*)wxWidgetHashTable
->Get ((long) w
)))
1798 wxLogDebug("Widget table clash: new widget is %ld, %s",
1799 (long)w
, win
->GetClassInfo()->GetClassName());
1803 wxWidgetHashTable
->Put((long) w
, win
);
1805 wxLogTrace("widget", "Widget 0x%p <-> window %p (%s)",
1806 (WXWidget
)w
, win
, win
->GetClassInfo()->GetClassName());
1811 wxWindow
*wxGetWindowFromTable(Widget w
)
1813 return (wxWindow
*)wxWidgetHashTable
->Get((long) w
);
1816 void wxDeleteWindowFromTable(Widget w
)
1818 wxWidgetHashTable
->Delete((long)w
);
1821 // ----------------------------------------------------------------------------
1822 // add/remove window from the table
1823 // ----------------------------------------------------------------------------
1825 // Add to hash table, add event handler
1826 bool wxWindow::AttachWidget (wxWindow
* WXUNUSED(parent
), WXWidget mainWidget
,
1827 WXWidget formWidget
, int x
, int y
, int width
, int height
)
1829 wxAddWindowToTable((Widget
) mainWidget
, this);
1830 if (CanAddEventHandler())
1832 XtAddEventHandler((Widget
) mainWidget
,
1833 ButtonPressMask
| ButtonReleaseMask
| PointerMotionMask
, // | KeyPressMask,
1835 wxPanelItemEventHandler
,
1842 XtOverrideTranslations ((Widget
) mainWidget
,
1843 ptr
= XtParseTranslationTable ("<Configure>: resize()"));
1844 XtFree ((char *) ptr
);
1847 // Some widgets have a parent form widget, e.g. wxRadioBox
1850 if (!wxAddWindowToTable((Widget
) formWidget
, this))
1854 XtOverrideTranslations ((Widget
) formWidget
,
1855 ptr
= XtParseTranslationTable ("<Configure>: resize()"));
1856 XtFree ((char *) ptr
);
1863 SetSize (x
, y
, width
, height
);
1868 // Remove event handler, remove from hash table
1869 bool wxWindow::DetachWidget(WXWidget widget
)
1871 if (CanAddEventHandler())
1873 XtRemoveEventHandler((Widget
) widget
,
1874 ButtonPressMask
| ButtonReleaseMask
| PointerMotionMask
, // | KeyPressMask,
1876 wxPanelItemEventHandler
,
1880 wxDeleteWindowFromTable((Widget
) widget
);
1884 // ----------------------------------------------------------------------------
1885 // Motif-specific accessors
1886 // ----------------------------------------------------------------------------
1888 // Get the underlying X window
1889 WXWindow
wxWindow::GetXWindow() const
1891 Widget wMain
= (Widget
)GetMainWidget();
1893 return (WXWindow
) XtWindow(wMain
);
1895 return (WXWindow
) 0;
1898 // Get the underlying X display
1899 WXDisplay
*wxWindow::GetXDisplay() const
1901 Widget wMain
= (Widget
)GetMainWidget();
1903 return (WXDisplay
*) XtDisplay(wMain
);
1905 return (WXDisplay
*) NULL
;
1908 WXWidget
wxWindow::GetMainWidget() const
1911 return m_drawingArea
;
1913 return m_mainWidget
;
1916 WXWidget
wxWindow::GetClientWidget() const
1918 if (m_drawingArea
!= (WXWidget
) 0)
1919 return m_drawingArea
;
1921 return GetMainWidget();
1924 WXWidget
wxWindow::GetTopWidget() const
1926 return GetMainWidget();
1929 WXWidget
wxWindow::GetLabelWidget() const
1931 return GetMainWidget();
1934 // ----------------------------------------------------------------------------
1936 // ----------------------------------------------------------------------------
1938 // All widgets should have this as their resize proc.
1939 // OnSize sent to wxWindow via client data.
1940 void wxWidgetResizeProc(Widget w
, XConfigureEvent
*WXUNUSED(event
), String
WXUNUSED(args
)[], int *WXUNUSED(num_args
))
1942 wxWindow
*win
= wxGetWindowFromTable(w
);
1946 if (win
->PreResize())
1949 win
->GetSize(&width
, &height
);
1950 wxSizeEvent
sizeEvent(wxSize(width
, height
), win
->GetId());
1951 sizeEvent
.SetEventObject(win
);
1952 win
->GetEventHandler()->ProcessEvent(sizeEvent
);
1956 static void wxCanvasRepaintProc(Widget drawingArea
,
1957 XtPointer clientData
,
1958 XmDrawingAreaCallbackStruct
* cbs
)
1960 if (!wxGetWindowFromTable(drawingArea
))
1963 XEvent
* event
= cbs
->event
;
1964 wxWindow
* win
= (wxWindow
*) clientData
;
1966 switch (event
->type
)
1970 win
->AddUpdateRect(event
->xexpose
.x
, event
->xexpose
.y
,
1971 event
->xexpose
.width
, event
->xexpose
.height
);
1973 if (event
-> xexpose
.count
== 0)
1976 win
->ClearUpdateRects();
1983 // Unable to deal with Enter/Leave without a separate EventHandler (Motif 1.1.4)
1984 static void wxCanvasEnterLeave(Widget drawingArea
,
1985 XtPointer
WXUNUSED(clientData
),
1986 XCrossingEvent
* event
)
1988 XmDrawingAreaCallbackStruct cbs
;
1991 ((XCrossingEvent
&) ev
) = *event
;
1993 cbs
.reason
= XmCR_INPUT
;
1996 wxCanvasInputEvent(drawingArea
, (XtPointer
) NULL
, &cbs
);
1999 // Fix to make it work under Motif 1.0 (!)
2000 static void wxCanvasMotionEvent (Widget
WXUNUSED(drawingArea
),
2001 XButtonEvent
*WXUNUSED(event
))
2003 #if XmVersion <= 1000
2004 XmDrawingAreaCallbackStruct cbs
;
2007 ev
= *((XEvent
*) event
);
2008 cbs
.reason
= XmCR_INPUT
;
2011 wxCanvasInputEvent (drawingArea
, (XtPointer
) NULL
, &cbs
);
2012 #endif // XmVersion <= 1000
2015 static void wxCanvasInputEvent(Widget drawingArea
,
2016 XtPointer
WXUNUSED(data
),
2017 XmDrawingAreaCallbackStruct
* cbs
)
2019 wxWindow
*canvas
= wxGetWindowFromTable(drawingArea
);
2025 if (cbs
->reason
!= XmCR_INPUT
)
2028 local_event
= *(cbs
->event
); // We must keep a copy!
2030 switch (local_event
.xany
.type
)
2038 // FIXME: most of this mouse event code is more or less
2039 // duplicated in wxTranslateMouseEvent
2041 wxEventType eventType
= wxEVT_NULL
;
2043 if (local_event
.xany
.type
== EnterNotify
)
2045 //if (local_event.xcrossing.mode!=NotifyNormal)
2046 // return ; // Ignore grab events
2047 eventType
= wxEVT_ENTER_WINDOW
;
2048 // canvas->GetEventHandler()->OnSetFocus();
2050 else if (local_event
.xany
.type
== LeaveNotify
)
2052 //if (local_event.xcrossingr.mode!=NotifyNormal)
2053 // return ; // Ignore grab events
2054 eventType
= wxEVT_LEAVE_WINDOW
;
2055 // canvas->GetEventHandler()->OnKillFocus();
2057 else if (local_event
.xany
.type
== MotionNotify
)
2059 eventType
= wxEVT_MOTION
;
2062 else if (local_event
.xany
.type
== ButtonPress
)
2064 if (local_event
.xbutton
.button
== Button1
)
2066 eventType
= wxEVT_LEFT_DOWN
;
2067 canvas
->SetButton1(TRUE
);
2069 else if (local_event
.xbutton
.button
== Button2
)
2071 eventType
= wxEVT_MIDDLE_DOWN
;
2072 canvas
->SetButton2(TRUE
);
2074 else if (local_event
.xbutton
.button
== Button3
)
2076 eventType
= wxEVT_RIGHT_DOWN
;
2077 canvas
->SetButton3(TRUE
);
2080 else if (local_event
.xany
.type
== ButtonRelease
)
2082 if (local_event
.xbutton
.button
== Button1
)
2084 eventType
= wxEVT_LEFT_UP
;
2085 canvas
->SetButton1(FALSE
);
2087 else if (local_event
.xbutton
.button
== Button2
)
2089 eventType
= wxEVT_MIDDLE_UP
;
2090 canvas
->SetButton2(FALSE
);
2092 else if (local_event
.xbutton
.button
== Button3
)
2094 eventType
= wxEVT_RIGHT_UP
;
2095 canvas
->SetButton3(FALSE
);
2099 wxMouseEvent
wxevent (eventType
);
2101 wxevent
.m_leftDown
= ((eventType
== wxEVT_LEFT_DOWN
)
2102 || (event_left_is_down (&local_event
)
2103 && (eventType
!= wxEVT_LEFT_UP
)));
2104 wxevent
.m_middleDown
= ((eventType
== wxEVT_MIDDLE_DOWN
)
2105 || (event_middle_is_down (&local_event
)
2106 && (eventType
!= wxEVT_MIDDLE_UP
)));
2107 wxevent
.m_rightDown
= ((eventType
== wxEVT_RIGHT_DOWN
)
2108 || (event_right_is_down (&local_event
)
2109 && (eventType
!= wxEVT_RIGHT_UP
)));
2111 wxevent
.m_shiftDown
= local_event
.xbutton
.state
& ShiftMask
;
2112 wxevent
.m_controlDown
= local_event
.xbutton
.state
& ControlMask
;
2113 wxevent
.m_altDown
= local_event
.xbutton
.state
& Mod3Mask
;
2114 wxevent
.m_metaDown
= local_event
.xbutton
.state
& Mod1Mask
;
2115 wxevent
.SetTimestamp(local_event
.xbutton
.time
);
2117 if ( eventType
== wxEVT_MOTION
)
2119 if (local_event
.xmotion
.is_hint
== NotifyHint
)
2122 Display
*dpy
= XtDisplay (drawingArea
);
2124 XQueryPointer (dpy
, XtWindow (drawingArea
),
2126 &local_event
.xmotion
.x_root
,
2127 &local_event
.xmotion
.y_root
,
2128 &local_event
.xmotion
.x
,
2129 &local_event
.xmotion
.y
,
2130 &local_event
.xmotion
.state
);
2137 // Now check if we need to translate this event into a double click
2138 if (TRUE
) // canvas->doubleClickAllowed)
2140 if (wxevent
.ButtonDown())
2142 long dclickTime
= XtGetMultiClickTime((Display
*) wxGetDisplay());
2144 // get button and time-stamp
2146 if (wxevent
.LeftDown())
2148 else if (wxevent
.MiddleDown())
2150 else if (wxevent
.RightDown())
2152 long ts
= wxevent
.GetTimestamp();
2154 // check, if single or double click
2155 int buttonLast
= canvas
->GetLastClickedButton();
2156 long lastTS
= canvas
->GetLastClickTime();
2157 if ( buttonLast
&& buttonLast
== button
&& (ts
- lastTS
) < dclickTime
)
2160 canvas
->SetLastClick(0, ts
);
2162 wxEventType typeDouble
;
2163 if ( eventType
== wxEVT_LEFT_DOWN
)
2164 typeDouble
= wxEVT_LEFT_DCLICK
;
2165 else if ( eventType
== wxEVT_MIDDLE_DOWN
)
2166 typeDouble
= wxEVT_MIDDLE_DCLICK
;
2167 else if ( eventType
== wxEVT_RIGHT_DOWN
)
2168 typeDouble
= wxEVT_RIGHT_DCLICK
;
2170 typeDouble
= wxEVT_NULL
;
2172 if ( typeDouble
!= wxEVT_NULL
)
2174 wxevent
.SetEventType(typeDouble
);
2179 // not fast enough or different button
2180 canvas
->SetLastClick(button
, ts
);
2185 wxevent
.SetId(canvas
->GetId());
2186 wxevent
.SetEventObject(canvas
);
2187 wxevent
.m_x
= local_event
.xbutton
.x
;
2188 wxevent
.m_y
= local_event
.xbutton
.y
;
2189 canvas
->GetEventHandler()->ProcessEvent (wxevent
);
2191 if (eventType
== wxEVT_ENTER_WINDOW
||
2192 eventType
== wxEVT_LEAVE_WINDOW
||
2193 eventType
== wxEVT_MOTION
2201 wxKeyEvent
event (wxEVT_CHAR
);
2202 if (wxTranslateKeyEvent (event
, canvas
, (Widget
) 0, &local_event
))
2204 // Implement wxFrame::OnCharHook by checking ancestor.
2205 wxWindow
*parent
= canvas
->GetParent();
2206 while (parent
&& !parent
->IsKindOf(CLASSINFO(wxFrame
)))
2207 parent
= parent
->GetParent();
2211 event
.SetEventType(wxEVT_CHAR_HOOK
);
2212 if (parent
->GetEventHandler()->ProcessEvent(event
))
2216 // For simplicity, OnKeyDown is the same as OnChar
2217 // TODO: filter modifier key presses from OnChar
2218 event
.SetEventType(wxEVT_KEY_DOWN
);
2220 // Only process OnChar if OnKeyDown didn't swallow it
2221 if (!canvas
->GetEventHandler()->ProcessEvent (event
))
2223 event
.SetEventType(wxEVT_CHAR
);
2224 canvas
->GetEventHandler()->ProcessEvent (event
);
2231 wxKeyEvent
event (wxEVT_KEY_UP
);
2232 if (wxTranslateKeyEvent (event
, canvas
, (Widget
) 0, &local_event
))
2234 canvas
->GetEventHandler()->ProcessEvent (event
);
2240 if (local_event
.xfocus
.detail
!= NotifyPointer
)
2242 wxFocusEvent
event(wxEVT_SET_FOCUS
, canvas
->GetId());
2243 event
.SetEventObject(canvas
);
2244 canvas
->GetEventHandler()->ProcessEvent(event
);
2250 if (local_event
.xfocus
.detail
!= NotifyPointer
)
2252 wxFocusEvent
event(wxEVT_KILL_FOCUS
, canvas
->GetId());
2253 event
.SetEventObject(canvas
);
2254 canvas
->GetEventHandler()->ProcessEvent(event
);
2263 static void wxPanelItemEventHandler(Widget wid
,
2264 XtPointer
WXUNUSED(client_data
),
2266 Boolean
*continueToDispatch
)
2268 // Widget can be a label or the actual widget.
2270 wxWindow
*window
= wxGetWindowFromTable(wid
);
2273 wxMouseEvent
wxevent(0);
2274 if (wxTranslateMouseEvent(wxevent
, window
, wid
, event
))
2276 window
->GetEventHandler()->ProcessEvent(wxevent
);
2280 // TODO: probably the key to allowing default behaviour to happen. Say we
2281 // set a m_doDefault flag to FALSE at the start of this function. Then in
2282 // e.g. wxWindow::OnMouseEvent we can call Default() which sets this flag to
2283 // TRUE, indicating that default processing can happen. Thus, behaviour can
2284 // appear to be overridden just by adding an event handler and not calling
2285 // wxWindow::OnWhatever. ALSO, maybe we can use this instead of the current
2286 // way of handling drawing area events, to simplify things.
2287 *continueToDispatch
= True
;
2290 static void wxScrollBarCallback(Widget scrollbar
,
2291 XtPointer clientData
,
2292 XmScrollBarCallbackStruct
*cbs
)
2294 wxWindow
*win
= wxGetWindowFromTable(scrollbar
);
2295 int orientation
= (int) clientData
;
2297 wxEventType eventType
= wxEVT_NULL
;
2298 switch (cbs
->reason
)
2300 case XmCR_INCREMENT
:
2302 eventType
= wxEVT_SCROLLWIN_LINEDOWN
;
2305 case XmCR_DECREMENT
:
2307 eventType
= wxEVT_SCROLLWIN_LINEUP
;
2312 eventType
= wxEVT_SCROLLWIN_THUMBTRACK
;
2315 case XmCR_VALUE_CHANGED
:
2317 eventType
= wxEVT_SCROLLWIN_THUMBRELEASE
;
2320 case XmCR_PAGE_INCREMENT
:
2322 eventType
= wxEVT_SCROLLWIN_PAGEDOWN
;
2325 case XmCR_PAGE_DECREMENT
:
2327 eventType
= wxEVT_SCROLLWIN_PAGEUP
;
2332 eventType
= wxEVT_SCROLLWIN_TOP
;
2335 case XmCR_TO_BOTTOM
:
2337 eventType
= wxEVT_SCROLLWIN_BOTTOM
;
2342 // Should never get here
2343 wxFAIL_MSG("Unknown scroll event.");
2348 wxScrollWinEvent
event(eventType
,
2350 ((orientation
== XmHORIZONTAL
) ?
2351 wxHORIZONTAL
: wxVERTICAL
));
2352 event
.SetEventObject( win
);
2353 win
->GetEventHandler()->ProcessEvent(event
);
2356 // For repainting arbitrary windows
2357 void wxUniversalRepaintProc(Widget w
, XtPointer
WXUNUSED(c_data
), XEvent
*event
, char *)
2362 wxWindow
* win
= wxGetWindowFromTable(w
);
2366 switch(event
-> type
)
2370 window
= (Window
) win
-> GetXWindow();
2371 display
= (Display
*) win
-> GetXDisplay();
2373 if (event
-> xexpose
.count
== 0)
2377 win
->ClearUpdateRects();
2381 win
->AddUpdateRect(event
->xexpose
.x
, event
->xexpose
.y
,
2382 event
->xexpose
.width
, event
->xexpose
.height
);
2390 // ----------------------------------------------------------------------------
2391 // CanvaseXXXSize() functions
2392 // ----------------------------------------------------------------------------
2394 void wxWindow::CanvasSetSize(int x
, int y
, int w
, int h
, int sizeFlags
)
2396 CanvasSetSizeIntr(x
, y
, w
, h
, sizeFlags
, FALSE
);
2399 // SetSize, but as per old wxCanvas (with drawing widget etc.)
2400 void wxWindow::CanvasSetSizeIntr(int x
, int y
, int w
, int h
, int sizeFlags
,
2403 // A bit of optimization to help sort out the flickers.
2404 int oldX
= -1, oldY
= -1, oldW
= -1, oldH
= -1;
2405 // see the top of the file, near DoSetSizeIntr
2408 GetSize(& oldW
, & oldH
);
2409 GetPosition(& oldX
, & oldY
);
2412 bool useOldPos
= FALSE
;
2413 bool useOldSize
= FALSE
;
2415 if ((x
== -1) && (x
== -1) && ((sizeFlags
& wxSIZE_ALLOW_MINUS_ONE
) == 0))
2417 else if (x
== oldX
&& y
== oldY
)
2420 if ((w
== -1) && (h
== -1))
2422 else if (w
== oldW
&& h
== oldH
)
2425 if (!wxNoOptimize::CanOptimize())
2427 useOldSize
= FALSE
; useOldPos
= FALSE
;
2430 if (useOldPos
&& useOldSize
)
2433 Widget drawingArea
= (Widget
) m_drawingArea
;
2434 bool managed
= XtIsManaged(m_borderWidget
? (Widget
) m_borderWidget
: (Widget
) m_scrolledWindow
);
2437 XtUnmanageChild (m_borderWidget
? (Widget
) m_borderWidget
: (Widget
) m_scrolledWindow
);
2438 XtVaSetValues(drawingArea
, XmNresizePolicy
, XmRESIZE_ANY
, NULL
);
2440 int xx
= x
; int yy
= y
;
2441 AdjustForParentClientOrigin(xx
, yy
, sizeFlags
);
2445 if (x
> -1 || (sizeFlags
& wxSIZE_ALLOW_MINUS_ONE
))
2447 XtVaSetValues (m_borderWidget
? (Widget
) m_borderWidget
: (Widget
) m_scrolledWindow
,
2451 if (y
> -1 || (sizeFlags
& wxSIZE_ALLOW_MINUS_ONE
))
2453 XtVaSetValues (m_borderWidget
? (Widget
) m_borderWidget
: (Widget
) m_scrolledWindow
,
2465 XtVaSetValues ((Widget
) m_borderWidget
, XmNwidth
, w
, NULL
);
2466 short thick
, margin
;
2467 XtVaGetValues ((Widget
) m_borderWidget
,
2468 XmNshadowThickness
, &thick
,
2469 XmNmarginWidth
, &margin
,
2471 w
-= 2 * (thick
+ margin
);
2474 XtVaSetValues ((Widget
) m_scrolledWindow
, XmNwidth
, w
, NULL
);
2478 XtVaGetValues ((Widget
) m_scrolledWindow
,
2479 XmNspacing
, &spacing
,
2480 XmNverticalScrollBar
, &sbar
,
2484 XtVaGetValues (sbar
, XmNwidth
, &wsbar
, NULL
);
2488 w
-= (spacing
+ wsbar
);
2491 XtVaSetValues(drawingArea
, XmNwidth
, w
, NULL
);
2498 XtVaSetValues ((Widget
) m_borderWidget
, XmNheight
, h
, NULL
);
2499 short thick
, margin
;
2500 XtVaGetValues ((Widget
) m_borderWidget
,
2501 XmNshadowThickness
, &thick
,
2502 XmNmarginHeight
, &margin
,
2504 h
-= 2 * (thick
+ margin
);
2507 XtVaSetValues ((Widget
) m_scrolledWindow
, XmNheight
, h
, NULL
);
2511 XtVaGetValues ((Widget
) m_scrolledWindow
,
2512 XmNspacing
, &spacing
,
2513 XmNhorizontalScrollBar
, &sbar
,
2517 XtVaGetValues (sbar
, XmNheight
, &wsbar
, NULL
);
2521 h
-= (spacing
+ wsbar
);
2524 XtVaSetValues(drawingArea
, XmNheight
, h
, NULL
);
2530 XtManageChild (m_borderWidget
? (Widget
) m_borderWidget
: (Widget
) m_scrolledWindow
);
2531 XtVaSetValues(drawingArea
, XmNresizePolicy
, XmRESIZE_NONE
, NULL
);
2535 GetClientSize (&ww
, &hh
);
2536 wxSizeEvent
sizeEvent(wxSize(ww
, hh
), GetId());
2537 sizeEvent
.SetEventObject(this);
2539 GetEventHandler()->ProcessEvent(sizeEvent
);
2543 void wxWindow::CanvasSetClientSize (int w
, int h
)
2545 Widget drawingArea
= (Widget
) m_drawingArea
;
2547 XtVaSetValues(drawingArea
, XmNresizePolicy
, XmRESIZE_ANY
, NULL
);
2550 XtVaSetValues(drawingArea
, XmNwidth
, w
, NULL
);
2552 XtVaSetValues(drawingArea
, XmNheight
, h
, NULL
);
2555 // TODO: is this necessary?
2556 allowRepainting
= FALSE
;
2558 XSync (XtDisplay (drawingArea
), FALSE
);
2560 while (XtAppPending (wxTheApp
->appContext
))
2562 XFlush (XtDisplay (drawingArea
));
2563 XtAppNextEvent (wxTheApp
->appContext
, &event
);
2564 XtDispatchEvent (&event
);
2568 XtVaSetValues(drawingArea
, XmNresizePolicy
, XmRESIZE_NONE
, NULL
);
2571 allowRepainting
= TRUE
;
2574 wxSizeEvent
sizeEvent(wxSize(w
, h
), GetId());
2575 sizeEvent
.SetEventObject(this);
2577 GetEventHandler()->ProcessEvent(sizeEvent
);
2581 void wxWindow::CanvasGetClientSize (int *w
, int *h
) const
2583 // Must return the same thing that was set via SetClientSize
2585 XtVaGetValues ((Widget
) m_drawingArea
, XmNwidth
, &xx
, XmNheight
, &yy
, NULL
);
2590 void wxWindow::CanvasGetSize (int *w
, int *h
) const
2593 if ((Widget
) m_borderWidget
)
2594 XtVaGetValues ((Widget
) m_borderWidget
, XmNwidth
, &xx
, XmNheight
, &yy
, NULL
);
2595 else if ((Widget
) m_scrolledWindow
)
2596 XtVaGetValues ((Widget
) m_scrolledWindow
, XmNwidth
, &xx
, XmNheight
, &yy
, NULL
);
2598 XtVaGetValues ((Widget
) m_drawingArea
, XmNwidth
, &xx
, XmNheight
, &yy
, NULL
);
2604 void wxWindow::CanvasGetPosition (int *x
, int *y
) const
2607 XtVaGetValues (m_borderWidget
? (Widget
) m_borderWidget
: (Widget
) m_scrolledWindow
, XmNx
, &xx
, XmNy
, &yy
, NULL
);
2609 // We may be faking the client origin.
2610 // So a window that's really at (0, 30) may appear
2611 // (to wxWin apps) to be at (0, 0).
2614 wxPoint
pt(GetParent()->GetClientAreaOrigin());
2623 // ----------------------------------------------------------------------------
2624 // TranslateXXXEvent() functions
2625 // ----------------------------------------------------------------------------
2627 bool wxTranslateMouseEvent(wxMouseEvent
& wxevent
, wxWindow
*win
, Widget widget
, XEvent
*xevent
)
2629 switch (xevent
->xany
.type
)
2631 case EnterNotify
: // never received here - yes ? MB
2632 case LeaveNotify
: // never received here - yes ? MB
2637 wxEventType eventType
= wxEVT_NULL
;
2639 // FIXME: this is never true I think - MB
2641 if (xevent
->xany
.type
== LeaveNotify
)
2643 win
->SetButton1(FALSE
);
2644 win
->SetButton2(FALSE
);
2645 win
->SetButton3(FALSE
);
2648 else if (xevent
->xany
.type
== MotionNotify
)
2650 eventType
= wxEVT_MOTION
;
2652 else if (xevent
->xany
.type
== ButtonPress
)
2654 wxevent
.SetTimestamp(xevent
->xbutton
.time
);
2656 if (xevent
->xbutton
.button
== Button1
)
2658 eventType
= wxEVT_LEFT_DOWN
;
2659 win
->SetButton1(TRUE
);
2662 else if (xevent
->xbutton
.button
== Button2
)
2664 eventType
= wxEVT_MIDDLE_DOWN
;
2665 win
->SetButton2(TRUE
);
2668 else if (xevent
->xbutton
.button
== Button3
)
2670 eventType
= wxEVT_RIGHT_DOWN
;
2671 win
->SetButton3(TRUE
);
2675 // check for a double click
2677 long dclickTime
= XtGetMultiClickTime((Display
*) wxGetDisplay());
2678 long ts
= wxevent
.GetTimestamp();
2680 int buttonLast
= win
->GetLastClickedButton();
2681 long lastTS
= win
->GetLastClickTime();
2682 if ( buttonLast
&& buttonLast
== button
&& (ts
- lastTS
) < dclickTime
)
2685 win
->SetLastClick(0, ts
);
2686 if ( eventType
== wxEVT_LEFT_DOWN
)
2687 eventType
= wxEVT_LEFT_DCLICK
;
2688 else if ( eventType
== wxEVT_MIDDLE_DOWN
)
2689 eventType
= wxEVT_MIDDLE_DCLICK
;
2690 else if ( eventType
== wxEVT_RIGHT_DOWN
)
2691 eventType
= wxEVT_RIGHT_DCLICK
;
2695 // not fast enough or different button
2696 win
->SetLastClick(button
, ts
);
2699 else if (xevent
->xany
.type
== ButtonRelease
)
2701 if (xevent
->xbutton
.button
== Button1
)
2703 eventType
= wxEVT_LEFT_UP
;
2704 win
->SetButton1(FALSE
);
2706 else if (xevent
->xbutton
.button
== Button2
)
2708 eventType
= wxEVT_MIDDLE_UP
;
2709 win
->SetButton2(FALSE
);
2711 else if (xevent
->xbutton
.button
== Button3
)
2713 eventType
= wxEVT_RIGHT_UP
;
2714 win
->SetButton3(FALSE
);
2723 wxevent
.SetEventType(eventType
);
2726 XtVaGetValues(widget
, XmNx
, &x1
, XmNy
, &y1
, NULL
);
2729 win
->GetPosition(&x2
, &y2
);
2731 // The button x/y must be translated to wxWindows
2732 // window space - the widget might be a label or button,
2736 if (widget
!= (Widget
)win
->GetMainWidget())
2742 wxevent
.m_x
= xevent
->xbutton
.x
+ dx
;
2743 wxevent
.m_y
= xevent
->xbutton
.y
+ dy
;
2745 wxevent
.m_leftDown
= ((eventType
== wxEVT_LEFT_DOWN
)
2746 || (event_left_is_down (xevent
)
2747 && (eventType
!= wxEVT_LEFT_UP
)));
2748 wxevent
.m_middleDown
= ((eventType
== wxEVT_MIDDLE_DOWN
)
2749 || (event_middle_is_down (xevent
)
2750 && (eventType
!= wxEVT_MIDDLE_UP
)));
2751 wxevent
.m_rightDown
= ((eventType
== wxEVT_RIGHT_DOWN
)
2752 || (event_right_is_down (xevent
)
2753 && (eventType
!= wxEVT_RIGHT_UP
)));
2755 wxevent
.m_shiftDown
= xevent
->xbutton
.state
& ShiftMask
;
2756 wxevent
.m_controlDown
= xevent
->xbutton
.state
& ControlMask
;
2757 wxevent
.m_altDown
= xevent
->xbutton
.state
& Mod3Mask
;
2758 wxevent
.m_metaDown
= xevent
->xbutton
.state
& Mod1Mask
;
2760 wxevent
.SetId(win
->GetId());
2761 wxevent
.SetEventObject(win
);
2769 bool wxTranslateKeyEvent(wxKeyEvent
& wxevent
, wxWindow
*win
, Widget
WXUNUSED(widget
), XEvent
*xevent
)
2771 switch (xevent
->xany
.type
)
2780 XComposeStatus compose
;
2781 (void) XLookupString ((XKeyEvent
*) xevent
, buf
, 20, &keySym
, &compose
);
2783 (void) XLookupString ((XKeyEvent
*) xevent
, buf
, 20, &keySym
, NULL
);
2784 int id
= wxCharCodeXToWX (keySym
);
2785 // id may be WXK_xxx code - these are outside ASCII range, so we
2786 // can't just use toupper() on id
2787 if (id
>= 'a' && id
<= 'z')
2790 if (xevent
->xkey
.state
& ShiftMask
)
2791 wxevent
.m_shiftDown
= TRUE
;
2792 if (xevent
->xkey
.state
& ControlMask
)
2793 wxevent
.m_controlDown
= TRUE
;
2794 if (xevent
->xkey
.state
& Mod3Mask
)
2795 wxevent
.m_altDown
= TRUE
;
2796 if (xevent
->xkey
.state
& Mod1Mask
)
2797 wxevent
.m_metaDown
= TRUE
;
2798 wxevent
.SetEventObject(win
);
2799 wxevent
.m_keyCode
= id
;
2800 wxevent
.SetTimestamp(xevent
->xkey
.time
);
2802 wxevent
.m_x
= xevent
->xbutton
.x
;
2803 wxevent
.m_y
= xevent
->xbutton
.y
;
2817 // ----------------------------------------------------------------------------
2819 // ----------------------------------------------------------------------------
2821 #define YAllocColor XAllocColor
2822 XColor g_itemColors
[5];
2823 int wxComputeColours (Display
*display
, wxColour
* back
, wxColour
* fore
)
2826 static XmColorProc colorProc
;
2828 result
= wxNO_COLORS
;
2832 g_itemColors
[0].red
= (((long) back
->Red ()) << 8);
2833 g_itemColors
[0].green
= (((long) back
->Green ()) << 8);
2834 g_itemColors
[0].blue
= (((long) back
->Blue ()) << 8);
2835 g_itemColors
[0].flags
= DoRed
| DoGreen
| DoBlue
;
2836 if (colorProc
== (XmColorProc
) NULL
)
2838 // Get a ptr to the actual function
2839 colorProc
= XmSetColorCalculation ((XmColorProc
) NULL
);
2840 // And set it back to motif.
2841 XmSetColorCalculation (colorProc
);
2843 (*colorProc
) (&g_itemColors
[wxBACK_INDEX
],
2844 &g_itemColors
[wxFORE_INDEX
],
2845 &g_itemColors
[wxSELE_INDEX
],
2846 &g_itemColors
[wxTOPS_INDEX
],
2847 &g_itemColors
[wxBOTS_INDEX
]);
2848 result
= wxBACK_COLORS
;
2852 g_itemColors
[wxFORE_INDEX
].red
= (((long) fore
->Red ()) << 8);
2853 g_itemColors
[wxFORE_INDEX
].green
= (((long) fore
->Green ()) << 8);
2854 g_itemColors
[wxFORE_INDEX
].blue
= (((long) fore
->Blue ()) << 8);
2855 g_itemColors
[wxFORE_INDEX
].flags
= DoRed
| DoGreen
| DoBlue
;
2856 if (result
== wxNO_COLORS
)
2857 result
= wxFORE_COLORS
;
2860 Display
*dpy
= display
;
2861 Colormap cmap
= (Colormap
) wxTheApp
->GetMainColormap((WXDisplay
*) dpy
);
2865 /* 5 Colours to allocate */
2866 for (int i
= 0; i
< 5; i
++)
2867 if (!YAllocColor (dpy
, cmap
, &g_itemColors
[i
]))
2868 result
= wxNO_COLORS
;
2872 /* Only 1 colour to allocate */
2873 if (!YAllocColor (dpy
, cmap
, &g_itemColors
[wxFORE_INDEX
]))
2874 result
= wxNO_COLORS
;
2881 // Changes the foreground and background colours to be derived from the current
2882 // background colour. To change the foreground colour, you must call
2883 // SetForegroundColour explicitly.
2884 void wxWindow::ChangeBackgroundColour()
2886 WXWidget mainWidget
= GetMainWidget();
2888 DoChangeBackgroundColour(mainWidget
, m_backgroundColour
);
2890 // This not necessary
2893 if (m_scrolledWindow
&& (GetMainWidget() != m_scrolledWindow
))
2895 DoChangeBackgroundColour(m_scrolledWindow
, m_backgroundColour
);
2896 // Have to set the scrollbar colours back since
2897 // the scrolled window seemed to change them
2898 wxColour backgroundColour
= wxSystemSettings::GetColour(wxSYS_COLOUR_3DFACE
);
2901 DoChangeBackgroundColour(m_hScrollBar
, backgroundColour
);
2903 DoChangeBackgroundColour(m_vScrollBar
, backgroundColour
);
2908 void wxWindow::ChangeForegroundColour()
2910 WXWidget mainWidget
= GetMainWidget();
2912 DoChangeForegroundColour(mainWidget
, m_foregroundColour
);
2913 if ( m_scrolledWindow
&& mainWidget
!= m_scrolledWindow
)
2914 DoChangeForegroundColour(m_scrolledWindow
, m_foregroundColour
);
2917 // Change a widget's foreground and background colours.
2918 void wxWindow::DoChangeForegroundColour(WXWidget widget
,
2919 wxColour
& foregroundColour
)
2921 wxDoChangeForegroundColour( widget
, foregroundColour
);
2924 void wxWindow::DoChangeBackgroundColour(WXWidget widget
,
2925 wxColour
& backgroundColour
,
2926 bool changeArmColour
)
2928 wxDoChangeBackgroundColour( widget
, backgroundColour
, changeArmColour
);
2931 bool wxWindow::SetBackgroundColour(const wxColour
& col
)
2933 if ( !wxWindowBase::SetBackgroundColour(col
) )
2936 ChangeBackgroundColour();
2941 bool wxWindow::SetForegroundColour(const wxColour
& col
)
2943 if ( !wxWindowBase::SetForegroundColour(col
) )
2946 ChangeForegroundColour();
2951 void wxWindow::ChangeFont(bool keepOriginalSize
)
2953 // Note that this causes the widget to be resized back
2954 // to its original size! We therefore have to set the size
2955 // back again. TODO: a better way in Motif?
2956 Widget w
= (Widget
) GetLabelWidget(); // Usually the main widget
2957 if (w
&& m_font
.Ok())
2959 int width
, height
, width1
, height1
;
2960 GetSize(& width
, & height
);
2962 wxDoChangeFont( GetLabelWidget(), m_font
);
2964 GetSize(& width1
, & height1
);
2965 if (keepOriginalSize
&& (width
!= width1
|| height
!= height1
))
2967 SetSize(-1, -1, width
, height
);
2972 // ----------------------------------------------------------------------------
2974 // ----------------------------------------------------------------------------
2976 wxWindow
*wxGetActiveWindow()
2979 wxFAIL_MSG("Not implemented");
2984 wxWindow
*wxWindowBase::GetCapture()
2986 return (wxWindow
*)g_captureWindow
;
2990 // Find the wxWindow at the current mouse position, returning the mouse
2992 wxWindow
* wxFindWindowAtPointer(wxPoint
& pt
)
2994 return wxFindWindowAtPoint(wxGetMousePosition());
2997 // Get the current mouse position.
2998 wxPoint
wxGetMousePosition()
3000 Display
*display
= (Display
*) wxGetDisplay();
3001 Window rootWindow
= RootWindowOfScreen (DefaultScreenOfDisplay(display
));
3002 Window rootReturn
, childReturn
;
3003 int rootX
, rootY
, winX
, winY
;
3004 unsigned int maskReturn
;
3006 XQueryPointer (display
,
3010 &rootX
, &rootY
, &winX
, &winY
, &maskReturn
);
3011 return wxPoint(rootX
, rootY
);
3015 // ----------------------------------------------------------------------------
3016 // wxNoOptimize: switch off size optimization
3017 // ----------------------------------------------------------------------------
3019 int wxNoOptimize::ms_count
= 0;