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