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_ABSTRACT_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_mainWidget
= (WXWindow
) 0;
104 m_winCaptured
= FALSE
;
107 m_isBeingDeleted
= FALSE
;
113 // real construction (Init() must have been called before!)
114 bool wxWindowX11
::Create(wxWindow
*parent
, wxWindowID id
,
118 const wxString
& name
)
120 wxCHECK_MSG( parent
, FALSE
, "can't create wxWindow without parent" );
122 CreateBase(parent
, id
, pos
, size
, style
, wxDefaultValidator
, name
);
125 parent
->AddChild(this);
127 m_backgroundColour
= wxSystemSettings
::GetColour(wxSYS_COLOUR_3DFACE
);
128 m_foregroundColour
= *wxBLACK
;
130 int w
= size
.GetWidth();
131 int h
= size
.GetHeight();
139 int screen
= DefaultScreen(wxGlobalDisplay());
143 parentWindow
= (Window
) parent
->GetMainWindow();
145 parentWindow
= RootWindow(wxGlobalDisplay(), screen
);
147 Window window
= XCreateSimpleWindow(wxGlobalDisplay(), parentWindow
,
149 m_backgroundColour
.AllocColour(wxGlobalDisplay()),
150 m_foregroundColour
.AllocColour(wxGlobalDisplay()));
151 m_mainWidget
= (WXWindow
) window
;
153 // Select event types wanted
154 XSelectInput(wxGlobalDisplay(), window
,
155 ExposureMask
| KeyPressMask
| KeyReleaseMask
| ButtonPressMask
| ButtonReleaseMask
|
156 ButtonMotionMask
| EnterWindowMask
| LeaveWindowMask
| PointerMotionMask
|
157 KeymapStateMask
| FocusChangeMask
| ColormapChangeMask
| StructureNotifyMask
|
160 wxAddWindowToTable(window
, (wxWindow
*) this);
162 // Is a subwindow, so map immediately
164 XMapWindow(wxGlobalDisplay(), window
);
166 // Without this, the cursor may not be restored properly (e.g. in splitter
168 SetCursor(*wxSTANDARD_CURSOR
);
169 SetFont(wxSystemSettings
::GetFont(wxSYS_DEFAULT_GUI_FONT
));
170 SetSize(pos
.x
, pos
.y
, size
.x
, size
.y
);
176 wxWindowX11
::~wxWindowX11()
178 if (g_captureWindow
== this)
179 g_captureWindow
= NULL
;
181 m_isBeingDeleted
= TRUE
;
183 // X11-specific actions first
184 Window main
= (Window
) m_mainWidget
;
187 // Removes event handlers
188 //DetachWidget(main);
192 m_parent
->RemoveChild( this );
196 // Destroy the window
199 XSelectInput( wxGlobalDisplay(), main
, NoEventMask
);
200 wxDeleteWindowFromTable( main
);
201 XDestroyWindow( wxGlobalDisplay(), main
);
206 // ---------------------------------------------------------------------------
208 // ---------------------------------------------------------------------------
210 void wxWindowX11
::SetFocus()
212 Window wMain
= (Window
) GetMainWindow();
215 XSetInputFocus(wxGlobalDisplay(), wMain
, RevertToParent
, CurrentTime
);
218 wmhints
.flags
= InputHint
;
219 wmhints
.input
= True
;
220 XSetWMHints(wxGlobalDisplay(), wMain
, &wmhints
);
224 // Get the window with the focus
225 wxWindow
*wxWindowBase
::FindFocus()
227 Window wFocus
= (Window
) 0;
230 XGetInputFocus(wxGlobalDisplay(), & wFocus
, & revert
);
233 wxWindow
*win
= NULL
;
236 win
= wxGetWindowFromTable(wFocus
);
237 wFocus
= wxGetWindowParent(wFocus
);
238 } while (wFocus
&& !win
);
246 // Enabling/disabling handled by event loop, and not sending events
248 bool wxWindowX11
::Enable(bool enable
)
250 if ( !wxWindowBase
::Enable(enable
) )
256 bool wxWindowX11
::Show(bool show
)
258 if ( !wxWindowBase
::Show(show
) )
261 Window xwin
= (Window
) GetXWindow();
262 Display
*xdisp
= (Display
*) GetXDisplay();
265 XMapWindow(xdisp
, xwin
);
269 XUnmapWindow(xdisp
, xwin
);
275 // Raise the window to the top of the Z order
276 void wxWindowX11
::Raise()
279 XRaiseWindow( wxGlobalDisplay(), (Window
) m_mainWidget
);
282 // Lower the window to the bottom of the Z order
283 void wxWindowX11
::Lower()
286 XLowerWindow( wxGlobalDisplay(), (Window
) m_mainWidget
);
289 void wxWindowX11
::DoCaptureMouse()
291 g_captureWindow
= (wxWindow
*) this;
297 int res
= XGrabPointer(wxGlobalDisplay(), (Window
) GetMainWindow(),
299 ButtonPressMask
| ButtonReleaseMask
| ButtonMotionMask
| EnterWindowMask
| LeaveWindowMask
| PointerMotionMask
,
303 None
, /* cursor */ // TODO: This may need to be set to the cursor of this window
306 if (res
!= GrabSuccess
)
308 wxLogDebug("Failed to grab pointer.");
312 res
= XGrabButton(wxGlobalDisplay(), AnyButton
, AnyModifier
,
313 (Window
) GetMainWindow(),
315 ButtonPressMask
| ButtonReleaseMask
| ButtonMotionMask
,
321 if (res
!= GrabSuccess
)
323 wxLogDebug("Failed to grab mouse buttons.");
324 XUngrabPointer(wxGlobalDisplay(), CurrentTime
);
328 res
= XGrabKeyboard(wxGlobalDisplay(), (Window
) GetMainWindow(),
330 ShiftMask
| LockMask
| ControlMask
| Mod1Mask
| Mod2Mask
| Mod3Mask
| Mod4Mask
| Mod5Mask
,
338 if (res
!= GrabSuccess
)
340 wxLogDebug("Failed to grab keyboard.");
341 XUngrabPointer(wxGlobalDisplay(), CurrentTime
);
342 XUngrabButton(wxGlobalDisplay(), AnyButton
, AnyModifier
,
343 (Window
) GetMainWindow());
347 m_winCaptured
= TRUE
;
351 void wxWindowX11
::DoReleaseMouse()
353 g_captureWindow
= NULL
;
354 if ( !m_winCaptured
)
357 Window wMain
= (Window
)GetMainWindow();
361 XUngrabPointer(wxGlobalDisplay(), wMain
);
362 XUngrabButton(wxGlobalDisplay(), AnyButton
, AnyModifier
,
364 XUngrabKeyboard(wxGlobalDisplay(), CurrentTime
);
367 m_winCaptured
= FALSE
;
370 bool wxWindowX11
::SetFont(const wxFont
& font
)
372 if ( !wxWindowBase
::SetFont(font
) )
381 bool wxWindowX11
::SetCursor(const wxCursor
& cursor
)
383 if ( !wxWindowBase
::SetCursor(cursor
) )
389 wxCursor
* cursor2
= NULL
;
391 cursor2
= & m_cursor
;
393 cursor2
= wxSTANDARD_CURSOR
;
395 WXDisplay
*dpy
= GetXDisplay();
396 WXCursor x_cursor
= cursor2
->GetXCursor(dpy
);
398 Window win
= (Window
) GetMainWindow();
399 XDefineCursor((Display
*) dpy
, win
, (Cursor
) x_cursor
);
404 // Coordinates relative to the window
405 void wxWindowX11
::WarpPointer (int x
, int y
)
408 XWarpPointer( wxGlobalDisplay(), None
, (Window
) m_mainWidget
, 0, 0, 0, 0, x
, y
);
411 // Does a physical scroll
412 void wxWindowX11
::ScrollWindow(int dx
, int dy
, const wxRect
*rect
)
417 // Use specified rectangle
418 x
= rect
->x
; y
= rect
->y
; w
= rect
->width
; h
= rect
->height
;
422 // Use whole client area
424 GetClientSize(& w
, & h
);
427 wxNode
*cnode
= m_children
.First();
430 wxWindow
*child
= (wxWindow
*) cnode
->Data();
433 child
->GetSize( &sx
, &sy
);
434 wxPoint
pos( child
->GetPosition() );
435 child
->SetSize( pos
.x
+ dx
, pos
.y
+ dy
, sx
, sy
, wxSIZE_ALLOW_MINUS_ONE
);
436 cnode
= cnode
->Next();
439 int x1
= (dx
>= 0) ? x
: x
- dx
;
440 int y1
= (dy
>= 0) ? y
: y
- dy
;
441 int w1
= w
- abs(dx
);
442 int h1
= h
- abs(dy
);
443 int x2
= (dx
>= 0) ? x
+ dx
: x
;
444 int y2
= (dy
>= 0) ? y
+ dy
: y
;
446 wxClientDC
dc((wxWindow
*) this);
448 dc
.SetLogicalFunction (wxCOPY
);
450 Window window
= (Window
) GetMainWindow();
451 Display
* display
= wxGlobalDisplay();
453 XCopyArea(display
, window
, window
, (GC
) dc
.GetGC(),
454 x1
, y1
, w1
, h1
, x2
, y2
);
456 dc
.SetAutoSetting(TRUE
);
457 wxBrush
brush(GetBackgroundColour(), wxSOLID
);
458 dc
.SetBrush(brush
); // FIXME: needed?
460 // We'll add rectangles to the list of update rectangles according to which
461 // bits we've exposed.
466 wxRect
*rect
= new wxRect
;
472 XFillRectangle(display
, window
,
473 (GC
) dc
.GetGC(), rect
->x
, rect
->y
, rect
->width
, rect
->height
);
477 rect
->width
= rect
->width
;
478 rect
->height
= rect
->height
;
480 updateRects
.Append((wxObject
*) rect
);
484 wxRect
*rect
= new wxRect
;
486 rect
->x
= x
+ w
+ dx
;
491 XFillRectangle(display
, window
,
492 (GC
) dc
.GetGC(), rect
->x
, rect
->y
, rect
->width
,
497 rect
->width
= rect
->width
;
498 rect
->height
= rect
->height
;
500 updateRects
.Append((wxObject
*) rect
);
504 wxRect
*rect
= new wxRect
;
511 XFillRectangle(display
, window
,
512 (GC
) dc
.GetGC(), rect
->x
, rect
->y
, rect
->width
, rect
->height
);
516 rect
->width
= rect
->width
;
517 rect
->height
= rect
->height
;
519 updateRects
.Append((wxObject
*) rect
);
523 wxRect
*rect
= new wxRect
;
526 rect
->y
= y
+ h
+ dy
;
530 XFillRectangle(display
, window
,
531 (GC
) dc
.GetGC(), rect
->x
, rect
->y
, rect
->width
, rect
->height
);
535 rect
->width
= rect
->width
;
536 rect
->height
= rect
->height
;
538 updateRects
.Append((wxObject
*) rect
);
540 dc
.SetBrush(wxNullBrush
);
542 // Now send expose events
544 wxNode
* node
= updateRects
.First();
547 wxRect
* rect
= (wxRect
*) node
->Data();
551 event
.display
= display
;
552 event
.send_event
= True
;
553 event
.window
= window
;
557 event
.width
= rect
->width
;
558 event
.height
= rect
->height
;
562 XSendEvent(display
, window
, False
, ExposureMask
, (XEvent
*)&event
);
568 // Delete the update rects
569 node
= updateRects
.First();
572 wxRect
* rect
= (wxRect
*) node
->Data();
579 // XmUpdateDisplay((Widget) GetMainWidget());
582 // ---------------------------------------------------------------------------
584 // ---------------------------------------------------------------------------
586 #if wxUSE_DRAG_AND_DROP
588 void wxWindowX11
::SetDropTarget(wxDropTarget
* WXUNUSED(pDropTarget
))
595 // Old style file-manager drag&drop
596 void wxWindowX11
::DragAcceptFiles(bool WXUNUSED(accept
))
601 // ----------------------------------------------------------------------------
603 // ----------------------------------------------------------------------------
607 void wxWindowX11
::DoSetToolTip(wxToolTip
* WXUNUSED(tooltip
))
612 #endif // wxUSE_TOOLTIPS
614 // ---------------------------------------------------------------------------
615 // moving and resizing
616 // ---------------------------------------------------------------------------
618 bool wxWindowX11
::PreResize()
624 void wxWindowX11
::DoGetSize(int *x
, int *y
) const
626 Window window
= (Window
) m_mainWidget
;
629 XWindowAttributes attr
;
630 Status status
= XGetWindowAttributes(wxGlobalDisplay(), window
, & attr
);
635 *x
= attr
.width
/* + 2*m_borderSize */ ;
636 *y
= attr
.height
/* + 2*m_borderSize */ ;
641 void wxWindowX11
::DoGetPosition(int *x
, int *y
) const
643 Window window
= (Window
) m_mainWidget
;
646 XWindowAttributes attr
;
647 Status status
= XGetWindowAttributes(wxGlobalDisplay(), window
, & attr
);
655 // We may be faking the client origin. So a window that's really at (0, 30)
656 // may appear (to wxWin apps) to be at (0, 0).
659 wxPoint
pt(GetParent()->GetClientAreaOrigin());
667 void wxWindowX11
::DoScreenToClient(int *x
, int *y
) const
669 Display
*display
= wxGlobalDisplay();
670 Window rootWindow
= RootWindowOfScreen(DefaultScreenOfDisplay(display
));
671 Window thisWindow
= (Window
) m_mainWidget
;
676 XTranslateCoordinates(display
, rootWindow
, thisWindow
, xx
, yy
, x
, y
, &childWindow
);
679 void wxWindowX11
::DoClientToScreen(int *x
, int *y
) const
681 Display
*display
= wxGlobalDisplay();
682 Window rootWindow
= RootWindowOfScreen(DefaultScreenOfDisplay(display
));
683 Window thisWindow
= (Window
) m_mainWidget
;
688 XTranslateCoordinates(display
, thisWindow
, rootWindow
, xx
, yy
, x
, y
, &childWindow
);
692 // Get size *available for subwindows* i.e. excluding menu bar etc.
693 void wxWindowX11
::DoGetClientSize(int *x
, int *y
) const
695 Window window
= (Window
) m_mainWidget
;
699 XWindowAttributes attr
;
700 Status status
= XGetWindowAttributes(wxGlobalDisplay(), window
, & attr
);
711 void wxWindowX11
::DoSetSize(int x
, int y
, int width
, int height
, int sizeFlags
)
713 if (!GetMainWindow())
716 XWindowChanges windowChanges
;
719 if (x
!= -1 || (sizeFlags
& wxSIZE_ALLOW_MINUS_ONE
))
724 if (y
!= -1 || (sizeFlags
& wxSIZE_ALLOW_MINUS_ONE
))
729 if (width
!= -1 || (sizeFlags
& wxSIZE_ALLOW_MINUS_ONE
))
731 windowChanges
.width
= width
/* - m_borderSize*2 */;
732 valueMask
|= CWWidth
;
734 if (height
!= -1 || (sizeFlags
& wxSIZE_ALLOW_MINUS_ONE
))
736 windowChanges
.height
= height
/* -m_borderSize*2*/;
737 valueMask
|= CWHeight
;
739 AdjustForParentClientOrigin( x
, y
, sizeFlags
);
741 XConfigureWindow(wxGlobalDisplay(), (Window
) GetMainWindow(),
742 valueMask
, & windowChanges
);
745 void wxWindowX11
::DoSetClientSize(int width
, int height
)
747 if (!GetMainWindow())
750 XWindowChanges windowChanges
;
755 windowChanges
.width
= width
;
756 valueMask
|= CWWidth
;
760 windowChanges
.height
= height
;
761 valueMask
|= CWHeight
;
763 XConfigureWindow(wxGlobalDisplay(), (Window
) GetMainWindow(),
764 valueMask
, & windowChanges
);
767 // For implementation purposes - sometimes decorations make the client area
769 wxPoint wxWindowX11
::GetClientAreaOrigin() const
771 return wxPoint(0, 0);
774 // Makes an adjustment to the window position (for example, a frame that has
775 // a toolbar that it manages itself).
776 void wxWindowX11
::AdjustForParentClientOrigin(int& x
, int& y
, int sizeFlags
)
778 if (((sizeFlags
& wxSIZE_NO_ADJUSTMENTS
) == 0) && GetParent())
780 wxPoint
pt(GetParent()->GetClientAreaOrigin());
781 x
+= pt
.x
; y
+= pt
.y
;
785 void wxWindowX11
::SetSizeHints(int minW
, int minH
, int maxW
, int maxH
, int incW
, int incH
)
792 XSizeHints sizeHints
;
795 if (minW
> -1 && minH
> -1)
797 sizeHints
.flags
|= PMinSize
;
798 sizeHints
.min_width
= minW
;
799 sizeHints
.min_height
= minH
;
801 if (maxW
> -1 && maxH
> -1)
803 sizeHints
.flags
|= PMaxSize
;
804 sizeHints
.max_width
= maxW
;
805 sizeHints
.max_height
= maxH
;
807 if (incW
> -1 && incH
> -1)
809 sizeHints
.flags
|= PResizeInc
;
810 sizeHints
.width_inc
= incW
;
811 sizeHints
.height_inc
= incH
;
814 XSetWMNormalHints(wxGlobalDisplay(), (Window
) GetMainWindow(), & sizeHints
);
817 void wxWindowX11
::DoMoveWindow(int x
, int y
, int width
, int height
)
819 DoSetSize(x
, y
, width
, height
);
822 // ---------------------------------------------------------------------------
824 // ---------------------------------------------------------------------------
826 int wxWindowX11
::GetCharHeight() const
828 wxCHECK_MSG( m_font
.Ok(), 0, "valid window font needed" );
830 WXFontStructPtr pFontStruct
= m_font
.GetFontStruct(1.0, GetXDisplay());
832 int direction
, ascent
, descent
;
834 XTextExtents ((XFontStruct
*) pFontStruct
, "x", 1, &direction
, &ascent
,
837 // return (overall.ascent + overall.descent);
838 return (ascent
+ descent
);
841 int wxWindowX11
::GetCharWidth() const
843 wxCHECK_MSG( m_font
.Ok(), 0, "valid window font needed" );
845 WXFontStructPtr pFontStruct
= m_font
.GetFontStruct(1.0, GetXDisplay());
847 int direction
, ascent
, descent
;
849 XTextExtents ((XFontStruct
*) pFontStruct
, "x", 1, &direction
, &ascent
,
852 return overall
.width
;
855 void wxWindowX11
::GetTextExtent(const wxString
& string
,
857 int *descent
, int *externalLeading
,
858 const wxFont
*theFont
) const
860 wxFont
*fontToUse
= (wxFont
*)theFont
;
862 fontToUse
= (wxFont
*) & m_font
;
864 wxCHECK_RET( fontToUse
->Ok(), "valid window font needed" );
866 WXFontStructPtr pFontStruct
= theFont
->GetFontStruct(1.0, GetXDisplay());
868 int direction
, ascent
, descent2
;
870 int slen
= string
.Len();
874 XTextExtents16((XFontStruct
*) pFontStruct
, (XChar2b
*) (char*) (const char*) string
, slen
, &direction
,
875 &ascent
, &descent2
, &overall
);
878 XTextExtents((XFontStruct
*) pFontStruct
, string
, slen
,
879 &direction
, &ascent
, &descent2
, &overall
);
882 *x
= (overall
.width
);
884 *y
= (ascent
+ descent2
);
888 *externalLeading
= 0;
892 // ----------------------------------------------------------------------------
894 // ----------------------------------------------------------------------------
896 void wxWindowX11
::Refresh(bool eraseBack
, const wxRect
*rect
)
902 // Schedule for later Updating in ::Update() or ::OnInternalIdle().
903 m_clearRegion
.Union( rect
->x
, rect
->y
, rect
->width
, rect
->height
);
908 GetSize( &width
, &height
);
910 // Schedule for later Updating in ::Update() or ::OnInternalIdle().
911 m_clearRegion
.Clear();
912 m_clearRegion
.Union( 0, 0, width
, height
);
918 // Schedule for later Updating in ::Update() or ::OnInternalIdle().
919 m_updateRegion
.Union( rect
->x
, rect
->y
, rect
->width
, rect
->height
);
924 GetSize( &width
, &height
);
926 // Schedule for later Updating in ::Update() or ::OnInternalIdle().
927 m_updateRegion
.Clear();
928 m_updateRegion
.Union( 0, 0, width
, height
);
931 // Actually don't schedule yet..
935 void wxWindowX11
::Update()
937 if (!m_updateRegion
.IsEmpty())
939 X11SendPaintEvents();
943 void wxWindowX11
::Clear()
945 wxClientDC
dc((wxWindow
*) this);
946 wxBrush
brush(GetBackgroundColour(), wxSOLID
);
947 dc
.SetBackground(brush
);
951 void wxWindowX11
::X11SendPaintEvents()
953 m_clipPaintRegion
= TRUE
;
955 if (!m_clearRegion
.IsEmpty())
957 wxWindowDC
dc( (wxWindow
*)this );
958 dc
.SetClippingRegion( m_clearRegion
);
960 wxEraseEvent
erase_event( GetId(), &dc
);
961 erase_event
.SetEventObject( this );
963 if (!GetEventHandler()->ProcessEvent(erase_event
))
965 wxRegionIterator
upd( m_clearRegion
);
968 // XClearArea( ... , upd.GetX(), upd.GetY(), upd.GetWidth(), upd.GetHeight() );
972 m_clearRegion
.Clear();
975 wxNcPaintEvent
nc_paint_event( GetId() );
976 nc_paint_event
.SetEventObject( this );
977 GetEventHandler()->ProcessEvent( nc_paint_event
);
979 wxPaintEvent
paint_event( GetId() );
980 paint_event
.SetEventObject( this );
981 GetEventHandler()->ProcessEvent( paint_event
);
983 m_clipPaintRegion
= FALSE
;
986 // ----------------------------------------------------------------------------
988 // ----------------------------------------------------------------------------
990 // Responds to colour changes: passes event on to children.
991 void wxWindowX11
::OnSysColourChanged(wxSysColourChangedEvent
& event
)
993 wxWindowList
::Node
*node
= GetChildren().GetFirst();
996 // Only propagate to non-top-level windows
997 wxWindow
*win
= node
->GetData();
998 if ( win
->GetParent() )
1000 wxSysColourChangedEvent event2
;
1001 event
.m_eventObject
= win
;
1002 win
->GetEventHandler()->ProcessEvent(event2
);
1005 node
= node
->GetNext();
1009 void wxWindowX11
::OnIdle(wxIdleEvent
& WXUNUSED(event
))
1011 // This calls the UI-update mechanism (querying windows for
1012 // menu/toolbar/control state information)
1016 // ----------------------------------------------------------------------------
1017 // function which maintain the global hash table mapping Widgets to wxWindows
1018 // ----------------------------------------------------------------------------
1020 bool wxAddWindowToTable(Window w
, wxWindow
*win
)
1022 wxWindow
*oldItem
= NULL
;
1023 if ((oldItem
= (wxWindow
*)wxWidgetHashTable
->Get ((long) w
)))
1025 wxLogDebug("Widget table clash: new widget is %ld, %s",
1026 (long)w
, win
->GetClassInfo()->GetClassName());
1030 wxWidgetHashTable
->Put((long) w
, win
);
1032 wxLogTrace("widget", "XWindow 0x%08x <-> window %p (%s)",
1033 w
, win
, win
->GetClassInfo()->GetClassName());
1038 wxWindow
*wxGetWindowFromTable(Window w
)
1040 return (wxWindow
*)wxWidgetHashTable
->Get((long) w
);
1043 void wxDeleteWindowFromTable(Window w
)
1045 wxWidgetHashTable
->Delete((long)w
);
1048 // ----------------------------------------------------------------------------
1049 // add/remove window from the table
1050 // ----------------------------------------------------------------------------
1052 // ----------------------------------------------------------------------------
1053 // X11-specific accessors
1054 // ----------------------------------------------------------------------------
1056 // Get the underlying X window
1057 WXWindow wxWindowX11
::GetXWindow() const
1059 return GetMainWindow();
1062 // Get the underlying X display
1063 WXDisplay
*wxWindowX11
::GetXDisplay() const
1065 return wxGetDisplay();
1068 WXWindow wxWindowX11
::GetMainWindow() const
1070 return m_mainWidget
;
1073 // ----------------------------------------------------------------------------
1074 // TranslateXXXEvent() functions
1075 // ----------------------------------------------------------------------------
1077 bool wxTranslateMouseEvent(wxMouseEvent
& wxevent
, wxWindow
*win
, Window window
, XEvent
*xevent
)
1079 switch (xevent
->xany
.type
)
1087 wxEventType eventType
= wxEVT_NULL
;
1089 if (xevent
->xany
.type
== EnterNotify
)
1091 //if (local_event.xcrossing.mode!=NotifyNormal)
1092 // return ; // Ignore grab events
1093 eventType
= wxEVT_ENTER_WINDOW
;
1094 // canvas->GetEventHandler()->OnSetFocus();
1096 else if (xevent
->xany
.type
== LeaveNotify
)
1098 //if (local_event.xcrossingr.mode!=NotifyNormal)
1099 // return ; // Ignore grab events
1100 eventType
= wxEVT_LEAVE_WINDOW
;
1101 // canvas->GetEventHandler()->OnKillFocus();
1103 else if (xevent
->xany
.type
== MotionNotify
)
1105 eventType
= wxEVT_MOTION
;
1107 else if (xevent
->xany
.type
== ButtonPress
)
1109 wxevent
.SetTimestamp(xevent
->xbutton
.time
);
1111 if (xevent
->xbutton
.button
== Button1
)
1113 eventType
= wxEVT_LEFT_DOWN
;
1116 else if (xevent
->xbutton
.button
== Button2
)
1118 eventType
= wxEVT_MIDDLE_DOWN
;
1121 else if (xevent
->xbutton
.button
== Button3
)
1123 eventType
= wxEVT_RIGHT_DOWN
;
1127 // check for a double click
1128 // TODO: where can we get this value from?
1129 //long dclickTime = XtGetMultiClickTime(wxGlobalDisplay());
1130 long dclickTime
= 200;
1131 long ts
= wxevent
.GetTimestamp();
1133 int buttonLast
= win
->GetLastClickedButton();
1134 long lastTS
= win
->GetLastClickTime();
1135 if ( buttonLast
&& buttonLast
== button
&& (ts
- lastTS
) < dclickTime
)
1138 win
->SetLastClick(0, ts
);
1139 if ( eventType
== wxEVT_LEFT_DOWN
)
1140 eventType
= wxEVT_LEFT_DCLICK
;
1141 else if ( eventType
== wxEVT_MIDDLE_DOWN
)
1142 eventType
= wxEVT_MIDDLE_DCLICK
;
1143 else if ( eventType
== wxEVT_RIGHT_DOWN
)
1144 eventType
= wxEVT_RIGHT_DCLICK
;
1148 // not fast enough or different button
1149 win
->SetLastClick(button
, ts
);
1152 else if (xevent
->xany
.type
== ButtonRelease
)
1154 if (xevent
->xbutton
.button
== Button1
)
1156 eventType
= wxEVT_LEFT_UP
;
1158 else if (xevent
->xbutton
.button
== Button2
)
1160 eventType
= wxEVT_MIDDLE_UP
;
1162 else if (xevent
->xbutton
.button
== Button3
)
1164 eventType
= wxEVT_RIGHT_UP
;
1173 wxevent
.SetEventType(eventType
);
1175 wxevent
.m_x
= xevent
->xbutton
.x
;
1176 wxevent
.m_y
= xevent
->xbutton
.y
;
1178 wxevent
.m_leftDown
= ((eventType
== wxEVT_LEFT_DOWN
)
1179 || (event_left_is_down (xevent
)
1180 && (eventType
!= wxEVT_LEFT_UP
)));
1181 wxevent
.m_middleDown
= ((eventType
== wxEVT_MIDDLE_DOWN
)
1182 || (event_middle_is_down (xevent
)
1183 && (eventType
!= wxEVT_MIDDLE_UP
)));
1184 wxevent
.m_rightDown
= ((eventType
== wxEVT_RIGHT_DOWN
)
1185 || (event_right_is_down (xevent
)
1186 && (eventType
!= wxEVT_RIGHT_UP
)));
1188 wxevent
.m_shiftDown
= xevent
->xbutton
.state
& ShiftMask
;
1189 wxevent
.m_controlDown
= xevent
->xbutton
.state
& ControlMask
;
1190 wxevent
.m_altDown
= xevent
->xbutton
.state
& Mod3Mask
;
1191 wxevent
.m_metaDown
= xevent
->xbutton
.state
& Mod1Mask
;
1193 wxevent
.SetId(win
->GetId());
1194 wxevent
.SetEventObject(win
);
1202 bool wxTranslateKeyEvent(wxKeyEvent
& wxevent
, wxWindow
*win
, Window
WXUNUSED(win
), XEvent
*xevent
)
1204 switch (xevent
->xany
.type
)
1212 (void) XLookupString ((XKeyEvent
*) xevent
, buf
, 20, &keySym
, NULL
);
1213 int id
= wxCharCodeXToWX (keySym
);
1215 if (xevent
->xkey
.state
& ShiftMask
)
1216 wxevent
.m_shiftDown
= TRUE
;
1217 if (xevent
->xkey
.state
& ControlMask
)
1218 wxevent
.m_controlDown
= TRUE
;
1219 if (xevent
->xkey
.state
& Mod3Mask
)
1220 wxevent
.m_altDown
= TRUE
;
1221 if (xevent
->xkey
.state
& Mod1Mask
)
1222 wxevent
.m_metaDown
= TRUE
;
1223 wxevent
.SetEventObject(win
);
1224 wxevent
.m_keyCode
= id
;
1225 wxevent
.SetTimestamp(xevent
->xkey
.time
);
1227 wxevent
.m_x
= xevent
->xbutton
.x
;
1228 wxevent
.m_y
= xevent
->xbutton
.y
;
1242 // ----------------------------------------------------------------------------
1244 // ----------------------------------------------------------------------------
1248 #define YAllocColor XAllocColor
1249 XColor g_itemColors
[5];
1250 int wxComputeColours (Display
*display
, wxColour
* back
, wxColour
* fore
)
1253 static XmColorProc colorProc
;
1255 result
= wxNO_COLORS
;
1259 g_itemColors
[0].red
= (((long) back
->Red ()) << 8);
1260 g_itemColors
[0].green
= (((long) back
->Green ()) << 8);
1261 g_itemColors
[0].blue
= (((long) back
->Blue ()) << 8);
1262 g_itemColors
[0].flags
= DoRed
| DoGreen
| DoBlue
;
1263 if (colorProc
== (XmColorProc
) NULL
)
1265 // Get a ptr to the actual function
1266 colorProc
= XmSetColorCalculation ((XmColorProc
) NULL
);
1267 // And set it back to motif.
1268 XmSetColorCalculation (colorProc
);
1270 (*colorProc
) (&g_itemColors
[wxBACK_INDEX
],
1271 &g_itemColors
[wxFORE_INDEX
],
1272 &g_itemColors
[wxSELE_INDEX
],
1273 &g_itemColors
[wxTOPS_INDEX
],
1274 &g_itemColors
[wxBOTS_INDEX
]);
1275 result
= wxBACK_COLORS
;
1279 g_itemColors
[wxFORE_INDEX
].red
= (((long) fore
->Red ()) << 8);
1280 g_itemColors
[wxFORE_INDEX
].green
= (((long) fore
->Green ()) << 8);
1281 g_itemColors
[wxFORE_INDEX
].blue
= (((long) fore
->Blue ()) << 8);
1282 g_itemColors
[wxFORE_INDEX
].flags
= DoRed
| DoGreen
| DoBlue
;
1283 if (result
== wxNO_COLORS
)
1284 result
= wxFORE_COLORS
;
1287 Display
*dpy
= display
;
1288 Colormap cmap
= (Colormap
) wxTheApp
->GetMainColormap((WXDisplay
*) dpy
);
1292 /* 5 Colours to allocate */
1293 for (int i
= 0; i
< 5; i
++)
1294 if (!YAllocColor (dpy
, cmap
, &g_itemColors
[i
]))
1295 result
= wxNO_COLORS
;
1299 /* Only 1 colour to allocate */
1300 if (!YAllocColor (dpy
, cmap
, &g_itemColors
[wxFORE_INDEX
]))
1301 result
= wxNO_COLORS
;
1309 bool wxWindowX11
::SetBackgroundColour(const wxColour
& col
)
1311 if ( !wxWindowBase
::SetBackgroundColour(col
) )
1314 if (!GetMainWindow())
1317 wxColour
colour( col
);
1318 XSetWindowAttributes attrib
;
1319 attrib
.background_pixel
= colour
.AllocColour(wxGlobalDisplay());
1321 XChangeWindowAttributes(wxGlobalDisplay(),
1322 (Window
) GetMainWindow(),
1329 bool wxWindowX11
::SetForegroundColour(const wxColour
& col
)
1331 if ( !wxWindowBase
::SetForegroundColour(col
) )
1337 // ----------------------------------------------------------------------------
1339 // ----------------------------------------------------------------------------
1341 wxWindow
*wxGetActiveWindow()
1344 wxFAIL_MSG("Not implemented");
1349 wxWindow
*wxWindowBase
::GetCapture()
1351 return (wxWindow
*)g_captureWindow
;
1355 // Find the wxWindow at the current mouse position, returning the mouse
1357 wxWindow
* wxFindWindowAtPointer(wxPoint
& pt
)
1359 return wxFindWindowAtPoint(wxGetMousePosition());
1362 // Get the current mouse position.
1363 wxPoint
wxGetMousePosition()
1365 Display
*display
= wxGlobalDisplay();
1366 Window rootWindow
= RootWindowOfScreen (DefaultScreenOfDisplay(display
));
1367 Window rootReturn
, childReturn
;
1368 int rootX
, rootY
, winX
, winY
;
1369 unsigned int maskReturn
;
1371 XQueryPointer (display
,
1375 &rootX
, &rootY
, &winX
, &winY
, &maskReturn
);
1376 return wxPoint(rootX
, rootY
);
1380 // ----------------------------------------------------------------------------
1381 // wxNoOptimize: switch off size optimization
1382 // ----------------------------------------------------------------------------
1384 int wxNoOptimize
::ms_count
= 0;