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