Implemented two-window approach for wxX11.
[wxWidgets.git] / src / x11 / window.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: windows.cpp
3 // Purpose: wxWindow
4 // Author: Julian Smart
5 // Modified by:
6 // Created: 17/09/98
7 // RCS-ID: $Id$
8 // Copyright: (c) Julian Smart
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
11
12 // ============================================================================
13 // declarations
14 // ============================================================================
15
16 // ----------------------------------------------------------------------------
17 // headers
18 // ----------------------------------------------------------------------------
19
20 #ifdef __GNUG__
21 #pragma implementation "window.h"
22 #endif
23
24 #include "wx/setup.h"
25 #include "wx/menu.h"
26 #include "wx/dc.h"
27 #include "wx/dcclient.h"
28 #include "wx/utils.h"
29 #include "wx/app.h"
30 #include "wx/panel.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"
37 #include "wx/frame.h"
38 #include "wx/scrolwin.h"
39 #include "wx/scrolbar.h"
40 #include "wx/module.h"
41 #include "wx/menuitem.h"
42 #include "wx/log.h"
43
44 #if wxUSE_DRAG_AND_DROP
45 #include "wx/dnd.h"
46 #endif
47
48 #include "wx/x11/private.h"
49 #include "X11/Xutil.h"
50
51 #if wxUSE_NANOX
52 // For wxGetLocalTime, used by XButtonEventGetTime
53 #include "wx/timer.h"
54 #endif
55
56 #include <string.h>
57
58 // ----------------------------------------------------------------------------
59 // global variables for this module
60 // ----------------------------------------------------------------------------
61
62 extern wxHashTable *wxWidgetHashTable;
63 extern wxHashTable *wxClientWidgetHashTable;
64 static wxWindow* g_captureWindow = NULL;
65
66 // ----------------------------------------------------------------------------
67 // macros
68 // ----------------------------------------------------------------------------
69
70 #define event_left_is_down(x) ((x)->xbutton.state & Button1Mask)
71 #define event_middle_is_down(x) ((x)->xbutton.state & Button2Mask)
72 #define event_right_is_down(x) ((x)->xbutton.state & Button3Mask)
73
74 // ----------------------------------------------------------------------------
75 // event tables
76 // ----------------------------------------------------------------------------
77
78 IMPLEMENT_ABSTRACT_CLASS(wxWindowX11, wxWindowBase)
79
80 BEGIN_EVENT_TABLE(wxWindowX11, wxWindowBase)
81 EVT_SYS_COLOUR_CHANGED(wxWindowX11::OnSysColourChanged)
82 END_EVENT_TABLE()
83
84 // ============================================================================
85 // implementation
86 // ============================================================================
87
88 // ----------------------------------------------------------------------------
89 // helper functions
90 // ----------------------------------------------------------------------------
91
92 // ----------------------------------------------------------------------------
93 // constructors
94 // ----------------------------------------------------------------------------
95
96 void wxWindowX11::Init()
97 {
98 // generic initializations first
99 InitBase();
100
101 // X11-specific
102 m_mainWindow = (WXWindow) 0;
103 m_clientWindow = (WXWindow) 0;
104 m_insertIntoMain = FALSE;
105
106 m_winCaptured = FALSE;
107 m_needsInputFocus = FALSE;
108 m_isShown = TRUE;
109 m_isBeingDeleted = FALSE;
110 m_lastTS = 0;
111 m_lastButton = 0;
112 }
113
114 // real construction (Init() must have been called before!)
115 bool wxWindowX11::Create(wxWindow *parent, wxWindowID id,
116 const wxPoint& pos,
117 const wxSize& size,
118 long style,
119 const wxString& name)
120 {
121 wxCHECK_MSG( parent, FALSE, "can't create wxWindow without parent" );
122
123 CreateBase(parent, id, pos, size, style, wxDefaultValidator, name);
124
125 parent->AddChild(this);
126
127 int w = size.GetWidth();
128 int h = size.GetHeight();
129 int x = size.GetX();
130 int y = size.GetY();
131 if (w == -1) w = 20;
132 if (h == -1) h = 20;
133 if (x == -1) x = 0;
134 if (y == -1) y = 0;
135
136 Display *xdisplay = (Display*) wxGlobalDisplay();
137 int xscreen = DefaultScreen( xdisplay );
138 Visual *xvisual = DefaultVisual( xdisplay, xscreen );
139 Colormap cm = DefaultColormap( xdisplay, xscreen );
140
141 m_backgroundColour = wxSystemSettings::GetColour(wxSYS_COLOUR_3DFACE);
142 m_backgroundColour.CalcPixel( (WXColormap) cm );
143
144 m_foregroundColour = *wxBLACK;
145 m_foregroundColour.CalcPixel( (WXColormap) cm );
146
147 Window xparent = (Window) parent->GetClientWindow();
148
149 // Add window's own scrollbars to main window, not to client window
150 if (parent->GetInsertIntoMain())
151 {
152 // wxLogDebug( "Inserted into main: %s", GetName().c_str() );
153 xparent = (Window) parent->GetMainWindow();
154 }
155
156 wxSize size2(size);
157 if (size2.x == -1)
158 size2.x = 20;
159 if (size2.y == -1)
160 size2.y = 20;
161
162 wxPoint pos2(pos);
163 if (pos2.x == -1)
164 pos2.x = 0;
165 if (pos2.y == -1)
166 pos2.y = 0;
167
168 #if !wxUSE_NANOX
169
170 #if wxUSE_TWO_WINDOWS
171 bool need_two_windows =
172 ((( wxSUNKEN_BORDER | wxRAISED_BORDER | wxSIMPLE_BORDER | wxHSCROLL | wxVSCROLL ) & m_windowStyle) != 0);
173 #else
174 bool need_two_windows = FALSE;
175 #endif
176
177 XSetWindowAttributes xattributes;
178 long xattributes_mask = 0;
179
180 xattributes_mask |= CWBackPixel;
181 xattributes.background_pixel = m_backgroundColour.GetPixel();
182
183 xattributes_mask |= CWBorderPixel;
184 xattributes.border_pixel = BlackPixel( xdisplay, xscreen );
185
186 xattributes_mask |= CWEventMask;
187
188 if (need_two_windows)
189 {
190 xattributes.event_mask =
191 ExposureMask | StructureNotifyMask | ColormapChangeMask;
192
193 Window xwindow = XCreateWindow( xdisplay, xparent, pos2.x, pos2.y, size2.x, size2.y,
194 0, DefaultDepth(xdisplay,xscreen), InputOutput, xvisual, xattributes_mask, &xattributes );
195
196 XSetWindowBackgroundPixmap( xdisplay, xwindow, None );
197
198 m_mainWindow = (WXWindow) xwindow;
199 wxAddWindowToTable( xwindow, (wxWindow*) this );
200
201 XMapWindow( xdisplay, xwindow );
202
203 xattributes.event_mask =
204 ExposureMask | KeyPressMask | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask |
205 ButtonMotionMask | EnterWindowMask | LeaveWindowMask | PointerMotionMask |
206 KeymapStateMask | FocusChangeMask | ColormapChangeMask | StructureNotifyMask |
207 PropertyChangeMask | VisibilityChangeMask ;
208
209 if (HasFlag( wxNO_FULL_REPAINT_ON_RESIZE ))
210 {
211 xattributes_mask |= CWBitGravity;
212 xattributes.bit_gravity = StaticGravity;
213 }
214
215 xwindow = XCreateWindow( xdisplay, xwindow, 0, 0, size2.x, size2.y,
216 0, DefaultDepth(xdisplay,xscreen), InputOutput, xvisual, xattributes_mask, &xattributes );
217
218 XSetWindowBackgroundPixmap( xdisplay, xwindow, None );
219
220 m_clientWindow = (WXWindow) xwindow;
221 wxAddClientWindowToTable( xwindow, (wxWindow*) this );
222
223 XMapWindow( xdisplay, xwindow );
224 }
225 else
226 {
227 // wxLogDebug( "No two windows needed %s", GetName().c_str() );
228
229 xattributes.event_mask =
230 ExposureMask | KeyPressMask | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask |
231 ButtonMotionMask | EnterWindowMask | LeaveWindowMask | PointerMotionMask |
232 KeymapStateMask | FocusChangeMask | ColormapChangeMask | StructureNotifyMask |
233 PropertyChangeMask | VisibilityChangeMask ;
234
235 if (HasFlag( wxNO_FULL_REPAINT_ON_RESIZE ))
236 {
237 xattributes_mask |= CWBitGravity;
238 xattributes.bit_gravity = StaticGravity;
239 }
240
241 Window xwindow = XCreateWindow( xdisplay, xparent, pos2.x, pos2.y, size2.x, size2.y,
242 0, DefaultDepth(xdisplay,xscreen), InputOutput, xvisual, xattributes_mask, &xattributes );
243
244 XSetWindowBackgroundPixmap( xdisplay, xwindow, None );
245
246 m_mainWindow = (WXWindow) xwindow;
247 m_clientWindow = m_mainWindow;
248 wxAddWindowToTable( xwindow, (wxWindow*) this );
249
250 XMapWindow( xdisplay, xwindow );
251 }
252 #else
253
254 int extraFlags = GR_EVENT_MASK_CLOSE_REQ;
255
256 long backColor, foreColor;
257 backColor = GR_RGB(m_backgroundColour.Red(), m_backgroundColour.Green(), m_backgroundColour.Blue());
258 foreColor = GR_RGB(m_foregroundColour.Red(), m_foregroundColour.Green(), m_foregroundColour.Blue());
259
260 Window xwindow = XCreateWindowWithColor( xdisplay, xparent, pos2.x, pos2.y, size2.x, size2.y,
261 0, 0, InputOutput, xvisual, backColor, foreColor);
262 XSelectInput( xdisplay, xwindow,
263 extraFlags | ExposureMask | KeyPressMask | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask |
264 ButtonMotionMask | EnterWindowMask | LeaveWindowMask | PointerMotionMask |
265 KeymapStateMask | FocusChangeMask | ColormapChangeMask | StructureNotifyMask |
266 PropertyChangeMask );
267
268 XSetWindowBackgroundPixmap( xdisplay, xwindow, None );
269
270 m_mainWindow = (WXWindow) xwindow;
271 wxAddWindowToTable( xwindow, (wxWindow*) this );
272
273 XMapWindow( xdisplay, xwindow );
274 #endif
275
276 // Is a subwindow, so map immediately
277 m_isShown = TRUE;
278
279 // Without this, the cursor may not be restored properly (e.g. in splitter
280 // sample).
281 SetCursor(*wxSTANDARD_CURSOR);
282 SetFont(wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT));
283
284 // Don't call this, it can have nasty repercussions for composite controls,
285 // for example
286 // SetSize(pos.x, pos.y, size.x, size.y);
287
288 return TRUE;
289 }
290
291 // Destructor
292 wxWindowX11::~wxWindowX11()
293 {
294 if (g_captureWindow == this)
295 g_captureWindow = NULL;
296
297 m_isBeingDeleted = TRUE;
298
299 if (m_parent)
300 m_parent->RemoveChild( this );
301
302 DestroyChildren();
303
304 if (m_clientWindow != m_mainWindow)
305 {
306 // Destroy the cleint window
307 Window xwindow = (Window) m_clientWindow;
308 wxDeleteClientWindowFromTable( xwindow );
309 XDestroyWindow( wxGlobalDisplay(), xwindow );
310 m_clientWindow = NULL;
311 }
312
313 // Destroy the window
314 Window xwindow = (Window) m_mainWindow;
315 wxDeleteWindowFromTable( xwindow );
316 XDestroyWindow( wxGlobalDisplay(), xwindow );
317 m_mainWindow = NULL;
318 }
319
320 // ---------------------------------------------------------------------------
321 // basic operations
322 // ---------------------------------------------------------------------------
323
324 void wxWindowX11::SetFocus()
325 {
326 Window xwindow = (Window) m_clientWindow;
327
328 wxCHECK_RET( xwindow, wxT("invalid window") );
329
330 wxCHECK_RET( AcceptsFocus(), wxT("set focus on window that doesn't accept the focus") );
331
332 #if 0
333 if (GetName() == "scrollBar")
334 {
335 char *crash = NULL;
336 *crash = 0;
337 }
338 #endif
339
340 if (wxWindowIsVisible(xwindow))
341 {
342 XSetInputFocus( wxGlobalDisplay(), xwindow, RevertToParent, CurrentTime );
343 m_needsInputFocus = FALSE;
344 }
345 else
346 {
347 m_needsInputFocus = TRUE;
348 }
349 }
350
351 // Get the window with the focus
352 wxWindow *wxWindowBase::FindFocus()
353 {
354 Window xfocus = (Window) 0;
355 int revert = 0;
356
357 XGetInputFocus( wxGlobalDisplay(), &xfocus, &revert);
358 if (xfocus)
359 {
360 wxWindow *win = wxGetWindowFromTable( xfocus );
361
362 return win;
363 }
364
365 return NULL;
366 }
367
368 // Enabling/disabling handled by event loop, and not sending events
369 // if disabled.
370 bool wxWindowX11::Enable(bool enable)
371 {
372 if ( !wxWindowBase::Enable(enable) )
373 return FALSE;
374
375 return TRUE;
376 }
377
378 bool wxWindowX11::Show(bool show)
379 {
380 wxWindowBase::Show(show);
381
382 Window xwindow = (Window) m_mainWindow;
383 Display *xdisp = wxGlobalDisplay();
384 if (show)
385 {
386 // wxLogDebug( "Mapping window of type %s", GetName().c_str() );
387 XMapWindow(xdisp, xwindow);
388 }
389 else
390 {
391 // wxLogDebug( "Unmapping window of type %s", GetName().c_str() );
392 XUnmapWindow(xdisp, xwindow);
393 }
394
395 return TRUE;
396 }
397
398 // Raise the window to the top of the Z order
399 void wxWindowX11::Raise()
400 {
401 if (m_mainWindow)
402 XRaiseWindow( wxGlobalDisplay(), (Window) m_mainWindow );
403 }
404
405 // Lower the window to the bottom of the Z order
406 void wxWindowX11::Lower()
407 {
408 if (m_mainWindow)
409 XLowerWindow( wxGlobalDisplay(), (Window) m_mainWindow );
410 }
411
412 void wxWindowX11::DoCaptureMouse()
413 {
414 if ((g_captureWindow != NULL) && (g_captureWindow != this))
415 {
416 wxASSERT_MSG(FALSE, "Trying to capture before mouse released.");
417
418 // Core dump now
419 int *tmp = NULL;
420 (*tmp) = 1;
421 return;
422 }
423
424 if (m_winCaptured)
425 return;
426
427 Window xwindow = (Window) m_clientWindow;
428
429 wxCHECK_RET( xwindow, wxT("invalid window") );
430
431 g_captureWindow = (wxWindow*) this;
432
433 if (xwindow)
434 {
435 int res = XGrabPointer(wxGlobalDisplay(), xwindow,
436 FALSE,
437 ButtonPressMask | ButtonReleaseMask | ButtonMotionMask | EnterWindowMask | LeaveWindowMask | PointerMotionMask,
438 GrabModeAsync,
439 GrabModeAsync,
440 None,
441 None, /* cursor */ // TODO: This may need to be set to the cursor of this window
442 CurrentTime );
443
444 if (res != GrabSuccess)
445 {
446 wxString msg;
447 msg.Printf("Failed to grab pointer for window %s", this->GetClassInfo()->GetClassName());
448 wxLogDebug(msg);
449 if (res == GrabNotViewable)
450 {
451 wxLogDebug("This is not a viewable window - perhaps not shown yet?");
452 }
453 g_captureWindow = NULL;
454 return;
455 }
456
457 m_winCaptured = TRUE;
458 }
459 }
460
461 void wxWindowX11::DoReleaseMouse()
462 {
463 g_captureWindow = NULL;
464
465 if ( !m_winCaptured )
466 return;
467
468 Window xwindow = (Window) m_clientWindow;
469
470 if (xwindow)
471 {
472 XUngrabPointer( wxGlobalDisplay(), CurrentTime );
473 }
474
475 // wxLogDebug( "Ungrabbed pointer in %s", GetName().c_str() );
476
477 m_winCaptured = FALSE;
478 }
479
480 bool wxWindowX11::SetFont(const wxFont& font)
481 {
482 if ( !wxWindowBase::SetFont(font) )
483 {
484 // nothing to do
485 return FALSE;
486 }
487
488 return TRUE;
489 }
490
491 bool wxWindowX11::SetCursor(const wxCursor& cursor)
492 {
493 if ( !wxWindowBase::SetCursor(cursor) )
494 {
495 // no change
496 return FALSE;
497 }
498
499 Window xwindow = (Window) m_clientWindow;
500
501 wxCHECK_MSG( xwindow, FALSE, wxT("invalid window") );
502
503 wxCursor cursorToUse;
504 if (m_cursor.Ok())
505 cursorToUse = m_cursor;
506 else
507 cursorToUse = *wxSTANDARD_CURSOR;
508
509 Cursor xcursor = (Cursor) cursorToUse.GetCursor();
510
511 XDefineCursor( wxGlobalDisplay(), xwindow, xcursor );
512
513 return TRUE;
514 }
515
516 // Coordinates relative to the window
517 void wxWindowX11::WarpPointer (int x, int y)
518 {
519 Window xwindow = (Window) m_clientWindow;
520
521 wxCHECK_RET( xwindow, wxT("invalid window") );
522
523 XWarpPointer( wxGlobalDisplay(), None, xwindow, 0, 0, 0, 0, x, y);
524 }
525
526 // Does a physical scroll
527 void wxWindowX11::ScrollWindow(int dx, int dy, const wxRect *rect)
528 {
529 // No scrolling requested.
530 if ((dx == 0) && (dy == 0)) return;
531
532 if (!m_updateRegion.IsEmpty())
533 {
534 m_updateRegion.Offset( dx, dy );
535
536 int cw = 0;
537 int ch = 0;
538 GetSize( &cw, &ch ); // GetClientSize() ??
539 m_updateRegion.Intersect( 0, 0, cw, ch );
540 }
541
542 if (!m_clearRegion.IsEmpty())
543 {
544 m_clearRegion.Offset( dx, dy );
545
546 int cw = 0;
547 int ch = 0;
548 GetSize( &cw, &ch ); // GetClientSize() ??
549 m_clearRegion.Intersect( 0, 0, cw, ch );
550 }
551
552 Window xwindow = (Window) GetClientWindow();
553
554 wxCHECK_RET( xwindow, wxT("invalid window") );
555
556 Display *xdisplay = wxGlobalDisplay();
557
558 GC xgc = XCreateGC( xdisplay, xwindow, 0, NULL );
559 XSetGraphicsExposures( xdisplay, xgc, True );
560
561 int s_x = 0;
562 int s_y = 0;
563 int cw;
564 int ch;
565 if (rect)
566 {
567 s_x = rect->x;
568 s_y = rect->y;
569
570 cw = rect->width;
571 ch = rect->height;
572 }
573 else
574 {
575 s_x = 0;
576 s_y = 0;
577 GetClientSize( &cw, &ch );
578 }
579
580 #if wxUSE_TWO_WINDOWS
581 wxPoint offset( 0,0 );
582 #else
583 wxPoint offset = GetClientAreaOrigin();
584 s_x += offset.x;
585 s_y += offset.y;
586 #endif
587
588 int w = cw - abs(dx);
589 int h = ch - abs(dy);
590
591 if ((h < 0) || (w < 0))
592 {
593 Refresh();
594 }
595 else
596 {
597 wxRect rect;
598 if (dx < 0) rect.x = cw+dx + offset.x; else rect.x = s_x;
599 if (dy < 0) rect.y = ch+dy + offset.y; else rect.y = s_y;
600 if (dy != 0) rect.width = cw; else rect.width = abs(dx);
601 if (dx != 0) rect.height = ch; else rect.height = abs(dy);
602
603 int d_x = s_x;
604 int d_y = s_y;
605
606 if (dx < 0) s_x += -dx;
607 if (dy < 0) s_y += -dy;
608 if (dx > 0) d_x = dx + offset.x;
609 if (dy > 0) d_y = dy + offset.y;
610
611 XCopyArea( xdisplay, xwindow, xwindow, xgc, s_x, s_y, w, h, d_x, d_y );
612
613 // wxLogDebug( "Copy: s_x %d s_y %d w %d h %d d_x %d d_y %d", s_x, s_y, w, h, d_x, d_y );
614
615 // wxLogDebug( "Update: %d %d %d %d", rect.x, rect.y, rect.width, rect.height );
616
617 m_updateRegion.Union( rect );
618 m_clearRegion.Union( rect );
619 }
620
621 XFreeGC( xdisplay, xgc );
622 }
623
624 // ---------------------------------------------------------------------------
625 // drag and drop
626 // ---------------------------------------------------------------------------
627
628 #if wxUSE_DRAG_AND_DROP
629
630 void wxWindowX11::SetDropTarget(wxDropTarget * WXUNUSED(pDropTarget))
631 {
632 // TODO
633 }
634
635 #endif
636
637 // Old style file-manager drag&drop
638 void wxWindowX11::DragAcceptFiles(bool WXUNUSED(accept))
639 {
640 // TODO
641 }
642
643 // ----------------------------------------------------------------------------
644 // tooltips
645 // ----------------------------------------------------------------------------
646
647 #if wxUSE_TOOLTIPS
648
649 void wxWindowX11::DoSetToolTip(wxToolTip * WXUNUSED(tooltip))
650 {
651 // TODO
652 }
653
654 #endif // wxUSE_TOOLTIPS
655
656 // ---------------------------------------------------------------------------
657 // moving and resizing
658 // ---------------------------------------------------------------------------
659
660 bool wxWindowX11::PreResize()
661 {
662 return TRUE;
663 }
664
665 // Get total size
666 void wxWindowX11::DoGetSize(int *x, int *y) const
667 {
668 Window xwindow = (Window) m_mainWindow;
669
670 wxCHECK_RET( xwindow, wxT("invalid window") );
671
672 //XSync(wxGlobalDisplay(), False);
673
674 XWindowAttributes attr;
675 Status status = XGetWindowAttributes( wxGlobalDisplay(), xwindow, &attr );
676 wxASSERT(status);
677
678 if (status)
679 {
680 *x = attr.width /* + 2*m_borderSize */ ;
681 *y = attr.height /* + 2*m_borderSize */ ;
682 }
683 }
684
685 void wxWindowX11::DoGetPosition(int *x, int *y) const
686 {
687 Window window = (Window) m_mainWindow;
688 if (window)
689 {
690 //XSync(wxGlobalDisplay(), False);
691 XWindowAttributes attr;
692 Status status = XGetWindowAttributes(wxGlobalDisplay(), window, & attr);
693 wxASSERT(status);
694
695 if (status)
696 {
697 *x = attr.x;
698 *y = attr.y;
699
700 // We may be faking the client origin. So a window that's really at (0, 30)
701 // may appear (to wxWin apps) to be at (0, 0).
702 if (GetParent())
703 {
704 wxPoint pt(GetParent()->GetClientAreaOrigin());
705 *x -= pt.x;
706 *y -= pt.y;
707 }
708 }
709 }
710 }
711
712 void wxWindowX11::DoScreenToClient(int *x, int *y) const
713 {
714 Display *display = wxGlobalDisplay();
715 Window rootWindow = RootWindowOfScreen(DefaultScreenOfDisplay(display));
716 Window thisWindow = (Window) m_clientWindow;
717
718 Window childWindow;
719 int xx = *x;
720 int yy = *y;
721 XTranslateCoordinates(display, rootWindow, thisWindow, xx, yy, x, y, &childWindow);
722 }
723
724 void wxWindowX11::DoClientToScreen(int *x, int *y) const
725 {
726 Display *display = wxGlobalDisplay();
727 Window rootWindow = RootWindowOfScreen(DefaultScreenOfDisplay(display));
728 Window thisWindow = (Window) m_clientWindow;
729
730 Window childWindow;
731 int xx = *x;
732 int yy = *y;
733 XTranslateCoordinates(display, thisWindow, rootWindow, xx, yy, x, y, &childWindow);
734 }
735
736
737 // Get size *available for subwindows* i.e. excluding menu bar etc.
738 void wxWindowX11::DoGetClientSize(int *x, int *y) const
739 {
740 Window window = (Window) m_mainWindow;
741
742 if (window)
743 {
744 XWindowAttributes attr;
745 Status status = XGetWindowAttributes( wxGlobalDisplay(), window, &attr );
746 wxASSERT(status);
747
748 if (status)
749 {
750 *x = attr.width ;
751 *y = attr.height ;
752 }
753 }
754 }
755
756 void wxWindowX11::DoSetSize(int x, int y, int width, int height, int sizeFlags)
757 {
758 // wxLogDebug("DoSetSize: %s (%ld) %d, %d %dx%d", GetClassInfo()->GetClassName(), GetId(), x, y, width, height);
759
760 Window xwindow = (Window) m_mainWindow;
761
762 wxCHECK_RET( xwindow, wxT("invalid window") );
763
764 XWindowAttributes attr;
765 Status status = XGetWindowAttributes( wxGlobalDisplay(), xwindow, &attr );
766 wxCHECK_RET( status, wxT("invalid window attributes") );
767
768 int new_x = attr.x;
769 int new_y = attr.y;
770 int new_w = attr.width;
771 int new_h = attr.height;
772
773 if (x != -1 || (sizeFlags & wxSIZE_ALLOW_MINUS_ONE))
774 {
775 int yy = 0;
776 AdjustForParentClientOrigin( x, yy, sizeFlags);
777 new_x = x;
778 }
779 if (y != -1 || (sizeFlags & wxSIZE_ALLOW_MINUS_ONE))
780 {
781 int xx = 0;
782 AdjustForParentClientOrigin( xx, y, sizeFlags);
783 new_y = y;
784 }
785 if (width != -1)
786 {
787 new_w = width;
788 if (new_w <= 0)
789 new_w = 20;
790 }
791 if (height != -1)
792 {
793 new_h = height;
794 if (new_h <= 0)
795 new_h = 20;
796 }
797
798 DoMoveWindow( new_x, new_y, new_w, new_h );
799
800 #if 0
801 wxSizeEvent event(wxSize(new_w, new_h), GetId());
802 event.SetEventObject(this);
803 GetEventHandler()->ProcessEvent(event);
804 #endif
805 }
806
807 void wxWindowX11::DoSetClientSize(int width, int height)
808 {
809 // wxLogDebug("DoSetClientSize: %s (%ld) %dx%d", GetClassInfo()->GetClassName(), GetId(), width, height);
810
811 Window xwindow = (Window) m_mainWindow;
812
813 wxCHECK_RET( xwindow, wxT("invalid window") );
814
815 XResizeWindow( wxGlobalDisplay(), xwindow, width, height );
816
817 if (m_mainWindow != m_clientWindow)
818 {
819 xwindow = (Window) m_clientWindow;
820
821 if (HasFlag( wxSUNKEN_BORDER) || HasFlag( wxRAISED_BORDER))
822 {
823 width -= 4;
824 height -= 4;
825 } else
826 if (HasFlag( wxSIMPLE_BORDER ))
827 {
828 width -= 2;
829 height -= 2;
830 }
831
832 XResizeWindow( wxGlobalDisplay(), xwindow, width, height );
833 }
834 }
835
836 // For implementation purposes - sometimes decorations make the client area
837 // smaller
838 wxPoint wxWindowX11::GetClientAreaOrigin() const
839 {
840 return wxPoint(0, 0);
841 }
842
843 void wxWindowX11::DoMoveWindow(int x, int y, int width, int height)
844 {
845 Window xwindow = (Window) m_mainWindow;
846
847 wxCHECK_RET( xwindow, wxT("invalid window") );
848
849 #if !wxUSE_NANOX
850
851 XMoveResizeWindow( wxGlobalDisplay(), xwindow, x, y, width, height );
852 if (m_mainWindow != m_clientWindow)
853 {
854 xwindow = (Window) m_clientWindow;
855
856 if (HasFlag( wxSUNKEN_BORDER) || HasFlag( wxRAISED_BORDER))
857 {
858 x = 2;
859 y = 2;
860 width -= 4;
861 height -= 4;
862 } else
863 if (HasFlag( wxSIMPLE_BORDER ))
864 {
865 x = 1;
866 y = 1;
867 width -= 2;
868 height -= 2;
869 } else
870 {
871 x = 0;
872 y = 0;
873 }
874
875 wxWindow *window = (wxWindow*) this;
876 wxScrollBar *sb = window->GetScrollbar( wxHORIZONTAL );
877 if (sb && sb->IsShown())
878 {
879 wxSize size = sb->GetSize();
880 height -= size.y;
881 }
882 sb = window->GetScrollbar( wxVERTICAL );
883 if (sb && sb->IsShown())
884 {
885 wxSize size = sb->GetSize();
886 width -= size.x;
887 }
888
889 XMoveResizeWindow( wxGlobalDisplay(), xwindow, x, y, width, height );
890 }
891
892 #else
893
894 XWindowChanges windowChanges;
895 windowChanges.x = x;
896 windowChanges.y = y;
897 windowChanges.width = width;
898 windowChanges.height = height;
899 windowChanges.stack_mode = 0;
900 int valueMask = CWX | CWY | CWWidth | CWHeight;
901
902 XConfigureWindow( wxGlobalDisplay(), xwindow, valueMask, &windowChanges );
903
904 #endif
905 }
906
907 void wxWindowX11::SetSizeHints(int minW, int minH, int maxW, int maxH, int incW, int incH)
908 {
909 m_minWidth = minW;
910 m_minHeight = minH;
911 m_maxWidth = maxW;
912 m_maxHeight = maxH;
913
914 #if !wxUSE_NANOX
915 XSizeHints sizeHints;
916 sizeHints.flags = 0;
917
918 if (minW > -1 && minH > -1)
919 {
920 sizeHints.flags |= PMinSize;
921 sizeHints.min_width = minW;
922 sizeHints.min_height = minH;
923 }
924 if (maxW > -1 && maxH > -1)
925 {
926 sizeHints.flags |= PMaxSize;
927 sizeHints.max_width = maxW;
928 sizeHints.max_height = maxH;
929 }
930 if (incW > -1 && incH > -1)
931 {
932 sizeHints.flags |= PResizeInc;
933 sizeHints.width_inc = incW;
934 sizeHints.height_inc = incH;
935 }
936
937 XSetWMNormalHints(wxGlobalDisplay(), (Window) m_mainWindow, &sizeHints );
938 #endif
939 }
940
941 // ---------------------------------------------------------------------------
942 // text metrics
943 // ---------------------------------------------------------------------------
944
945 int wxWindowX11::GetCharHeight() const
946 {
947 wxCHECK_MSG( m_font.Ok(), 0, "valid window font needed" );
948
949 WXFontStructPtr pFontStruct = m_font.GetFontStruct(1.0, wxGlobalDisplay());
950
951 int direction, ascent, descent;
952 XCharStruct overall;
953 XTextExtents ((XFontStruct*) pFontStruct, "x", 1, &direction, &ascent,
954 &descent, &overall);
955
956 // return (overall.ascent + overall.descent);
957 return (ascent + descent);
958 }
959
960 int wxWindowX11::GetCharWidth() const
961 {
962 wxCHECK_MSG( m_font.Ok(), 0, "valid window font needed" );
963
964 WXFontStructPtr pFontStruct = m_font.GetFontStruct(1.0, wxGlobalDisplay());
965
966 int direction, ascent, descent;
967 XCharStruct overall;
968 XTextExtents ((XFontStruct*) pFontStruct, "x", 1, &direction, &ascent,
969 &descent, &overall);
970
971 return overall.width;
972 }
973
974 void wxWindowX11::GetTextExtent(const wxString& string,
975 int *x, int *y,
976 int *descent, int *externalLeading,
977 const wxFont *theFont) const
978 {
979 wxFont fontToUse = m_font;
980 if (theFont) fontToUse = *theFont;
981
982 wxCHECK_RET( fontToUse.Ok(), wxT("invalid font") );
983
984 WXFontStructPtr pFontStruct = fontToUse.GetFontStruct(1.0, wxGlobalDisplay());
985
986 int direction, ascent, descent2;
987 XCharStruct overall;
988 int slen = string.Len();
989
990 #if 0
991 if (use16)
992 XTextExtents16((XFontStruct*) pFontStruct, (XChar2b *) (char*) (const char*) string, slen, &direction,
993 &ascent, &descent2, &overall);
994 #endif
995
996 XTextExtents((XFontStruct*) pFontStruct, (char*) string.c_str(), slen,
997 &direction, &ascent, &descent2, &overall);
998
999 if ( x )
1000 *x = (overall.width);
1001 if ( y )
1002 *y = (ascent + descent2);
1003 if (descent)
1004 *descent = descent2;
1005 if (externalLeading)
1006 *externalLeading = 0;
1007
1008 }
1009
1010 // ----------------------------------------------------------------------------
1011 // painting
1012 // ----------------------------------------------------------------------------
1013
1014 void wxWindowX11::Refresh(bool eraseBack, const wxRect *rect)
1015 {
1016 if (eraseBack)
1017 {
1018 if (rect)
1019 {
1020 // Schedule for later Updating in ::Update() or ::OnInternalIdle().
1021 m_clearRegion.Union( rect->x, rect->y, rect->width, rect->height );
1022 }
1023 else
1024 {
1025 int height,width;
1026 GetSize( &width, &height );
1027
1028 // Schedule for later Updating in ::Update() or ::OnInternalIdle().
1029 m_clearRegion.Clear();
1030 m_clearRegion.Union( 0, 0, width, height );
1031 }
1032 }
1033
1034 if (rect)
1035 {
1036 // Schedule for later Updating in ::Update() or ::OnInternalIdle().
1037 m_updateRegion.Union( rect->x, rect->y, rect->width, rect->height );
1038 }
1039 else
1040 {
1041 int height,width;
1042 GetSize( &width, &height );
1043
1044 // Schedule for later Updating in ::Update() or ::OnInternalIdle().
1045 m_updateRegion.Clear();
1046 m_updateRegion.Union( 0, 0, width, height );
1047 }
1048 }
1049
1050 void wxWindowX11::Update()
1051 {
1052 if (m_updateNcArea)
1053 {
1054 // Send nc paint events.
1055 SendNcPaintEvents();
1056 }
1057
1058 if (!m_updateRegion.IsEmpty())
1059 {
1060 // wxLogDebug("wxWindowX11::Update: %s", GetClassInfo()->GetClassName());
1061 // Actually send erase events.
1062 SendEraseEvents();
1063
1064 // Actually send paint events.
1065 SendPaintEvents();
1066 }
1067 }
1068
1069 void wxWindowX11::Clear()
1070 {
1071 // wxClientDC dc((wxWindow*) this);
1072 // wxBrush brush(GetBackgroundColour(), wxSOLID);
1073 // dc.SetBackground(brush);
1074 // dc.Clear();
1075 }
1076
1077 void wxWindowX11::SendEraseEvents()
1078 {
1079 if (m_clearRegion.IsEmpty()) return;
1080
1081 wxClientDC dc( (wxWindow*)this );
1082 dc.SetClippingRegion( m_clearRegion );
1083
1084 wxEraseEvent erase_event( GetId(), &dc );
1085 erase_event.SetEventObject( this );
1086
1087 if (!GetEventHandler()->ProcessEvent(erase_event))
1088 {
1089 Window xwindow = (Window) m_clientWindow;
1090 Display *xdisplay = wxGlobalDisplay();
1091 GC xgc = XCreateGC( xdisplay, xwindow, 0, NULL );
1092 XSetFillStyle( xdisplay, xgc, FillSolid );
1093 XSetForeground( xdisplay, xgc, m_backgroundColour.GetPixel() );
1094 wxRegionIterator upd( m_clearRegion );
1095 while (upd)
1096 {
1097 XFillRectangle( xdisplay, xwindow, xgc,
1098 upd.GetX(), upd.GetY(), upd.GetWidth(), upd.GetHeight() );
1099 upd ++;
1100 }
1101 XFreeGC( xdisplay, xgc );
1102 }
1103
1104 m_clearRegion.Clear();
1105 }
1106
1107 void wxWindowX11::SendPaintEvents()
1108 {
1109 // wxLogDebug("SendPaintEvents: %s (%ld)", GetClassInfo()->GetClassName(), GetId());
1110
1111 m_clipPaintRegion = TRUE;
1112
1113 wxPaintEvent paint_event( GetId() );
1114 paint_event.SetEventObject( this );
1115 GetEventHandler()->ProcessEvent( paint_event );
1116
1117 m_updateRegion.Clear();
1118
1119 m_clipPaintRegion = FALSE;
1120 }
1121
1122 void wxWindowX11::SendNcPaintEvents()
1123 {
1124 wxNcPaintEvent nc_paint_event( GetId() );
1125 nc_paint_event.SetEventObject( this );
1126 GetEventHandler()->ProcessEvent( nc_paint_event );
1127 }
1128
1129 // ----------------------------------------------------------------------------
1130 // event handlers
1131 // ----------------------------------------------------------------------------
1132
1133 // Responds to colour changes: passes event on to children.
1134 void wxWindowX11::OnSysColourChanged(wxSysColourChangedEvent& event)
1135 {
1136 wxWindowList::Node *node = GetChildren().GetFirst();
1137 while ( node )
1138 {
1139 // Only propagate to non-top-level windows
1140 wxWindow *win = node->GetData();
1141 if ( win->GetParent() )
1142 {
1143 wxSysColourChangedEvent event2;
1144 event.m_eventObject = win;
1145 win->GetEventHandler()->ProcessEvent(event2);
1146 }
1147
1148 node = node->GetNext();
1149 }
1150 }
1151
1152 void wxWindowX11::OnInternalIdle()
1153 {
1154 // Update invalidated regions.
1155 Update();
1156
1157 // This calls the UI-update mechanism (querying windows for
1158 // menu/toolbar/control state information)
1159 UpdateWindowUI();
1160
1161 // Set the input focus if couldn't do it before
1162 if (m_needsInputFocus)
1163 {
1164 SetFocus();
1165 }
1166 }
1167
1168 // ----------------------------------------------------------------------------
1169 // function which maintain the global hash table mapping Widgets to wxWindows
1170 // ----------------------------------------------------------------------------
1171
1172 bool wxAddWindowToTable(Window w, wxWindow *win)
1173 {
1174 wxWindow *oldItem = NULL;
1175 if ((oldItem = (wxWindow *)wxWidgetHashTable->Get ((long) w)))
1176 {
1177 wxLogDebug("Widget table clash: new widget is %ld, %s",
1178 (long)w, win->GetClassInfo()->GetClassName());
1179 return FALSE;
1180 }
1181
1182 wxWidgetHashTable->Put((long) w, win);
1183
1184 wxLogTrace("widget", "XWindow 0x%08x <-> window %p (%s)",
1185 w, win, win->GetClassInfo()->GetClassName());
1186
1187 return TRUE;
1188 }
1189
1190 wxWindow *wxGetWindowFromTable(Window w)
1191 {
1192 return (wxWindow *)wxWidgetHashTable->Get((long) w);
1193 }
1194
1195 void wxDeleteWindowFromTable(Window w)
1196 {
1197 wxWidgetHashTable->Delete((long)w);
1198 }
1199
1200 // ----------------------------------------------------------------------------
1201 // function which maintain the global hash table mapping client widgets
1202 // ----------------------------------------------------------------------------
1203
1204 bool wxAddClientWindowToTable(Window w, wxWindow *win)
1205 {
1206 wxWindow *oldItem = NULL;
1207 if ((oldItem = (wxWindow *)wxClientWidgetHashTable->Get ((long) w)))
1208 {
1209 wxLogDebug("Client window table clash: new window is %ld, %s",
1210 (long)w, win->GetClassInfo()->GetClassName());
1211 return FALSE;
1212 }
1213
1214 wxClientWidgetHashTable->Put((long) w, win);
1215
1216 wxLogTrace("widget", "XWindow 0x%08x <-> window %p (%s)",
1217 w, win, win->GetClassInfo()->GetClassName());
1218
1219 return TRUE;
1220 }
1221
1222 wxWindow *wxGetClientWindowFromTable(Window w)
1223 {
1224 return (wxWindow *)wxClientWidgetHashTable->Get((long) w);
1225 }
1226
1227 void wxDeleteClientWindowFromTable(Window w)
1228 {
1229 wxClientWidgetHashTable->Delete((long)w);
1230 }
1231
1232 // ----------------------------------------------------------------------------
1233 // add/remove window from the table
1234 // ----------------------------------------------------------------------------
1235
1236 // ----------------------------------------------------------------------------
1237 // X11-specific accessors
1238 // ----------------------------------------------------------------------------
1239
1240 WXWindow wxWindowX11::GetMainWindow() const
1241 {
1242 return m_mainWindow;
1243 }
1244
1245 WXWindow wxWindowX11::GetClientWindow() const
1246 {
1247 return m_clientWindow;
1248 }
1249
1250 // ----------------------------------------------------------------------------
1251 // TranslateXXXEvent() functions
1252 // ----------------------------------------------------------------------------
1253
1254 bool wxTranslateMouseEvent(wxMouseEvent& wxevent, wxWindow *win, Window window, XEvent *xevent)
1255 {
1256 switch (XEventGetType(xevent))
1257 {
1258 case EnterNotify:
1259 case LeaveNotify:
1260 case ButtonPress:
1261 case ButtonRelease:
1262 case MotionNotify:
1263 {
1264 wxEventType eventType = wxEVT_NULL;
1265
1266 if (XEventGetType(xevent) == EnterNotify)
1267 {
1268 //if (local_event.xcrossing.mode!=NotifyNormal)
1269 // return ; // Ignore grab events
1270 eventType = wxEVT_ENTER_WINDOW;
1271 // canvas->GetEventHandler()->OnSetFocus();
1272 }
1273 else if (XEventGetType(xevent) == LeaveNotify)
1274 {
1275 //if (local_event.xcrossingr.mode!=NotifyNormal)
1276 // return ; // Ignore grab events
1277 eventType = wxEVT_LEAVE_WINDOW;
1278 // canvas->GetEventHandler()->OnKillFocus();
1279 }
1280 else if (XEventGetType(xevent) == MotionNotify)
1281 {
1282 eventType = wxEVT_MOTION;
1283 }
1284 else if (XEventGetType(xevent) == ButtonPress)
1285 {
1286 wxevent.SetTimestamp(XButtonEventGetTime(xevent));
1287 int button = 0;
1288 if (XButtonEventLChanged(xevent))
1289 {
1290 eventType = wxEVT_LEFT_DOWN;
1291 button = 1;
1292 }
1293 else if (XButtonEventMChanged(xevent))
1294 {
1295 eventType = wxEVT_MIDDLE_DOWN;
1296 button = 2;
1297 }
1298 else if (XButtonEventRChanged(xevent))
1299 {
1300 eventType = wxEVT_RIGHT_DOWN;
1301 button = 3;
1302 }
1303
1304 // check for a double click
1305 // TODO: where can we get this value from?
1306 //long dclickTime = XtGetMultiClickTime(wxGlobalDisplay());
1307 long dclickTime = 200;
1308 long ts = wxevent.GetTimestamp();
1309
1310 int buttonLast = win->GetLastClickedButton();
1311 long lastTS = win->GetLastClickTime();
1312 if ( buttonLast && buttonLast == button && (ts - lastTS) < dclickTime )
1313 {
1314 // I have a dclick
1315 win->SetLastClick(0, ts);
1316 if ( eventType == wxEVT_LEFT_DOWN )
1317 eventType = wxEVT_LEFT_DCLICK;
1318 else if ( eventType == wxEVT_MIDDLE_DOWN )
1319 eventType = wxEVT_MIDDLE_DCLICK;
1320 else if ( eventType == wxEVT_RIGHT_DOWN )
1321 eventType = wxEVT_RIGHT_DCLICK;
1322 }
1323 else
1324 {
1325 // not fast enough or different button
1326 win->SetLastClick(button, ts);
1327 }
1328 }
1329 else if (XEventGetType(xevent) == ButtonRelease)
1330 {
1331 if (XButtonEventLChanged(xevent))
1332 {
1333 eventType = wxEVT_LEFT_UP;
1334 }
1335 else if (XButtonEventMChanged(xevent))
1336 {
1337 eventType = wxEVT_MIDDLE_UP;
1338 }
1339 else if (XButtonEventRChanged(xevent))
1340 {
1341 eventType = wxEVT_RIGHT_UP;
1342 }
1343 else return FALSE;
1344 }
1345 else
1346 {
1347 return FALSE;
1348 }
1349
1350 wxevent.SetEventType(eventType);
1351
1352 wxevent.m_x = XButtonEventGetX(xevent);
1353 wxevent.m_y = XButtonEventGetY(xevent);
1354
1355 wxevent.m_leftDown = ((eventType == wxEVT_LEFT_DOWN)
1356 || (XButtonEventLIsDown(xevent)
1357 && (eventType != wxEVT_LEFT_UP)));
1358 wxevent.m_middleDown = ((eventType == wxEVT_MIDDLE_DOWN)
1359 || (XButtonEventMIsDown(xevent)
1360 && (eventType != wxEVT_MIDDLE_UP)));
1361 wxevent.m_rightDown = ((eventType == wxEVT_RIGHT_DOWN)
1362 || (XButtonEventRIsDown (xevent)
1363 && (eventType != wxEVT_RIGHT_UP)));
1364
1365 wxevent.m_shiftDown = XButtonEventShiftIsDown(xevent);
1366 wxevent.m_controlDown = XButtonEventCtrlIsDown(xevent);
1367 wxevent.m_altDown = XButtonEventAltIsDown(xevent);
1368 wxevent.m_metaDown = XButtonEventMetaIsDown(xevent);
1369
1370 wxevent.SetId(win->GetId());
1371 wxevent.SetEventObject(win);
1372
1373 return TRUE;
1374 }
1375 }
1376 return FALSE;
1377 }
1378
1379 bool wxTranslateKeyEvent(wxKeyEvent& wxevent, wxWindow *win, Window WXUNUSED(win), XEvent *xevent)
1380 {
1381 switch (XEventGetType(xevent))
1382 {
1383 case KeyPress:
1384 case KeyRelease:
1385 {
1386 char buf[20];
1387
1388 KeySym keySym;
1389 (void) XLookupString ((XKeyEvent *) xevent, buf, 20, &keySym, NULL);
1390 int id = wxCharCodeXToWX (keySym);
1391
1392 wxevent.m_shiftDown = XKeyEventShiftIsDown(xevent);
1393 wxevent.m_controlDown = XKeyEventCtrlIsDown(xevent);
1394 wxevent.m_altDown = XKeyEventAltIsDown(xevent);
1395 wxevent.m_metaDown = XKeyEventMetaIsDown(xevent);
1396 wxevent.SetEventObject(win);
1397 wxevent.m_keyCode = id;
1398 wxevent.SetTimestamp(XKeyEventGetTime(xevent));
1399
1400 wxevent.m_x = XKeyEventGetX(xevent);
1401 wxevent.m_y = XKeyEventGetY(xevent);
1402
1403 if (id > -1)
1404 return TRUE;
1405 else
1406 return FALSE;
1407 break;
1408 }
1409 default:
1410 break;
1411 }
1412 return FALSE;
1413 }
1414
1415 // ----------------------------------------------------------------------------
1416 // Colour stuff
1417 // ----------------------------------------------------------------------------
1418
1419 bool wxWindowX11::SetBackgroundColour(const wxColour& col)
1420 {
1421 wxWindowBase::SetBackgroundColour(col);
1422
1423 Display *xdisplay = (Display*) wxGlobalDisplay();
1424 int xscreen = DefaultScreen( xdisplay );
1425 Colormap cm = DefaultColormap( xdisplay, xscreen );
1426
1427 m_backgroundColour.CalcPixel( (WXColormap) cm );
1428
1429 if (!GetMainWindow())
1430 return FALSE;
1431
1432 /*
1433 XSetWindowAttributes attrib;
1434 attrib.background_pixel = colour.GetPixel();
1435
1436 XChangeWindowAttributes(wxGlobalDisplay(),
1437 (Window) GetMainWindow(),
1438 CWBackPixel,
1439 & attrib);
1440 */
1441
1442 return TRUE;
1443 }
1444
1445 bool wxWindowX11::SetForegroundColour(const wxColour& col)
1446 {
1447 if ( !wxWindowBase::SetForegroundColour(col) )
1448 return FALSE;
1449
1450 return TRUE;
1451 }
1452
1453 // ----------------------------------------------------------------------------
1454 // global functions
1455 // ----------------------------------------------------------------------------
1456
1457 wxWindow *wxGetActiveWindow()
1458 {
1459 // TODO
1460 wxFAIL_MSG("Not implemented");
1461 return NULL;
1462 }
1463
1464 /* static */
1465 wxWindow *wxWindowBase::GetCapture()
1466 {
1467 return (wxWindow *)g_captureWindow;
1468 }
1469
1470
1471 // Find the wxWindow at the current mouse position, returning the mouse
1472 // position.
1473 wxWindow* wxFindWindowAtPointer(wxPoint& pt)
1474 {
1475 return wxFindWindowAtPoint(wxGetMousePosition());
1476 }
1477
1478 // Get the current mouse position.
1479 wxPoint wxGetMousePosition()
1480 {
1481 #if wxUSE_NANOX
1482 /* TODO */
1483 return wxPoint(0, 0);
1484 #else
1485 Display *display = wxGlobalDisplay();
1486 Window rootWindow = RootWindowOfScreen (DefaultScreenOfDisplay(display));
1487 Window rootReturn, childReturn;
1488 int rootX, rootY, winX, winY;
1489 unsigned int maskReturn;
1490
1491 XQueryPointer (display,
1492 rootWindow,
1493 &rootReturn,
1494 &childReturn,
1495 &rootX, &rootY, &winX, &winY, &maskReturn);
1496 return wxPoint(rootX, rootY);
1497 #endif
1498 }
1499
1500
1501 // ----------------------------------------------------------------------------
1502 // wxNoOptimize: switch off size optimization
1503 // ----------------------------------------------------------------------------
1504
1505 int wxNoOptimize::ms_count = 0;
1506