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
47 #include "wx/x11/private.h"
48 #include "X11/Xutil.h"
52 // ----------------------------------------------------------------------------
54 // ----------------------------------------------------------------------------
56 static const int SCROLL_MARGIN
= 4;
58 // ----------------------------------------------------------------------------
59 // global variables for this module
60 // ----------------------------------------------------------------------------
62 extern wxHashTable
*wxWidgetHashTable
;
63 static wxWindow
* g_captureWindow
= NULL
;
65 // ----------------------------------------------------------------------------
67 // ----------------------------------------------------------------------------
69 #define event_left_is_down(x) ((x)->xbutton.state & Button1Mask)
70 #define event_middle_is_down(x) ((x)->xbutton.state & Button2Mask)
71 #define event_right_is_down(x) ((x)->xbutton.state & Button3Mask)
73 // ----------------------------------------------------------------------------
75 // ----------------------------------------------------------------------------
77 IMPLEMENT_DYNAMIC_CLASS(wxWindowX11
, wxWindowBase
)
79 BEGIN_EVENT_TABLE(wxWindowX11
, wxWindowBase
)
80 EVT_SYS_COLOUR_CHANGED(wxWindowX11::OnSysColourChanged
)
81 EVT_IDLE(wxWindowX11::OnIdle
)
84 // ============================================================================
86 // ============================================================================
88 // ----------------------------------------------------------------------------
90 // ----------------------------------------------------------------------------
92 // ----------------------------------------------------------------------------
94 // ----------------------------------------------------------------------------
96 void wxWindowX11::Init()
98 // generic initializations first
102 m_needsRefresh
= TRUE
;
103 m_mainWidget
= (WXWindow
) 0;
107 m_button3Pressed
= FALSE
;
109 m_winCaptured
= FALSE
;
112 m_isBeingDeleted
= FALSE
;
118 m_drawingArea
= (WXWindow
) 0;
126 m_backingPixmap
= (WXPixmap
) 0;
135 m_canAddEventHandler
= FALSE
;
138 // real construction (Init() must have been called before!)
139 bool wxWindowX11::Create(wxWindow
*parent
, wxWindowID id
,
143 const wxString
& name
)
145 wxCHECK_MSG( parent
, FALSE
, "can't create wxWindow without parent" );
147 CreateBase(parent
, id
, pos
, size
, style
, wxDefaultValidator
, name
);
149 parent
->AddChild(this);
151 m_backgroundColour
= wxSystemSettings::GetColour(wxSYS_COLOUR_3DFACE
);
152 m_foregroundColour
= *wxBLACK
;
154 if (style
& wxSIMPLE_BORDER
)
156 } else if (style
& wxSUNKEN_BORDER
)
158 } else if (style
& wxRAISED_BORDER
)
162 // TODO: create XWindow
165 wxAddWindowToTable((Window
) m_drawingArea
, this);
166 wxAddWindowToTable((Window
) m_scrolledWindow
, this);
169 // Without this, the cursor may not be restored properly (e.g. in splitter
171 SetCursor(*wxSTANDARD_CURSOR
);
172 SetFont(wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT
));
173 SetSize(pos
.x
, pos
.y
, size
.x
, size
.y
);
179 wxWindowX11::~wxWindowX11()
181 if (g_captureWindow
== this)
182 g_captureWindow
= NULL
;
184 m_isBeingDeleted
= TRUE
;
186 // X11-specific actions first
187 WXWindow wMain
= GetMainWindow();
190 // Removes event handlers
191 //DetachWidget(wMain);
197 m_parent
->RemoveChild( this );
202 // If m_drawingArea, we're a fully-fledged window with drawing area,
203 // scrollbars etc. (what wxCanvas used to be)
206 // Destroy children before destroying self
210 XFreePixmap (XtDisplay ((Widget
) GetMainWidget()), (Pixmap
) m_backingPixmap
);
212 Widget w
= (Widget
) m_drawingArea
;
213 wxDeleteWindowFromTable(w
);
218 m_drawingArea
= (WXWidget
) 0;
221 // Only if we're _really_ a canvas (not a dialog box/panel)
222 if (m_scrolledWindow
)
224 wxDeleteWindowFromTable((Widget
) m_scrolledWindow
);
229 wxDeleteWindowFromTable((Widget
) m_hScrollBar
);
230 XtUnmanageChild((Widget
) m_hScrollBar
);
234 wxDeleteWindowFromTable((Widget
) m_vScrollBar
);
235 XtUnmanageChild((Widget
) m_vScrollBar
);
239 XtDestroyWidget((Widget
) m_hScrollBar
);
241 XtDestroyWidget((Widget
) m_vScrollBar
);
243 UnmanageAndDestroy(m_scrolledWindow
);
247 XtDestroyWidget ((Widget
) m_borderWidget
);
248 m_borderWidget
= (WXWidget
) 0;
251 else // Why wasn't this here before? JACS 8/3/2000
256 // Destroy the window
260 // XtDestroyWidget((Widget) GetMainWidget());
261 SetMainWindow((WXWindow
) NULL
);
265 // ----------------------------------------------------------------------------
266 // scrollbar management
267 // ----------------------------------------------------------------------------
270 void wxWindowX11::CreateScrollbar(wxOrientation orientation
)
274 wxCHECK_RET( m_drawingArea
, "this window can't have scrollbars" );
276 XtVaSetValues((Widget
) m_scrolledWindow
, XmNresizePolicy
, XmRESIZE_NONE
, NULL
);
278 // Add scrollbars if required
279 if (orientation
== wxHORIZONTAL
)
281 Widget hScrollBar
= XtVaCreateManagedWidget ("hsb",
282 xmScrollBarWidgetClass
, (Widget
) m_scrolledWindow
,
283 XmNorientation
, XmHORIZONTAL
,
285 XtAddCallback (hScrollBar
, XmNvalueChangedCallback
, (XtCallbackProc
) wxScrollBarCallback
, (XtPointer
) XmHORIZONTAL
);
286 XtAddCallback (hScrollBar
, XmNdragCallback
, (XtCallbackProc
) wxScrollBarCallback
, (XtPointer
) XmHORIZONTAL
);
287 XtAddCallback (hScrollBar
, XmNincrementCallback
, (XtCallbackProc
) wxScrollBarCallback
, (XtPointer
) XmHORIZONTAL
);
288 XtAddCallback (hScrollBar
, XmNdecrementCallback
, (XtCallbackProc
) wxScrollBarCallback
, (XtPointer
) XmHORIZONTAL
);
289 XtAddCallback (hScrollBar
, XmNpageIncrementCallback
, (XtCallbackProc
) wxScrollBarCallback
, (XtPointer
) XmHORIZONTAL
);
290 XtAddCallback (hScrollBar
, XmNpageDecrementCallback
, (XtCallbackProc
) wxScrollBarCallback
, (XtPointer
) XmHORIZONTAL
);
291 XtAddCallback (hScrollBar
, XmNtoTopCallback
, (XtCallbackProc
) wxScrollBarCallback
, (XtPointer
) XmHORIZONTAL
);
292 XtAddCallback (hScrollBar
, XmNtoBottomCallback
, (XtCallbackProc
) wxScrollBarCallback
, (XtPointer
) XmHORIZONTAL
);
294 XtVaSetValues (hScrollBar
,
299 m_hScrollBar
= (WXWidget
) hScrollBar
;
301 wxColour backgroundColour
= wxSystemSettings::GetColour(wxSYS_COLOUR_3DFACE
);
302 DoChangeBackgroundColour(m_hScrollBar
, backgroundColour
, TRUE
);
304 XtRealizeWidget(hScrollBar
);
306 XtVaSetValues((Widget
) m_scrolledWindow
,
307 XmNhorizontalScrollBar
, (Widget
) m_hScrollBar
,
312 wxAddWindowToTable( hScrollBar
, this );
315 if (orientation
== wxVERTICAL
)
317 Widget vScrollBar
= XtVaCreateManagedWidget ("vsb",
318 xmScrollBarWidgetClass
, (Widget
) m_scrolledWindow
,
319 XmNorientation
, XmVERTICAL
,
321 XtAddCallback (vScrollBar
, XmNvalueChangedCallback
, (XtCallbackProc
) wxScrollBarCallback
, (XtPointer
) XmVERTICAL
);
322 XtAddCallback (vScrollBar
, XmNdragCallback
, (XtCallbackProc
) wxScrollBarCallback
, (XtPointer
) XmVERTICAL
);
323 XtAddCallback (vScrollBar
, XmNincrementCallback
, (XtCallbackProc
) wxScrollBarCallback
, (XtPointer
) XmVERTICAL
);
324 XtAddCallback (vScrollBar
, XmNdecrementCallback
, (XtCallbackProc
) wxScrollBarCallback
, (XtPointer
) XmVERTICAL
);
325 XtAddCallback (vScrollBar
, XmNpageIncrementCallback
, (XtCallbackProc
) wxScrollBarCallback
, (XtPointer
) XmVERTICAL
);
326 XtAddCallback (vScrollBar
, XmNpageDecrementCallback
, (XtCallbackProc
) wxScrollBarCallback
, (XtPointer
) XmVERTICAL
);
327 XtAddCallback (vScrollBar
, XmNtoTopCallback
, (XtCallbackProc
) wxScrollBarCallback
, (XtPointer
) XmVERTICAL
);
328 XtAddCallback (vScrollBar
, XmNtoBottomCallback
, (XtCallbackProc
) wxScrollBarCallback
, (XtPointer
) XmVERTICAL
);
330 XtVaSetValues (vScrollBar
,
335 m_vScrollBar
= (WXWidget
) vScrollBar
;
336 wxColour backgroundColour
= wxSystemSettings::GetColour(wxSYS_COLOUR_3DFACE
);
337 DoChangeBackgroundColour(m_vScrollBar
, backgroundColour
, TRUE
);
339 XtRealizeWidget(vScrollBar
);
341 XtVaSetValues((Widget
) m_scrolledWindow
,
342 XmNverticalScrollBar
, (Widget
) m_vScrollBar
,
347 wxAddWindowToTable( vScrollBar
, this );
350 XtVaSetValues((Widget
) m_scrolledWindow
, XmNresizePolicy
, XmRESIZE_ANY
, NULL
);
354 void wxWindowX11::DestroyScrollbar(wxOrientation orientation
)
358 wxCHECK_RET( m_drawingArea
, "this window can't have scrollbars" );
360 XtVaSetValues((Widget
) m_scrolledWindow
, XmNresizePolicy
, XmRESIZE_NONE
, NULL
);
361 // Add scrollbars if required
362 if (orientation
== wxHORIZONTAL
)
366 wxDeleteWindowFromTable((Widget
)m_hScrollBar
);
367 XtDestroyWidget((Widget
) m_hScrollBar
);
369 m_hScrollBar
= (WXWidget
) 0;
372 XtVaSetValues((Widget
) m_scrolledWindow
,
373 XmNhorizontalScrollBar
, (Widget
) 0,
378 if (orientation
== wxVERTICAL
)
382 wxDeleteWindowFromTable((Widget
)m_vScrollBar
);
383 XtDestroyWidget((Widget
) m_vScrollBar
);
385 m_vScrollBar
= (WXWidget
) 0;
388 XtVaSetValues((Widget
) m_scrolledWindow
,
389 XmNverticalScrollBar
, (Widget
) 0,
393 XtVaSetValues((Widget
) m_scrolledWindow
, XmNresizePolicy
, XmRESIZE_ANY
, NULL
);
397 // ---------------------------------------------------------------------------
399 // ---------------------------------------------------------------------------
401 void wxWindowX11::SetFocus()
405 Widget wMain
= (Widget
) GetMainWidget();
406 XmProcessTraversal(wMain
, XmTRAVERSE_CURRENT
);
407 XmProcessTraversal((Widget
) GetMainWidget(), XmTRAVERSE_CURRENT
);
411 // Get the window with the focus
412 wxWindow
*wxWindowBase::FindFocus()
419 // (1) Can there be multiple focussed widgets in an application?
420 // In which case we need to find the top-level window that's
422 // (2) The widget with the focus may not be in the widget table
423 // depending on which widgets I put in the table
424 wxWindow
*winFocus
= (wxWindow
*)NULL
;
425 for ( wxWindowList::Node
*node
= wxTopLevelWindows
.GetFirst();
427 node
= node
->GetNext() )
429 wxWindow
*win
= node
->GetData();
431 Widget w
= XmGetFocusWidget ((Widget
) win
->GetTopWidget());
433 if (w
!= (Widget
) NULL
)
435 winFocus
= wxGetWindowFromTable(w
);
445 bool wxWindowX11::Enable(bool enable
)
447 if ( !wxWindowBase::Enable(enable
) )
452 Widget wMain
= (Widget
)GetMainWidget();
455 XtSetSensitive(wMain
, enable
);
456 XmUpdateDisplay(wMain
);
463 bool wxWindowX11::Show(bool show
)
465 if ( !wxWindowBase::Show(show
) )
468 Window xwin
= (Window
) GetXWindow();
469 Display
*xdisp
= (Display
*) GetXDisplay();
471 XMapWindow(xdisp
, xwin
);
473 XUnmapWindow(xdisp
, xwin
);
478 // Raise the window to the top of the Z order
479 void wxWindowX11::Raise()
481 Window window
= (Window
) GetTopWindow();
483 XRaiseWindow((Display
*) wxGetDisplay(), window
);
486 // Lower the window to the bottom of the Z order
487 void wxWindowX11::Lower()
489 Window window
= (Window
) GetTopWindow();
491 XLowerWindow((Display
*) wxGetDisplay(), window
);
494 void wxWindowX11::SetTitle(const wxString
& title
)
497 // XtVaSetValues((Widget)GetMainWidget(), XmNtitle, title.c_str(), NULL);
500 wxString
wxWindowX11::GetTitle() const
503 return wxEmptyString
;
506 XtVaGetValues((Widget
)GetMainWidget(), XmNtitle
, &title
, NULL
);
508 return wxString(title
);
512 void wxWindowX11::DoCaptureMouse()
514 g_captureWindow
= (wxWindow
*) this;
520 Widget wMain
= (Widget
)GetMainWidget();
522 XtAddGrab(wMain
, TRUE
, FALSE
);
525 m_winCaptured
= TRUE
;
528 void wxWindowX11::DoReleaseMouse()
530 g_captureWindow
= NULL
;
531 if ( !m_winCaptured
)
536 Widget wMain
= (Widget
)GetMainWidget();
541 m_winCaptured
= FALSE
;
544 bool wxWindowX11::SetFont(const wxFont
& font
)
546 if ( !wxWindowBase::SetFont(font
) )
557 bool wxWindowX11::SetCursor(const wxCursor
& cursor
)
559 if ( !wxWindowBase::SetCursor(cursor
) )
565 wxCursor
* cursor2
= NULL
;
567 cursor2
= & m_cursor
;
569 cursor2
= wxSTANDARD_CURSOR
;
571 WXDisplay
*dpy
= GetXDisplay();
572 WXCursor x_cursor
= cursor2
->GetXCursor(dpy
);
574 Window win
= (Window
) GetMainWindow();
575 XDefineCursor((Display
*) dpy
, win
, (Cursor
) x_cursor
);
580 // Coordinates relative to the window
581 void wxWindowX11::WarpPointer (int x
, int y
)
583 Window wClient
= (Window
) GetClientWindow();
585 XWarpPointer((Display
*) wxGetDisplay(), None
, wClient
, 0, 0, 0, 0, x
, y
);
588 // ---------------------------------------------------------------------------
590 // ---------------------------------------------------------------------------
592 int wxWindowX11::GetScrollPos(int orient
) const
594 if (orient
== wxHORIZONTAL
)
600 // This now returns the whole range, not just the number of positions that we
602 int wxWindowX11::GetScrollRange(int WXUNUSED(orient
)) const
607 Widget scrollBar
= (Widget
)GetScrollbar((wxOrientation
)orient
);
608 wxCHECK_MSG( scrollBar
, 0, "no such scrollbar" );
611 XtVaGetValues(scrollBar
, XmNmaximum
, &range
, NULL
);
616 int wxWindowX11::GetScrollThumb(int orient
) const
622 Widget scrollBar
= (Widget
)GetScrollbar((wxOrientation
)orient
);
623 wxCHECK_MSG( scrollBar
, 0, "no such scrollbar" );
626 XtVaGetValues(scrollBar
, XmNsliderSize
, &thumb
, NULL
);
631 void wxWindowX11::SetScrollPos(int orient
, int pos
, bool WXUNUSED(refresh
))
636 Widget scrollBar
= (Widget
)GetScrollbar((wxOrientation
)orient
);
640 XtVaSetValues (scrollBar
, XmNvalue
, pos
, NULL
);
643 SetInternalScrollPos((wxOrientation
)orient
, pos
);
646 // New function that will replace some of the above.
647 void wxWindowX11::SetScrollbar(int WXUNUSED(orient
), int WXUNUSED(pos
), int WXUNUSED(thumbVisible
),
648 int WXUNUSED(range
), bool WXUNUSED(refresh
))
653 GetSize(& oldW
, & oldH
);
657 if (thumbVisible
== 0)
660 if (thumbVisible
> range
)
661 thumbVisible
= range
;
663 // Save the old state to see if it changed
664 WXWidget oldScrollBar
= GetScrollbar((wxOrientation
)orient
);
666 if (orient
== wxHORIZONTAL
)
668 if (thumbVisible
== range
)
671 DestroyScrollbar(wxHORIZONTAL
);
676 CreateScrollbar(wxHORIZONTAL
);
679 if (orient
== wxVERTICAL
)
681 if (thumbVisible
== range
)
684 DestroyScrollbar(wxVERTICAL
);
689 CreateScrollbar(wxVERTICAL
);
692 WXWidget newScrollBar
= GetScrollbar((wxOrientation
)orient
);
694 if (oldScrollBar
!= newScrollBar
)
696 // This is important! Without it, scrollbars misbehave badly.
697 XtUnrealizeWidget((Widget
) m_scrolledWindow
);
698 XmScrolledWindowSetAreas ((Widget
) m_scrolledWindow
, (Widget
) m_hScrollBar
, (Widget
) m_vScrollBar
, (Widget
) m_drawingArea
);
699 XtRealizeWidget((Widget
) m_scrolledWindow
);
700 XtManageChild((Widget
) m_scrolledWindow
);
705 XtVaSetValues((Widget
) newScrollBar
,
709 XmNsliderSize
, thumbVisible
,
713 SetInternalScrollPos((wxOrientation
)orient
, pos
);
716 GetSize(& newW
, & newH
);
718 // Adjusting scrollbars can resize the canvas accidentally
719 if (newW
!= oldW
|| newH
!= oldH
)
720 SetSize(-1, -1, oldW
, oldH
);
724 // Does a physical scroll
725 void wxWindowX11::ScrollWindow(int dx
, int dy
, const wxRect
*rect
)
730 // Use specified rectangle
731 x
= rect
->x
; y
= rect
->y
; w
= rect
->width
; h
= rect
->height
;
735 // Use whole client area
737 GetClientSize(& w
, & h
);
740 wxNode
*cnode
= m_children
.First();
743 wxWindow
*child
= (wxWindow
*) cnode
->Data();
746 child
->GetSize( &sx
, &sy
);
747 wxPoint
pos( child
->GetPosition() );
748 child
->SetSize( pos
.x
+ dx
, pos
.y
+ dy
, sx
, sy
, wxSIZE_ALLOW_MINUS_ONE
);
749 cnode
= cnode
->Next();
752 int x1
= (dx
>= 0) ? x
: x
- dx
;
753 int y1
= (dy
>= 0) ? y
: y
- dy
;
754 int w1
= w
- abs(dx
);
755 int h1
= h
- abs(dy
);
756 int x2
= (dx
>= 0) ? x
+ dx
: x
;
757 int y2
= (dy
>= 0) ? y
+ dy
: y
;
759 wxClientDC
dc((wxWindow
*) this);
761 dc
.SetLogicalFunction (wxCOPY
);
763 Window window
= (Window
) GetMainWindow();
764 Display
* display
= (Display
*) wxGetDisplay();
766 XCopyArea(display
, window
, window
, (GC
) dc
.GetGC(),
767 x1
, y1
, w1
, h1
, x2
, y2
);
769 dc
.SetAutoSetting(TRUE
);
770 wxBrush
brush(GetBackgroundColour(), wxSOLID
);
771 dc
.SetBrush(brush
); // FIXME: needed?
773 // We'll add rectangles to the list of update rectangles according to which
774 // bits we've exposed.
779 wxRect
*rect
= new wxRect
;
785 XFillRectangle(display
, window
,
786 (GC
) dc
.GetGC(), rect
->x
, rect
->y
, rect
->width
, rect
->height
);
790 rect
->width
= rect
->width
;
791 rect
->height
= rect
->height
;
793 updateRects
.Append((wxObject
*) rect
);
797 wxRect
*rect
= new wxRect
;
799 rect
->x
= x
+ w
+ dx
;
804 XFillRectangle(display
, window
,
805 (GC
) dc
.GetGC(), rect
->x
, rect
->y
, rect
->width
,
810 rect
->width
= rect
->width
;
811 rect
->height
= rect
->height
;
813 updateRects
.Append((wxObject
*) rect
);
817 wxRect
*rect
= new wxRect
;
824 XFillRectangle(display
, window
,
825 (GC
) dc
.GetGC(), rect
->x
, rect
->y
, rect
->width
, rect
->height
);
829 rect
->width
= rect
->width
;
830 rect
->height
= rect
->height
;
832 updateRects
.Append((wxObject
*) rect
);
836 wxRect
*rect
= new wxRect
;
839 rect
->y
= y
+ h
+ dy
;
843 XFillRectangle(display
, window
,
844 (GC
) dc
.GetGC(), rect
->x
, rect
->y
, rect
->width
, rect
->height
);
848 rect
->width
= rect
->width
;
849 rect
->height
= rect
->height
;
851 updateRects
.Append((wxObject
*) rect
);
853 dc
.SetBrush(wxNullBrush
);
855 // Now send expose events
857 wxNode
* node
= updateRects
.First();
860 wxRect
* rect
= (wxRect
*) node
->Data();
864 event
.display
= display
;
865 event
.send_event
= True
;
866 event
.window
= window
;
870 event
.width
= rect
->width
;
871 event
.height
= rect
->height
;
875 XSendEvent(display
, window
, False
, ExposureMask
, (XEvent
*)&event
);
881 // Delete the update rects
882 node
= updateRects
.First();
885 wxRect
* rect
= (wxRect
*) node
->Data();
892 // XmUpdateDisplay((Widget) GetMainWidget());
895 // ---------------------------------------------------------------------------
897 // ---------------------------------------------------------------------------
899 #if wxUSE_DRAG_AND_DROP
901 void wxWindowX11::SetDropTarget(wxDropTarget
* WXUNUSED(pDropTarget
))
908 // Old style file-manager drag&drop
909 void wxWindowX11::DragAcceptFiles(bool WXUNUSED(accept
))
914 // ----------------------------------------------------------------------------
916 // ----------------------------------------------------------------------------
920 void wxWindowX11::DoSetToolTip(wxToolTip
* WXUNUSED(tooltip
))
925 #endif // wxUSE_TOOLTIPS
927 // ---------------------------------------------------------------------------
928 // moving and resizing
929 // ---------------------------------------------------------------------------
931 bool wxWindowX11::PreResize()
937 void wxWindowX11::DoGetSize(int *x
, int *y
) const
947 Widget widget
= (Widget
) GetTopWidget();
949 XtVaGetValues(widget
, XmNwidth
, &xx
, XmNheight
, &yy
, NULL
);
950 if(x
) *x
= xx
; if(y
) *y
= yy
;
954 void wxWindowX11::DoGetPosition(int *x
, int *y
) const
960 CanvasGetPosition(x
, y
);
963 Widget widget
= (Widget
) GetTopWidget();
965 XtVaGetValues(widget
, XmNx
, &xx
, XmNy
, &yy
, NULL
);
967 // We may be faking the client origin. So a window that's really at (0, 30)
968 // may appear (to wxWin apps) to be at (0, 0).
971 wxPoint
pt(GetParent()->GetClientAreaOrigin());
976 if(x
) *x
= xx
; if(y
) *y
= yy
;
980 void wxWindowX11::DoScreenToClient(int *x
, int *y
) const
982 Display
*display
= (Display
*) wxGetDisplay();
983 Window rootWindow
= RootWindowOfScreen(DefaultScreenOfDisplay(display
));
984 Window thisWindow
= (Window
) GetClientWindow();
989 XTranslateCoordinates(display
, rootWindow
, thisWindow
, xx
, yy
, x
, y
, &childWindow
);
992 void wxWindowX11::DoClientToScreen(int *x
, int *y
) const
994 Display
*display
= (Display
*) wxGetDisplay();
995 Window rootWindow
= RootWindowOfScreen(DefaultScreenOfDisplay(display
));
996 Window thisWindow
= (Window
) GetClientWindow();
1001 XTranslateCoordinates(display
, thisWindow
, rootWindow
, xx
, yy
, x
, y
, &childWindow
);
1005 // Get size *available for subwindows* i.e. excluding menu bar etc.
1006 void wxWindowX11::DoGetClientSize(int *x
, int *y
) const
1010 Widget widget
= (Widget
) GetClientWidget();
1012 XtVaGetValues(widget
, XmNwidth
, &xx
, XmNheight
, &yy
, NULL
);
1013 if(x
) *x
= xx
; if(y
) *y
= yy
;
1017 void wxWindowX11::DoSetSize(int x
, int y
, int width
, int height
, int sizeFlags
)
1021 // A bit of optimization to help sort out the flickers.
1022 int oldX
, oldY
, oldW
, oldH
;
1023 GetSize(& oldW
, & oldH
);
1024 GetPosition(& oldX
, & oldY
);
1026 if ( !(sizeFlags
& wxSIZE_ALLOW_MINUS_ONE
) )
1039 bool nothingChanged
= (x
== oldX
) && (y
== oldY
) &&
1040 (width
== oldW
) && (height
== oldH
);
1042 if (!wxNoOptimize::CanOptimize())
1044 nothingChanged
= FALSE
;
1047 if ( !nothingChanged
)
1051 CanvasSetSize(x
, y
, width
, height
, sizeFlags
);
1055 Widget widget
= (Widget
) GetTopWidget();
1059 bool managed
= XtIsManaged( widget
);
1061 XtUnmanageChild(widget
);
1065 AdjustForParentClientOrigin(xx
, yy
, sizeFlags
);
1067 DoMoveWindow(xx
, yy
, width
, height
);
1070 XtManageChild(widget
);
1076 void wxWindowX11::DoSetClientSize(int width
, int height
)
1082 CanvasSetClientSize(width
, height
);
1086 Widget widget
= (Widget
) GetTopWidget();
1089 XtVaSetValues(widget
, XmNwidth
, width
, NULL
);
1091 XtVaSetValues(widget
, XmNheight
, height
, NULL
);
1093 wxSizeEvent
sizeEvent(wxSize(width
, height
), GetId());
1094 sizeEvent
.SetEventObject(this);
1096 GetEventHandler()->ProcessEvent(sizeEvent
);
1100 // For implementation purposes - sometimes decorations make the client area
1102 wxPoint
wxWindowX11::GetClientAreaOrigin() const
1104 return wxPoint(0, 0);
1107 // Makes an adjustment to the window position (for example, a frame that has
1108 // a toolbar that it manages itself).
1109 void wxWindowX11::AdjustForParentClientOrigin(int& x
, int& y
, int sizeFlags
)
1111 if (((sizeFlags
& wxSIZE_NO_ADJUSTMENTS
) == 0) && GetParent())
1113 wxPoint
pt(GetParent()->GetClientAreaOrigin());
1114 x
+= pt
.x
; y
+= pt
.y
;
1118 void wxWindowX11::SetSizeHints(int minW
, int minH
, int maxW
, int maxH
, int incW
, int incH
)
1127 wxFrame
*frame
= wxDynamicCast(this, wxFrame
);
1130 // TODO what about dialogs?
1134 Widget widget
= (Widget
) frame
->GetShellWidget();
1137 XtVaSetValues(widget
, XmNminWidth
, minW
, NULL
);
1139 XtVaSetValues(widget
, XmNminHeight
, minH
, NULL
);
1141 XtVaSetValues(widget
, XmNmaxWidth
, maxW
, NULL
);
1143 XtVaSetValues(widget
, XmNmaxHeight
, maxH
, NULL
);
1145 XtVaSetValues(widget
, XmNwidthInc
, incW
, NULL
);
1147 XtVaSetValues(widget
, XmNheightInc
, incH
, NULL
);
1151 void wxWindowX11::DoMoveWindow(int x
, int y
, int width
, int height
)
1155 XtVaSetValues((Widget
)GetTopWidget(),
1164 // ---------------------------------------------------------------------------
1166 // ---------------------------------------------------------------------------
1168 int wxWindowX11::GetCharHeight() const
1170 wxCHECK_MSG( m_font
.Ok(), 0, "valid window font needed" );
1172 WXFontStructPtr pFontStruct
= m_font
.GetFontStruct(1.0, GetXDisplay());
1174 int direction
, ascent
, descent
;
1175 XCharStruct overall
;
1176 XTextExtents ((XFontStruct
*) pFontStruct
, "x", 1, &direction
, &ascent
,
1177 &descent
, &overall
);
1179 // return (overall.ascent + overall.descent);
1180 return (ascent
+ descent
);
1183 int wxWindowX11::GetCharWidth() const
1185 wxCHECK_MSG( m_font
.Ok(), 0, "valid window font needed" );
1187 WXFontStructPtr pFontStruct
= m_font
.GetFontStruct(1.0, GetXDisplay());
1189 int direction
, ascent
, descent
;
1190 XCharStruct overall
;
1191 XTextExtents ((XFontStruct
*) pFontStruct
, "x", 1, &direction
, &ascent
,
1192 &descent
, &overall
);
1194 return overall
.width
;
1197 void wxWindowX11::GetTextExtent(const wxString
& string
,
1199 int *descent
, int *externalLeading
,
1200 const wxFont
*theFont
) const
1202 wxFont
*fontToUse
= (wxFont
*)theFont
;
1204 fontToUse
= (wxFont
*) & m_font
;
1206 wxCHECK_RET( fontToUse
->Ok(), "valid window font needed" );
1208 WXFontStructPtr pFontStruct
= theFont
->GetFontStruct(1.0, GetXDisplay());
1210 int direction
, ascent
, descent2
;
1211 XCharStruct overall
;
1212 int slen
= string
.Len();
1216 XTextExtents16((XFontStruct
*) pFontStruct
, (XChar2b
*) (char*) (const char*) string
, slen
, &direction
,
1217 &ascent
, &descent2
, &overall
);
1220 XTextExtents((XFontStruct
*) pFontStruct
, string
, slen
,
1221 &direction
, &ascent
, &descent2
, &overall
);
1224 *x
= (overall
.width
);
1226 *y
= (ascent
+ descent2
);
1228 *descent
= descent2
;
1229 if (externalLeading
)
1230 *externalLeading
= 0;
1234 // ----------------------------------------------------------------------------
1236 // ----------------------------------------------------------------------------
1238 void wxWindowX11::Refresh(bool eraseBack
, const wxRect
*rect
)
1240 m_needsRefresh
= TRUE
;
1241 Display
*display
= (Display
*) wxGetDisplay();
1242 Window thisWindow
= (Window
) GetMainWindow();
1244 XExposeEvent dummyEvent
;
1246 GetSize(&width
, &height
);
1248 dummyEvent
.type
= Expose
;
1249 dummyEvent
.display
= display
;
1250 dummyEvent
.send_event
= True
;
1251 dummyEvent
.window
= thisWindow
;
1254 dummyEvent
.x
= rect
->x
;
1255 dummyEvent
.y
= rect
->y
;
1256 dummyEvent
.width
= rect
->width
;
1257 dummyEvent
.height
= rect
->height
;
1263 dummyEvent
.width
= width
;
1264 dummyEvent
.height
= height
;
1266 dummyEvent
.count
= 0;
1270 wxClientDC
dc((wxWindow
*) this);
1271 wxBrush
backgroundBrush(GetBackgroundColour(), wxSOLID
);
1272 dc
.SetBackground(backgroundBrush
);
1279 XSendEvent(display
, thisWindow
, False
, ExposureMask
, (XEvent
*)&dummyEvent
);
1282 void wxWindowX11::Clear()
1284 wxClientDC
dc((wxWindow
*) this);
1285 wxBrush
brush(GetBackgroundColour(), wxSOLID
);
1286 dc
.SetBackground(brush
);
1290 void wxWindowX11::ClearUpdateRects()
1292 wxRectList::Node
* node
= m_updateRects
.GetFirst();
1295 wxRect
* rect
= node
->GetData();
1297 node
= node
->GetNext();
1300 m_updateRects
.Clear();
1303 void wxWindowX11::DoPaint()
1305 // Set an erase event first
1306 wxEraseEvent
eraseEvent(GetId());
1307 eraseEvent
.SetEventObject(this);
1308 GetEventHandler()->ProcessEvent(eraseEvent
);
1310 wxPaintEvent
event(GetId());
1311 event
.SetEventObject(this);
1312 GetEventHandler()->ProcessEvent(event
);
1314 m_needsRefresh
= FALSE
;
1317 // ----------------------------------------------------------------------------
1319 // ----------------------------------------------------------------------------
1321 // Responds to colour changes: passes event on to children.
1322 void wxWindowX11::OnSysColourChanged(wxSysColourChangedEvent
& event
)
1324 wxWindowList::Node
*node
= GetChildren().GetFirst();
1327 // Only propagate to non-top-level windows
1328 wxWindow
*win
= node
->GetData();
1329 if ( win
->GetParent() )
1331 wxSysColourChangedEvent event2
;
1332 event
.m_eventObject
= win
;
1333 win
->GetEventHandler()->ProcessEvent(event2
);
1336 node
= node
->GetNext();
1340 void wxWindowX11::OnIdle(wxIdleEvent
& WXUNUSED(event
))
1342 // This calls the UI-update mechanism (querying windows for
1343 // menu/toolbar/control state information)
1347 // ----------------------------------------------------------------------------
1349 // ----------------------------------------------------------------------------
1351 bool wxWindowX11::ProcessAccelerator(wxKeyEvent
& event
)
1353 if (!m_acceleratorTable
.Ok())
1356 const wxAcceleratorEntry
* entry
= m_acceleratorTable
.GetEntry(event
);
1359 // Bingo, we have a match. Now find a control that matches the
1360 // entry command id.
1362 // Need to go up to the top of the window hierarchy, since it might
1363 // be e.g. a menu item
1364 wxWindow
* parent
= (wxWindow
*) this;
1365 while ( parent
&& !parent
->IsTopLevel() )
1366 parent
= parent
->GetParent();
1371 wxFrame
* frame
= wxDynamicCast(parent
, wxFrame
);
1374 // Try for a menu command
1375 if (frame
->GetMenuBar())
1377 wxMenuItem
* item
= frame
->GetMenuBar()->FindItem(entry
->GetCommand());
1380 wxCommandEvent
commandEvent(wxEVT_COMMAND_MENU_SELECTED
, entry
->GetCommand());
1381 commandEvent
.SetEventObject(frame
);
1383 // If ProcessEvent returns TRUE (it was handled), then
1384 // the calling code will skip the event handling.
1385 return frame
->GetEventHandler()->ProcessEvent(commandEvent
);
1390 // Find a child matching the command id
1391 wxWindow
* child
= parent
->FindWindow(entry
->GetCommand());
1397 // Now we process those kinds of windows that we can.
1398 // For now, only buttons.
1399 if ( wxDynamicCast(child
, wxButton
) )
1401 wxCommandEvent
commandEvent (wxEVT_COMMAND_BUTTON_CLICKED
, child
->GetId());
1402 commandEvent
.SetEventObject(child
);
1403 return child
->GetEventHandler()->ProcessEvent(commandEvent
);
1410 // We didn't match the key event against an accelerator.
1414 // ============================================================================
1415 // X11-specific stuff from here on
1416 // ============================================================================
1418 // ----------------------------------------------------------------------------
1419 // function which maintain the global hash table mapping Widgets to wxWindows
1420 // ----------------------------------------------------------------------------
1422 bool wxAddWindowToTable(Window w
, wxWindow
*win
)
1424 wxWindow
*oldItem
= NULL
;
1425 if ((oldItem
= (wxWindow
*)wxWidgetHashTable
->Get ((long) w
)))
1427 wxLogDebug("Widget table clash: new widget is %ld, %s",
1428 (long)w
, win
->GetClassInfo()->GetClassName());
1432 wxWidgetHashTable
->Put((long) w
, win
);
1434 wxLogTrace("widget", "XWindow 0x%08x <-> window %p (%s)",
1435 w
, win
, win
->GetClassInfo()->GetClassName());
1440 wxWindow
*wxGetWindowFromTable(Window w
)
1442 return (wxWindow
*)wxWidgetHashTable
->Get((long) w
);
1445 void wxDeleteWindowFromTable(Window w
)
1447 wxWidgetHashTable
->Delete((long)w
);
1450 // ----------------------------------------------------------------------------
1451 // add/remove window from the table
1452 // ----------------------------------------------------------------------------
1454 // Add to hash table, add event handler
1455 bool wxWindowX11::AttachWindow (wxWindow
* WXUNUSED(parent
), WXWindow mainWidget
,
1456 int x
, int y
, int width
, int height
)
1458 wxAddWindowToTable((Window
) mainWidget
, (wxWindow
*) this);
1462 if (CanAddEventHandler())
1464 XtAddEventHandler((Widget
) mainWidget
,
1465 ButtonPressMask
| ButtonReleaseMask
| PointerMotionMask
, // | KeyPressMask,
1467 wxPanelItemEventHandler
,
1474 XtOverrideTranslations ((Widget
) mainWidget
,
1475 ptr
= XtParseTranslationTable ("<Configure>: resize()"));
1476 XtFree ((char *) ptr
);
1479 // Some widgets have a parent form widget, e.g. wxRadioBox
1482 if (!wxAddWindowToTable((Widget
) formWidget
, this))
1486 XtOverrideTranslations ((Widget
) formWidget
,
1487 ptr
= XtParseTranslationTable ("<Configure>: resize()"));
1488 XtFree ((char *) ptr
);
1496 SetSize (x
, y
, width
, height
);
1501 // Remove event handler, remove from hash table
1502 bool wxWindowX11::DetachWindow(WXWindow widget
)
1506 if (CanAddEventHandler())
1508 XtRemoveEventHandler((Widget
) widget
,
1509 ButtonPressMask
| ButtonReleaseMask
| PointerMotionMask
, // | KeyPressMask,
1511 wxPanelItemEventHandler
,
1516 wxDeleteWindowFromTable((Window
) widget
);
1520 // ----------------------------------------------------------------------------
1521 // X11-specific accessors
1522 // ----------------------------------------------------------------------------
1524 // Get the underlying X window
1525 WXWindow
wxWindowX11::GetXWindow() const
1527 return GetMainWindow();
1530 // Get the underlying X display
1531 WXDisplay
*wxWindowX11::GetXDisplay() const
1533 return wxGetDisplay();
1536 WXWindow
wxWindowX11::GetMainWindow() const
1539 return m_drawingArea
;
1541 return m_mainWidget
;
1544 WXWindow
wxWindowX11::GetClientWindow() const
1546 if (m_drawingArea
!= (WXWindow
) 0)
1547 return m_drawingArea
;
1549 return GetMainWindow();
1552 WXWindow
wxWindowX11::GetTopWindow() const
1554 return GetMainWindow();
1557 WXWindow
wxWindowX11::GetLabelWindow() const
1559 return GetMainWindow();
1562 // ----------------------------------------------------------------------------
1564 // ----------------------------------------------------------------------------
1566 // TODO: implement wxWindow scrollbar, presumably using wxScrollBar
1568 static void wxScrollBarCallback(Widget scrollbar
,
1569 XtPointer clientData
,
1570 XmScrollBarCallbackStruct
*cbs
)
1572 wxWindow
*win
= wxGetWindowFromTable(scrollbar
);
1573 int orientation
= (int) clientData
;
1575 wxEventType eventType
= wxEVT_NULL
;
1576 switch (cbs
->reason
)
1578 case XmCR_INCREMENT
:
1580 eventType
= wxEVT_SCROLLWIN_LINEDOWN
;
1583 case XmCR_DECREMENT
:
1585 eventType
= wxEVT_SCROLLWIN_LINEUP
;
1590 eventType
= wxEVT_SCROLLWIN_THUMBTRACK
;
1593 case XmCR_VALUE_CHANGED
:
1595 eventType
= wxEVT_SCROLLWIN_THUMBRELEASE
;
1598 case XmCR_PAGE_INCREMENT
:
1600 eventType
= wxEVT_SCROLLWIN_PAGEDOWN
;
1603 case XmCR_PAGE_DECREMENT
:
1605 eventType
= wxEVT_SCROLLWIN_PAGEUP
;
1610 eventType
= wxEVT_SCROLLWIN_TOP
;
1613 case XmCR_TO_BOTTOM
:
1615 eventType
= wxEVT_SCROLLWIN_BOTTOM
;
1620 // Should never get here
1621 wxFAIL_MSG("Unknown scroll event.");
1626 wxScrollWinEvent
event(eventType
,
1628 ((orientation
== XmHORIZONTAL
) ?
1629 wxHORIZONTAL
: wxVERTICAL
));
1630 event
.SetEventObject( win
);
1631 win
->GetEventHandler()->ProcessEvent(event
);
1636 // ----------------------------------------------------------------------------
1637 // CanvaseXXXSize() functions
1638 // ----------------------------------------------------------------------------
1640 // SetSize, but as per old wxCanvas (with drawing widget etc.)
1641 void wxWindowX11::CanvasSetSize (int x
, int y
, int w
, int h
, int sizeFlags
)
1645 // A bit of optimization to help sort out the flickers.
1646 int oldX
, oldY
, oldW
, oldH
;
1647 GetSize(& oldW
, & oldH
);
1648 GetPosition(& oldX
, & oldY
);
1650 bool useOldPos
= FALSE
;
1651 bool useOldSize
= FALSE
;
1653 if ((x
== -1) && (x
== -1) && ((sizeFlags
& wxSIZE_ALLOW_MINUS_ONE
) == 0))
1655 else if (x
== oldX
&& y
== oldY
)
1658 if ((w
== -1) && (h
== -1))
1660 else if (w
== oldW
&& h
== oldH
)
1663 if (!wxNoOptimize::CanOptimize())
1665 useOldSize
= FALSE
; useOldPos
= FALSE
;
1668 if (useOldPos
&& useOldSize
)
1671 Widget drawingArea
= (Widget
) m_drawingArea
;
1672 bool managed
= XtIsManaged(m_borderWidget
? (Widget
) m_borderWidget
: (Widget
) m_scrolledWindow
);
1675 XtUnmanageChild (m_borderWidget
? (Widget
) m_borderWidget
: (Widget
) m_scrolledWindow
);
1676 XtVaSetValues(drawingArea
, XmNresizePolicy
, XmRESIZE_ANY
, NULL
);
1678 int xx
= x
; int yy
= y
;
1679 AdjustForParentClientOrigin(xx
, yy
, sizeFlags
);
1683 if (x
> -1 || (sizeFlags
& wxSIZE_ALLOW_MINUS_ONE
))
1685 XtVaSetValues (m_borderWidget
? (Widget
) m_borderWidget
: (Widget
) m_scrolledWindow
,
1689 if (y
> -1 || (sizeFlags
& wxSIZE_ALLOW_MINUS_ONE
))
1691 XtVaSetValues (m_borderWidget
? (Widget
) m_borderWidget
: (Widget
) m_scrolledWindow
,
1703 XtVaSetValues ((Widget
) m_borderWidget
, XmNwidth
, w
, NULL
);
1704 short thick
, margin
;
1705 XtVaGetValues ((Widget
) m_borderWidget
,
1706 XmNshadowThickness
, &thick
,
1707 XmNmarginWidth
, &margin
,
1709 w
-= 2 * (thick
+ margin
);
1712 XtVaSetValues ((Widget
) m_scrolledWindow
, XmNwidth
, w
, NULL
);
1716 XtVaGetValues ((Widget
) m_scrolledWindow
,
1717 XmNspacing
, &spacing
,
1718 XmNverticalScrollBar
, &sbar
,
1722 XtVaGetValues (sbar
, XmNwidth
, &wsbar
, NULL
);
1726 w
-= (spacing
+ wsbar
);
1729 XtVaSetValues(drawingArea
, XmNwidth
, w
, NULL
);
1736 XtVaSetValues ((Widget
) m_borderWidget
, XmNheight
, h
, NULL
);
1737 short thick
, margin
;
1738 XtVaGetValues ((Widget
) m_borderWidget
,
1739 XmNshadowThickness
, &thick
,
1740 XmNmarginHeight
, &margin
,
1742 h
-= 2 * (thick
+ margin
);
1745 XtVaSetValues ((Widget
) m_scrolledWindow
, XmNheight
, h
, NULL
);
1749 XtVaGetValues ((Widget
) m_scrolledWindow
,
1750 XmNspacing
, &spacing
,
1751 XmNhorizontalScrollBar
, &sbar
,
1755 XtVaGetValues (sbar
, XmNheight
, &wsbar
, NULL
);
1759 h
-= (spacing
+ wsbar
);
1762 XtVaSetValues(drawingArea
, XmNheight
, h
, NULL
);
1768 XtManageChild (m_borderWidget
? (Widget
) m_borderWidget
: (Widget
) m_scrolledWindow
);
1769 XtVaSetValues(drawingArea
, XmNresizePolicy
, XmRESIZE_NONE
, NULL
);
1774 void wxWindowX11::CanvasSetClientSize (int w
, int h
)
1778 Widget drawingArea
= (Widget
) m_drawingArea
;
1780 XtVaSetValues(drawingArea
, XmNresizePolicy
, XmRESIZE_ANY
, NULL
);
1783 XtVaSetValues(drawingArea
, XmNwidth
, w
, NULL
);
1785 XtVaSetValues(drawingArea
, XmNheight
, h
, NULL
);
1787 XtVaSetValues(drawingArea
, XmNresizePolicy
, XmRESIZE_NONE
, NULL
);
1791 void wxWindowX11::CanvasGetClientSize (int *w
, int *h
) const
1795 // Must return the same thing that was set via SetClientSize
1797 XtVaGetValues ((Widget
) m_drawingArea
, XmNwidth
, &xx
, XmNheight
, &yy
, NULL
);
1803 void wxWindowX11::CanvasGetSize (int *w
, int *h
) const
1808 if ((Widget
) m_borderWidget
)
1809 XtVaGetValues ((Widget
) m_borderWidget
, XmNwidth
, &xx
, XmNheight
, &yy
, NULL
);
1810 else if ((Widget
) m_scrolledWindow
)
1811 XtVaGetValues ((Widget
) m_scrolledWindow
, XmNwidth
, &xx
, XmNheight
, &yy
, NULL
);
1813 XtVaGetValues ((Widget
) m_drawingArea
, XmNwidth
, &xx
, XmNheight
, &yy
, NULL
);
1820 void wxWindowX11::CanvasGetPosition (int *x
, int *y
) const
1825 XtVaGetValues (m_borderWidget
? (Widget
) m_borderWidget
: (Widget
) m_scrolledWindow
, XmNx
, &xx
, XmNy
, &yy
, NULL
);
1827 // We may be faking the client origin.
1828 // So a window that's really at (0, 30) may appear
1829 // (to wxWin apps) to be at (0, 0).
1832 wxPoint
pt(GetParent()->GetClientAreaOrigin());
1842 // ----------------------------------------------------------------------------
1843 // TranslateXXXEvent() functions
1844 // ----------------------------------------------------------------------------
1846 bool wxTranslateMouseEvent(wxMouseEvent
& wxevent
, wxWindow
*win
, Window window
, XEvent
*xevent
)
1848 switch (xevent
->xany
.type
)
1856 wxEventType eventType
= wxEVT_NULL
;
1858 if (xevent
->xany
.type
== EnterNotify
)
1860 //if (local_event.xcrossing.mode!=NotifyNormal)
1861 // return ; // Ignore grab events
1862 eventType
= wxEVT_ENTER_WINDOW
;
1863 // canvas->GetEventHandler()->OnSetFocus();
1865 else if (xevent
->xany
.type
== LeaveNotify
)
1867 //if (local_event.xcrossingr.mode!=NotifyNormal)
1868 // return ; // Ignore grab events
1869 eventType
= wxEVT_LEAVE_WINDOW
;
1870 // canvas->GetEventHandler()->OnKillFocus();
1872 else if (xevent
->xany
.type
== MotionNotify
)
1874 eventType
= wxEVT_MOTION
;
1876 else if (xevent
->xany
.type
== ButtonPress
)
1878 wxevent
.SetTimestamp(xevent
->xbutton
.time
);
1880 if (xevent
->xbutton
.button
== Button1
)
1882 eventType
= wxEVT_LEFT_DOWN
;
1883 win
->SetButton1(TRUE
);
1886 else if (xevent
->xbutton
.button
== Button2
)
1888 eventType
= wxEVT_MIDDLE_DOWN
;
1889 win
->SetButton2(TRUE
);
1892 else if (xevent
->xbutton
.button
== Button3
)
1894 eventType
= wxEVT_RIGHT_DOWN
;
1895 win
->SetButton3(TRUE
);
1899 // check for a double click
1900 // TODO: where can we get this value from?
1901 //long dclickTime = XtGetMultiClickTime((Display*) wxGetDisplay());
1902 long dclickTime
= 200;
1903 long ts
= wxevent
.GetTimestamp();
1905 int buttonLast
= win
->GetLastClickedButton();
1906 long lastTS
= win
->GetLastClickTime();
1907 if ( buttonLast
&& buttonLast
== button
&& (ts
- lastTS
) < dclickTime
)
1910 win
->SetLastClick(0, ts
);
1911 if ( eventType
== wxEVT_LEFT_DOWN
)
1912 eventType
= wxEVT_LEFT_DCLICK
;
1913 else if ( eventType
== wxEVT_MIDDLE_DOWN
)
1914 eventType
= wxEVT_MIDDLE_DCLICK
;
1915 else if ( eventType
== wxEVT_RIGHT_DOWN
)
1916 eventType
= wxEVT_RIGHT_DCLICK
;
1920 // not fast enough or different button
1921 win
->SetLastClick(button
, ts
);
1924 else if (xevent
->xany
.type
== ButtonRelease
)
1926 if (xevent
->xbutton
.button
== Button1
)
1928 eventType
= wxEVT_LEFT_UP
;
1929 win
->SetButton1(FALSE
);
1931 else if (xevent
->xbutton
.button
== Button2
)
1933 eventType
= wxEVT_MIDDLE_UP
;
1934 win
->SetButton2(FALSE
);
1936 else if (xevent
->xbutton
.button
== Button3
)
1938 eventType
= wxEVT_RIGHT_UP
;
1939 win
->SetButton3(FALSE
);
1948 wxevent
.SetEventType(eventType
);
1950 wxevent
.m_x
= xevent
->xbutton
.x
;
1951 wxevent
.m_y
= xevent
->xbutton
.y
;
1953 wxevent
.m_leftDown
= ((eventType
== wxEVT_LEFT_DOWN
)
1954 || (event_left_is_down (xevent
)
1955 && (eventType
!= wxEVT_LEFT_UP
)));
1956 wxevent
.m_middleDown
= ((eventType
== wxEVT_MIDDLE_DOWN
)
1957 || (event_middle_is_down (xevent
)
1958 && (eventType
!= wxEVT_MIDDLE_UP
)));
1959 wxevent
.m_rightDown
= ((eventType
== wxEVT_RIGHT_DOWN
)
1960 || (event_right_is_down (xevent
)
1961 && (eventType
!= wxEVT_RIGHT_UP
)));
1963 wxevent
.m_shiftDown
= xevent
->xbutton
.state
& ShiftMask
;
1964 wxevent
.m_controlDown
= xevent
->xbutton
.state
& ControlMask
;
1965 wxevent
.m_altDown
= xevent
->xbutton
.state
& Mod3Mask
;
1966 wxevent
.m_metaDown
= xevent
->xbutton
.state
& Mod1Mask
;
1968 wxevent
.SetId(win
->GetId());
1969 wxevent
.SetEventObject(win
);
1977 bool wxTranslateKeyEvent(wxKeyEvent
& wxevent
, wxWindow
*win
, Window
WXUNUSED(win
), XEvent
*xevent
)
1979 switch (xevent
->xany
.type
)
1987 (void) XLookupString ((XKeyEvent
*) xevent
, buf
, 20, &keySym
, NULL
);
1988 int id
= wxCharCodeXToWX (keySym
);
1990 if (xevent
->xkey
.state
& ShiftMask
)
1991 wxevent
.m_shiftDown
= TRUE
;
1992 if (xevent
->xkey
.state
& ControlMask
)
1993 wxevent
.m_controlDown
= TRUE
;
1994 if (xevent
->xkey
.state
& Mod3Mask
)
1995 wxevent
.m_altDown
= TRUE
;
1996 if (xevent
->xkey
.state
& Mod1Mask
)
1997 wxevent
.m_metaDown
= TRUE
;
1998 wxevent
.SetEventObject(win
);
1999 wxevent
.m_keyCode
= id
;
2000 wxevent
.SetTimestamp(xevent
->xkey
.time
);
2002 wxevent
.m_x
= xevent
->xbutton
.x
;
2003 wxevent
.m_y
= xevent
->xbutton
.y
;
2017 // ----------------------------------------------------------------------------
2019 // ----------------------------------------------------------------------------
2023 #define YAllocColor XAllocColor
2024 XColor g_itemColors
[5];
2025 int wxComputeColours (Display
*display
, wxColour
* back
, wxColour
* fore
)
2028 static XmColorProc colorProc
;
2030 result
= wxNO_COLORS
;
2034 g_itemColors
[0].red
= (((long) back
->Red ()) << 8);
2035 g_itemColors
[0].green
= (((long) back
->Green ()) << 8);
2036 g_itemColors
[0].blue
= (((long) back
->Blue ()) << 8);
2037 g_itemColors
[0].flags
= DoRed
| DoGreen
| DoBlue
;
2038 if (colorProc
== (XmColorProc
) NULL
)
2040 // Get a ptr to the actual function
2041 colorProc
= XmSetColorCalculation ((XmColorProc
) NULL
);
2042 // And set it back to motif.
2043 XmSetColorCalculation (colorProc
);
2045 (*colorProc
) (&g_itemColors
[wxBACK_INDEX
],
2046 &g_itemColors
[wxFORE_INDEX
],
2047 &g_itemColors
[wxSELE_INDEX
],
2048 &g_itemColors
[wxTOPS_INDEX
],
2049 &g_itemColors
[wxBOTS_INDEX
]);
2050 result
= wxBACK_COLORS
;
2054 g_itemColors
[wxFORE_INDEX
].red
= (((long) fore
->Red ()) << 8);
2055 g_itemColors
[wxFORE_INDEX
].green
= (((long) fore
->Green ()) << 8);
2056 g_itemColors
[wxFORE_INDEX
].blue
= (((long) fore
->Blue ()) << 8);
2057 g_itemColors
[wxFORE_INDEX
].flags
= DoRed
| DoGreen
| DoBlue
;
2058 if (result
== wxNO_COLORS
)
2059 result
= wxFORE_COLORS
;
2062 Display
*dpy
= display
;
2063 Colormap cmap
= (Colormap
) wxTheApp
->GetMainColormap((WXDisplay
*) dpy
);
2067 /* 5 Colours to allocate */
2068 for (int i
= 0; i
< 5; i
++)
2069 if (!YAllocColor (dpy
, cmap
, &g_itemColors
[i
]))
2070 result
= wxNO_COLORS
;
2074 /* Only 1 colour to allocate */
2075 if (!YAllocColor (dpy
, cmap
, &g_itemColors
[wxFORE_INDEX
]))
2076 result
= wxNO_COLORS
;
2084 // Changes the foreground and background colours to be derived from the current
2085 // background colour. To change the foreground colour, you must call
2086 // SetForegroundColour explicitly.
2087 void wxWindowX11::ChangeBackgroundColour()
2091 WXWidget mainWidget
= GetMainWidget();
2093 DoChangeBackgroundColour(mainWidget
, m_backgroundColour
);
2097 void wxWindowX11::ChangeForegroundColour()
2101 WXWidget mainWidget
= GetMainWidget();
2103 DoChangeForegroundColour(mainWidget
, m_foregroundColour
);
2104 if ( m_scrolledWindow
&& mainWidget
!= m_scrolledWindow
)
2105 DoChangeForegroundColour(m_scrolledWindow
, m_foregroundColour
);
2109 // Change a widget's foreground and background colours.
2110 void wxWindowX11::DoChangeForegroundColour(WXWindow widget
, wxColour
& foregroundColour
)
2114 // When should we specify the foreground, if it's calculated
2115 // by wxComputeColours?
2116 // Solution: say we start with the default (computed) foreground colour.
2117 // If we call SetForegroundColour explicitly for a control or window,
2118 // then the foreground is changed.
2119 // Therefore SetBackgroundColour computes the foreground colour, and
2120 // SetForegroundColour changes the foreground colour. The ordering is
2123 Widget w
= (Widget
)widget
;
2126 XmNforeground
, foregroundColour
.AllocColour(XtDisplay(w
)),
2132 void wxWindowX11::DoChangeBackgroundColour(WXWindow widget
, wxColour
& backgroundColour
, bool changeArmColour
)
2136 wxComputeColours (XtDisplay((Widget
) widget
), & backgroundColour
,
2139 XtVaSetValues ((Widget
) widget
,
2140 XmNbackground
, g_itemColors
[wxBACK_INDEX
].pixel
,
2141 XmNtopShadowColor
, g_itemColors
[wxTOPS_INDEX
].pixel
,
2142 XmNbottomShadowColor
, g_itemColors
[wxBOTS_INDEX
].pixel
,
2143 XmNforeground
, g_itemColors
[wxFORE_INDEX
].pixel
,
2146 if (changeArmColour
)
2147 XtVaSetValues ((Widget
) widget
,
2148 XmNarmColor
, g_itemColors
[wxSELE_INDEX
].pixel
,
2153 bool wxWindowX11::SetBackgroundColour(const wxColour
& col
)
2155 if ( !wxWindowBase::SetBackgroundColour(col
) )
2158 ChangeBackgroundColour();
2163 bool wxWindowX11::SetForegroundColour(const wxColour
& col
)
2165 if ( !wxWindowBase::SetForegroundColour(col
) )
2168 ChangeForegroundColour();
2173 void wxWindowX11::ChangeFont(bool keepOriginalSize
)
2177 // Note that this causes the widget to be resized back
2178 // to its original size! We therefore have to set the size
2179 // back again. TODO: a better way in Motif?
2180 Widget w
= (Widget
) GetLabelWidget(); // Usually the main widget
2181 if (w
&& m_font
.Ok())
2183 int width
, height
, width1
, height1
;
2184 GetSize(& width
, & height
);
2186 // lesstif 0.87 hangs here
2187 #ifndef LESSTIF_VERSION
2189 XmNfontList
, (XmFontList
) m_font
.GetFontList(1.0, XtDisplay(w
)),
2193 GetSize(& width1
, & height1
);
2194 if (keepOriginalSize
&& (width
!= width1
|| height
!= height1
))
2196 SetSize(-1, -1, width
, height
);
2202 // ----------------------------------------------------------------------------
2204 // ----------------------------------------------------------------------------
2206 wxWindow
*wxGetActiveWindow()
2209 wxFAIL_MSG("Not implemented");
2214 wxWindow
*wxWindowBase::GetCapture()
2216 return (wxWindow
*)g_captureWindow
;
2220 // Find the wxWindow at the current mouse position, returning the mouse
2222 wxWindow
* wxFindWindowAtPointer(wxPoint
& pt
)
2224 return wxFindWindowAtPoint(wxGetMousePosition());
2227 // Get the current mouse position.
2228 wxPoint
wxGetMousePosition()
2230 Display
*display
= (Display
*) wxGetDisplay();
2231 Window rootWindow
= RootWindowOfScreen (DefaultScreenOfDisplay(display
));
2232 Window rootReturn
, childReturn
;
2233 int rootX
, rootY
, winX
, winY
;
2234 unsigned int maskReturn
;
2236 XQueryPointer (display
,
2240 &rootX
, &rootY
, &winX
, &winY
, &maskReturn
);
2241 return wxPoint(rootX
, rootY
);
2245 // ----------------------------------------------------------------------------
2246 // wxNoOptimize: switch off size optimization
2247 // ----------------------------------------------------------------------------
2249 int wxNoOptimize::ms_count
= 0;