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