1 /////////////////////////////////////////////////////////////////////////////
4 // Author: Julian Smart
8 // Copyright: (c) Julian Smart
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
12 // ============================================================================
14 // ============================================================================
16 // ----------------------------------------------------------------------------
18 // ----------------------------------------------------------------------------
21 #pragma implementation "window.h"
27 #include "wx/dcclient.h"
31 #include "wx/layout.h"
32 #include "wx/dialog.h"
33 #include "wx/listbox.h"
34 #include "wx/button.h"
35 #include "wx/settings.h"
36 #include "wx/msgdlg.h"
38 #include "wx/scrolwin.h"
39 #include "wx/module.h"
40 #include "wx/menuitem.h"
43 #if wxUSE_DRAG_AND_DROP
49 #include <Xm/DrawingA.h>
50 #include <Xm/ScrolledW.h>
51 #include <Xm/ScrollBar.h>
54 #include <Xm/RowColumn.h> // for XmMenuPosition
56 #include "wx/motif/private.h"
60 // ----------------------------------------------------------------------------
62 // ----------------------------------------------------------------------------
64 static const int SCROLL_MARGIN
= 4;
66 // ----------------------------------------------------------------------------
67 // global variables for this module
68 // ----------------------------------------------------------------------------
70 extern wxHashTable
*wxWidgetHashTable
;
72 // ----------------------------------------------------------------------------
74 // ----------------------------------------------------------------------------
76 static void wxCanvasRepaintProc(Widget
, XtPointer
, XmDrawingAreaCallbackStruct
* cbs
);
77 static void wxCanvasInputEvent(Widget drawingArea
, XtPointer data
, XmDrawingAreaCallbackStruct
* cbs
);
78 static void wxCanvasMotionEvent(Widget
, XButtonEvent
* event
);
79 static void wxCanvasEnterLeave(Widget drawingArea
, XtPointer clientData
, XCrossingEvent
* event
);
80 static void wxScrollBarCallback(Widget widget
, XtPointer clientData
,
81 XmScrollBarCallbackStruct
*cbs
);
82 static void wxPanelItemEventHandler(Widget wid
,
83 XtPointer client_data
,
85 Boolean
*continueToDispatch
);
90 // Helper function for 16-bit fonts
91 static int str16len(const char *s
)
95 while (s
[0] && s
[1]) {
105 // ----------------------------------------------------------------------------
107 // ----------------------------------------------------------------------------
109 #define event_left_is_down(x) ((x)->xbutton.state & Button1Mask)
110 #define event_middle_is_down(x) ((x)->xbutton.state & Button2Mask)
111 #define event_right_is_down(x) ((x)->xbutton.state & Button3Mask)
113 // ----------------------------------------------------------------------------
115 // ----------------------------------------------------------------------------
117 #if !USE_SHARED_LIBRARY
118 IMPLEMENT_DYNAMIC_CLASS(wxWindow
, wxWindowBase
)
120 BEGIN_EVENT_TABLE(wxWindow
, wxWindowBase
)
121 EVT_SYS_COLOUR_CHANGED(wxWindow::OnSysColourChanged
)
122 EVT_IDLE(wxWindow::OnIdle
)
124 #endif // USE_SHARED_LIBRARY
126 // ============================================================================
128 // ============================================================================
130 // ----------------------------------------------------------------------------
132 // ----------------------------------------------------------------------------
134 void wxWindow::UnmanageAndDestroy(WXWidget widget
)
136 Widget w
= (Widget
)widget
;
144 bool wxWindow::MapOrUnmap(WXWidget widget
, bool map
)
146 Widget w
= (Widget
)widget
;
158 // ----------------------------------------------------------------------------
160 // ----------------------------------------------------------------------------
162 void wxWindow::Init()
164 // generic initializations first
168 m_needsRefresh
= TRUE
;
169 m_mainWidget
= (WXWidget
) 0;
173 m_button3Pressed
= FALSE
;
175 m_winCaptured
= FALSE
;
178 m_isBeingDeleted
= FALSE
;
184 m_drawingArea
= (WXWidget
) 0;
192 m_backingPixmap
= (WXPixmap
) 0;
201 m_canAddEventHandler
= FALSE
;
204 // real construction (Init() must have been called before!)
205 bool wxWindow::Create(wxWindow
*parent
, wxWindowID id
,
209 const wxString
& name
)
211 wxCHECK_MSG( parent
, FALSE
, "can't create wxWindow without parent" );
213 CreateBase(parent
, id
, pos
, size
, style
, wxDefaultValidator
, name
);
215 parent
->AddChild(this);
217 m_backgroundColour
= wxSystemSettings::GetSystemColour(wxSYS_COLOUR_3DFACE
);
218 m_foregroundColour
= *wxBLACK
;
220 //// TODO: we should probably optimize by only creating a
221 //// a drawing area if we have one or more scrollbars (wxVSCROLL/wxHSCROLL).
222 //// But for now, let's simplify things by always creating the
223 //// drawing area, since otherwise the translations are different.
225 // New translations for getting mouse motion feedback
226 static const String translations
=
227 "<Btn1Motion>: wxCanvasMotionEvent() DrawingAreaInput() ManagerGadgetButtonMotion()\n\
228 <Btn2Motion>: wxCanvasMotionEvent() DrawingAreaInput() ManagerGadgetButtonMotion()\n\
229 <Btn3Motion>: wxCanvasMotionEvent() DrawingAreaInput() ManagerGadgetButtonMotion()\n\
230 <BtnMotion>: wxCanvasMotionEvent() DrawingAreaInput() ManagerGadgetButtonMotion()\n\
231 <Btn1Down>: DrawingAreaInput() ManagerGadgetArm()\n\
232 <Btn2Down>: DrawingAreaInput() ManagerGadgetArm()\n\
233 <Btn3Down>: DrawingAreaInput() ManagerGadgetArm()\n\
234 <Btn1Up>: DrawingAreaInput() ManagerGadgetActivate()\n\
235 <Btn2Up>: DrawingAreaInput() ManagerGadgetActivate()\n\
236 <Btn3Up>: DrawingAreaInput() ManagerGadgetActivate()\n\
237 <Motion>: wxCanvasMotionEvent() DrawingAreaInput()\n\
238 <EnterWindow>: wxCanvasMotionEvent() DrawingAreaInput()\n\
239 <LeaveWindow>: wxCanvasMotionEvent() DrawingAreaInput()\n\
240 <Key>: DrawingAreaInput()";
242 XtActionsRec actions
[1];
243 actions
[0].string
= "wxCanvasMotionEvent";
244 actions
[0].proc
= (XtActionProc
) wxCanvasMotionEvent
;
245 XtAppAddActions ((XtAppContext
) wxTheApp
->GetAppContext(), actions
, 1);
247 Widget parentWidget
= (Widget
) parent
->GetClientWidget();
249 if (style
& wxSIMPLE_BORDER
)
251 m_borderWidget
= (WXWidget
)XtVaCreateManagedWidget
254 xmFrameWidgetClass
, parentWidget
,
255 XmNshadowType
, XmSHADOW_IN
,
256 XmNshadowThickness
, 1,
259 } else if (style
& wxSUNKEN_BORDER
)
261 m_borderWidget
= (WXWidget
)XtVaCreateManagedWidget
264 xmFrameWidgetClass
, parentWidget
,
265 XmNshadowType
, XmSHADOW_IN
,
268 } else if (style
& wxRAISED_BORDER
)
270 m_borderWidget
= (WXWidget
)XtVaCreateManagedWidget
273 xmFrameWidgetClass
, parentWidget
,
274 XmNshadowType
, XmSHADOW_OUT
,
279 m_scrolledWindow
= (WXWidget
)XtVaCreateManagedWidget
282 xmScrolledWindowWidgetClass
,
283 m_borderWidget
? (Widget
) m_borderWidget
285 XmNresizePolicy
, XmRESIZE_NONE
,
287 XmNscrollingPolicy
, XmAPPLICATION_DEFINED
,
288 //XmNscrollBarDisplayPolicy, XmAS_NEEDED,
292 XtTranslations ptr
= XtParseTranslationTable(translations
);
293 m_drawingArea
= (WXWidget
)XtVaCreateWidget
296 xmDrawingAreaWidgetClass
, (Widget
) m_scrolledWindow
,
297 XmNunitType
, XmPIXELS
,
298 // XmNresizePolicy, XmRESIZE_ANY,
299 XmNresizePolicy
, XmRESIZE_NONE
,
302 XmNtranslations
, ptr
,
305 XtFree((char *) ptr
);
308 if (GetWindowStyleFlag() & wxOVERRIDE_KEY_TRANSLATIONS
)
310 ptr
= XtParseTranslationTable ("<Key>: DrawingAreaInput()");
311 XtOverrideTranslations ((Widget
) m_drawingArea
, ptr
);
312 XtFree ((char *) ptr
);
316 wxAddWindowToTable((Widget
) m_drawingArea
, this);
317 wxAddWindowToTable((Widget
) m_scrolledWindow
, this);
319 // This order is very important in Motif 1.2.1
320 XtRealizeWidget ((Widget
) m_scrolledWindow
);
321 XtRealizeWidget ((Widget
) m_drawingArea
);
322 XtManageChild ((Widget
) m_drawingArea
);
324 ptr
= XtParseTranslationTable("<Configure>: resize()");
325 XtOverrideTranslations((Widget
) m_drawingArea
, ptr
);
326 XtFree ((char *) ptr
);
328 XtAddCallback ((Widget
) m_drawingArea
, XmNexposeCallback
, (XtCallbackProc
) wxCanvasRepaintProc
, (XtPointer
) this);
329 XtAddCallback ((Widget
) m_drawingArea
, XmNinputCallback
, (XtCallbackProc
) wxCanvasInputEvent
, (XtPointer
) this);
333 display
= XtDisplay (scrolledWindow
);
334 xwindow
= XtWindow (drawingArea
);
338 (Widget
)m_drawingArea
,
339 PointerMotionHintMask
| EnterWindowMask
|
340 LeaveWindowMask
| FocusChangeMask
,
342 (XtEventHandler
) wxCanvasEnterLeave
,
346 // Scrolled widget needs to have its colour changed or we get a little blue
347 // square where the scrollbars abutt
348 wxColour backgroundColour
= wxSystemSettings::GetSystemColour(wxSYS_COLOUR_3DFACE
);
349 DoChangeBackgroundColour(m_scrolledWindow
, backgroundColour
, TRUE
);
350 DoChangeBackgroundColour(m_drawingArea
, backgroundColour
, TRUE
);
352 XmScrolledWindowSetAreas(
353 (Widget
)m_scrolledWindow
,
354 (Widget
) 0, (Widget
) 0,
355 (Widget
) m_drawingArea
);
359 XtRealizeWidget ((Widget
) m_hScrollBar
);
361 XtRealizeWidget ((Widget
) m_vScrollBar
);
364 // Without this, the cursor may not be restored properly (e.g. in splitter
366 SetCursor(*wxSTANDARD_CURSOR
);
367 SetFont(wxSystemSettings::GetSystemFont(wxSYS_DEFAULT_GUI_FONT
));
368 SetSize(pos
.x
, pos
.y
, size
.x
, size
.y
);
374 wxWindow::~wxWindow()
376 m_isBeingDeleted
= TRUE
;
378 // Motif-specific actions first
379 WXWidget wMain
= GetMainWidget();
382 // Removes event handlers
389 m_parent
->RemoveChild( this );
391 // If m_drawingArea, we're a fully-fledged window with drawing area,
392 // scrollbars etc. (what wxCanvas used to be)
395 // Destroy children before destroying self
399 XFreePixmap (XtDisplay ((Widget
) GetMainWidget()), (Pixmap
) m_backingPixmap
);
401 Widget w
= (Widget
) m_drawingArea
;
402 wxDeleteWindowFromTable(w
);
409 m_mainWidget
= (WXWidget
) 0;
411 // Only if we're _really_ a canvas (not a dialog box/panel)
412 if (m_scrolledWindow
)
414 wxDeleteWindowFromTable((Widget
) m_scrolledWindow
);
419 wxDeleteWindowFromTable((Widget
) m_hScrollBar
);
423 wxDeleteWindowFromTable((Widget
) m_vScrollBar
);
426 UnmanageAndDestroy(m_hScrollBar
);
427 UnmanageAndDestroy(m_vScrollBar
);
428 UnmanageAndDestroy(m_scrolledWindow
);
432 XtDestroyWidget ((Widget
) m_borderWidget
);
433 m_borderWidget
= (WXWidget
) 0;
437 // Destroy the window
440 // If this line (XtDestroyWidget) causes a crash, you may comment it out.
441 // Child widgets will get destroyed automatically when a frame
442 // or dialog is destroyed, but before that you may get some memory
443 // leaks and potential layout problems if you delete and then add
445 XtDestroyWidget((Widget
) GetMainWidget());
446 SetMainWidget((WXWidget
) NULL
);
450 // ----------------------------------------------------------------------------
451 // scrollbar management
452 // ----------------------------------------------------------------------------
455 void wxWindow::CreateScrollbar(wxOrientation orientation
)
457 wxCHECK_RET( m_drawingArea
, "this window can't have scrollbars" );
459 XtVaSetValues((Widget
) m_scrolledWindow
, XmNresizePolicy
, XmRESIZE_NONE
, NULL
);
461 // Add scrollbars if required
462 if (orientation
== wxHORIZONTAL
)
464 Widget hScrollBar
= XtVaCreateManagedWidget ("hsb",
465 xmScrollBarWidgetClass
, (Widget
) m_scrolledWindow
,
466 XmNorientation
, XmHORIZONTAL
,
468 // XtAddCallback (hScrollBar, XmNvalueChangedCallback, (XtCallbackProc) wxScrollBarCallback, (XtPointer) XmHORIZONTAL);
469 XtAddCallback (hScrollBar
, XmNdragCallback
, (XtCallbackProc
) wxScrollBarCallback
, (XtPointer
) XmHORIZONTAL
);
470 XtAddCallback (hScrollBar
, XmNincrementCallback
, (XtCallbackProc
) wxScrollBarCallback
, (XtPointer
) XmHORIZONTAL
);
471 XtAddCallback (hScrollBar
, XmNdecrementCallback
, (XtCallbackProc
) wxScrollBarCallback
, (XtPointer
) XmHORIZONTAL
);
472 XtAddCallback (hScrollBar
, XmNpageIncrementCallback
, (XtCallbackProc
) wxScrollBarCallback
, (XtPointer
) XmHORIZONTAL
);
473 XtAddCallback (hScrollBar
, XmNpageDecrementCallback
, (XtCallbackProc
) wxScrollBarCallback
, (XtPointer
) XmHORIZONTAL
);
474 XtAddCallback (hScrollBar
, XmNtoTopCallback
, (XtCallbackProc
) wxScrollBarCallback
, (XtPointer
) XmHORIZONTAL
);
475 XtAddCallback (hScrollBar
, XmNtoBottomCallback
, (XtCallbackProc
) wxScrollBarCallback
, (XtPointer
) XmHORIZONTAL
);
477 XtVaSetValues (hScrollBar
,
482 m_hScrollBar
= (WXWidget
) hScrollBar
;
484 wxColour backgroundColour
= wxSystemSettings::GetSystemColour(wxSYS_COLOUR_3DFACE
);
485 DoChangeBackgroundColour(m_hScrollBar
, backgroundColour
, TRUE
);
487 XtRealizeWidget(hScrollBar
);
489 XtVaSetValues((Widget
) m_scrolledWindow
,
490 XmNhorizontalScrollBar
, (Widget
) m_hScrollBar
,
495 wxAddWindowToTable( hScrollBar
, this );
498 if (orientation
== wxVERTICAL
)
500 Widget vScrollBar
= XtVaCreateManagedWidget ("vsb",
501 xmScrollBarWidgetClass
, (Widget
) m_scrolledWindow
,
502 XmNorientation
, XmVERTICAL
,
504 // XtAddCallback (vScrollBar, XmNvalueChangedCallback, (XtCallbackProc) wxScrollBarCallback, (XtPointer) XmVERTICAL);
505 XtAddCallback (vScrollBar
, XmNdragCallback
, (XtCallbackProc
) wxScrollBarCallback
, (XtPointer
) XmVERTICAL
);
506 XtAddCallback (vScrollBar
, XmNincrementCallback
, (XtCallbackProc
) wxScrollBarCallback
, (XtPointer
) XmVERTICAL
);
507 XtAddCallback (vScrollBar
, XmNdecrementCallback
, (XtCallbackProc
) wxScrollBarCallback
, (XtPointer
) XmVERTICAL
);
508 XtAddCallback (vScrollBar
, XmNpageIncrementCallback
, (XtCallbackProc
) wxScrollBarCallback
, (XtPointer
) XmVERTICAL
);
509 XtAddCallback (vScrollBar
, XmNpageDecrementCallback
, (XtCallbackProc
) wxScrollBarCallback
, (XtPointer
) XmVERTICAL
);
510 XtAddCallback (vScrollBar
, XmNtoTopCallback
, (XtCallbackProc
) wxScrollBarCallback
, (XtPointer
) XmVERTICAL
);
511 XtAddCallback (vScrollBar
, XmNtoBottomCallback
, (XtCallbackProc
) wxScrollBarCallback
, (XtPointer
) XmVERTICAL
);
513 XtVaSetValues (vScrollBar
,
518 m_vScrollBar
= (WXWidget
) vScrollBar
;
519 wxColour backgroundColour
= wxSystemSettings::GetSystemColour(wxSYS_COLOUR_3DFACE
);
520 DoChangeBackgroundColour(m_vScrollBar
, backgroundColour
, TRUE
);
522 XtRealizeWidget(vScrollBar
);
524 XtVaSetValues((Widget
) m_scrolledWindow
,
525 XmNverticalScrollBar
, (Widget
) m_vScrollBar
,
530 wxAddWindowToTable( vScrollBar
, this );
533 XtVaSetValues((Widget
) m_scrolledWindow
, XmNresizePolicy
, XmRESIZE_ANY
, NULL
);
536 void wxWindow::DestroyScrollbar(wxOrientation orientation
)
538 wxCHECK_RET( m_drawingArea
, "this window can't have scrollbars" );
540 XtVaSetValues((Widget
) m_scrolledWindow
, XmNresizePolicy
, XmRESIZE_NONE
, NULL
);
541 // Add scrollbars if required
542 if (orientation
== wxHORIZONTAL
)
546 wxDeleteWindowFromTable((Widget
)m_hScrollBar
);
547 XtDestroyWidget((Widget
) m_hScrollBar
);
549 m_hScrollBar
= (WXWidget
) 0;
552 XtVaSetValues((Widget
) m_scrolledWindow
,
553 XmNhorizontalScrollBar
, (Widget
) 0,
558 if (orientation
== wxVERTICAL
)
562 wxDeleteWindowFromTable((Widget
)m_vScrollBar
);
563 XtDestroyWidget((Widget
) m_vScrollBar
);
565 m_vScrollBar
= (WXWidget
) 0;
568 XtVaSetValues((Widget
) m_scrolledWindow
,
569 XmNverticalScrollBar
, (Widget
) 0,
573 XtVaSetValues((Widget
) m_scrolledWindow
, XmNresizePolicy
, XmRESIZE_ANY
, NULL
);
576 // ---------------------------------------------------------------------------
578 // ---------------------------------------------------------------------------
580 void wxWindow::SetFocus()
582 Widget wMain
= (Widget
) GetMainWidget();
583 XmProcessTraversal(wMain
, XmTRAVERSE_CURRENT
);
584 XmProcessTraversal((Widget
) GetMainWidget(), XmTRAVERSE_CURRENT
);
587 // Get the window with the focus
588 wxWindow
*wxWindowBase::FindFocus()
591 // (1) Can there be multiple focussed widgets in an application?
592 // In which case we need to find the top-level window that's
594 // (2) The widget with the focus may not be in the widget table
595 // depending on which widgets I put in the table
596 wxWindow
*winFocus
= (wxWindow
*)NULL
;
597 for ( wxWindowList::Node
*node
= wxTopLevelWindows
.GetFirst();
599 node
= node
->GetNext() )
601 wxWindow
*win
= node
->GetData();
603 Widget w
= XmGetFocusWidget ((Widget
) win
->GetTopWidget());
605 if (w
!= (Widget
) NULL
)
607 winFocus
= wxGetWindowFromTable(w
);
616 bool wxWindow::Enable(bool enable
)
618 if ( !wxWindowBase::Enable(enable
) )
621 Widget wMain
= (Widget
)GetMainWidget();
624 XtSetSensitive(wMain
, enable
);
625 XmUpdateDisplay(wMain
);
631 bool wxWindow::Show(bool show
)
633 if ( !wxWindowBase::Show(show
) )
636 if (m_borderWidget
|| m_scrolledWindow
)
638 MapOrUnmap(m_drawingArea
, show
);
639 MapOrUnmap(m_borderWidget
? m_borderWidget
: m_scrolledWindow
, show
);
643 if ( !MapOrUnmap(GetTopWidget(), show
) )
644 MapOrUnmap(GetMainWidget(), show
);
648 Window xwin
= (Window
) GetXWindow();
649 Display
*xdisp
= (Display
*) GetXDisplay();
651 XMapWindow(xdisp
, xwin
);
653 XUnmapWindow(xdisp
, xwin
);
659 // Raise the window to the top of the Z order
660 void wxWindow::Raise()
662 Widget wTop
= (Widget
) GetTopWidget();
663 Window window
= XtWindow(wTop
);
664 XRaiseWindow(XtDisplay(wTop
), window
);
667 // Lower the window to the bottom of the Z order
668 void wxWindow::Lower()
670 Widget wTop
= (Widget
) GetTopWidget();
671 Window window
= XtWindow(wTop
);
672 XLowerWindow(XtDisplay(wTop
), window
);
675 void wxWindow::SetTitle(const wxString
& title
)
677 XtVaSetValues((Widget
)GetMainWidget(), XmNtitle
, title
.c_str(), NULL
);
680 wxString
wxWindow::GetTitle() const
683 XtVaGetValues((Widget
)GetMainWidget(), XmNtitle
, &title
, NULL
);
685 return wxString(title
);
688 void wxWindow::CaptureMouse()
693 Widget wMain
= (Widget
)GetMainWidget();
695 XtAddGrab(wMain
, TRUE
, FALSE
);
697 m_winCaptured
= TRUE
;
700 void wxWindow::ReleaseMouse()
702 if ( !m_winCaptured
)
705 Widget wMain
= (Widget
)GetMainWidget();
709 m_winCaptured
= FALSE
;
712 bool wxWindow::SetFont(const wxFont
& font
)
714 if ( !wxWindowBase::SetFont(font
) )
725 bool wxWindow::SetCursor(const wxCursor
& cursor
)
727 if ( !wxWindowBase::SetCursor(cursor
) )
733 wxASSERT_MSG( m_cursor
.Ok(),
734 wxT("cursor must be valid after call to the base version"));
736 WXDisplay
*dpy
= GetXDisplay();
737 WXCursor x_cursor
= m_cursor
.GetXCursor(dpy
);
739 Widget w
= (Widget
) GetMainWidget();
740 Window win
= XtWindow(w
);
741 XDefineCursor((Display
*) dpy
, win
, (Cursor
) x_cursor
);
746 // Coordinates relative to the window
747 void wxWindow::WarpPointer (int x
, int y
)
749 Widget wClient
= (Widget
)GetClientWidget();
751 XWarpPointer(XtDisplay(wClient
), None
, XtWindow(wClient
), 0, 0, 0, 0, x
, y
);
754 // ---------------------------------------------------------------------------
756 // ---------------------------------------------------------------------------
758 int wxWindow::GetScrollPos(int orient
) const
760 if (orient
== wxHORIZONTAL
)
766 Widget scrollBar
= (Widget
) ((orient
== wxHORIZONTAL
) ? m_hScrollBar
: m_vScrollBar
);
770 XtVaGetValues(scrollBar
, XmNvalue
, &pos
, NULL
);
778 // This now returns the whole range, not just the number of positions that we
780 int wxWindow::GetScrollRange(int orient
) const
782 Widget scrollBar
= (Widget
)GetScrollbar((wxOrientation
)orient
);
783 wxCHECK_MSG( scrollBar
, 0, "no such scrollbar" );
786 XtVaGetValues(scrollBar
, XmNmaximum
, &range
, NULL
);
790 int wxWindow::GetScrollThumb(int orient
) const
792 Widget scrollBar
= (Widget
)GetScrollbar((wxOrientation
)orient
);
793 wxCHECK_MSG( scrollBar
, 0, "no such scrollbar" );
796 XtVaGetValues(scrollBar
, XmNsliderSize
, &thumb
, NULL
);
800 void wxWindow::SetScrollPos(int orient
, int pos
, bool WXUNUSED(refresh
))
802 Widget scrollBar
= (Widget
)GetScrollbar((wxOrientation
)orient
);
806 XtVaSetValues (scrollBar
, XmNvalue
, pos
, NULL
);
809 SetInternalScrollPos((wxOrientation
)orient
, pos
);
812 // New function that will replace some of the above.
813 void wxWindow::SetScrollbar(int orient
, int pos
, int thumbVisible
,
814 int range
, bool WXUNUSED(refresh
))
817 GetSize(& oldW
, & oldH
);
821 if (thumbVisible
== 0)
824 if (thumbVisible
> range
)
825 thumbVisible
= range
;
827 // Save the old state to see if it changed
828 WXWidget oldScrollBar
= GetScrollbar((wxOrientation
)orient
);
830 if (orient
== wxHORIZONTAL
)
832 if (thumbVisible
== range
)
835 DestroyScrollbar(wxHORIZONTAL
);
840 CreateScrollbar(wxHORIZONTAL
);
843 if (orient
== wxVERTICAL
)
845 if (thumbVisible
== range
)
848 DestroyScrollbar(wxVERTICAL
);
853 CreateScrollbar(wxVERTICAL
);
856 WXWidget newScrollBar
= GetScrollbar((wxOrientation
)orient
);
858 if (oldScrollBar
!= newScrollBar
)
860 // This is important! Without it, scrollbars misbehave badly.
861 XtUnrealizeWidget((Widget
) m_scrolledWindow
);
862 XmScrolledWindowSetAreas ((Widget
) m_scrolledWindow
, (Widget
) m_hScrollBar
, (Widget
) m_vScrollBar
, (Widget
) m_drawingArea
);
863 XtRealizeWidget((Widget
) m_scrolledWindow
);
864 XtManageChild((Widget
) m_scrolledWindow
);
869 XtVaSetValues((Widget
) newScrollBar
,
873 XmNsliderSize
, thumbVisible
,
877 SetInternalScrollPos((wxOrientation
)orient
, pos
);
880 GetSize(& newW
, & newH
);
882 // Adjusting scrollbars can resize the canvas accidentally
883 if (newW
!= oldW
|| newH
!= oldH
)
884 SetSize(-1, -1, oldW
, oldH
);
887 // Does a physical scroll
888 void wxWindow::ScrollWindow(int dx
, int dy
, const wxRect
*rect
)
893 // Use specified rectangle
894 x
= rect
->x
; y
= rect
->y
; w
= rect
->width
; h
= rect
->height
;
898 // Use whole client area
900 GetClientSize(& w
, & h
);
903 wxNode
*cnode
= m_children
.First();
906 wxWindow
*child
= (wxWindow
*) cnode
->Data();
909 child
->GetSize( &sx
, &sy
);
910 wxPoint
pos( child
->GetPosition() );
911 child
->SetSize( pos
.x
+ dx
, pos
.y
+ dy
, sx
, sy
, wxSIZE_ALLOW_MINUS_ONE
);
912 cnode
= cnode
->Next();
915 int x1
= (dx
>= 0) ? x
: x
- dx
;
916 int y1
= (dy
>= 0) ? y
: y
- dy
;
917 int w1
= w
- abs(dx
);
918 int h1
= h
- abs(dy
);
919 int x2
= (dx
>= 0) ? x
+ dx
: x
;
920 int y2
= (dy
>= 0) ? y
+ dy
: y
;
924 dc
.SetLogicalFunction (wxCOPY
);
926 Widget widget
= (Widget
) GetMainWidget();
927 Window window
= XtWindow(widget
);
928 Display
* display
= XtDisplay(widget
);
930 XCopyArea(display
, window
, window
, (GC
) dc
.GetGC(),
931 x1
, y1
, w1
, h1
, x2
, y2
);
933 dc
.SetAutoSetting(TRUE
);
934 wxBrush
brush(GetBackgroundColour(), wxSOLID
);
935 dc
.SetBrush(brush
); // FIXME: needed?
937 // We'll add rectangles to the list of update rectangles according to which
938 // bits we've exposed.
943 wxRect
*rect
= new wxRect
;
949 XFillRectangle(display
, window
,
950 (GC
) dc
.GetGC(), rect
->x
, rect
->y
, rect
->width
, rect
->height
);
954 rect
->width
= rect
->width
;
955 rect
->height
= rect
->height
;
957 updateRects
.Append((wxObject
*) rect
);
961 wxRect
*rect
= new wxRect
;
963 rect
->x
= x
+ w
+ dx
;
968 XFillRectangle(display
, window
,
969 (GC
) dc
.GetGC(), rect
->x
, rect
->y
, rect
->width
,
974 rect
->width
= rect
->width
;
975 rect
->height
= rect
->height
;
977 updateRects
.Append((wxObject
*) rect
);
981 wxRect
*rect
= new wxRect
;
988 XFillRectangle(display
, window
,
989 (GC
) dc
.GetGC(), rect
->x
, rect
->y
, rect
->width
, rect
->height
);
993 rect
->width
= rect
->width
;
994 rect
->height
= rect
->height
;
996 updateRects
.Append((wxObject
*) rect
);
1000 wxRect
*rect
= new wxRect
;
1003 rect
->y
= y
+ h
+ dy
;
1007 XFillRectangle(display
, window
,
1008 (GC
) dc
.GetGC(), rect
->x
, rect
->y
, rect
->width
, rect
->height
);
1012 rect
->width
= rect
->width
;
1013 rect
->height
= rect
->height
;
1015 updateRects
.Append((wxObject
*) rect
);
1017 dc
.SetBrush(wxNullBrush
);
1019 // Now send expose events
1021 wxNode
* node
= updateRects
.First();
1024 wxRect
* rect
= (wxRect
*) node
->Data();
1027 event
.type
= Expose
;
1028 event
.display
= display
;
1029 event
.send_event
= True
;
1030 event
.window
= window
;
1034 event
.width
= rect
->width
;
1035 event
.height
= rect
->height
;
1039 XSendEvent(display
, window
, False
, ExposureMask
, (XEvent
*)&event
);
1041 node
= node
->Next();
1045 // Delete the update rects
1046 node
= updateRects
.First();
1049 wxRect
* rect
= (wxRect
*) node
->Data();
1051 node
= node
->Next();
1054 XmUpdateDisplay((Widget
) GetMainWidget());
1057 // ---------------------------------------------------------------------------
1059 // ---------------------------------------------------------------------------
1061 #if wxUSE_DRAG_AND_DROP
1063 void wxWindow::SetDropTarget(wxDropTarget
* WXUNUSED(pDropTarget
))
1070 // Old style file-manager drag&drop
1071 void wxWindow::DragAcceptFiles(bool WXUNUSED(accept
))
1076 // ----------------------------------------------------------------------------
1078 // ----------------------------------------------------------------------------
1082 void wxWindow::DoSetToolTip(wxToolTip
* WXUNUSED(tooltip
))
1087 #endif // wxUSE_TOOLTIPS
1089 // ----------------------------------------------------------------------------
1091 // ----------------------------------------------------------------------------
1093 bool wxWindow::DoPopupMenu(wxMenu
*menu
, int x
, int y
)
1095 Widget widget
= (Widget
) GetMainWidget();
1097 /* The menuId field seems to be usused, so we'll use it to
1098 indicate whether a menu is popped up or not:
1099 0: Not currently created as a popup
1100 -1: Created as a popup, but not active
1104 if (menu
->GetParent() && (menu
->GetId() != -1))
1107 if (menu
->GetMainWidget()) {
1108 menu
->DestroyMenu(TRUE
);
1111 menu
->SetId(1); /* Mark as popped-up */
1112 menu
->CreateMenu(NULL
, widget
, menu
);
1113 menu
->SetInvokingWindow(this);
1117 // menu->SetParent(parent);
1118 // parent->children->Append(menu); // Store menu for later deletion
1120 Widget menuWidget
= (Widget
) menu
->GetMainWidget();
1128 if (this->IsKindOf(CLASSINFO(wxCanvas)))
1130 wxCanvas *canvas = (wxCanvas *) this;
1131 deviceX = canvas->GetDC ()->LogicalToDeviceX (x);
1132 deviceY = canvas->GetDC ()->LogicalToDeviceY (y);
1136 Display
*display
= XtDisplay (widget
);
1137 Window rootWindow
= RootWindowOfScreen (XtScreen((Widget
)widget
));
1138 Window thisWindow
= XtWindow (widget
);
1140 XTranslateCoordinates (display
, thisWindow
, rootWindow
, (int) deviceX
, (int) deviceY
,
1141 &rootX
, &rootY
, &childWindow
);
1143 XButtonPressedEvent event
;
1144 event
.type
= ButtonPress
;
1150 event
.x_root
= rootX
;
1151 event
.y_root
= rootY
;
1153 XmMenuPosition (menuWidget
, &event
);
1154 XtManageChild (menuWidget
);
1159 // ---------------------------------------------------------------------------
1160 // moving and resizing
1161 // ---------------------------------------------------------------------------
1163 bool wxWindow::PreResize()
1169 void wxWindow::DoGetSize(int *x
, int *y
) const
1173 CanvasGetSize(x
, y
);
1177 Widget widget
= (Widget
) GetTopWidget();
1179 XtVaGetValues(widget
, XmNwidth
, &xx
, XmNheight
, &yy
, NULL
);
1183 void wxWindow::DoGetPosition(int *x
, int *y
) const
1187 CanvasGetPosition(x
, y
);
1190 Widget widget
= (Widget
) GetTopWidget();
1192 XtVaGetValues(widget
, XmNx
, &xx
, XmNy
, &yy
, NULL
);
1194 // We may be faking the client origin. So a window that's really at (0, 30)
1195 // may appear (to wxWin apps) to be at (0, 0).
1198 wxPoint
pt(GetParent()->GetClientAreaOrigin());
1206 void wxWindow::DoScreenToClient(int *x
, int *y
) const
1208 Widget widget
= (Widget
) GetClientWidget();
1209 Display
*display
= XtDisplay((Widget
) GetMainWidget());
1210 Window rootWindow
= RootWindowOfScreen(XtScreen(widget
));
1211 Window thisWindow
= XtWindow(widget
);
1216 XTranslateCoordinates(display
, rootWindow
, thisWindow
, xx
, yy
, x
, y
, &childWindow
);
1219 void wxWindow::DoClientToScreen(int *x
, int *y
) const
1221 Widget widget
= (Widget
) GetClientWidget();
1222 Display
*display
= XtDisplay(widget
);
1223 Window rootWindow
= RootWindowOfScreen(XtScreen(widget
));
1224 Window thisWindow
= XtWindow(widget
);
1229 XTranslateCoordinates(display
, thisWindow
, rootWindow
, xx
, yy
, x
, y
, &childWindow
);
1233 // Get size *available for subwindows* i.e. excluding menu bar etc.
1234 void wxWindow::DoGetClientSize(int *x
, int *y
) const
1236 Widget widget
= (Widget
) GetClientWidget();
1238 XtVaGetValues(widget
, XmNwidth
, &xx
, XmNheight
, &yy
, NULL
);
1242 void wxWindow::DoSetSize(int x
, int y
, int width
, int height
, int sizeFlags
)
1244 // A bit of optimization to help sort out the flickers.
1245 int oldX
, oldY
, oldW
, oldH
;
1246 GetSize(& oldW
, & oldH
);
1247 GetPosition(& oldX
, & oldY
);
1249 bool useOldPos
= FALSE
;
1250 bool useOldSize
= FALSE
;
1252 if ((x
== -1) && (x
== -1) && ((sizeFlags
& wxSIZE_ALLOW_MINUS_ONE
) == 0))
1254 else if (x
== oldX
&& y
== oldY
)
1257 if ((width
== -1) && (height
== -1))
1259 else if (width
== oldW
&& height
== oldH
)
1262 if (!wxNoOptimize::CanOptimize())
1264 useOldSize
= FALSE
; useOldPos
= FALSE
;
1267 if (useOldPos
&& useOldSize
)
1272 CanvasSetSize(x
, y
, width
, height
, sizeFlags
);
1275 Widget widget
= (Widget
) GetTopWidget();
1279 bool managed
= XtIsManaged( widget
);
1281 XtUnmanageChild(widget
);
1283 int xx
= x
; int yy
= y
;
1284 AdjustForParentClientOrigin(xx
, yy
, sizeFlags
);
1288 if (x
> -1 || (sizeFlags
& wxSIZE_ALLOW_MINUS_ONE
))
1289 XtVaSetValues(widget
, XmNx
, xx
, NULL
);
1290 if (y
> -1 || (sizeFlags
& wxSIZE_ALLOW_MINUS_ONE
))
1291 XtVaSetValues(widget
, XmNy
, yy
, NULL
);
1296 XtVaSetValues(widget
, XmNwidth
, width
, NULL
);
1298 XtVaSetValues(widget
, XmNheight
, height
, NULL
);
1302 XtManageChild(widget
);
1304 // How about this bit. Maybe we don't need to generate size events
1305 // all the time -- they'll be generated when the window is sized anyway.
1307 wxSizeEvent
sizeEvent(wxSize(width
, height
), GetId());
1308 sizeEvent
.SetEventObject(this);
1310 GetEventHandler()->ProcessEvent(sizeEvent
);
1314 void wxWindow::DoSetClientSize(int width
, int height
)
1318 CanvasSetClientSize(width
, height
);
1322 Widget widget
= (Widget
) GetTopWidget();
1325 XtVaSetValues(widget
, XmNwidth
, width
, NULL
);
1327 XtVaSetValues(widget
, XmNheight
, height
, NULL
);
1329 wxSizeEvent
sizeEvent(wxSize(width
, height
), GetId());
1330 sizeEvent
.SetEventObject(this);
1332 GetEventHandler()->ProcessEvent(sizeEvent
);
1335 // For implementation purposes - sometimes decorations make the client area
1337 wxPoint
wxWindow::GetClientAreaOrigin() const
1339 return wxPoint(0, 0);
1342 // Makes an adjustment to the window position (for example, a frame that has
1343 // a toolbar that it manages itself).
1344 void wxWindow::AdjustForParentClientOrigin(int& x
, int& y
, int sizeFlags
)
1346 if (((sizeFlags
& wxSIZE_NO_ADJUSTMENTS
) == 0) && GetParent())
1348 wxPoint
pt(GetParent()->GetClientAreaOrigin());
1349 x
+= pt
.x
; y
+= pt
.y
;
1353 void wxWindow::SetSizeHints(int minW
, int minH
, int maxW
, int maxH
, int incW
, int incH
)
1360 wxFrame
*frame
= wxDynamicCast(this, wxFrame
);
1363 // TODO what about dialogs?
1367 Widget widget
= (Widget
) frame
->GetShellWidget();
1370 XtVaSetValues(widget
, XmNminWidth
, minW
, NULL
);
1372 XtVaSetValues(widget
, XmNminHeight
, minH
, NULL
);
1374 XtVaSetValues(widget
, XmNmaxWidth
, maxW
, NULL
);
1376 XtVaSetValues(widget
, XmNmaxHeight
, maxH
, NULL
);
1378 XtVaSetValues(widget
, XmNwidthInc
, incW
, NULL
);
1380 XtVaSetValues(widget
, XmNheightInc
, incH
, NULL
);
1383 // ---------------------------------------------------------------------------
1385 // ---------------------------------------------------------------------------
1387 int wxWindow::GetCharHeight() const
1389 wxCHECK_MSG( m_font
.Ok(), 0, "valid window font needed" );
1391 WXFontStructPtr pFontStruct
= m_font
.GetFontStruct(1.0, GetXDisplay());
1393 int direction
, ascent
, descent
;
1394 XCharStruct overall
;
1395 XTextExtents ((XFontStruct
*) pFontStruct
, "x", 1, &direction
, &ascent
,
1396 &descent
, &overall
);
1398 // return (overall.ascent + overall.descent);
1399 return (ascent
+ descent
);
1402 int wxWindow::GetCharWidth() const
1404 wxCHECK_MSG( m_font
.Ok(), 0, "valid window font needed" );
1406 WXFontStructPtr pFontStruct
= m_font
.GetFontStruct(1.0, GetXDisplay());
1408 int direction
, ascent
, descent
;
1409 XCharStruct overall
;
1410 XTextExtents ((XFontStruct
*) pFontStruct
, "x", 1, &direction
, &ascent
,
1411 &descent
, &overall
);
1413 return overall
.width
;
1416 void wxWindow::GetTextExtent(const wxString
& string
,
1418 int *descent
, int *externalLeading
,
1419 const wxFont
*theFont
) const
1421 wxFont
*fontToUse
= (wxFont
*)theFont
;
1423 fontToUse
= (wxFont
*) & m_font
;
1425 wxCHECK_RET( fontToUse
->Ok(), "valid window font needed" );
1427 WXFontStructPtr pFontStruct
= theFont
->GetFontStruct(1.0, GetXDisplay());
1429 int direction
, ascent
, descent2
;
1430 XCharStruct overall
;
1431 int slen
= string
.Len();
1435 XTextExtents16((XFontStruct
*) pFontStruct
, (XChar2b
*) (char*) (const char*) string
, slen
, &direction
,
1436 &ascent
, &descent2
, &overall
);
1439 XTextExtents((XFontStruct
*) pFontStruct
, string
, slen
,
1440 &direction
, &ascent
, &descent2
, &overall
);
1443 *x
= (overall
.width
);
1445 *y
= (ascent
+ descent2
);
1447 *descent
= descent2
;
1448 if (externalLeading
)
1449 *externalLeading
= 0;
1453 // ----------------------------------------------------------------------------
1455 // ----------------------------------------------------------------------------
1457 void wxWindow::Refresh(bool eraseBack
, const wxRect
*rect
)
1459 m_needsRefresh
= TRUE
;
1460 Display
*display
= XtDisplay((Widget
) GetMainWidget());
1461 Window thisWindow
= XtWindow((Widget
) GetMainWidget());
1463 XExposeEvent dummyEvent
;
1465 GetSize(&width
, &height
);
1467 dummyEvent
.type
= Expose
;
1468 dummyEvent
.display
= display
;
1469 dummyEvent
.send_event
= True
;
1470 dummyEvent
.window
= thisWindow
;
1473 dummyEvent
.x
= rect
->x
;
1474 dummyEvent
.y
= rect
->y
;
1475 dummyEvent
.width
= rect
->width
;
1476 dummyEvent
.height
= rect
->height
;
1482 dummyEvent
.width
= width
;
1483 dummyEvent
.height
= height
;
1485 dummyEvent
.count
= 0;
1489 wxClientDC
dc(this);
1490 wxBrush
backgroundBrush(GetBackgroundColour(), wxSOLID
);
1491 dc
.SetBackground(backgroundBrush
);
1498 XSendEvent(display
, thisWindow
, False
, ExposureMask
, (XEvent
*)&dummyEvent
);
1501 void wxWindow::Clear()
1503 wxClientDC
dc(this);
1504 wxBrush
brush(GetBackgroundColour(), wxSOLID
);
1505 dc
.SetBackground(brush
);
1509 void wxWindow::ClearUpdateRects()
1511 wxRectList::Node
* node
= m_updateRects
.GetFirst();
1514 wxRect
* rect
= node
->GetData();
1516 node
= node
->GetNext();
1519 m_updateRects
.Clear();
1522 void wxWindow::DoPaint()
1524 //TODO : make a temporary gc so we can do the XCopyArea below
1525 if (m_backingPixmap
&& !m_needsRefresh
)
1529 GC tempGC
= (GC
) dc
.GetBackingGC();
1531 Widget widget
= (Widget
) GetMainWidget();
1536 // We have to test whether it's a wxScrolledWindow (hack!) because
1537 // otherwise we don't know how many pixels have been scrolled. We might
1538 // solve this in the future by defining virtual wxWindow functions to get
1539 // the scroll position in pixels. Or, each kind of scrolled window has to
1540 // implement backing stores itself, using generic wxWindows code.
1541 wxScrolledWindow
* scrolledWindow
= wxDynamicCast(this, wxScrolledWindow
);
1542 if ( scrolledWindow
)
1545 scrolledWindow
->CalcScrolledPosition(0, 0, &x
, &y
);
1551 // TODO: This could be optimized further by only copying the areas in the
1552 // current update region.
1554 // Only blit the part visible in the client area. The backing pixmap
1555 // always starts at 0, 0 but we may be looking at only a portion of it.
1556 wxSize clientArea
= GetClientSize();
1557 int toBlitX
= m_pixmapWidth
- scrollPosX
;
1558 int toBlitY
= m_pixmapHeight
- scrollPosY
;
1560 // Copy whichever is samller, the amount of pixmap we have to copy,
1561 // or the size of the client area.
1562 toBlitX
= wxMin(toBlitX
, clientArea
.x
);
1563 toBlitY
= wxMin(toBlitY
, clientArea
.y
);
1565 // Make sure we're not negative
1566 toBlitX
= wxMax(0, toBlitX
);
1567 toBlitY
= wxMax(0, toBlitY
);
1572 (Pixmap
) m_backingPixmap
,
1575 scrollPosX
, scrollPosY
, // Start at the scroll position
1576 toBlitX
, toBlitY
, // How much of the pixmap to copy
1582 // Set an erase event first
1583 wxEraseEvent
eraseEvent(GetId());
1584 eraseEvent
.SetEventObject(this);
1585 GetEventHandler()->ProcessEvent(eraseEvent
);
1587 wxPaintEvent
event(GetId());
1588 event
.SetEventObject(this);
1589 GetEventHandler()->ProcessEvent(event
);
1591 m_needsRefresh
= FALSE
;
1595 // ----------------------------------------------------------------------------
1597 // ----------------------------------------------------------------------------
1599 // Responds to colour changes: passes event on to children.
1600 void wxWindow::OnSysColourChanged(wxSysColourChangedEvent
& event
)
1602 wxWindowList::Node
*node
= GetChildren().GetFirst();
1605 // Only propagate to non-top-level windows
1606 wxWindow
*win
= node
->GetData();
1607 if ( win
->GetParent() )
1609 wxSysColourChangedEvent event2
;
1610 event
.m_eventObject
= win
;
1611 win
->GetEventHandler()->ProcessEvent(event2
);
1614 node
= node
->GetNext();
1618 void wxWindow::OnIdle(wxIdleEvent
& WXUNUSED(event
))
1620 // This calls the UI-update mechanism (querying windows for
1621 // menu/toolbar/control state information)
1625 // ----------------------------------------------------------------------------
1627 // ----------------------------------------------------------------------------
1629 bool wxWindow::ProcessAccelerator(wxKeyEvent
& event
)
1631 if (!m_acceleratorTable
.Ok())
1634 int count
= m_acceleratorTable
.GetCount();
1635 wxAcceleratorEntry
* entries
= m_acceleratorTable
.GetEntries();
1637 for (i
= 0; i
< count
; i
++)
1639 wxAcceleratorEntry
* entry
= & (entries
[i
]);
1640 if (entry
->MatchesEvent(event
))
1642 // Bingo, we have a match. Now find a control that matches the entry
1645 // Need to go up to the top of the window hierarchy, since it might
1646 // be e.g. a menu item
1647 wxWindow
* parent
= this;
1648 while ( parent
&& !parent
->IsTopLevel() )
1649 parent
= parent
->GetParent();
1654 wxFrame
* frame
= wxDynamicCast(parent
, wxFrame
);
1657 // Try for a menu command
1658 if (frame
->GetMenuBar())
1660 wxMenuItem
* item
= frame
->GetMenuBar()->FindItem(entry
->GetCommand());
1663 wxCommandEvent
commandEvent(wxEVT_COMMAND_MENU_SELECTED
, entry
->GetCommand());
1664 commandEvent
.SetEventObject(frame
);
1666 // If ProcessEvent returns TRUE (it was handled), then
1667 // the calling code will skip the event handling.
1668 return frame
->GetEventHandler()->ProcessEvent(commandEvent
);
1673 // Find a child matching the command id
1674 wxWindow
* child
= parent
->FindWindow(entry
->GetCommand());
1680 // Now we process those kinds of windows that we can.
1681 // For now, only buttons.
1682 if ( wxDynamicCast(child
, wxButton
) )
1684 wxCommandEvent
commandEvent (wxEVT_COMMAND_BUTTON_CLICKED
, child
->GetId());
1685 commandEvent
.SetEventObject(child
);
1686 return child
->GetEventHandler()->ProcessEvent(commandEvent
);
1693 // We didn't match the key event against an accelerator.
1697 // ============================================================================
1698 // Motif-specific stuff from here on
1699 // ============================================================================
1701 // ----------------------------------------------------------------------------
1702 // function which maintain the global hash table mapping Widgets to wxWindows
1703 // ----------------------------------------------------------------------------
1705 bool wxAddWindowToTable(Widget w
, wxWindow
*win
)
1707 wxWindow
*oldItem
= NULL
;
1708 if ((oldItem
= (wxWindow
*)wxWidgetHashTable
->Get ((long) w
)))
1710 wxLogDebug("Widget table clash: new widget is %ld, %s",
1711 (long)w
, win
->GetClassInfo()->GetClassName());
1715 wxWidgetHashTable
->Put((long) w
, win
);
1717 wxLogDebug("Widget 0x%08x <-> window %p (%s)",
1718 w
, win
, win
->GetClassInfo()->GetClassName());
1723 wxWindow
*wxGetWindowFromTable(Widget w
)
1725 return (wxWindow
*)wxWidgetHashTable
->Get((long) w
);
1728 void wxDeleteWindowFromTable(Widget w
)
1730 wxWidgetHashTable
->Delete((long)w
);
1733 // ----------------------------------------------------------------------------
1734 // add/remove window from the table
1735 // ----------------------------------------------------------------------------
1737 // Add to hash table, add event handler
1738 bool wxWindow::AttachWidget (wxWindow
* WXUNUSED(parent
), WXWidget mainWidget
,
1739 WXWidget formWidget
, int x
, int y
, int width
, int height
)
1741 wxAddWindowToTable((Widget
) mainWidget
, this);
1742 if (CanAddEventHandler())
1744 XtAddEventHandler((Widget
) mainWidget
,
1745 ButtonPressMask
| ButtonReleaseMask
| PointerMotionMask
, // | KeyPressMask,
1747 wxPanelItemEventHandler
,
1754 XtOverrideTranslations ((Widget
) mainWidget
,
1755 ptr
= XtParseTranslationTable ("<Configure>: resize()"));
1756 XtFree ((char *) ptr
);
1759 // Some widgets have a parent form widget, e.g. wxRadioBox
1762 if (!wxAddWindowToTable((Widget
) formWidget
, this))
1766 XtOverrideTranslations ((Widget
) formWidget
,
1767 ptr
= XtParseTranslationTable ("<Configure>: resize()"));
1768 XtFree ((char *) ptr
);
1775 SetSize (x
, y
, width
, height
);
1780 // Remove event handler, remove from hash table
1781 bool wxWindow::DetachWidget(WXWidget widget
)
1783 if (CanAddEventHandler())
1785 XtRemoveEventHandler((Widget
) widget
,
1786 ButtonPressMask
| ButtonReleaseMask
| PointerMotionMask
, // | KeyPressMask,
1788 wxPanelItemEventHandler
,
1792 wxDeleteWindowFromTable((Widget
) widget
);
1796 // ----------------------------------------------------------------------------
1797 // Motif-specific accessors
1798 // ----------------------------------------------------------------------------
1800 // Get the underlying X window
1801 WXWindow
wxWindow::GetXWindow() const
1803 Widget wMain
= (Widget
)GetMainWidget();
1805 return (WXWindow
) XtWindow(wMain
);
1807 return (WXWindow
) 0;
1810 // Get the underlying X display
1811 WXDisplay
*wxWindow::GetXDisplay() const
1813 Widget wMain
= (Widget
)GetMainWidget();
1815 return (WXDisplay
*) XtDisplay(wMain
);
1817 return (WXDisplay
*) NULL
;
1820 WXWidget
wxWindow::GetMainWidget() const
1823 return m_drawingArea
;
1825 return m_mainWidget
;
1828 WXWidget
wxWindow::GetClientWidget() const
1830 if (m_drawingArea
!= (WXWidget
) 0)
1831 return m_drawingArea
;
1833 return GetMainWidget();
1836 WXWidget
wxWindow::GetTopWidget() const
1838 return GetMainWidget();
1841 WXWidget
wxWindow::GetLabelWidget() const
1843 return GetMainWidget();
1846 // ----------------------------------------------------------------------------
1848 // ----------------------------------------------------------------------------
1850 // All widgets should have this as their resize proc.
1851 // OnSize sent to wxWindow via client data.
1852 void wxWidgetResizeProc(Widget w
, XConfigureEvent
*WXUNUSED(event
), String
WXUNUSED(args
)[], int *WXUNUSED(num_args
))
1854 wxWindow
*win
= wxGetWindowFromTable(w
);
1858 if (win
->PreResize())
1861 win
->GetSize(&width
, &height
);
1862 wxSizeEvent
sizeEvent(wxSize(width
, height
), win
->GetId());
1863 sizeEvent
.SetEventObject(win
);
1864 win
->GetEventHandler()->ProcessEvent(sizeEvent
);
1868 static void wxCanvasRepaintProc(Widget drawingArea
,
1869 XtPointer clientData
,
1870 XmDrawingAreaCallbackStruct
* cbs
)
1872 if (!wxGetWindowFromTable(drawingArea
))
1875 XEvent
* event
= cbs
->event
;
1876 wxWindow
* win
= (wxWindow
*) clientData
;
1878 switch (event
->type
)
1882 win
->AddUpdateRect(event
->xexpose
.x
, event
->xexpose
.y
,
1883 event
->xexpose
.width
, event
->xexpose
.height
);
1885 if (event
-> xexpose
.count
== 0)
1888 win
->ClearUpdateRects();
1895 // Unable to deal with Enter/Leave without a separate EventHandler (Motif 1.1.4)
1896 static void wxCanvasEnterLeave(Widget drawingArea
,
1897 XtPointer
WXUNUSED(clientData
),
1898 XCrossingEvent
* event
)
1900 XmDrawingAreaCallbackStruct cbs
;
1903 ((XCrossingEvent
&) ev
) = *event
;
1905 cbs
.reason
= XmCR_INPUT
;
1908 wxCanvasInputEvent(drawingArea
, (XtPointer
) NULL
, &cbs
);
1911 // Fix to make it work under Motif 1.0 (!)
1912 static void wxCanvasMotionEvent (Widget
WXUNUSED(drawingArea
), XButtonEvent
* WXUNUSED(event
))
1914 #if XmVersion <= 1000
1915 XmDrawingAreaCallbackStruct cbs
;
1918 ev
= *((XEvent
*) event
);
1919 cbs
.reason
= XmCR_INPUT
;
1922 wxCanvasInputEvent (drawingArea
, (XtPointer
) NULL
, &cbs
);
1923 #endif // XmVersion <= 1000
1926 static void wxCanvasInputEvent(Widget drawingArea
,
1927 XtPointer
WXUNUSED(data
),
1928 XmDrawingAreaCallbackStruct
* cbs
)
1930 wxWindow
*canvas
= wxGetWindowFromTable(drawingArea
);
1936 if (cbs
->reason
!= XmCR_INPUT
)
1939 local_event
= *(cbs
->event
); // We must keep a copy!
1941 switch (local_event
.xany
.type
)
1949 // FIXME: most of this mouse event code is more or less
1950 // duplicated in wxTranslateMouseEvent
1952 wxEventType eventType
= wxEVT_NULL
;
1954 if (local_event
.xany
.type
== EnterNotify
)
1956 //if (local_event.xcrossing.mode!=NotifyNormal)
1957 // return ; // Ignore grab events
1958 eventType
= wxEVT_ENTER_WINDOW
;
1959 // canvas->GetEventHandler()->OnSetFocus();
1961 else if (local_event
.xany
.type
== LeaveNotify
)
1963 //if (local_event.xcrossingr.mode!=NotifyNormal)
1964 // return ; // Ignore grab events
1965 eventType
= wxEVT_LEAVE_WINDOW
;
1966 // canvas->GetEventHandler()->OnKillFocus();
1968 else if (local_event
.xany
.type
== MotionNotify
)
1970 eventType
= wxEVT_MOTION
;
1971 if (local_event
.xmotion
.is_hint
== NotifyHint
)
1974 Display
*dpy
= XtDisplay (drawingArea
);
1976 XQueryPointer (dpy
, XtWindow (drawingArea
),
1978 &local_event
.xmotion
.x_root
,
1979 &local_event
.xmotion
.y_root
,
1980 &local_event
.xmotion
.x
,
1981 &local_event
.xmotion
.y
,
1982 &local_event
.xmotion
.state
);
1989 else if (local_event
.xany
.type
== ButtonPress
)
1991 if (local_event
.xbutton
.button
== Button1
)
1993 eventType
= wxEVT_LEFT_DOWN
;
1994 canvas
->SetButton1(TRUE
);
1996 else if (local_event
.xbutton
.button
== Button2
)
1998 eventType
= wxEVT_MIDDLE_DOWN
;
1999 canvas
->SetButton2(TRUE
);
2001 else if (local_event
.xbutton
.button
== Button3
)
2003 eventType
= wxEVT_RIGHT_DOWN
;
2004 canvas
->SetButton3(TRUE
);
2007 else if (local_event
.xany
.type
== ButtonRelease
)
2009 if (local_event
.xbutton
.button
== Button1
)
2011 eventType
= wxEVT_LEFT_UP
;
2012 canvas
->SetButton1(FALSE
);
2014 else if (local_event
.xbutton
.button
== Button2
)
2016 eventType
= wxEVT_MIDDLE_UP
;
2017 canvas
->SetButton2(FALSE
);
2019 else if (local_event
.xbutton
.button
== Button3
)
2021 eventType
= wxEVT_RIGHT_UP
;
2022 canvas
->SetButton3(FALSE
);
2026 wxMouseEvent
wxevent (eventType
);
2028 wxevent
.m_leftDown
= ((eventType
== wxEVT_LEFT_DOWN
)
2029 || (event_left_is_down (&local_event
)
2030 && (eventType
!= wxEVT_LEFT_UP
)));
2031 wxevent
.m_middleDown
= ((eventType
== wxEVT_MIDDLE_DOWN
)
2032 || (event_middle_is_down (&local_event
)
2033 && (eventType
!= wxEVT_MIDDLE_UP
)));
2034 wxevent
.m_rightDown
= ((eventType
== wxEVT_RIGHT_DOWN
)
2035 || (event_right_is_down (&local_event
)
2036 && (eventType
!= wxEVT_RIGHT_UP
)));
2038 wxevent
.m_shiftDown
= local_event
.xbutton
.state
& ShiftMask
;
2039 wxevent
.m_controlDown
= local_event
.xbutton
.state
& ControlMask
;
2040 wxevent
.m_altDown
= local_event
.xbutton
.state
& Mod3Mask
;
2041 wxevent
.m_metaDown
= local_event
.xbutton
.state
& Mod1Mask
;
2042 wxevent
.SetTimestamp(local_event
.xbutton
.time
);
2044 // Now check if we need to translate this event into a double click
2045 if (TRUE
) // canvas->doubleClickAllowed)
2047 if (wxevent
.ButtonDown())
2049 long dclickTime
= XtGetMultiClickTime((Display
*) wxGetDisplay());
2051 // get button and time-stamp
2053 if (wxevent
.LeftDown())
2055 else if (wxevent
.MiddleDown())
2057 else if (wxevent
.RightDown())
2059 long ts
= wxevent
.GetTimestamp();
2061 // check, if single or double click
2062 int buttonLast
= canvas
->GetLastClickedButton();
2063 long lastTS
= canvas
->GetLastClickTime();
2064 if ( buttonLast
&& buttonLast
== button
&& (ts
- lastTS
) < dclickTime
)
2067 canvas
->SetLastClick(0, ts
);
2068 switch ( eventType
)
2070 case wxEVT_LEFT_DOWN
:
2071 wxevent
.SetEventType(wxEVT_LEFT_DCLICK
);
2073 case wxEVT_MIDDLE_DOWN
:
2074 wxevent
.SetEventType(wxEVT_MIDDLE_DCLICK
);
2076 case wxEVT_RIGHT_DOWN
:
2077 wxevent
.SetEventType(wxEVT_RIGHT_DCLICK
);
2087 // not fast enough or different button
2088 canvas
->SetLastClick(button
, ts
);
2093 wxevent
.SetId(canvas
->GetId());
2094 wxevent
.SetEventObject(canvas
);
2095 wxevent
.m_x
= local_event
.xbutton
.x
;
2096 wxevent
.m_y
= local_event
.xbutton
.y
;
2097 canvas
->GetEventHandler()->ProcessEvent (wxevent
);
2099 if (eventType
== wxEVT_ENTER_WINDOW
||
2100 eventType
== wxEVT_LEAVE_WINDOW
||
2101 eventType
== wxEVT_MOTION
2111 XComposeStatus compose
;
2112 (void) XLookupString ((XKeyEvent
*) & local_event
, wxBuffer
, 20, &keySym
, &compose
);
2115 (void) XLookupString ((XKeyEvent
*) & local_event
, wxBuffer
, 20, &keySym
, NULL
);
2116 int id
= wxCharCodeXToWX (keySym
);
2118 wxEventType eventType
= wxEVT_CHAR
;
2120 wxKeyEvent
event (eventType
);
2122 if (local_event
.xkey
.state
& ShiftMask
)
2123 event
.m_shiftDown
= TRUE
;
2124 if (local_event
.xkey
.state
& ControlMask
)
2125 event
.m_controlDown
= TRUE
;
2126 if (local_event
.xkey
.state
& Mod3Mask
)
2127 event
.m_altDown
= TRUE
;
2128 if (local_event
.xkey
.state
& Mod1Mask
)
2129 event
.m_metaDown
= TRUE
;
2130 event
.SetEventObject(canvas
);
2131 event
.m_keyCode
= id
;
2132 event
.SetTimestamp(local_event
.xkey
.time
);
2136 // Implement wxFrame::OnCharHook by checking ancestor.
2137 wxWindow
*parent
= canvas
->GetParent();
2138 while (parent
&& !parent
->IsKindOf(CLASSINFO(wxFrame
)))
2139 parent
= parent
->GetParent();
2143 event
.SetEventType(wxEVT_CHAR_HOOK
);
2144 if (parent
->GetEventHandler()->ProcessEvent(event
))
2148 // For simplicity, OnKeyDown is the same as OnChar
2149 // TODO: filter modifier key presses from OnChar
2150 event
.SetEventType(wxEVT_KEY_DOWN
);
2152 // Only process OnChar if OnKeyDown didn't swallow it
2153 if (!canvas
->GetEventHandler()->ProcessEvent (event
))
2155 event
.SetEventType(wxEVT_CHAR
);
2156 canvas
->GetEventHandler()->ProcessEvent (event
);
2164 (void) XLookupString ((XKeyEvent
*) & local_event
, wxBuffer
, 20, &keySym
, NULL
);
2165 int id
= wxCharCodeXToWX (keySym
);
2167 wxKeyEvent
event (wxEVT_KEY_UP
);
2169 if (local_event
.xkey
.state
& ShiftMask
)
2170 event
.m_shiftDown
= TRUE
;
2171 if (local_event
.xkey
.state
& ControlMask
)
2172 event
.m_controlDown
= TRUE
;
2173 if (local_event
.xkey
.state
& Mod3Mask
)
2174 event
.m_altDown
= TRUE
;
2175 if (local_event
.xkey
.state
& Mod1Mask
)
2176 event
.m_metaDown
= TRUE
;
2177 event
.SetEventObject(canvas
);
2178 event
.m_keyCode
= id
;
2179 event
.SetTimestamp(local_event
.xkey
.time
);
2183 canvas
->GetEventHandler()->ProcessEvent (event
);
2189 if (local_event
.xfocus
.detail
!= NotifyPointer
)
2191 wxFocusEvent
event(wxEVT_SET_FOCUS
, canvas
->GetId());
2192 event
.SetEventObject(canvas
);
2193 canvas
->GetEventHandler()->ProcessEvent(event
);
2199 if (local_event
.xfocus
.detail
!= NotifyPointer
)
2201 wxFocusEvent
event(wxEVT_KILL_FOCUS
, canvas
->GetId());
2202 event
.SetEventObject(canvas
);
2203 canvas
->GetEventHandler()->ProcessEvent(event
);
2212 static void wxPanelItemEventHandler(Widget wid
,
2213 XtPointer
WXUNUSED(client_data
),
2215 Boolean
*continueToDispatch
)
2217 // Widget can be a label or the actual widget.
2219 wxWindow
*window
= wxGetWindowFromTable(wid
);
2222 wxMouseEvent
wxevent(0);
2223 if (wxTranslateMouseEvent(wxevent
, window
, wid
, event
))
2225 window
->GetEventHandler()->ProcessEvent(wxevent
);
2229 // TODO: probably the key to allowing default behaviour to happen. Say we
2230 // set a m_doDefault flag to FALSE at the start of this function. Then in
2231 // e.g. wxWindow::OnMouseEvent we can call Default() which sets this flag to
2232 // TRUE, indicating that default processing can happen. Thus, behaviour can
2233 // appear to be overridden just by adding an event handler and not calling
2234 // wxWindow::OnWhatever. ALSO, maybe we can use this instead of the current
2235 // way of handling drawing area events, to simplify things.
2236 *continueToDispatch
= True
;
2239 static void wxScrollBarCallback(Widget scrollbar
,
2240 XtPointer clientData
,
2241 XmScrollBarCallbackStruct
*cbs
)
2243 wxWindow
*win
= wxGetWindowFromTable(scrollbar
);
2244 int orientation
= (int) clientData
;
2246 wxEventType eventType
= wxEVT_NULL
;
2247 switch (cbs
->reason
)
2249 case XmCR_INCREMENT
:
2251 eventType
= wxEVT_SCROLLWIN_LINEDOWN
;
2254 case XmCR_DECREMENT
:
2256 eventType
= wxEVT_SCROLLWIN_LINEUP
;
2261 eventType
= wxEVT_SCROLLWIN_THUMBTRACK
;
2264 case XmCR_VALUE_CHANGED
:
2266 // TODO: Should this be intercepted too, or will it cause
2267 // duplicate events?
2268 eventType
= wxEVT_SCROLLWIN_THUMBTRACK
;
2271 case XmCR_PAGE_INCREMENT
:
2273 eventType
= wxEVT_SCROLLWIN_PAGEDOWN
;
2276 case XmCR_PAGE_DECREMENT
:
2278 eventType
= wxEVT_SCROLLWIN_PAGEUP
;
2283 eventType
= wxEVT_SCROLLWIN_TOP
;
2286 case XmCR_TO_BOTTOM
:
2288 eventType
= wxEVT_SCROLLWIN_BOTTOM
;
2293 // Should never get here
2294 wxFAIL_MSG("Unknown scroll event.");
2299 wxScrollWinEvent
event(eventType
,
2301 ((orientation
== XmHORIZONTAL
) ?
2302 wxHORIZONTAL
: wxVERTICAL
));
2303 event
.SetEventObject( win
);
2304 win
->GetEventHandler()->ProcessEvent(event
);
2307 // For repainting arbitrary windows
2308 void wxUniversalRepaintProc(Widget w
, XtPointer
WXUNUSED(c_data
), XEvent
*event
, char *)
2313 wxWindow
* win
= wxGetWindowFromTable(w
);
2317 switch(event
-> type
)
2321 window
= (Window
) win
-> GetXWindow();
2322 display
= (Display
*) win
-> GetXDisplay();
2324 if (event
-> xexpose
.count
== 0)
2328 win
->ClearUpdateRects();
2332 win
->AddUpdateRect(event
->xexpose
.x
, event
->xexpose
.y
,
2333 event
->xexpose
.width
, event
->xexpose
.height
);
2341 // ----------------------------------------------------------------------------
2342 // CanvaseXXXSize() functions
2343 // ----------------------------------------------------------------------------
2345 // SetSize, but as per old wxCanvas (with drawing widget etc.)
2346 void wxWindow::CanvasSetSize (int x
, int y
, int w
, int h
, int sizeFlags
)
2348 // A bit of optimization to help sort out the flickers.
2349 int oldX
, oldY
, oldW
, oldH
;
2350 GetSize(& oldW
, & oldH
);
2351 GetPosition(& oldX
, & oldY
);
2353 bool useOldPos
= FALSE
;
2354 bool useOldSize
= FALSE
;
2356 if ((x
== -1) && (x
== -1) && ((sizeFlags
& wxSIZE_ALLOW_MINUS_ONE
) == 0))
2358 else if (x
== oldX
&& y
== oldY
)
2361 if ((w
== -1) && (h
== -1))
2363 else if (w
== oldW
&& h
== oldH
)
2366 if (!wxNoOptimize::CanOptimize())
2368 useOldSize
= FALSE
; useOldPos
= FALSE
;
2371 if (useOldPos
&& useOldSize
)
2374 Widget drawingArea
= (Widget
) m_drawingArea
;
2375 bool managed
= XtIsManaged(m_borderWidget
? (Widget
) m_borderWidget
: (Widget
) m_scrolledWindow
);
2378 XtUnmanageChild (m_borderWidget
? (Widget
) m_borderWidget
: (Widget
) m_scrolledWindow
);
2379 XtVaSetValues(drawingArea
, XmNresizePolicy
, XmRESIZE_ANY
, NULL
);
2381 int xx
= x
; int yy
= y
;
2382 AdjustForParentClientOrigin(xx
, yy
, sizeFlags
);
2386 if (x
> -1 || (sizeFlags
& wxSIZE_ALLOW_MINUS_ONE
))
2388 XtVaSetValues (m_borderWidget
? (Widget
) m_borderWidget
: (Widget
) m_scrolledWindow
,
2392 if (y
> -1 || (sizeFlags
& wxSIZE_ALLOW_MINUS_ONE
))
2394 XtVaSetValues (m_borderWidget
? (Widget
) m_borderWidget
: (Widget
) m_scrolledWindow
,
2406 XtVaSetValues ((Widget
) m_borderWidget
, XmNwidth
, w
, NULL
);
2407 short thick
, margin
;
2408 XtVaGetValues ((Widget
) m_borderWidget
,
2409 XmNshadowThickness
, &thick
,
2410 XmNmarginWidth
, &margin
,
2412 w
-= 2 * (thick
+ margin
);
2415 XtVaSetValues ((Widget
) m_scrolledWindow
, XmNwidth
, w
, NULL
);
2419 XtVaGetValues ((Widget
) m_scrolledWindow
,
2420 XmNspacing
, &spacing
,
2421 XmNverticalScrollBar
, &sbar
,
2425 XtVaGetValues (sbar
, XmNwidth
, &wsbar
, NULL
);
2429 w
-= (spacing
+ wsbar
);
2432 XtVaSetValues(drawingArea
, XmNwidth
, w
, NULL
);
2439 XtVaSetValues ((Widget
) m_borderWidget
, XmNheight
, h
, NULL
);
2440 short thick
, margin
;
2441 XtVaGetValues ((Widget
) m_borderWidget
,
2442 XmNshadowThickness
, &thick
,
2443 XmNmarginHeight
, &margin
,
2445 h
-= 2 * (thick
+ margin
);
2448 XtVaSetValues ((Widget
) m_scrolledWindow
, XmNheight
, h
, NULL
);
2452 XtVaGetValues ((Widget
) m_scrolledWindow
,
2453 XmNspacing
, &spacing
,
2454 XmNhorizontalScrollBar
, &sbar
,
2458 XtVaGetValues (sbar
, XmNheight
, &wsbar
, NULL
);
2462 h
-= (spacing
+ wsbar
);
2465 XtVaSetValues(drawingArea
, XmNheight
, h
, NULL
);
2471 XtManageChild (m_borderWidget
? (Widget
) m_borderWidget
: (Widget
) m_scrolledWindow
);
2472 XtVaSetValues(drawingArea
, XmNresizePolicy
, XmRESIZE_NONE
, NULL
);
2476 GetClientSize (&ww
, &hh
);
2477 wxSizeEvent
sizeEvent(wxSize(ww
, hh
), GetId());
2478 sizeEvent
.SetEventObject(this);
2480 GetEventHandler()->ProcessEvent(sizeEvent
);
2484 void wxWindow::CanvasSetClientSize (int w
, int h
)
2486 Widget drawingArea
= (Widget
) m_drawingArea
;
2488 XtVaSetValues(drawingArea
, XmNresizePolicy
, XmRESIZE_ANY
, NULL
);
2491 XtVaSetValues(drawingArea
, XmNwidth
, w
, NULL
);
2493 XtVaSetValues(drawingArea
, XmNheight
, h
, NULL
);
2496 // TODO: is this necessary?
2497 allowRepainting
= FALSE
;
2499 XSync (XtDisplay (drawingArea
), FALSE
);
2501 while (XtAppPending (wxTheApp
->appContext
))
2503 XFlush (XtDisplay (drawingArea
));
2504 XtAppNextEvent (wxTheApp
->appContext
, &event
);
2505 XtDispatchEvent (&event
);
2509 XtVaSetValues(drawingArea
, XmNresizePolicy
, XmRESIZE_NONE
, NULL
);
2512 allowRepainting
= TRUE
;
2515 wxSizeEvent
sizeEvent(wxSize(w
, h
), GetId());
2516 sizeEvent
.SetEventObject(this);
2518 GetEventHandler()->ProcessEvent(sizeEvent
);
2522 void wxWindow::CanvasGetClientSize (int *w
, int *h
) const
2524 // Must return the same thing that was set via SetClientSize
2526 XtVaGetValues ((Widget
) m_drawingArea
, XmNwidth
, &xx
, XmNheight
, &yy
, NULL
);
2531 void wxWindow::CanvasGetSize (int *w
, int *h
) const
2534 if ((Widget
) m_borderWidget
)
2535 XtVaGetValues ((Widget
) m_borderWidget
, XmNwidth
, &xx
, XmNheight
, &yy
, NULL
);
2536 else if ((Widget
) m_scrolledWindow
)
2537 XtVaGetValues ((Widget
) m_scrolledWindow
, XmNwidth
, &xx
, XmNheight
, &yy
, NULL
);
2539 XtVaGetValues ((Widget
) m_drawingArea
, XmNwidth
, &xx
, XmNheight
, &yy
, NULL
);
2545 void wxWindow::CanvasGetPosition (int *x
, int *y
) const
2548 XtVaGetValues (m_borderWidget
? (Widget
) m_borderWidget
: (Widget
) m_scrolledWindow
, XmNx
, &xx
, XmNy
, &yy
, NULL
);
2550 // We may be faking the client origin.
2551 // So a window that's really at (0, 30) may appear
2552 // (to wxWin apps) to be at (0, 0).
2555 wxPoint
pt(GetParent()->GetClientAreaOrigin());
2564 // ----------------------------------------------------------------------------
2565 // TranslateXXXEvent() functions
2566 // ----------------------------------------------------------------------------
2568 bool wxTranslateMouseEvent(wxMouseEvent
& wxevent
, wxWindow
*win
, Widget widget
, XEvent
*xevent
)
2570 switch (xevent
->xany
.type
)
2572 case EnterNotify
: // never received here - yes ? MB
2573 case LeaveNotify
: // never received here - yes ? MB
2578 wxEventType eventType
= wxEVT_NULL
;
2580 // FIXME: this is never true I think - MB
2582 if (xevent
->xany
.type
== LeaveNotify
)
2584 win
->SetButton1(FALSE
);
2585 win
->SetButton2(FALSE
);
2586 win
->SetButton3(FALSE
);
2589 else if (xevent
->xany
.type
== MotionNotify
)
2591 eventType
= wxEVT_MOTION
;
2593 else if (xevent
->xany
.type
== ButtonPress
)
2595 wxevent
.SetTimestamp(xevent
->xbutton
.time
);
2597 if (xevent
->xbutton
.button
== Button1
)
2599 eventType
= wxEVT_LEFT_DOWN
;
2600 win
->SetButton1(TRUE
);
2603 else if (xevent
->xbutton
.button
== Button2
)
2605 eventType
= wxEVT_MIDDLE_DOWN
;
2606 win
->SetButton2(TRUE
);
2609 else if (xevent
->xbutton
.button
== Button3
)
2611 eventType
= wxEVT_RIGHT_DOWN
;
2612 win
->SetButton3(TRUE
);
2616 // check for a double click
2618 long dclickTime
= XtGetMultiClickTime((Display
*) wxGetDisplay());
2619 long ts
= wxevent
.GetTimestamp();
2621 int buttonLast
= win
->GetLastClickedButton();
2622 long lastTS
= win
->GetLastClickTime();
2623 if ( buttonLast
&& buttonLast
== button
&& (ts
- lastTS
) < dclickTime
)
2626 win
->SetLastClick(0, ts
);
2627 switch ( eventType
)
2629 case wxEVT_LEFT_DOWN
:
2630 eventType
= wxEVT_LEFT_DCLICK
;
2632 case wxEVT_MIDDLE_DOWN
:
2633 eventType
= wxEVT_MIDDLE_DCLICK
;
2635 case wxEVT_RIGHT_DOWN
:
2636 eventType
= wxEVT_RIGHT_DCLICK
;
2646 // not fast enough or different button
2647 win
->SetLastClick(button
, ts
);
2650 else if (xevent
->xany
.type
== ButtonRelease
)
2652 if (xevent
->xbutton
.button
== Button1
)
2654 eventType
= wxEVT_LEFT_UP
;
2655 win
->SetButton1(FALSE
);
2657 else if (xevent
->xbutton
.button
== Button2
)
2659 eventType
= wxEVT_MIDDLE_UP
;
2660 win
->SetButton2(FALSE
);
2662 else if (xevent
->xbutton
.button
== Button3
)
2664 eventType
= wxEVT_RIGHT_UP
;
2665 win
->SetButton3(FALSE
);
2674 wxevent
.SetEventType(eventType
);
2677 XtVaGetValues(widget
, XmNx
, &x1
, XmNy
, &y1
, NULL
);
2680 win
->GetPosition(&x2
, &y2
);
2682 // The button x/y must be translated to wxWindows
2683 // window space - the widget might be a label or button,
2687 if (widget
!= (Widget
)win
->GetMainWidget())
2693 wxevent
.m_x
= xevent
->xbutton
.x
+ dx
;
2694 wxevent
.m_y
= xevent
->xbutton
.y
+ dy
;
2696 wxevent
.m_leftDown
= ((eventType
== wxEVT_LEFT_DOWN
)
2697 || (event_left_is_down (xevent
)
2698 && (eventType
!= wxEVT_LEFT_UP
)));
2699 wxevent
.m_middleDown
= ((eventType
== wxEVT_MIDDLE_DOWN
)
2700 || (event_middle_is_down (xevent
)
2701 && (eventType
!= wxEVT_MIDDLE_UP
)));
2702 wxevent
.m_rightDown
= ((eventType
== wxEVT_RIGHT_DOWN
)
2703 || (event_right_is_down (xevent
)
2704 && (eventType
!= wxEVT_RIGHT_UP
)));
2706 wxevent
.m_shiftDown
= xevent
->xbutton
.state
& ShiftMask
;
2707 wxevent
.m_controlDown
= xevent
->xbutton
.state
& ControlMask
;
2708 wxevent
.m_altDown
= xevent
->xbutton
.state
& Mod3Mask
;
2709 wxevent
.m_metaDown
= xevent
->xbutton
.state
& Mod1Mask
;
2711 wxevent
.SetId(win
->GetId());
2712 wxevent
.SetEventObject(win
);
2720 bool wxTranslateKeyEvent(wxKeyEvent
& wxevent
, wxWindow
*win
, Widget
WXUNUSED(widget
), XEvent
*xevent
)
2722 switch (xevent
->xany
.type
)
2731 XComposeStatus compose
;
2732 (void) XLookupString ((XKeyEvent
*) xevent
, buf
, 20, &keySym
, &compose
);
2734 (void) XLookupString ((XKeyEvent
*) xevent
, buf
, 20, &keySym
, NULL
);
2735 int id
= wxCharCodeXToWX (keySym
);
2737 if (xevent
->xkey
.state
& ShiftMask
)
2738 wxevent
.m_shiftDown
= TRUE
;
2739 if (xevent
->xkey
.state
& ControlMask
)
2740 wxevent
.m_controlDown
= TRUE
;
2741 if (xevent
->xkey
.state
& Mod3Mask
)
2742 wxevent
.m_altDown
= TRUE
;
2743 if (xevent
->xkey
.state
& Mod1Mask
)
2744 wxevent
.m_metaDown
= TRUE
;
2745 wxevent
.SetEventObject(win
);
2746 wxevent
.m_keyCode
= id
;
2747 wxevent
.SetTimestamp(xevent
->xkey
.time
);
2749 wxevent
.m_x
= xevent
->xbutton
.x
;
2750 wxevent
.m_y
= xevent
->xbutton
.y
;
2764 // ----------------------------------------------------------------------------
2766 // ----------------------------------------------------------------------------
2768 #define YAllocColor XAllocColor
2769 XColor g_itemColors
[5];
2770 int wxComputeColours (Display
*display
, wxColour
* back
, wxColour
* fore
)
2773 static XmColorProc colorProc
;
2775 result
= wxNO_COLORS
;
2779 g_itemColors
[0].red
= (((long) back
->Red ()) << 8);
2780 g_itemColors
[0].green
= (((long) back
->Green ()) << 8);
2781 g_itemColors
[0].blue
= (((long) back
->Blue ()) << 8);
2782 g_itemColors
[0].flags
= DoRed
| DoGreen
| DoBlue
;
2783 if (colorProc
== (XmColorProc
) NULL
)
2785 // Get a ptr to the actual function
2786 colorProc
= XmSetColorCalculation ((XmColorProc
) NULL
);
2787 // And set it back to motif.
2788 XmSetColorCalculation (colorProc
);
2790 (*colorProc
) (&g_itemColors
[wxBACK_INDEX
],
2791 &g_itemColors
[wxFORE_INDEX
],
2792 &g_itemColors
[wxSELE_INDEX
],
2793 &g_itemColors
[wxTOPS_INDEX
],
2794 &g_itemColors
[wxBOTS_INDEX
]);
2795 result
= wxBACK_COLORS
;
2799 g_itemColors
[wxFORE_INDEX
].red
= (((long) fore
->Red ()) << 8);
2800 g_itemColors
[wxFORE_INDEX
].green
= (((long) fore
->Green ()) << 8);
2801 g_itemColors
[wxFORE_INDEX
].blue
= (((long) fore
->Blue ()) << 8);
2802 g_itemColors
[wxFORE_INDEX
].flags
= DoRed
| DoGreen
| DoBlue
;
2803 if (result
== wxNO_COLORS
)
2804 result
= wxFORE_COLORS
;
2807 Display
*dpy
= display
;
2808 Colormap cmap
= (Colormap
) wxTheApp
->GetMainColormap((WXDisplay
*) dpy
);
2812 /* 5 Colours to allocate */
2813 for (int i
= 0; i
< 5; i
++)
2814 if (!YAllocColor (dpy
, cmap
, &g_itemColors
[i
]))
2815 result
= wxNO_COLORS
;
2819 /* Only 1 colour to allocate */
2820 if (!YAllocColor (dpy
, cmap
, &g_itemColors
[wxFORE_INDEX
]))
2821 result
= wxNO_COLORS
;
2828 // Changes the foreground and background colours to be derived from the current
2829 // background colour. To change the foreground colour, you must call
2830 // SetForegroundColour explicitly.
2831 void wxWindow::ChangeBackgroundColour()
2833 WXWidget mainWidget
= GetMainWidget();
2835 DoChangeBackgroundColour(mainWidget
, m_backgroundColour
);
2837 // This not necessary
2840 if (m_scrolledWindow
&& (GetMainWidget() != m_scrolledWindow
))
2842 DoChangeBackgroundColour(m_scrolledWindow
, m_backgroundColour
);
2843 // Have to set the scrollbar colours back since
2844 // the scrolled window seemed to change them
2845 wxColour backgroundColour
= wxSystemSettings::GetSystemColour(wxSYS_COLOUR_3DFACE
);
2848 DoChangeBackgroundColour(m_hScrollBar
, backgroundColour
);
2850 DoChangeBackgroundColour(m_vScrollBar
, backgroundColour
);
2855 void wxWindow::ChangeForegroundColour()
2857 WXWidget mainWidget
= GetMainWidget();
2859 DoChangeForegroundColour(mainWidget
, m_foregroundColour
);
2860 if ( m_scrolledWindow
&& mainWidget
!= m_scrolledWindow
)
2861 DoChangeForegroundColour(m_scrolledWindow
, m_foregroundColour
);
2864 // Change a widget's foreground and background colours.
2865 void wxWindow::DoChangeForegroundColour(WXWidget widget
, wxColour
& foregroundColour
)
2867 // When should we specify the foreground, if it's calculated
2868 // by wxComputeColours?
2869 // Solution: say we start with the default (computed) foreground colour.
2870 // If we call SetForegroundColour explicitly for a control or window,
2871 // then the foreground is changed.
2872 // Therefore SetBackgroundColour computes the foreground colour, and
2873 // SetForegroundColour changes the foreground colour. The ordering is
2876 Widget w
= (Widget
)widget
;
2879 XmNforeground
, foregroundColour
.AllocColour(XtDisplay(w
)),
2884 void wxWindow::DoChangeBackgroundColour(WXWidget widget
, wxColour
& backgroundColour
, bool changeArmColour
)
2886 wxComputeColours (XtDisplay((Widget
) widget
), & backgroundColour
,
2889 XtVaSetValues ((Widget
) widget
,
2890 XmNbackground
, g_itemColors
[wxBACK_INDEX
].pixel
,
2891 XmNtopShadowColor
, g_itemColors
[wxTOPS_INDEX
].pixel
,
2892 XmNbottomShadowColor
, g_itemColors
[wxBOTS_INDEX
].pixel
,
2893 XmNforeground
, g_itemColors
[wxFORE_INDEX
].pixel
,
2896 if (changeArmColour
)
2897 XtVaSetValues ((Widget
) widget
,
2898 XmNarmColor
, g_itemColors
[wxSELE_INDEX
].pixel
,
2902 bool wxWindow::SetBackgroundColour(const wxColour
& col
)
2904 if ( !wxWindowBase::SetBackgroundColour(col
) )
2907 ChangeBackgroundColour();
2912 bool wxWindow::SetForegroundColour(const wxColour
& col
)
2914 if ( !wxWindowBase::SetForegroundColour(col
) )
2917 ChangeForegroundColour();
2922 void wxWindow::ChangeFont(bool keepOriginalSize
)
2924 // Note that this causes the widget to be resized back
2925 // to its original size! We therefore have to set the size
2926 // back again. TODO: a better way in Motif?
2927 Widget w
= (Widget
) GetLabelWidget(); // Usually the main widget
2928 if (w
&& m_font
.Ok())
2930 int width
, height
, width1
, height1
;
2931 GetSize(& width
, & height
);
2933 // lesstif 0.87 hangs here
2934 #ifndef LESSTIF_VERSION
2936 XmNfontList
, (XmFontList
) m_font
.GetFontList(1.0, XtDisplay(w
)),
2940 GetSize(& width1
, & height1
);
2941 if (keepOriginalSize
&& (width
!= width1
|| height
!= height1
))
2943 SetSize(-1, -1, width
, height
);
2948 // ----------------------------------------------------------------------------
2950 // ----------------------------------------------------------------------------
2952 wxWindow
*wxGetActiveWindow()
2958 // ----------------------------------------------------------------------------
2959 // wxNoOptimize: switch off size optimization
2960 // ----------------------------------------------------------------------------
2962 int wxNoOptimize::ms_count
= 0;