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 // ----------------------------------------------------------------------------
53 // global variables for this module
54 // ----------------------------------------------------------------------------
56 extern wxHashTable
*wxWidgetHashTable
;
57 static wxWindow
* g_captureWindow
= NULL
;
59 // ----------------------------------------------------------------------------
61 // ----------------------------------------------------------------------------
63 #define event_left_is_down(x) ((x)->xbutton.state & Button1Mask)
64 #define event_middle_is_down(x) ((x)->xbutton.state & Button2Mask)
65 #define event_right_is_down(x) ((x)->xbutton.state & Button3Mask)
67 // ----------------------------------------------------------------------------
69 // ----------------------------------------------------------------------------
71 IMPLEMENT_ABSTRACT_CLASS(wxWindowX11
, wxWindowBase
)
73 BEGIN_EVENT_TABLE(wxWindowX11
, wxWindowBase
)
74 EVT_SYS_COLOUR_CHANGED(wxWindowX11::OnSysColourChanged
)
77 // ============================================================================
79 // ============================================================================
81 // ----------------------------------------------------------------------------
83 // ----------------------------------------------------------------------------
85 // ----------------------------------------------------------------------------
87 // ----------------------------------------------------------------------------
89 void wxWindowX11::Init()
91 // generic initializations first
95 m_mainWidget
= (WXWindow
) 0;
97 m_winCaptured
= FALSE
;
100 m_isBeingDeleted
= FALSE
;
106 // real construction (Init() must have been called before!)
107 bool wxWindowX11::Create(wxWindow
*parent
, wxWindowID id
,
111 const wxString
& name
)
113 wxCHECK_MSG( parent
, FALSE
, "can't create wxWindow without parent" );
115 CreateBase(parent
, id
, pos
, size
, style
, wxDefaultValidator
, name
);
117 parent
->AddChild(this);
119 int w
= size
.GetWidth();
120 int h
= size
.GetHeight();
128 Display
*xdisplay
= (Display
*) wxGlobalDisplay();
129 int xscreen
= DefaultScreen( xdisplay
);
130 Colormap cm
= DefaultColormap( xdisplay
, xscreen
);
132 m_backgroundColour
= wxSystemSettings::GetColour(wxSYS_COLOUR_3DFACE
);
133 m_backgroundColour
.CalcPixel( (WXColormap
) cm
);
136 m_foregroundColour
= *wxBLACK
;
137 m_foregroundColour
.CalcPixel( (WXColormap
) cm
);
140 Window parentWindow
= (Window
) parent
->GetMainWindow();
142 Window window
= XCreateSimpleWindow(
143 xdisplay
, parentWindow
,
145 m_backgroundColour
.GetPixel(),
146 m_backgroundColour
.GetPixel() );
148 m_mainWidget
= (WXWindow
) window
;
150 // Select event types wanted
151 XSelectInput(wxGlobalDisplay(), window
,
152 ExposureMask
| KeyPressMask
| KeyReleaseMask
| ButtonPressMask
| ButtonReleaseMask
|
153 ButtonMotionMask
| EnterWindowMask
| LeaveWindowMask
| PointerMotionMask
|
154 KeymapStateMask
| FocusChangeMask
| ColormapChangeMask
| StructureNotifyMask
|
157 wxAddWindowToTable(window
, (wxWindow
*) this);
159 // Is a subwindow, so map immediately
161 XMapWindow(wxGlobalDisplay(), window
);
163 // Without this, the cursor may not be restored properly (e.g. in splitter
165 SetCursor(*wxSTANDARD_CURSOR
);
166 SetFont(wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT
));
167 SetSize(pos
.x
, pos
.y
, size
.x
, size
.y
);
173 wxWindowX11::~wxWindowX11()
175 if (g_captureWindow
== this)
176 g_captureWindow
= NULL
;
178 m_isBeingDeleted
= TRUE
;
180 // X11-specific actions first
181 Window main
= (Window
) m_mainWidget
;
184 // Removes event handlers
185 //DetachWidget(main);
189 m_parent
->RemoveChild( this );
193 // Destroy the window
196 XSelectInput( wxGlobalDisplay(), main
, NoEventMask
);
197 wxDeleteWindowFromTable( main
);
198 XDestroyWindow( wxGlobalDisplay(), main
);
203 // ---------------------------------------------------------------------------
205 // ---------------------------------------------------------------------------
207 void wxWindowX11::SetFocus()
209 Window wMain
= (Window
) GetMainWindow();
212 XSetInputFocus(wxGlobalDisplay(), wMain
, RevertToParent
, CurrentTime
);
215 wmhints
.flags
= InputHint
;
216 wmhints
.input
= True
;
217 XSetWMHints(wxGlobalDisplay(), wMain
, &wmhints
);
221 // Get the window with the focus
222 wxWindow
*wxWindowBase::FindFocus()
224 Window wFocus
= (Window
) 0;
227 XGetInputFocus(wxGlobalDisplay(), & wFocus
, & revert
);
230 wxWindow
*win
= NULL
;
233 win
= wxGetWindowFromTable(wFocus
);
234 wFocus
= wxGetWindowParent(wFocus
);
235 } while (wFocus
&& !win
);
243 // Enabling/disabling handled by event loop, and not sending events
245 bool wxWindowX11::Enable(bool enable
)
247 if ( !wxWindowBase::Enable(enable
) )
253 bool wxWindowX11::Show(bool show
)
255 wxWindowBase::Show(show
);
257 Window xwin
= (Window
) GetXWindow();
258 Display
*xdisp
= (Display
*) GetXDisplay();
262 msg
.Printf("Mapping window of type %s", GetClassInfo()->GetClassName());
264 XMapWindow(xdisp
, xwin
);
270 msg
.Printf("Unmapping window of type %s", GetClassInfo()->GetClassName());
272 XUnmapWindow(xdisp
, xwin
);
278 // Raise the window to the top of the Z order
279 void wxWindowX11::Raise()
282 XRaiseWindow( wxGlobalDisplay(), (Window
) m_mainWidget
);
285 // Lower the window to the bottom of the Z order
286 void wxWindowX11::Lower()
289 XLowerWindow( wxGlobalDisplay(), (Window
) m_mainWidget
);
292 void wxWindowX11::DoCaptureMouse()
294 if ((g_captureWindow
!= NULL
) && (g_captureWindow
!= this))
296 wxASSERT_MSG(FALSE
, "Trying to capture before mouse released.");
307 Window xwindow
= (Window
) GetMainWindow();
309 g_captureWindow
= (wxWindow
*) this;
313 int res
= XGrabPointer(wxGlobalDisplay(), xwindow
,
315 ButtonPressMask
| ButtonReleaseMask
| ButtonMotionMask
| EnterWindowMask
| LeaveWindowMask
| PointerMotionMask
,
319 None
, /* cursor */ // TODO: This may need to be set to the cursor of this window
322 if (res
!= GrabSuccess
)
325 msg
.Printf("Failed to grab pointer for window %s", this->GetClassInfo()->GetClassName());
327 if (res
== GrabNotViewable
)
329 wxLogDebug("This is not a viewable window - perhaps not shown yet?");
331 g_captureWindow
= NULL
;
335 wxLogDebug("Grabbed pointer");
338 res
= XGrabButton(wxGlobalDisplay(), AnyButton
, AnyModifier
,
339 (Window
) GetMainWindow(),
341 ButtonPressMask
| ButtonReleaseMask
| ButtonMotionMask
,
347 if (res
!= GrabSuccess
)
349 wxLogDebug("Failed to grab mouse buttons.");
350 XUngrabPointer(wxGlobalDisplay(), CurrentTime
);
356 res
= XGrabKeyboard(wxGlobalDisplay(), (Window
) GetMainWindow(),
357 ShiftMask
| LockMask
| ControlMask
| Mod1Mask
| Mod2Mask
| Mod3Mask
| Mod4Mask
| Mod5Mask
,
363 if (res
!= GrabSuccess
)
365 wxLogDebug("Failed to grab keyboard.");
366 XUngrabPointer(wxGlobalDisplay(), CurrentTime
);
367 XUngrabButton(wxGlobalDisplay(), AnyButton
, AnyModifier
,
368 (Window
) GetMainWindow());
373 m_winCaptured
= TRUE
;
377 void wxWindowX11::DoReleaseMouse()
379 g_captureWindow
= NULL
;
381 if ( !m_winCaptured
)
384 Window xwindow
= (Window
) GetMainWindow();
388 XUngrabPointer( wxGlobalDisplay(), CurrentTime
);
390 XUngrabButton( wxGlobalDisplay(), AnyButton
, AnyModifier
, xwindow
);
391 XUngrabKeyboard( wxGlobalDisplay(), CurrentTime
);
394 wxLogDebug("Ungrabbed pointer");
396 m_winCaptured
= FALSE
;
399 bool wxWindowX11::SetFont(const wxFont
& font
)
401 if ( !wxWindowBase::SetFont(font
) )
410 bool wxWindowX11::SetCursor(const wxCursor
& cursor
)
412 if ( !wxWindowBase::SetCursor(cursor
) )
418 wxCursor
* cursor2
= NULL
;
420 cursor2
= & m_cursor
;
422 cursor2
= wxSTANDARD_CURSOR
;
424 WXCursor x_cursor
= cursor2
->GetCursor();
426 Window win
= (Window
) GetMainWindow();
427 XDefineCursor((Display
*) wxGlobalDisplay(), win
, (Cursor
) x_cursor
);
432 // Coordinates relative to the window
433 void wxWindowX11::WarpPointer (int x
, int y
)
436 XWarpPointer( wxGlobalDisplay(), None
, (Window
) m_mainWidget
, 0, 0, 0, 0, x
, y
);
439 // Does a physical scroll
440 void wxWindowX11::ScrollWindow(int dx
, int dy
, const wxRect
*rect
)
446 // Use specified rectangle
447 x
= rect
->x
; y
= rect
->y
; w
= rect
->width
; h
= rect
->height
;
451 // Use whole client area
453 GetClientSize(& w
, & h
);
456 wxNode
*cnode
= m_children
.First();
459 wxWindow
*child
= (wxWindow
*) cnode
->Data();
462 child
->GetSize( &sx
, &sy
);
463 wxPoint
pos( child
->GetPosition() );
464 child
->SetSize( pos
.x
+ dx
, pos
.y
+ dy
, sx
, sy
, wxSIZE_ALLOW_MINUS_ONE
);
465 cnode
= cnode
->Next();
468 int x1
= (dx
>= 0) ? x
: x
- dx
;
469 int y1
= (dy
>= 0) ? y
: y
- dy
;
470 int w1
= w
- abs(dx
);
471 int h1
= h
- abs(dy
);
472 int x2
= (dx
>= 0) ? x
+ dx
: x
;
473 int y2
= (dy
>= 0) ? y
+ dy
: y
;
475 wxClientDC
dc((wxWindow
*) this);
477 dc
.SetLogicalFunction (wxCOPY
);
479 Window window
= (Window
) GetMainWindow();
480 Display
* display
= wxGlobalDisplay();
482 XCopyArea(display
, window
, window
, (GC
) dc
.GetGC(),
483 x1
, y1
, w1
, h1
, x2
, y2
);
485 dc
.SetAutoSetting(TRUE
);
486 wxBrush
brush(GetBackgroundColour(), wxSOLID
);
487 dc
.SetBrush(brush
); // FIXME: needed?
489 // We'll add rectangles to the list of update rectangles according to which
490 // bits we've exposed.
495 wxRect
*rect
= new wxRect
;
501 XFillRectangle(display
, window
,
502 (GC
) dc
.GetGC(), rect
->x
, rect
->y
, rect
->width
, rect
->height
);
506 rect
->width
= rect
->width
;
507 rect
->height
= rect
->height
;
509 updateRects
.Append((wxObject
*) rect
);
513 wxRect
*rect
= new wxRect
;
515 rect
->x
= x
+ w
+ dx
;
520 XFillRectangle(display
, window
,
521 (GC
) dc
.GetGC(), rect
->x
, rect
->y
, rect
->width
,
526 rect
->width
= rect
->width
;
527 rect
->height
= rect
->height
;
529 updateRects
.Append((wxObject
*) rect
);
533 wxRect
*rect
= new wxRect
;
540 XFillRectangle(display
, window
,
541 (GC
) dc
.GetGC(), rect
->x
, rect
->y
, rect
->width
, rect
->height
);
545 rect
->width
= rect
->width
;
546 rect
->height
= rect
->height
;
548 updateRects
.Append((wxObject
*) rect
);
552 wxRect
*rect
= new wxRect
;
555 rect
->y
= y
+ h
+ dy
;
559 XFillRectangle(display
, window
,
560 (GC
) dc
.GetGC(), rect
->x
, rect
->y
, rect
->width
, rect
->height
);
564 rect
->width
= rect
->width
;
565 rect
->height
= rect
->height
;
567 updateRects
.Append((wxObject
*) rect
);
569 dc
.SetBrush(wxNullBrush
);
571 // Now send expose events
573 wxNode
* node
= updateRects
.First();
576 wxRect
* rect
= (wxRect
*) node
->Data();
580 event
.display
= display
;
581 event
.send_event
= True
;
582 event
.window
= window
;
586 event
.width
= rect
->width
;
587 event
.height
= rect
->height
;
591 XSendEvent(display
, window
, False
, ExposureMask
, (XEvent
*)&event
);
597 // Delete the update rects
598 node
= updateRects
.First();
601 wxRect
* rect
= (wxRect
*) node
->Data();
608 // ---------------------------------------------------------------------------
610 // ---------------------------------------------------------------------------
612 #if wxUSE_DRAG_AND_DROP
614 void wxWindowX11::SetDropTarget(wxDropTarget
* WXUNUSED(pDropTarget
))
621 // Old style file-manager drag&drop
622 void wxWindowX11::DragAcceptFiles(bool WXUNUSED(accept
))
627 // ----------------------------------------------------------------------------
629 // ----------------------------------------------------------------------------
633 void wxWindowX11::DoSetToolTip(wxToolTip
* WXUNUSED(tooltip
))
638 #endif // wxUSE_TOOLTIPS
640 // ---------------------------------------------------------------------------
641 // moving and resizing
642 // ---------------------------------------------------------------------------
644 bool wxWindowX11::PreResize()
650 void wxWindowX11::DoGetSize(int *x
, int *y
) const
652 Window window
= (Window
) m_mainWidget
;
655 XWindowAttributes attr
;
656 Status status
= XGetWindowAttributes(wxGlobalDisplay(), window
, & attr
);
661 *x
= attr
.width
/* + 2*m_borderSize */ ;
662 *y
= attr
.height
/* + 2*m_borderSize */ ;
667 void wxWindowX11::DoGetPosition(int *x
, int *y
) const
669 Window window
= (Window
) m_mainWidget
;
672 XWindowAttributes attr
;
673 Status status
= XGetWindowAttributes(wxGlobalDisplay(), window
, & attr
);
681 // We may be faking the client origin. So a window that's really at (0, 30)
682 // may appear (to wxWin apps) to be at (0, 0).
685 wxPoint
pt(GetParent()->GetClientAreaOrigin());
693 void wxWindowX11::DoScreenToClient(int *x
, int *y
) const
695 Display
*display
= wxGlobalDisplay();
696 Window rootWindow
= RootWindowOfScreen(DefaultScreenOfDisplay(display
));
697 Window thisWindow
= (Window
) m_mainWidget
;
702 XTranslateCoordinates(display
, rootWindow
, thisWindow
, xx
, yy
, x
, y
, &childWindow
);
705 void wxWindowX11::DoClientToScreen(int *x
, int *y
) const
707 Display
*display
= wxGlobalDisplay();
708 Window rootWindow
= RootWindowOfScreen(DefaultScreenOfDisplay(display
));
709 Window thisWindow
= (Window
) m_mainWidget
;
714 XTranslateCoordinates(display
, thisWindow
, rootWindow
, xx
, yy
, x
, y
, &childWindow
);
718 // Get size *available for subwindows* i.e. excluding menu bar etc.
719 void wxWindowX11::DoGetClientSize(int *x
, int *y
) const
721 Window window
= (Window
) m_mainWidget
;
725 XWindowAttributes attr
;
726 Status status
= XGetWindowAttributes( wxGlobalDisplay(), window
, &attr
);
737 void wxWindowX11::DoSetSize(int x
, int y
, int width
, int height
, int sizeFlags
)
739 if (!GetMainWindow())
742 XWindowChanges windowChanges
;
745 if (x
!= -1 || (sizeFlags
& wxSIZE_ALLOW_MINUS_ONE
))
748 AdjustForParentClientOrigin( x
, yy
, sizeFlags
);
752 if (y
!= -1 || (sizeFlags
& wxSIZE_ALLOW_MINUS_ONE
))
755 AdjustForParentClientOrigin( xx
, y
, sizeFlags
);
759 if (width
!= -1 || (sizeFlags
& wxSIZE_ALLOW_MINUS_ONE
))
761 windowChanges
.width
= width
/* - m_borderSize*2 */;
762 valueMask
|= CWWidth
;
764 if (height
!= -1 || (sizeFlags
& wxSIZE_ALLOW_MINUS_ONE
))
766 windowChanges
.height
= height
/* -m_borderSize*2*/;
767 valueMask
|= CWHeight
;
770 XConfigureWindow(wxGlobalDisplay(), (Window
) GetMainWindow(),
771 valueMask
, & windowChanges
);
774 void wxWindowX11::DoSetClientSize(int width
, int height
)
776 if (!GetMainWindow())
779 XWindowChanges windowChanges
;
784 windowChanges
.width
= width
;
785 valueMask
|= CWWidth
;
789 windowChanges
.height
= height
;
790 valueMask
|= CWHeight
;
792 XConfigureWindow(wxGlobalDisplay(), (Window
) GetMainWindow(),
793 valueMask
, & windowChanges
);
796 // For implementation purposes - sometimes decorations make the client area
798 wxPoint
wxWindowX11::GetClientAreaOrigin() const
800 return wxPoint(0, 0);
803 // Makes an adjustment to the window position (for example, a frame that has
804 // a toolbar that it manages itself).
805 void wxWindowX11::AdjustForParentClientOrigin(int& x
, int& y
, int sizeFlags
)
807 if (((sizeFlags
& wxSIZE_NO_ADJUSTMENTS
) == 0) && GetParent())
809 wxPoint
pt(GetParent()->GetClientAreaOrigin());
810 x
+= pt
.x
; y
+= pt
.y
;
814 void wxWindowX11::SetSizeHints(int minW
, int minH
, int maxW
, int maxH
, int incW
, int incH
)
821 XSizeHints sizeHints
;
824 if (minW
> -1 && minH
> -1)
826 sizeHints
.flags
|= PMinSize
;
827 sizeHints
.min_width
= minW
;
828 sizeHints
.min_height
= minH
;
830 if (maxW
> -1 && maxH
> -1)
832 sizeHints
.flags
|= PMaxSize
;
833 sizeHints
.max_width
= maxW
;
834 sizeHints
.max_height
= maxH
;
836 if (incW
> -1 && incH
> -1)
838 sizeHints
.flags
|= PResizeInc
;
839 sizeHints
.width_inc
= incW
;
840 sizeHints
.height_inc
= incH
;
843 XSetWMNormalHints(wxGlobalDisplay(), (Window
) GetMainWindow(), & sizeHints
);
846 void wxWindowX11::DoMoveWindow(int x
, int y
, int width
, int height
)
848 DoSetSize(x
, y
, width
, height
);
851 // ---------------------------------------------------------------------------
853 // ---------------------------------------------------------------------------
855 int wxWindowX11::GetCharHeight() const
857 wxCHECK_MSG( m_font
.Ok(), 0, "valid window font needed" );
859 WXFontStructPtr pFontStruct
= m_font
.GetFontStruct(1.0, GetXDisplay());
861 int direction
, ascent
, descent
;
863 XTextExtents ((XFontStruct
*) pFontStruct
, "x", 1, &direction
, &ascent
,
866 // return (overall.ascent + overall.descent);
867 return (ascent
+ descent
);
870 int wxWindowX11::GetCharWidth() const
872 wxCHECK_MSG( m_font
.Ok(), 0, "valid window font needed" );
874 WXFontStructPtr pFontStruct
= m_font
.GetFontStruct(1.0, GetXDisplay());
876 int direction
, ascent
, descent
;
878 XTextExtents ((XFontStruct
*) pFontStruct
, "x", 1, &direction
, &ascent
,
881 return overall
.width
;
884 void wxWindowX11::GetTextExtent(const wxString
& string
,
886 int *descent
, int *externalLeading
,
887 const wxFont
*theFont
) const
889 wxFont fontToUse
= m_font
;
890 if (theFont
) fontToUse
= *theFont
;
892 wxCHECK_RET( fontToUse
.Ok(), wxT("invalid font") );
894 WXFontStructPtr pFontStruct
= fontToUse
.GetFontStruct(1.0, GetXDisplay());
896 int direction
, ascent
, descent2
;
898 int slen
= string
.Len();
902 XTextExtents16((XFontStruct
*) pFontStruct
, (XChar2b
*) (char*) (const char*) string
, slen
, &direction
,
903 &ascent
, &descent2
, &overall
);
906 XTextExtents((XFontStruct
*) pFontStruct
, string
.c_str(), slen
,
907 &direction
, &ascent
, &descent2
, &overall
);
910 *x
= (overall
.width
);
912 *y
= (ascent
+ descent2
);
916 *externalLeading
= 0;
920 // ----------------------------------------------------------------------------
922 // ----------------------------------------------------------------------------
924 void wxWindowX11::Refresh(bool eraseBack
, const wxRect
*rect
)
930 // Schedule for later Updating in ::Update() or ::OnInternalIdle().
931 m_clearRegion
.Union( rect
->x
, rect
->y
, rect
->width
, rect
->height
);
936 GetSize( &width
, &height
);
938 // Schedule for later Updating in ::Update() or ::OnInternalIdle().
939 m_clearRegion
.Clear();
940 m_clearRegion
.Union( 0, 0, width
, height
);
946 // Schedule for later Updating in ::Update() or ::OnInternalIdle().
947 m_updateRegion
.Union( rect
->x
, rect
->y
, rect
->width
, rect
->height
);
952 GetSize( &width
, &height
);
954 // Schedule for later Updating in ::Update() or ::OnInternalIdle().
955 m_updateRegion
.Clear();
956 m_updateRegion
.Union( 0, 0, width
, height
);
960 void wxWindowX11::Update()
962 if (!m_updateRegion
.IsEmpty())
964 X11SendPaintEvents();
968 void wxWindowX11::Clear()
970 wxClientDC
dc((wxWindow
*) this);
971 wxBrush
brush(GetBackgroundColour(), wxSOLID
);
972 dc
.SetBackground(brush
);
976 void wxWindowX11::X11SendPaintEvents()
978 m_clipPaintRegion
= TRUE
;
980 // if (!m_clearRegion.IsEmpty())
982 wxWindowDC
dc( (wxWindow
*)this );
983 dc
.SetClippingRegion( m_clearRegion
);
985 wxEraseEvent
erase_event( GetId(), &dc
);
986 erase_event
.SetEventObject( this );
988 if (!GetEventHandler()->ProcessEvent(erase_event
))
990 wxRegionIterator
upd( m_clearRegion
);
993 XClearArea( wxGlobalDisplay(), (Window
) m_mainWidget
,
994 upd
.GetX(), upd
.GetY(), upd
.GetWidth(), upd
.GetHeight(), False
);
998 m_clearRegion
.Clear();
1001 wxNcPaintEvent
nc_paint_event( GetId() );
1002 nc_paint_event
.SetEventObject( this );
1003 GetEventHandler()->ProcessEvent( nc_paint_event
);
1005 wxPaintEvent
paint_event( GetId() );
1006 paint_event
.SetEventObject( this );
1007 GetEventHandler()->ProcessEvent( paint_event
);
1009 m_updateRegion
.Clear();
1011 m_clipPaintRegion
= FALSE
;
1014 // ----------------------------------------------------------------------------
1016 // ----------------------------------------------------------------------------
1018 // Responds to colour changes: passes event on to children.
1019 void wxWindowX11::OnSysColourChanged(wxSysColourChangedEvent
& event
)
1021 wxWindowList::Node
*node
= GetChildren().GetFirst();
1024 // Only propagate to non-top-level windows
1025 wxWindow
*win
= node
->GetData();
1026 if ( win
->GetParent() )
1028 wxSysColourChangedEvent event2
;
1029 event
.m_eventObject
= win
;
1030 win
->GetEventHandler()->ProcessEvent(event2
);
1033 node
= node
->GetNext();
1037 void wxWindowX11::OnInternalIdle()
1039 // Update invalidated regions.
1042 // This calls the UI-update mechanism (querying windows for
1043 // menu/toolbar/control state information)
1047 // ----------------------------------------------------------------------------
1048 // function which maintain the global hash table mapping Widgets to wxWindows
1049 // ----------------------------------------------------------------------------
1051 bool wxAddWindowToTable(Window w
, wxWindow
*win
)
1053 wxWindow
*oldItem
= NULL
;
1054 if ((oldItem
= (wxWindow
*)wxWidgetHashTable
->Get ((long) w
)))
1056 wxLogDebug("Widget table clash: new widget is %ld, %s",
1057 (long)w
, win
->GetClassInfo()->GetClassName());
1061 wxWidgetHashTable
->Put((long) w
, win
);
1063 wxLogTrace("widget", "XWindow 0x%08x <-> window %p (%s)",
1064 w
, win
, win
->GetClassInfo()->GetClassName());
1069 wxWindow
*wxGetWindowFromTable(Window w
)
1071 return (wxWindow
*)wxWidgetHashTable
->Get((long) w
);
1074 void wxDeleteWindowFromTable(Window w
)
1076 wxWidgetHashTable
->Delete((long)w
);
1079 // ----------------------------------------------------------------------------
1080 // add/remove window from the table
1081 // ----------------------------------------------------------------------------
1083 // ----------------------------------------------------------------------------
1084 // X11-specific accessors
1085 // ----------------------------------------------------------------------------
1087 // Get the underlying X window
1088 WXWindow
wxWindowX11::GetXWindow() const
1090 return GetMainWindow();
1093 // Get the underlying X display
1094 WXDisplay
*wxWindowX11::GetXDisplay() const
1096 return wxGetDisplay();
1099 WXWindow
wxWindowX11::GetMainWindow() const
1101 return m_mainWidget
;
1104 // ----------------------------------------------------------------------------
1105 // TranslateXXXEvent() functions
1106 // ----------------------------------------------------------------------------
1108 bool wxTranslateMouseEvent(wxMouseEvent
& wxevent
, wxWindow
*win
, Window window
, XEvent
*xevent
)
1110 switch (xevent
->xany
.type
)
1118 wxEventType eventType
= wxEVT_NULL
;
1120 if (xevent
->xany
.type
== EnterNotify
)
1122 //if (local_event.xcrossing.mode!=NotifyNormal)
1123 // return ; // Ignore grab events
1124 eventType
= wxEVT_ENTER_WINDOW
;
1125 // canvas->GetEventHandler()->OnSetFocus();
1127 else if (xevent
->xany
.type
== LeaveNotify
)
1129 //if (local_event.xcrossingr.mode!=NotifyNormal)
1130 // return ; // Ignore grab events
1131 eventType
= wxEVT_LEAVE_WINDOW
;
1132 // canvas->GetEventHandler()->OnKillFocus();
1134 else if (xevent
->xany
.type
== MotionNotify
)
1136 eventType
= wxEVT_MOTION
;
1138 else if (xevent
->xany
.type
== ButtonPress
)
1140 wxevent
.SetTimestamp(xevent
->xbutton
.time
);
1142 if (xevent
->xbutton
.button
== Button1
)
1144 eventType
= wxEVT_LEFT_DOWN
;
1147 else if (xevent
->xbutton
.button
== Button2
)
1149 eventType
= wxEVT_MIDDLE_DOWN
;
1152 else if (xevent
->xbutton
.button
== Button3
)
1154 eventType
= wxEVT_RIGHT_DOWN
;
1158 // check for a double click
1159 // TODO: where can we get this value from?
1160 //long dclickTime = XtGetMultiClickTime(wxGlobalDisplay());
1161 long dclickTime
= 200;
1162 long ts
= wxevent
.GetTimestamp();
1164 int buttonLast
= win
->GetLastClickedButton();
1165 long lastTS
= win
->GetLastClickTime();
1166 if ( buttonLast
&& buttonLast
== button
&& (ts
- lastTS
) < dclickTime
)
1169 win
->SetLastClick(0, ts
);
1170 if ( eventType
== wxEVT_LEFT_DOWN
)
1171 eventType
= wxEVT_LEFT_DCLICK
;
1172 else if ( eventType
== wxEVT_MIDDLE_DOWN
)
1173 eventType
= wxEVT_MIDDLE_DCLICK
;
1174 else if ( eventType
== wxEVT_RIGHT_DOWN
)
1175 eventType
= wxEVT_RIGHT_DCLICK
;
1179 // not fast enough or different button
1180 win
->SetLastClick(button
, ts
);
1183 else if (xevent
->xany
.type
== ButtonRelease
)
1185 if (xevent
->xbutton
.button
== Button1
)
1187 eventType
= wxEVT_LEFT_UP
;
1189 else if (xevent
->xbutton
.button
== Button2
)
1191 eventType
= wxEVT_MIDDLE_UP
;
1193 else if (xevent
->xbutton
.button
== Button3
)
1195 eventType
= wxEVT_RIGHT_UP
;
1204 wxevent
.SetEventType(eventType
);
1206 wxevent
.m_x
= xevent
->xbutton
.x
;
1207 wxevent
.m_y
= xevent
->xbutton
.y
;
1209 wxevent
.m_leftDown
= ((eventType
== wxEVT_LEFT_DOWN
)
1210 || (event_left_is_down (xevent
)
1211 && (eventType
!= wxEVT_LEFT_UP
)));
1212 wxevent
.m_middleDown
= ((eventType
== wxEVT_MIDDLE_DOWN
)
1213 || (event_middle_is_down (xevent
)
1214 && (eventType
!= wxEVT_MIDDLE_UP
)));
1215 wxevent
.m_rightDown
= ((eventType
== wxEVT_RIGHT_DOWN
)
1216 || (event_right_is_down (xevent
)
1217 && (eventType
!= wxEVT_RIGHT_UP
)));
1219 wxevent
.m_shiftDown
= xevent
->xbutton
.state
& ShiftMask
;
1220 wxevent
.m_controlDown
= xevent
->xbutton
.state
& ControlMask
;
1221 wxevent
.m_altDown
= xevent
->xbutton
.state
& Mod3Mask
;
1222 wxevent
.m_metaDown
= xevent
->xbutton
.state
& Mod1Mask
;
1224 wxevent
.SetId(win
->GetId());
1225 wxevent
.SetEventObject(win
);
1233 bool wxTranslateKeyEvent(wxKeyEvent
& wxevent
, wxWindow
*win
, Window
WXUNUSED(win
), XEvent
*xevent
)
1235 switch (xevent
->xany
.type
)
1243 (void) XLookupString ((XKeyEvent
*) xevent
, buf
, 20, &keySym
, NULL
);
1244 int id
= wxCharCodeXToWX (keySym
);
1246 if (xevent
->xkey
.state
& ShiftMask
)
1247 wxevent
.m_shiftDown
= TRUE
;
1248 if (xevent
->xkey
.state
& ControlMask
)
1249 wxevent
.m_controlDown
= TRUE
;
1250 if (xevent
->xkey
.state
& Mod3Mask
)
1251 wxevent
.m_altDown
= TRUE
;
1252 if (xevent
->xkey
.state
& Mod1Mask
)
1253 wxevent
.m_metaDown
= TRUE
;
1254 wxevent
.SetEventObject(win
);
1255 wxevent
.m_keyCode
= id
;
1256 wxevent
.SetTimestamp(xevent
->xkey
.time
);
1258 wxevent
.m_x
= xevent
->xbutton
.x
;
1259 wxevent
.m_y
= xevent
->xbutton
.y
;
1273 // ----------------------------------------------------------------------------
1275 // ----------------------------------------------------------------------------
1279 #define YAllocColor XAllocColor
1280 XColor g_itemColors
[5];
1281 int wxComputeColours (Display
*display
, wxColour
* back
, wxColour
* fore
)
1284 static XmColorProc colorProc
;
1286 result
= wxNO_COLORS
;
1290 g_itemColors
[0].red
= (((long) back
->Red ()) << 8);
1291 g_itemColors
[0].green
= (((long) back
->Green ()) << 8);
1292 g_itemColors
[0].blue
= (((long) back
->Blue ()) << 8);
1293 g_itemColors
[0].flags
= DoRed
| DoGreen
| DoBlue
;
1294 if (colorProc
== (XmColorProc
) NULL
)
1296 // Get a ptr to the actual function
1297 colorProc
= XmSetColorCalculation ((XmColorProc
) NULL
);
1298 // And set it back to motif.
1299 XmSetColorCalculation (colorProc
);
1301 (*colorProc
) (&g_itemColors
[wxBACK_INDEX
],
1302 &g_itemColors
[wxFORE_INDEX
],
1303 &g_itemColors
[wxSELE_INDEX
],
1304 &g_itemColors
[wxTOPS_INDEX
],
1305 &g_itemColors
[wxBOTS_INDEX
]);
1306 result
= wxBACK_COLORS
;
1310 g_itemColors
[wxFORE_INDEX
].red
= (((long) fore
->Red ()) << 8);
1311 g_itemColors
[wxFORE_INDEX
].green
= (((long) fore
->Green ()) << 8);
1312 g_itemColors
[wxFORE_INDEX
].blue
= (((long) fore
->Blue ()) << 8);
1313 g_itemColors
[wxFORE_INDEX
].flags
= DoRed
| DoGreen
| DoBlue
;
1314 if (result
== wxNO_COLORS
)
1315 result
= wxFORE_COLORS
;
1318 Display
*dpy
= display
;
1319 Colormap cmap
= (Colormap
) wxTheApp
->GetMainColormap((WXDisplay
*) dpy
);
1323 /* 5 Colours to allocate */
1324 for (int i
= 0; i
< 5; i
++)
1325 if (!YAllocColor (dpy
, cmap
, &g_itemColors
[i
]))
1326 result
= wxNO_COLORS
;
1330 /* Only 1 colour to allocate */
1331 if (!YAllocColor (dpy
, cmap
, &g_itemColors
[wxFORE_INDEX
]))
1332 result
= wxNO_COLORS
;
1340 bool wxWindowX11::SetBackgroundColour(const wxColour
& col
)
1342 wxWindowBase::SetBackgroundColour(col
);
1344 if (!GetMainWindow())
1347 Display
*xdisplay
= (Display
*) wxGlobalDisplay();
1348 int xscreen
= DefaultScreen( xdisplay
);
1349 Colormap cm
= DefaultColormap( xdisplay
, xscreen
);
1351 wxColour
colour( col
);
1352 colour
.CalcPixel( (WXColormap
) cm
);
1354 XSetWindowAttributes attrib
;
1355 attrib
.background_pixel
= colour
.GetPixel();
1357 XChangeWindowAttributes(wxGlobalDisplay(),
1358 (Window
) GetMainWindow(),
1365 bool wxWindowX11::SetForegroundColour(const wxColour
& col
)
1367 if ( !wxWindowBase::SetForegroundColour(col
) )
1373 // ----------------------------------------------------------------------------
1375 // ----------------------------------------------------------------------------
1377 wxWindow
*wxGetActiveWindow()
1380 wxFAIL_MSG("Not implemented");
1385 wxWindow
*wxWindowBase::GetCapture()
1387 return (wxWindow
*)g_captureWindow
;
1391 // Find the wxWindow at the current mouse position, returning the mouse
1393 wxWindow
* wxFindWindowAtPointer(wxPoint
& pt
)
1395 return wxFindWindowAtPoint(wxGetMousePosition());
1398 // Get the current mouse position.
1399 wxPoint
wxGetMousePosition()
1401 Display
*display
= wxGlobalDisplay();
1402 Window rootWindow
= RootWindowOfScreen (DefaultScreenOfDisplay(display
));
1403 Window rootReturn
, childReturn
;
1404 int rootX
, rootY
, winX
, winY
;
1405 unsigned int maskReturn
;
1407 XQueryPointer (display
,
1411 &rootX
, &rootY
, &winX
, &winY
, &maskReturn
);
1412 return wxPoint(rootX
, rootY
);
1416 // ----------------------------------------------------------------------------
1417 // wxNoOptimize: switch off size optimization
1418 // ----------------------------------------------------------------------------
1420 int wxNoOptimize::ms_count
= 0;