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