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
), XButtonEvent
* WXUNUSED(event
))
2002 #if XmVersion <= 1000
2003 XmDrawingAreaCallbackStruct cbs
;
2006 ev
= *((XEvent
*) event
);
2007 cbs
.reason
= XmCR_INPUT
;
2010 wxCanvasInputEvent (drawingArea
, (XtPointer
) NULL
, &cbs
);
2011 #endif // XmVersion <= 1000
2014 static void wxCanvasInputEvent(Widget drawingArea
,
2015 XtPointer
WXUNUSED(data
),
2016 XmDrawingAreaCallbackStruct
* cbs
)
2018 wxWindow
*canvas
= wxGetWindowFromTable(drawingArea
);
2024 if (cbs
->reason
!= XmCR_INPUT
)
2027 local_event
= *(cbs
->event
); // We must keep a copy!
2029 switch (local_event
.xany
.type
)
2037 // FIXME: most of this mouse event code is more or less
2038 // duplicated in wxTranslateMouseEvent
2040 wxEventType eventType
= wxEVT_NULL
;
2042 if (local_event
.xany
.type
== EnterNotify
)
2044 //if (local_event.xcrossing.mode!=NotifyNormal)
2045 // return ; // Ignore grab events
2046 eventType
= wxEVT_ENTER_WINDOW
;
2047 // canvas->GetEventHandler()->OnSetFocus();
2049 else if (local_event
.xany
.type
== LeaveNotify
)
2051 //if (local_event.xcrossingr.mode!=NotifyNormal)
2052 // return ; // Ignore grab events
2053 eventType
= wxEVT_LEAVE_WINDOW
;
2054 // canvas->GetEventHandler()->OnKillFocus();
2056 else if (local_event
.xany
.type
== MotionNotify
)
2058 eventType
= wxEVT_MOTION
;
2061 else if (local_event
.xany
.type
== ButtonPress
)
2063 if (local_event
.xbutton
.button
== Button1
)
2065 eventType
= wxEVT_LEFT_DOWN
;
2066 canvas
->SetButton1(TRUE
);
2068 else if (local_event
.xbutton
.button
== Button2
)
2070 eventType
= wxEVT_MIDDLE_DOWN
;
2071 canvas
->SetButton2(TRUE
);
2073 else if (local_event
.xbutton
.button
== Button3
)
2075 eventType
= wxEVT_RIGHT_DOWN
;
2076 canvas
->SetButton3(TRUE
);
2079 else if (local_event
.xany
.type
== ButtonRelease
)
2081 if (local_event
.xbutton
.button
== Button1
)
2083 eventType
= wxEVT_LEFT_UP
;
2084 canvas
->SetButton1(FALSE
);
2086 else if (local_event
.xbutton
.button
== Button2
)
2088 eventType
= wxEVT_MIDDLE_UP
;
2089 canvas
->SetButton2(FALSE
);
2091 else if (local_event
.xbutton
.button
== Button3
)
2093 eventType
= wxEVT_RIGHT_UP
;
2094 canvas
->SetButton3(FALSE
);
2098 wxMouseEvent
wxevent (eventType
);
2100 wxevent
.m_leftDown
= ((eventType
== wxEVT_LEFT_DOWN
)
2101 || (event_left_is_down (&local_event
)
2102 && (eventType
!= wxEVT_LEFT_UP
)));
2103 wxevent
.m_middleDown
= ((eventType
== wxEVT_MIDDLE_DOWN
)
2104 || (event_middle_is_down (&local_event
)
2105 && (eventType
!= wxEVT_MIDDLE_UP
)));
2106 wxevent
.m_rightDown
= ((eventType
== wxEVT_RIGHT_DOWN
)
2107 || (event_right_is_down (&local_event
)
2108 && (eventType
!= wxEVT_RIGHT_UP
)));
2110 wxevent
.m_shiftDown
= local_event
.xbutton
.state
& ShiftMask
;
2111 wxevent
.m_controlDown
= local_event
.xbutton
.state
& ControlMask
;
2112 wxevent
.m_altDown
= local_event
.xbutton
.state
& Mod3Mask
;
2113 wxevent
.m_metaDown
= local_event
.xbutton
.state
& Mod1Mask
;
2114 wxevent
.SetTimestamp(local_event
.xbutton
.time
);
2116 if ( eventType
== wxEVT_MOTION
)
2118 if (local_event
.xmotion
.is_hint
== NotifyHint
)
2121 Display
*dpy
= XtDisplay (drawingArea
);
2123 XQueryPointer (dpy
, XtWindow (drawingArea
),
2125 &local_event
.xmotion
.x_root
,
2126 &local_event
.xmotion
.y_root
,
2127 &local_event
.xmotion
.x
,
2128 &local_event
.xmotion
.y
,
2129 &local_event
.xmotion
.state
);
2136 // Now check if we need to translate this event into a double click
2137 if (TRUE
) // canvas->doubleClickAllowed)
2139 if (wxevent
.ButtonDown())
2141 long dclickTime
= XtGetMultiClickTime((Display
*) wxGetDisplay());
2143 // get button and time-stamp
2145 if (wxevent
.LeftDown())
2147 else if (wxevent
.MiddleDown())
2149 else if (wxevent
.RightDown())
2151 long ts
= wxevent
.GetTimestamp();
2153 // check, if single or double click
2154 int buttonLast
= canvas
->GetLastClickedButton();
2155 long lastTS
= canvas
->GetLastClickTime();
2156 if ( buttonLast
&& buttonLast
== button
&& (ts
- lastTS
) < dclickTime
)
2159 canvas
->SetLastClick(0, ts
);
2161 wxEventType typeDouble
;
2162 if ( eventType
== wxEVT_LEFT_DOWN
)
2163 typeDouble
= wxEVT_LEFT_DCLICK
;
2164 else if ( eventType
== wxEVT_MIDDLE_DOWN
)
2165 typeDouble
= wxEVT_MIDDLE_DCLICK
;
2166 else if ( eventType
== wxEVT_RIGHT_DOWN
)
2167 typeDouble
= wxEVT_RIGHT_DCLICK
;
2169 typeDouble
= wxEVT_NULL
;
2171 if ( typeDouble
!= wxEVT_NULL
)
2173 wxevent
.SetEventType(typeDouble
);
2178 // not fast enough or different button
2179 canvas
->SetLastClick(button
, ts
);
2184 wxevent
.SetId(canvas
->GetId());
2185 wxevent
.SetEventObject(canvas
);
2186 wxevent
.m_x
= local_event
.xbutton
.x
;
2187 wxevent
.m_y
= local_event
.xbutton
.y
;
2188 canvas
->GetEventHandler()->ProcessEvent (wxevent
);
2190 if (eventType
== wxEVT_ENTER_WINDOW
||
2191 eventType
== wxEVT_LEAVE_WINDOW
||
2192 eventType
== wxEVT_MOTION
2200 wxKeyEvent
event (wxEVT_CHAR
);
2201 if (wxTranslateKeyEvent (event
, canvas
, (Widget
) 0, &local_event
))
2203 // Implement wxFrame::OnCharHook by checking ancestor.
2204 wxWindow
*parent
= canvas
->GetParent();
2205 while (parent
&& !parent
->IsKindOf(CLASSINFO(wxFrame
)))
2206 parent
= parent
->GetParent();
2210 event
.SetEventType(wxEVT_CHAR_HOOK
);
2211 if (parent
->GetEventHandler()->ProcessEvent(event
))
2215 // For simplicity, OnKeyDown is the same as OnChar
2216 // TODO: filter modifier key presses from OnChar
2217 event
.SetEventType(wxEVT_KEY_DOWN
);
2219 // Only process OnChar if OnKeyDown didn't swallow it
2220 if (!canvas
->GetEventHandler()->ProcessEvent (event
))
2222 event
.SetEventType(wxEVT_CHAR
);
2223 canvas
->GetEventHandler()->ProcessEvent (event
);
2230 wxKeyEvent
event (wxEVT_KEY_UP
);
2231 if (wxTranslateKeyEvent (event
, canvas
, (Widget
) 0, &local_event
))
2233 canvas
->GetEventHandler()->ProcessEvent (event
);
2239 if (local_event
.xfocus
.detail
!= NotifyPointer
)
2241 wxFocusEvent
event(wxEVT_SET_FOCUS
, canvas
->GetId());
2242 event
.SetEventObject(canvas
);
2243 canvas
->GetEventHandler()->ProcessEvent(event
);
2249 if (local_event
.xfocus
.detail
!= NotifyPointer
)
2251 wxFocusEvent
event(wxEVT_KILL_FOCUS
, canvas
->GetId());
2252 event
.SetEventObject(canvas
);
2253 canvas
->GetEventHandler()->ProcessEvent(event
);
2262 static void wxPanelItemEventHandler(Widget wid
,
2263 XtPointer
WXUNUSED(client_data
),
2265 Boolean
*continueToDispatch
)
2267 // Widget can be a label or the actual widget.
2269 wxWindow
*window
= wxGetWindowFromTable(wid
);
2272 wxMouseEvent
wxevent(0);
2273 if (wxTranslateMouseEvent(wxevent
, window
, wid
, event
))
2275 window
->GetEventHandler()->ProcessEvent(wxevent
);
2279 // TODO: probably the key to allowing default behaviour to happen. Say we
2280 // set a m_doDefault flag to FALSE at the start of this function. Then in
2281 // e.g. wxWindow::OnMouseEvent we can call Default() which sets this flag to
2282 // TRUE, indicating that default processing can happen. Thus, behaviour can
2283 // appear to be overridden just by adding an event handler and not calling
2284 // wxWindow::OnWhatever. ALSO, maybe we can use this instead of the current
2285 // way of handling drawing area events, to simplify things.
2286 *continueToDispatch
= True
;
2289 static void wxScrollBarCallback(Widget scrollbar
,
2290 XtPointer clientData
,
2291 XmScrollBarCallbackStruct
*cbs
)
2293 wxWindow
*win
= wxGetWindowFromTable(scrollbar
);
2294 int orientation
= (int) clientData
;
2296 wxEventType eventType
= wxEVT_NULL
;
2297 switch (cbs
->reason
)
2299 case XmCR_INCREMENT
:
2301 eventType
= wxEVT_SCROLLWIN_LINEDOWN
;
2304 case XmCR_DECREMENT
:
2306 eventType
= wxEVT_SCROLLWIN_LINEUP
;
2311 eventType
= wxEVT_SCROLLWIN_THUMBTRACK
;
2314 case XmCR_VALUE_CHANGED
:
2316 eventType
= wxEVT_SCROLLWIN_THUMBRELEASE
;
2319 case XmCR_PAGE_INCREMENT
:
2321 eventType
= wxEVT_SCROLLWIN_PAGEDOWN
;
2324 case XmCR_PAGE_DECREMENT
:
2326 eventType
= wxEVT_SCROLLWIN_PAGEUP
;
2331 eventType
= wxEVT_SCROLLWIN_TOP
;
2334 case XmCR_TO_BOTTOM
:
2336 eventType
= wxEVT_SCROLLWIN_BOTTOM
;
2341 // Should never get here
2342 wxFAIL_MSG("Unknown scroll event.");
2347 wxScrollWinEvent
event(eventType
,
2349 ((orientation
== XmHORIZONTAL
) ?
2350 wxHORIZONTAL
: wxVERTICAL
));
2351 event
.SetEventObject( win
);
2352 win
->GetEventHandler()->ProcessEvent(event
);
2355 // For repainting arbitrary windows
2356 void wxUniversalRepaintProc(Widget w
, XtPointer
WXUNUSED(c_data
), XEvent
*event
, char *)
2361 wxWindow
* win
= wxGetWindowFromTable(w
);
2365 switch(event
-> type
)
2369 window
= (Window
) win
-> GetXWindow();
2370 display
= (Display
*) win
-> GetXDisplay();
2372 if (event
-> xexpose
.count
== 0)
2376 win
->ClearUpdateRects();
2380 win
->AddUpdateRect(event
->xexpose
.x
, event
->xexpose
.y
,
2381 event
->xexpose
.width
, event
->xexpose
.height
);
2389 // ----------------------------------------------------------------------------
2390 // CanvaseXXXSize() functions
2391 // ----------------------------------------------------------------------------
2393 void wxWindow::CanvasSetSize(int x
, int y
, int w
, int h
, int sizeFlags
)
2395 CanvasSetSizeIntr(x
, y
, w
, h
, sizeFlags
, FALSE
);
2398 // SetSize, but as per old wxCanvas (with drawing widget etc.)
2399 void wxWindow::CanvasSetSizeIntr(int x
, int y
, int w
, int h
, int sizeFlags
,
2402 // A bit of optimization to help sort out the flickers.
2403 int oldX
= -1, oldY
= -1, oldW
= -1, oldH
= -1;
2404 // see the top of the file, near DoSetSizeIntr
2407 GetSize(& oldW
, & oldH
);
2408 GetPosition(& oldX
, & oldY
);
2411 bool useOldPos
= FALSE
;
2412 bool useOldSize
= FALSE
;
2414 if ((x
== -1) && (x
== -1) && ((sizeFlags
& wxSIZE_ALLOW_MINUS_ONE
) == 0))
2416 else if (x
== oldX
&& y
== oldY
)
2419 if ((w
== -1) && (h
== -1))
2421 else if (w
== oldW
&& h
== oldH
)
2424 if (!wxNoOptimize::CanOptimize())
2426 useOldSize
= FALSE
; useOldPos
= FALSE
;
2429 if (useOldPos
&& useOldSize
)
2432 Widget drawingArea
= (Widget
) m_drawingArea
;
2433 bool managed
= XtIsManaged(m_borderWidget
? (Widget
) m_borderWidget
: (Widget
) m_scrolledWindow
);
2436 XtUnmanageChild (m_borderWidget
? (Widget
) m_borderWidget
: (Widget
) m_scrolledWindow
);
2437 XtVaSetValues(drawingArea
, XmNresizePolicy
, XmRESIZE_ANY
, NULL
);
2439 int xx
= x
; int yy
= y
;
2440 AdjustForParentClientOrigin(xx
, yy
, sizeFlags
);
2444 if (x
> -1 || (sizeFlags
& wxSIZE_ALLOW_MINUS_ONE
))
2446 XtVaSetValues (m_borderWidget
? (Widget
) m_borderWidget
: (Widget
) m_scrolledWindow
,
2450 if (y
> -1 || (sizeFlags
& wxSIZE_ALLOW_MINUS_ONE
))
2452 XtVaSetValues (m_borderWidget
? (Widget
) m_borderWidget
: (Widget
) m_scrolledWindow
,
2464 XtVaSetValues ((Widget
) m_borderWidget
, XmNwidth
, w
, NULL
);
2465 short thick
, margin
;
2466 XtVaGetValues ((Widget
) m_borderWidget
,
2467 XmNshadowThickness
, &thick
,
2468 XmNmarginWidth
, &margin
,
2470 w
-= 2 * (thick
+ margin
);
2473 XtVaSetValues ((Widget
) m_scrolledWindow
, XmNwidth
, w
, NULL
);
2477 XtVaGetValues ((Widget
) m_scrolledWindow
,
2478 XmNspacing
, &spacing
,
2479 XmNverticalScrollBar
, &sbar
,
2483 XtVaGetValues (sbar
, XmNwidth
, &wsbar
, NULL
);
2487 w
-= (spacing
+ wsbar
);
2490 XtVaSetValues(drawingArea
, XmNwidth
, w
, NULL
);
2497 XtVaSetValues ((Widget
) m_borderWidget
, XmNheight
, h
, NULL
);
2498 short thick
, margin
;
2499 XtVaGetValues ((Widget
) m_borderWidget
,
2500 XmNshadowThickness
, &thick
,
2501 XmNmarginHeight
, &margin
,
2503 h
-= 2 * (thick
+ margin
);
2506 XtVaSetValues ((Widget
) m_scrolledWindow
, XmNheight
, h
, NULL
);
2510 XtVaGetValues ((Widget
) m_scrolledWindow
,
2511 XmNspacing
, &spacing
,
2512 XmNhorizontalScrollBar
, &sbar
,
2516 XtVaGetValues (sbar
, XmNheight
, &wsbar
, NULL
);
2520 h
-= (spacing
+ wsbar
);
2523 XtVaSetValues(drawingArea
, XmNheight
, h
, NULL
);
2529 XtManageChild (m_borderWidget
? (Widget
) m_borderWidget
: (Widget
) m_scrolledWindow
);
2530 XtVaSetValues(drawingArea
, XmNresizePolicy
, XmRESIZE_NONE
, NULL
);
2534 GetClientSize (&ww
, &hh
);
2535 wxSizeEvent
sizeEvent(wxSize(ww
, hh
), GetId());
2536 sizeEvent
.SetEventObject(this);
2538 GetEventHandler()->ProcessEvent(sizeEvent
);
2542 void wxWindow::CanvasSetClientSize (int w
, int h
)
2544 Widget drawingArea
= (Widget
) m_drawingArea
;
2546 XtVaSetValues(drawingArea
, XmNresizePolicy
, XmRESIZE_ANY
, NULL
);
2549 XtVaSetValues(drawingArea
, XmNwidth
, w
, NULL
);
2551 XtVaSetValues(drawingArea
, XmNheight
, h
, NULL
);
2554 // TODO: is this necessary?
2555 allowRepainting
= FALSE
;
2557 XSync (XtDisplay (drawingArea
), FALSE
);
2559 while (XtAppPending (wxTheApp
->appContext
))
2561 XFlush (XtDisplay (drawingArea
));
2562 XtAppNextEvent (wxTheApp
->appContext
, &event
);
2563 XtDispatchEvent (&event
);
2567 XtVaSetValues(drawingArea
, XmNresizePolicy
, XmRESIZE_NONE
, NULL
);
2570 allowRepainting
= TRUE
;
2573 wxSizeEvent
sizeEvent(wxSize(w
, h
), GetId());
2574 sizeEvent
.SetEventObject(this);
2576 GetEventHandler()->ProcessEvent(sizeEvent
);
2580 void wxWindow::CanvasGetClientSize (int *w
, int *h
) const
2582 // Must return the same thing that was set via SetClientSize
2584 XtVaGetValues ((Widget
) m_drawingArea
, XmNwidth
, &xx
, XmNheight
, &yy
, NULL
);
2589 void wxWindow::CanvasGetSize (int *w
, int *h
) const
2592 if ((Widget
) m_borderWidget
)
2593 XtVaGetValues ((Widget
) m_borderWidget
, XmNwidth
, &xx
, XmNheight
, &yy
, NULL
);
2594 else if ((Widget
) m_scrolledWindow
)
2595 XtVaGetValues ((Widget
) m_scrolledWindow
, XmNwidth
, &xx
, XmNheight
, &yy
, NULL
);
2597 XtVaGetValues ((Widget
) m_drawingArea
, XmNwidth
, &xx
, XmNheight
, &yy
, NULL
);
2603 void wxWindow::CanvasGetPosition (int *x
, int *y
) const
2606 XtVaGetValues (m_borderWidget
? (Widget
) m_borderWidget
: (Widget
) m_scrolledWindow
, XmNx
, &xx
, XmNy
, &yy
, NULL
);
2608 // We may be faking the client origin.
2609 // So a window that's really at (0, 30) may appear
2610 // (to wxWin apps) to be at (0, 0).
2613 wxPoint
pt(GetParent()->GetClientAreaOrigin());
2622 // ----------------------------------------------------------------------------
2623 // TranslateXXXEvent() functions
2624 // ----------------------------------------------------------------------------
2626 bool wxTranslateMouseEvent(wxMouseEvent
& wxevent
, wxWindow
*win
, Widget widget
, XEvent
*xevent
)
2628 switch (xevent
->xany
.type
)
2630 case EnterNotify
: // never received here - yes ? MB
2631 case LeaveNotify
: // never received here - yes ? MB
2636 wxEventType eventType
= wxEVT_NULL
;
2638 // FIXME: this is never true I think - MB
2640 if (xevent
->xany
.type
== LeaveNotify
)
2642 win
->SetButton1(FALSE
);
2643 win
->SetButton2(FALSE
);
2644 win
->SetButton3(FALSE
);
2647 else if (xevent
->xany
.type
== MotionNotify
)
2649 eventType
= wxEVT_MOTION
;
2651 else if (xevent
->xany
.type
== ButtonPress
)
2653 wxevent
.SetTimestamp(xevent
->xbutton
.time
);
2655 if (xevent
->xbutton
.button
== Button1
)
2657 eventType
= wxEVT_LEFT_DOWN
;
2658 win
->SetButton1(TRUE
);
2661 else if (xevent
->xbutton
.button
== Button2
)
2663 eventType
= wxEVT_MIDDLE_DOWN
;
2664 win
->SetButton2(TRUE
);
2667 else if (xevent
->xbutton
.button
== Button3
)
2669 eventType
= wxEVT_RIGHT_DOWN
;
2670 win
->SetButton3(TRUE
);
2674 // check for a double click
2676 long dclickTime
= XtGetMultiClickTime((Display
*) wxGetDisplay());
2677 long ts
= wxevent
.GetTimestamp();
2679 int buttonLast
= win
->GetLastClickedButton();
2680 long lastTS
= win
->GetLastClickTime();
2681 if ( buttonLast
&& buttonLast
== button
&& (ts
- lastTS
) < dclickTime
)
2684 win
->SetLastClick(0, ts
);
2685 if ( eventType
== wxEVT_LEFT_DOWN
)
2686 eventType
= wxEVT_LEFT_DCLICK
;
2687 else if ( eventType
== wxEVT_MIDDLE_DOWN
)
2688 eventType
= wxEVT_MIDDLE_DCLICK
;
2689 else if ( eventType
== wxEVT_RIGHT_DOWN
)
2690 eventType
= wxEVT_RIGHT_DCLICK
;
2694 // not fast enough or different button
2695 win
->SetLastClick(button
, ts
);
2698 else if (xevent
->xany
.type
== ButtonRelease
)
2700 if (xevent
->xbutton
.button
== Button1
)
2702 eventType
= wxEVT_LEFT_UP
;
2703 win
->SetButton1(FALSE
);
2705 else if (xevent
->xbutton
.button
== Button2
)
2707 eventType
= wxEVT_MIDDLE_UP
;
2708 win
->SetButton2(FALSE
);
2710 else if (xevent
->xbutton
.button
== Button3
)
2712 eventType
= wxEVT_RIGHT_UP
;
2713 win
->SetButton3(FALSE
);
2722 wxevent
.SetEventType(eventType
);
2725 XtVaGetValues(widget
, XmNx
, &x1
, XmNy
, &y1
, NULL
);
2728 win
->GetPosition(&x2
, &y2
);
2730 // The button x/y must be translated to wxWindows
2731 // window space - the widget might be a label or button,
2735 if (widget
!= (Widget
)win
->GetMainWidget())
2741 wxevent
.m_x
= xevent
->xbutton
.x
+ dx
;
2742 wxevent
.m_y
= xevent
->xbutton
.y
+ dy
;
2744 wxevent
.m_leftDown
= ((eventType
== wxEVT_LEFT_DOWN
)
2745 || (event_left_is_down (xevent
)
2746 && (eventType
!= wxEVT_LEFT_UP
)));
2747 wxevent
.m_middleDown
= ((eventType
== wxEVT_MIDDLE_DOWN
)
2748 || (event_middle_is_down (xevent
)
2749 && (eventType
!= wxEVT_MIDDLE_UP
)));
2750 wxevent
.m_rightDown
= ((eventType
== wxEVT_RIGHT_DOWN
)
2751 || (event_right_is_down (xevent
)
2752 && (eventType
!= wxEVT_RIGHT_UP
)));
2754 wxevent
.m_shiftDown
= xevent
->xbutton
.state
& ShiftMask
;
2755 wxevent
.m_controlDown
= xevent
->xbutton
.state
& ControlMask
;
2756 wxevent
.m_altDown
= xevent
->xbutton
.state
& Mod3Mask
;
2757 wxevent
.m_metaDown
= xevent
->xbutton
.state
& Mod1Mask
;
2759 wxevent
.SetId(win
->GetId());
2760 wxevent
.SetEventObject(win
);
2768 bool wxTranslateKeyEvent(wxKeyEvent
& wxevent
, wxWindow
*win
, Widget
WXUNUSED(widget
), XEvent
*xevent
)
2770 switch (xevent
->xany
.type
)
2779 XComposeStatus compose
;
2780 (void) XLookupString ((XKeyEvent
*) xevent
, buf
, 20, &keySym
, &compose
);
2782 (void) XLookupString ((XKeyEvent
*) xevent
, buf
, 20, &keySym
, NULL
);
2783 int id
= wxCharCodeXToWX (keySym
);
2784 // id may be WXK_xxx code - these are outside ASCII range, so we
2785 // can't just use toupper() on id
2786 if (id
>= 'a' && id
<= 'z')
2789 if (xevent
->xkey
.state
& ShiftMask
)
2790 wxevent
.m_shiftDown
= TRUE
;
2791 if (xevent
->xkey
.state
& ControlMask
)
2792 wxevent
.m_controlDown
= TRUE
;
2793 if (xevent
->xkey
.state
& Mod3Mask
)
2794 wxevent
.m_altDown
= TRUE
;
2795 if (xevent
->xkey
.state
& Mod1Mask
)
2796 wxevent
.m_metaDown
= TRUE
;
2797 wxevent
.SetEventObject(win
);
2798 wxevent
.m_keyCode
= id
;
2799 wxevent
.SetTimestamp(xevent
->xkey
.time
);
2801 wxevent
.m_x
= xevent
->xbutton
.x
;
2802 wxevent
.m_y
= xevent
->xbutton
.y
;
2816 // ----------------------------------------------------------------------------
2818 // ----------------------------------------------------------------------------
2820 #define YAllocColor XAllocColor
2821 XColor g_itemColors
[5];
2822 int wxComputeColours (Display
*display
, wxColour
* back
, wxColour
* fore
)
2825 static XmColorProc colorProc
;
2827 result
= wxNO_COLORS
;
2831 g_itemColors
[0].red
= (((long) back
->Red ()) << 8);
2832 g_itemColors
[0].green
= (((long) back
->Green ()) << 8);
2833 g_itemColors
[0].blue
= (((long) back
->Blue ()) << 8);
2834 g_itemColors
[0].flags
= DoRed
| DoGreen
| DoBlue
;
2835 if (colorProc
== (XmColorProc
) NULL
)
2837 // Get a ptr to the actual function
2838 colorProc
= XmSetColorCalculation ((XmColorProc
) NULL
);
2839 // And set it back to motif.
2840 XmSetColorCalculation (colorProc
);
2842 (*colorProc
) (&g_itemColors
[wxBACK_INDEX
],
2843 &g_itemColors
[wxFORE_INDEX
],
2844 &g_itemColors
[wxSELE_INDEX
],
2845 &g_itemColors
[wxTOPS_INDEX
],
2846 &g_itemColors
[wxBOTS_INDEX
]);
2847 result
= wxBACK_COLORS
;
2851 g_itemColors
[wxFORE_INDEX
].red
= (((long) fore
->Red ()) << 8);
2852 g_itemColors
[wxFORE_INDEX
].green
= (((long) fore
->Green ()) << 8);
2853 g_itemColors
[wxFORE_INDEX
].blue
= (((long) fore
->Blue ()) << 8);
2854 g_itemColors
[wxFORE_INDEX
].flags
= DoRed
| DoGreen
| DoBlue
;
2855 if (result
== wxNO_COLORS
)
2856 result
= wxFORE_COLORS
;
2859 Display
*dpy
= display
;
2860 Colormap cmap
= (Colormap
) wxTheApp
->GetMainColormap((WXDisplay
*) dpy
);
2864 /* 5 Colours to allocate */
2865 for (int i
= 0; i
< 5; i
++)
2866 if (!YAllocColor (dpy
, cmap
, &g_itemColors
[i
]))
2867 result
= wxNO_COLORS
;
2871 /* Only 1 colour to allocate */
2872 if (!YAllocColor (dpy
, cmap
, &g_itemColors
[wxFORE_INDEX
]))
2873 result
= wxNO_COLORS
;
2880 // Changes the foreground and background colours to be derived from the current
2881 // background colour. To change the foreground colour, you must call
2882 // SetForegroundColour explicitly.
2883 void wxWindow::ChangeBackgroundColour()
2885 WXWidget mainWidget
= GetMainWidget();
2887 DoChangeBackgroundColour(mainWidget
, m_backgroundColour
);
2889 // This not necessary
2892 if (m_scrolledWindow
&& (GetMainWidget() != m_scrolledWindow
))
2894 DoChangeBackgroundColour(m_scrolledWindow
, m_backgroundColour
);
2895 // Have to set the scrollbar colours back since
2896 // the scrolled window seemed to change them
2897 wxColour backgroundColour
= wxSystemSettings::GetColour(wxSYS_COLOUR_3DFACE
);
2900 DoChangeBackgroundColour(m_hScrollBar
, backgroundColour
);
2902 DoChangeBackgroundColour(m_vScrollBar
, backgroundColour
);
2907 void wxWindow::ChangeForegroundColour()
2909 WXWidget mainWidget
= GetMainWidget();
2911 DoChangeForegroundColour(mainWidget
, m_foregroundColour
);
2912 if ( m_scrolledWindow
&& mainWidget
!= m_scrolledWindow
)
2913 DoChangeForegroundColour(m_scrolledWindow
, m_foregroundColour
);
2916 // Change a widget's foreground and background colours.
2917 void wxWindow::DoChangeForegroundColour(WXWidget widget
,
2918 wxColour
& foregroundColour
)
2920 wxDoChangeForegroundColour( widget
, foregroundColour
);
2923 void wxWindow::DoChangeBackgroundColour(WXWidget widget
,
2924 wxColour
& backgroundColour
,
2925 bool changeArmColour
)
2927 wxDoChangeBackgroundColour( widget
, backgroundColour
, changeArmColour
);
2930 bool wxWindow::SetBackgroundColour(const wxColour
& col
)
2932 if ( !wxWindowBase::SetBackgroundColour(col
) )
2935 ChangeBackgroundColour();
2940 bool wxWindow::SetForegroundColour(const wxColour
& col
)
2942 if ( !wxWindowBase::SetForegroundColour(col
) )
2945 ChangeForegroundColour();
2950 void wxWindow::ChangeFont(bool keepOriginalSize
)
2952 // Note that this causes the widget to be resized back
2953 // to its original size! We therefore have to set the size
2954 // back again. TODO: a better way in Motif?
2955 Widget w
= (Widget
) GetLabelWidget(); // Usually the main widget
2956 if (w
&& m_font
.Ok())
2958 int width
, height
, width1
, height1
;
2959 GetSize(& width
, & height
);
2961 wxDoChangeFont( GetLabelWidget(), m_font
);
2963 GetSize(& width1
, & height1
);
2964 if (keepOriginalSize
&& (width
!= width1
|| height
!= height1
))
2966 SetSize(-1, -1, width
, height
);
2971 // ----------------------------------------------------------------------------
2973 // ----------------------------------------------------------------------------
2975 wxWindow
*wxGetActiveWindow()
2978 wxFAIL_MSG("Not implemented");
2983 wxWindow
*wxWindowBase::GetCapture()
2985 return (wxWindow
*)g_captureWindow
;
2989 // Find the wxWindow at the current mouse position, returning the mouse
2991 wxWindow
* wxFindWindowAtPointer(wxPoint
& pt
)
2993 return wxFindWindowAtPoint(wxGetMousePosition());
2996 // Get the current mouse position.
2997 wxPoint
wxGetMousePosition()
2999 Display
*display
= (Display
*) wxGetDisplay();
3000 Window rootWindow
= RootWindowOfScreen (DefaultScreenOfDisplay(display
));
3001 Window rootReturn
, childReturn
;
3002 int rootX
, rootY
, winX
, winY
;
3003 unsigned int maskReturn
;
3005 XQueryPointer (display
,
3009 &rootX
, &rootY
, &winX
, &winY
, &maskReturn
);
3010 return wxPoint(rootX
, rootY
);
3014 // ----------------------------------------------------------------------------
3015 // wxNoOptimize: switch off size optimization
3016 // ----------------------------------------------------------------------------
3018 int wxNoOptimize::ms_count
= 0;