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