]> git.saurik.com Git - wxWidgets.git/blame - src/x11/window.cpp
compilation fix for wxUSE_TOOLTIPS=0 (i.e. wxUniv)
[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
52// ----------------------------------------------------------------------------
53// constants
54// ----------------------------------------------------------------------------
55
56static const int SCROLL_MARGIN = 4;
57
58// ----------------------------------------------------------------------------
59// global variables for this module
60// ----------------------------------------------------------------------------
61
62extern wxHashTable *wxWidgetHashTable;
63static wxWindow* g_captureWindow = NULL;
64
83df96d6
JS
65// ----------------------------------------------------------------------------
66// macros
67// ----------------------------------------------------------------------------
68
69#define event_left_is_down(x) ((x)->xbutton.state & Button1Mask)
70#define event_middle_is_down(x) ((x)->xbutton.state & Button2Mask)
71#define event_right_is_down(x) ((x)->xbutton.state & Button3Mask)
72
73// ----------------------------------------------------------------------------
74// event tables
75// ----------------------------------------------------------------------------
76
bc797f4c 77IMPLEMENT_DYNAMIC_CLASS(wxWindowX11, wxWindowBase)
83df96d6 78
bc797f4c
JS
79BEGIN_EVENT_TABLE(wxWindowX11, wxWindowBase)
80 EVT_SYS_COLOUR_CHANGED(wxWindowX11::OnSysColourChanged)
81 EVT_IDLE(wxWindowX11::OnIdle)
82END_EVENT_TABLE()
83df96d6
JS
83
84// ============================================================================
85// implementation
86// ============================================================================
87
88// ----------------------------------------------------------------------------
89// helper functions
90// ----------------------------------------------------------------------------
91
83df96d6
JS
92// ----------------------------------------------------------------------------
93// constructors
94// ----------------------------------------------------------------------------
95
bc797f4c 96void wxWindowX11::Init()
83df96d6
JS
97{
98 // generic initializations first
99 InitBase();
100
7266b672 101 // X11-specific
83df96d6 102 m_needsRefresh = TRUE;
7266b672 103 m_mainWidget = (WXWindow) 0;
83df96d6
JS
104
105 m_button1Pressed =
106 m_button2Pressed =
107 m_button3Pressed = FALSE;
108
109 m_winCaptured = FALSE;
110
111 m_isShown = TRUE;
112 m_isBeingDeleted = FALSE;
113
114 m_hScrollBar =
115 m_vScrollBar =
116 m_borderWidget =
117 m_scrolledWindow =
7266b672 118 m_drawingArea = (WXWindow) 0;
83df96d6
JS
119
120 m_hScroll =
121 m_vScroll = FALSE;
122
123 m_scrollPosX =
124 m_scrollPosY = 0;
125
126 m_backingPixmap = (WXPixmap) 0;
127 m_pixmapWidth =
128 m_pixmapHeight = 0;
129
130 m_pixmapOffsetX =
131 m_pixmapOffsetY = 0;
132
133 m_lastTS = 0;
134 m_lastButton = 0;
135 m_canAddEventHandler = FALSE;
136}
137
138// real construction (Init() must have been called before!)
bc797f4c 139bool wxWindowX11::Create(wxWindow *parent, wxWindowID id,
83df96d6
JS
140 const wxPoint& pos,
141 const wxSize& size,
142 long style,
143 const wxString& name)
144{
145 wxCHECK_MSG( parent, FALSE, "can't create wxWindow without parent" );
146
147 CreateBase(parent, id, pos, size, style, wxDefaultValidator, name);
148
149 parent->AddChild(this);
150
151 m_backgroundColour = wxSystemSettings::GetColour(wxSYS_COLOUR_3DFACE);
152 m_foregroundColour = *wxBLACK;
153
83df96d6
JS
154 if (style & wxSIMPLE_BORDER)
155 {
83df96d6
JS
156 } else if (style & wxSUNKEN_BORDER)
157 {
83df96d6
JS
158 } else if (style & wxRAISED_BORDER)
159 {
83df96d6
JS
160 }
161
bc797f4c 162 // TODO: create XWindow
83df96d6
JS
163
164#if 0
bc797f4c
JS
165 wxAddWindowToTable((Window) m_drawingArea, this);
166 wxAddWindowToTable((Window) m_scrolledWindow, this);
167#endif
83df96d6
JS
168
169 // Without this, the cursor may not be restored properly (e.g. in splitter
170 // sample).
171 SetCursor(*wxSTANDARD_CURSOR);
172 SetFont(wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT));
173 SetSize(pos.x, pos.y, size.x, size.y);
174
175 return TRUE;
176}
177
178// Destructor
7266b672 179wxWindowX11::~wxWindowX11()
83df96d6
JS
180{
181 if (g_captureWindow == this)
182 g_captureWindow = NULL;
183
184 m_isBeingDeleted = TRUE;
185
7266b672 186 // X11-specific actions first
bc797f4c 187 WXWindow wMain = GetMainWindow();
83df96d6
JS
188 if ( wMain )
189 {
190 // Removes event handlers
bc797f4c 191 //DetachWidget(wMain);
83df96d6
JS
192 }
193
194 ClearUpdateRects();
195
196 if ( m_parent )
197 m_parent->RemoveChild( this );
198
bc797f4c
JS
199 // TODO
200
201#if 0
83df96d6
JS
202 // If m_drawingArea, we're a fully-fledged window with drawing area,
203 // scrollbars etc. (what wxCanvas used to be)
204 if ( m_drawingArea )
205 {
206 // Destroy children before destroying self
207 DestroyChildren();
208
209 if (m_backingPixmap)
210 XFreePixmap (XtDisplay ((Widget) GetMainWidget()), (Pixmap) m_backingPixmap);
211
212 Widget w = (Widget) m_drawingArea;
213 wxDeleteWindowFromTable(w);
214
215 if (w)
216 {
217 XtDestroyWidget(w);
218 m_drawingArea = (WXWidget) 0;
219 }
220
221 // Only if we're _really_ a canvas (not a dialog box/panel)
222 if (m_scrolledWindow)
223 {
224 wxDeleteWindowFromTable((Widget) m_scrolledWindow);
225 }
226
227 if (m_hScrollBar)
228 {
229 wxDeleteWindowFromTable((Widget) m_hScrollBar);
230 XtUnmanageChild((Widget) m_hScrollBar);
231 }
232 if (m_vScrollBar)
233 {
234 wxDeleteWindowFromTable((Widget) m_vScrollBar);
235 XtUnmanageChild((Widget) m_vScrollBar);
236 }
237
238 if (m_hScrollBar)
239 XtDestroyWidget((Widget) m_hScrollBar);
240 if (m_vScrollBar)
241 XtDestroyWidget((Widget) m_vScrollBar);
242
243 UnmanageAndDestroy(m_scrolledWindow);
244
245 if (m_borderWidget)
246 {
247 XtDestroyWidget ((Widget) m_borderWidget);
248 m_borderWidget = (WXWidget) 0;
249 }
250 }
251 else // Why wasn't this here before? JACS 8/3/2000
bc797f4c 252#endif
83df96d6
JS
253 DestroyChildren();
254
255
256 // Destroy the window
bc797f4c
JS
257 if (GetMainWindow())
258 {
259 // TODO
260 // XtDestroyWidget((Widget) GetMainWidget());
261 SetMainWindow((WXWindow) NULL);
83df96d6
JS
262 }
263}
264
265// ----------------------------------------------------------------------------
266// scrollbar management
267// ----------------------------------------------------------------------------
268
269// Helper function
bc797f4c 270void wxWindowX11::CreateScrollbar(wxOrientation orientation)
83df96d6 271{
bc797f4c
JS
272 // TODO
273#if 0
83df96d6
JS
274 wxCHECK_RET( m_drawingArea, "this window can't have scrollbars" );
275
276 XtVaSetValues((Widget) m_scrolledWindow, XmNresizePolicy, XmRESIZE_NONE, NULL);
277
278 // Add scrollbars if required
279 if (orientation == wxHORIZONTAL)
280 {
281 Widget hScrollBar = XtVaCreateManagedWidget ("hsb",
282 xmScrollBarWidgetClass, (Widget) m_scrolledWindow,
283 XmNorientation, XmHORIZONTAL,
284 NULL);
285 XtAddCallback (hScrollBar, XmNvalueChangedCallback, (XtCallbackProc) wxScrollBarCallback, (XtPointer) XmHORIZONTAL);
286 XtAddCallback (hScrollBar, XmNdragCallback, (XtCallbackProc) wxScrollBarCallback, (XtPointer) XmHORIZONTAL);
287 XtAddCallback (hScrollBar, XmNincrementCallback, (XtCallbackProc) wxScrollBarCallback, (XtPointer) XmHORIZONTAL);
288 XtAddCallback (hScrollBar, XmNdecrementCallback, (XtCallbackProc) wxScrollBarCallback, (XtPointer) XmHORIZONTAL);
289 XtAddCallback (hScrollBar, XmNpageIncrementCallback, (XtCallbackProc) wxScrollBarCallback, (XtPointer) XmHORIZONTAL);
290 XtAddCallback (hScrollBar, XmNpageDecrementCallback, (XtCallbackProc) wxScrollBarCallback, (XtPointer) XmHORIZONTAL);
291 XtAddCallback (hScrollBar, XmNtoTopCallback, (XtCallbackProc) wxScrollBarCallback, (XtPointer) XmHORIZONTAL);
292 XtAddCallback (hScrollBar, XmNtoBottomCallback, (XtCallbackProc) wxScrollBarCallback, (XtPointer) XmHORIZONTAL);
293
294 XtVaSetValues (hScrollBar,
295 XmNincrement, 1,
296 XmNvalue, 0,
297 NULL);
298
299 m_hScrollBar = (WXWidget) hScrollBar;
300
301 wxColour backgroundColour = wxSystemSettings::GetColour(wxSYS_COLOUR_3DFACE);
302 DoChangeBackgroundColour(m_hScrollBar, backgroundColour, TRUE);
303
304 XtRealizeWidget(hScrollBar);
305
306 XtVaSetValues((Widget) m_scrolledWindow,
307 XmNhorizontalScrollBar, (Widget) m_hScrollBar,
308 NULL);
309
310 m_hScroll = TRUE;
311
312 wxAddWindowToTable( hScrollBar, this );
313 }
314
315 if (orientation == wxVERTICAL)
316 {
317 Widget vScrollBar = XtVaCreateManagedWidget ("vsb",
318 xmScrollBarWidgetClass, (Widget) m_scrolledWindow,
319 XmNorientation, XmVERTICAL,
320 NULL);
321 XtAddCallback (vScrollBar, XmNvalueChangedCallback, (XtCallbackProc) wxScrollBarCallback, (XtPointer) XmVERTICAL);
322 XtAddCallback (vScrollBar, XmNdragCallback, (XtCallbackProc) wxScrollBarCallback, (XtPointer) XmVERTICAL);
323 XtAddCallback (vScrollBar, XmNincrementCallback, (XtCallbackProc) wxScrollBarCallback, (XtPointer) XmVERTICAL);
324 XtAddCallback (vScrollBar, XmNdecrementCallback, (XtCallbackProc) wxScrollBarCallback, (XtPointer) XmVERTICAL);
325 XtAddCallback (vScrollBar, XmNpageIncrementCallback, (XtCallbackProc) wxScrollBarCallback, (XtPointer) XmVERTICAL);
326 XtAddCallback (vScrollBar, XmNpageDecrementCallback, (XtCallbackProc) wxScrollBarCallback, (XtPointer) XmVERTICAL);
327 XtAddCallback (vScrollBar, XmNtoTopCallback, (XtCallbackProc) wxScrollBarCallback, (XtPointer) XmVERTICAL);
328 XtAddCallback (vScrollBar, XmNtoBottomCallback, (XtCallbackProc) wxScrollBarCallback, (XtPointer) XmVERTICAL);
329
330 XtVaSetValues (vScrollBar,
331 XmNincrement, 1,
332 XmNvalue, 0,
333 NULL);
334
335 m_vScrollBar = (WXWidget) vScrollBar;
336 wxColour backgroundColour = wxSystemSettings::GetColour(wxSYS_COLOUR_3DFACE);
337 DoChangeBackgroundColour(m_vScrollBar, backgroundColour, TRUE);
338
339 XtRealizeWidget(vScrollBar);
340
341 XtVaSetValues((Widget) m_scrolledWindow,
342 XmNverticalScrollBar, (Widget) m_vScrollBar,
343 NULL);
344
345 m_vScroll = TRUE;
346
347 wxAddWindowToTable( vScrollBar, this );
348 }
349
350 XtVaSetValues((Widget) m_scrolledWindow, XmNresizePolicy, XmRESIZE_ANY, NULL);
bc797f4c 351#endif
83df96d6
JS
352}
353
bc797f4c 354void wxWindowX11::DestroyScrollbar(wxOrientation orientation)
83df96d6 355{
bc797f4c
JS
356 // TODO
357#if 0
83df96d6
JS
358 wxCHECK_RET( m_drawingArea, "this window can't have scrollbars" );
359
360 XtVaSetValues((Widget) m_scrolledWindow, XmNresizePolicy, XmRESIZE_NONE, NULL);
361 // Add scrollbars if required
362 if (orientation == wxHORIZONTAL)
363 {
364 if (m_hScrollBar)
365 {
366 wxDeleteWindowFromTable((Widget)m_hScrollBar);
367 XtDestroyWidget((Widget) m_hScrollBar);
368 }
369 m_hScrollBar = (WXWidget) 0;
370 m_hScroll = FALSE;
371
372 XtVaSetValues((Widget) m_scrolledWindow,
373 XmNhorizontalScrollBar, (Widget) 0,
374 NULL);
375
376 }
377
378 if (orientation == wxVERTICAL)
379 {
380 if (m_vScrollBar)
381 {
382 wxDeleteWindowFromTable((Widget)m_vScrollBar);
383 XtDestroyWidget((Widget) m_vScrollBar);
384 }
385 m_vScrollBar = (WXWidget) 0;
386 m_vScroll = FALSE;
387
388 XtVaSetValues((Widget) m_scrolledWindow,
389 XmNverticalScrollBar, (Widget) 0,
390 NULL);
391
392 }
393 XtVaSetValues((Widget) m_scrolledWindow, XmNresizePolicy, XmRESIZE_ANY, NULL);
bc797f4c 394#endif
83df96d6
JS
395}
396
397// ---------------------------------------------------------------------------
398// basic operations
399// ---------------------------------------------------------------------------
400
bc797f4c 401void wxWindowX11::SetFocus()
83df96d6 402{
bc797f4c
JS
403 // TODO
404#if 0
83df96d6
JS
405 Widget wMain = (Widget) GetMainWidget();
406 XmProcessTraversal(wMain, XmTRAVERSE_CURRENT);
407 XmProcessTraversal((Widget) GetMainWidget(), XmTRAVERSE_CURRENT);
bc797f4c 408#endif
83df96d6
JS
409}
410
411// Get the window with the focus
412wxWindow *wxWindowBase::FindFocus()
413{
bc797f4c
JS
414 // TODO
415 return NULL;
416#if 0
417
83df96d6
JS
418 // TODO Problems:
419 // (1) Can there be multiple focussed widgets in an application?
420 // In which case we need to find the top-level window that's
421 // currently active.
422 // (2) The widget with the focus may not be in the widget table
423 // depending on which widgets I put in the table
424 wxWindow *winFocus = (wxWindow *)NULL;
425 for ( wxWindowList::Node *node = wxTopLevelWindows.GetFirst();
426 node;
427 node = node->GetNext() )
428 {
429 wxWindow *win = node->GetData();
430
431 Widget w = XmGetFocusWidget ((Widget) win->GetTopWidget());
432
433 if (w != (Widget) NULL)
434 {
435 winFocus = wxGetWindowFromTable(w);
436 if ( winFocus )
437 break;
438 }
439 }
440
441 return winFocus;
bc797f4c 442#endif
83df96d6
JS
443}
444
bc797f4c 445bool wxWindowX11::Enable(bool enable)
83df96d6
JS
446{
447 if ( !wxWindowBase::Enable(enable) )
448 return FALSE;
449
bc797f4c
JS
450 // TODO
451#if 0
83df96d6
JS
452 Widget wMain = (Widget)GetMainWidget();
453 if ( wMain )
454 {
455 XtSetSensitive(wMain, enable);
456 XmUpdateDisplay(wMain);
457 }
bc797f4c 458#endif
83df96d6
JS
459
460 return TRUE;
461}
462
bc797f4c 463bool wxWindowX11::Show(bool show)
83df96d6
JS
464{
465 if ( !wxWindowBase::Show(show) )
466 return FALSE;
467
83df96d6
JS
468 Window xwin = (Window) GetXWindow();
469 Display *xdisp = (Display*) GetXDisplay();
470 if (show)
471 XMapWindow(xdisp, xwin);
472 else
473 XUnmapWindow(xdisp, xwin);
83df96d6
JS
474
475 return TRUE;
476}
477
478// Raise the window to the top of the Z order
bc797f4c 479void wxWindowX11::Raise()
83df96d6 480{
7266b672 481 Window window = (Window) GetTopWindow();
bc797f4c 482 if (window)
7266b672 483 XRaiseWindow((Display*) wxGetDisplay(), window);
83df96d6
JS
484}
485
486// Lower the window to the bottom of the Z order
bc797f4c 487void wxWindowX11::Lower()
83df96d6 488{
7266b672 489 Window window = (Window) GetTopWindow();
bc797f4c 490 if (window)
7266b672 491 XLowerWindow((Display*) wxGetDisplay(), window);
83df96d6
JS
492}
493
bc797f4c 494void wxWindowX11::SetTitle(const wxString& title)
83df96d6 495{
bc797f4c
JS
496 // TODO
497// XtVaSetValues((Widget)GetMainWidget(), XmNtitle, title.c_str(), NULL);
83df96d6
JS
498}
499
bc797f4c 500wxString wxWindowX11::GetTitle() const
83df96d6 501{
bc797f4c
JS
502 // TODO
503 return wxEmptyString;
504#if 0
83df96d6
JS
505 char *title;
506 XtVaGetValues((Widget)GetMainWidget(), XmNtitle, &title, NULL);
507
508 return wxString(title);
bc797f4c 509#endif
83df96d6
JS
510}
511
bc797f4c 512void wxWindowX11::DoCaptureMouse()
83df96d6 513{
7266b672 514 g_captureWindow = (wxWindow*) this;
83df96d6
JS
515 if ( m_winCaptured )
516 return;
517
bc797f4c
JS
518 // TODO
519#if 0
83df96d6
JS
520 Widget wMain = (Widget)GetMainWidget();
521 if ( wMain )
522 XtAddGrab(wMain, TRUE, FALSE);
bc797f4c 523#endif
83df96d6
JS
524
525 m_winCaptured = TRUE;
526}
527
bc797f4c 528void wxWindowX11::DoReleaseMouse()
83df96d6
JS
529{
530 g_captureWindow = NULL;
531 if ( !m_winCaptured )
532 return;
533
bc797f4c
JS
534 // TODO
535#if 0
83df96d6
JS
536 Widget wMain = (Widget)GetMainWidget();
537 if ( wMain )
538 XtRemoveGrab(wMain);
bc797f4c 539#endif
83df96d6
JS
540
541 m_winCaptured = FALSE;
542}
543
bc797f4c 544bool wxWindowX11::SetFont(const wxFont& font)
83df96d6
JS
545{
546 if ( !wxWindowBase::SetFont(font) )
547 {
548 // nothing to do
549 return FALSE;
550 }
551
552 ChangeFont();
553
554 return TRUE;
555}
556
bc797f4c 557bool wxWindowX11::SetCursor(const wxCursor& cursor)
83df96d6
JS
558{
559 if ( !wxWindowBase::SetCursor(cursor) )
560 {
561 // no change
562 return FALSE;
563 }
564
83df96d6
JS
565 wxCursor* cursor2 = NULL;
566 if (m_cursor.Ok())
567 cursor2 = & m_cursor;
568 else
569 cursor2 = wxSTANDARD_CURSOR;
570
571 WXDisplay *dpy = GetXDisplay();
572 WXCursor x_cursor = cursor2->GetXCursor(dpy);
573
bc797f4c 574 Window win = (Window) GetMainWindow();
83df96d6
JS
575 XDefineCursor((Display*) dpy, win, (Cursor) x_cursor);
576
577 return TRUE;
578}
579
580// Coordinates relative to the window
bc797f4c 581void wxWindowX11::WarpPointer (int x, int y)
83df96d6 582{
bc797f4c 583 Window wClient = (Window) GetClientWindow();
83df96d6 584
7266b672 585 XWarpPointer((Display*) wxGetDisplay(), None, wClient, 0, 0, 0, 0, x, y);
83df96d6
JS
586}
587
588// ---------------------------------------------------------------------------
589// scrolling stuff
590// ---------------------------------------------------------------------------
591
bc797f4c 592int wxWindowX11::GetScrollPos(int orient) const
83df96d6
JS
593{
594 if (orient == wxHORIZONTAL)
595 return m_scrollPosX;
596 else
597 return m_scrollPosY;
83df96d6
JS
598}
599
600// This now returns the whole range, not just the number of positions that we
601// can scroll.
bc797f4c 602int wxWindowX11::GetScrollRange(int WXUNUSED(orient)) const
83df96d6 603{
bc797f4c
JS
604 // TODO
605 return 0;
606#if 0
83df96d6
JS
607 Widget scrollBar = (Widget)GetScrollbar((wxOrientation)orient);
608 wxCHECK_MSG( scrollBar, 0, "no such scrollbar" );
609
610 int range;
611 XtVaGetValues(scrollBar, XmNmaximum, &range, NULL);
612 return range;
bc797f4c 613#endif
83df96d6
JS
614}
615
bc797f4c 616int wxWindowX11::GetScrollThumb(int orient) const
83df96d6 617{
bc797f4c
JS
618 // TODO
619 return 0;
620
621#if 0
83df96d6
JS
622 Widget scrollBar = (Widget)GetScrollbar((wxOrientation)orient);
623 wxCHECK_MSG( scrollBar, 0, "no such scrollbar" );
624
625 int thumb;
626 XtVaGetValues(scrollBar, XmNsliderSize, &thumb, NULL);
627 return thumb;
bc797f4c 628#endif
83df96d6
JS
629}
630
7266b672 631void wxWindowX11::SetScrollPos(int orient, int pos, bool WXUNUSED(refresh))
83df96d6 632{
bc797f4c
JS
633 // TODO
634
635#if 0
83df96d6
JS
636 Widget scrollBar = (Widget)GetScrollbar((wxOrientation)orient);
637
638 if ( scrollBar )
639 {
640 XtVaSetValues (scrollBar, XmNvalue, pos, NULL);
641 }
bc797f4c 642#endif
83df96d6
JS
643 SetInternalScrollPos((wxOrientation)orient, pos);
644}
645
646// New function that will replace some of the above.
bc797f4c
JS
647void wxWindowX11::SetScrollbar(int WXUNUSED(orient), int WXUNUSED(pos), int WXUNUSED(thumbVisible),
648 int WXUNUSED(range), bool WXUNUSED(refresh))
83df96d6 649{
bc797f4c
JS
650 // TODO
651#if 0
83df96d6
JS
652 int oldW, oldH;
653 GetSize(& oldW, & oldH);
654
655 if (range == 0)
656 range = 1;
657 if (thumbVisible == 0)
658 thumbVisible = 1;
659
660 if (thumbVisible > range)
661 thumbVisible = range;
662
663 // Save the old state to see if it changed
664 WXWidget oldScrollBar = GetScrollbar((wxOrientation)orient);
665
666 if (orient == wxHORIZONTAL)
667 {
668 if (thumbVisible == range)
669 {
670 if (m_hScrollBar)
671 DestroyScrollbar(wxHORIZONTAL);
672 }
673 else
674 {
675 if (!m_hScrollBar)
676 CreateScrollbar(wxHORIZONTAL);
677 }
678 }
679 if (orient == wxVERTICAL)
680 {
681 if (thumbVisible == range)
682 {
683 if (m_vScrollBar)
684 DestroyScrollbar(wxVERTICAL);
685 }
686 else
687 {
688 if (!m_vScrollBar)
689 CreateScrollbar(wxVERTICAL);
690 }
691 }
692 WXWidget newScrollBar = GetScrollbar((wxOrientation)orient);
693
694 if (oldScrollBar != newScrollBar)
695 {
696 // This is important! Without it, scrollbars misbehave badly.
697 XtUnrealizeWidget((Widget) m_scrolledWindow);
698 XmScrolledWindowSetAreas ((Widget) m_scrolledWindow, (Widget) m_hScrollBar, (Widget) m_vScrollBar, (Widget) m_drawingArea);
699 XtRealizeWidget((Widget) m_scrolledWindow);
700 XtManageChild((Widget) m_scrolledWindow);
701 }
702
703 if (newScrollBar)
704 {
705 XtVaSetValues((Widget) newScrollBar,
706 XmNvalue, pos,
707 XmNminimum, 0,
708 XmNmaximum, range,
709 XmNsliderSize, thumbVisible,
710 NULL);
711 }
712
713 SetInternalScrollPos((wxOrientation)orient, pos);
714
715 int newW, newH;
716 GetSize(& newW, & newH);
717
718 // Adjusting scrollbars can resize the canvas accidentally
719 if (newW != oldW || newH != oldH)
720 SetSize(-1, -1, oldW, oldH);
bc797f4c 721#endif
83df96d6
JS
722}
723
724// Does a physical scroll
bc797f4c 725void wxWindowX11::ScrollWindow(int dx, int dy, const wxRect *rect)
83df96d6
JS
726{
727 int x, y, w, h;
728 if (rect)
729 {
730 // Use specified rectangle
731 x = rect->x; y = rect->y; w = rect->width; h = rect->height;
732 }
733 else
734 {
735 // Use whole client area
736 x = 0; y = 0;
737 GetClientSize(& w, & h);
738 }
bc797f4c 739
83df96d6
JS
740 wxNode *cnode = m_children.First();
741 while (cnode)
742 {
743 wxWindow *child = (wxWindow*) cnode->Data();
bc797f4c
JS
744 int sx = 0;
745 int sy = 0;
746 child->GetSize( &sx, &sy );
83df96d6 747 wxPoint pos( child->GetPosition() );
bc797f4c
JS
748 child->SetSize( pos.x + dx, pos.y + dy, sx, sy, wxSIZE_ALLOW_MINUS_ONE );
749 cnode = cnode->Next();
83df96d6 750 }
bc797f4c 751
83df96d6
JS
752 int x1 = (dx >= 0) ? x : x - dx;
753 int y1 = (dy >= 0) ? y : y - dy;
754 int w1 = w - abs(dx);
755 int h1 = h - abs(dy);
756 int x2 = (dx >= 0) ? x + dx : x;
757 int y2 = (dy >= 0) ? y + dy : y;
bc797f4c 758
7266b672 759 wxClientDC dc((wxWindow*) this);
bc797f4c 760
83df96d6 761 dc.SetLogicalFunction (wxCOPY);
bc797f4c
JS
762
763 Window window = (Window) GetMainWindow();
7266b672 764 Display* display = (Display*) wxGetDisplay();
bc797f4c 765
83df96d6 766 XCopyArea(display, window, window, (GC) dc.GetGC(),
bc797f4c
JS
767 x1, y1, w1, h1, x2, y2);
768
83df96d6
JS
769 dc.SetAutoSetting(TRUE);
770 wxBrush brush(GetBackgroundColour(), wxSOLID);
771 dc.SetBrush(brush); // FIXME: needed?
bc797f4c 772
83df96d6
JS
773 // We'll add rectangles to the list of update rectangles according to which
774 // bits we've exposed.
775 wxList updateRects;
bc797f4c 776
83df96d6
JS
777 if (dx > 0)
778 {
779 wxRect *rect = new wxRect;
780 rect->x = x;
781 rect->y = y;
782 rect->width = dx;
783 rect->height = h;
bc797f4c 784
83df96d6
JS
785 XFillRectangle(display, window,
786 (GC) dc.GetGC(), rect->x, rect->y, rect->width, rect->height);
bc797f4c 787
83df96d6
JS
788 rect->x = rect->x;
789 rect->y = rect->y;
790 rect->width = rect->width;
791 rect->height = rect->height;
bc797f4c 792
83df96d6
JS
793 updateRects.Append((wxObject*) rect);
794 }
795 else if (dx < 0)
796 {
797 wxRect *rect = new wxRect;
bc797f4c 798
83df96d6
JS
799 rect->x = x + w + dx;
800 rect->y = y;
801 rect->width = -dx;
802 rect->height = h;
bc797f4c 803
83df96d6
JS
804 XFillRectangle(display, window,
805 (GC) dc.GetGC(), rect->x, rect->y, rect->width,
806 rect->height);
bc797f4c 807
83df96d6
JS
808 rect->x = rect->x;
809 rect->y = rect->y;
810 rect->width = rect->width;
811 rect->height = rect->height;
bc797f4c 812
83df96d6
JS
813 updateRects.Append((wxObject*) rect);
814 }
815 if (dy > 0)
816 {
817 wxRect *rect = new wxRect;
bc797f4c 818
83df96d6
JS
819 rect->x = x;
820 rect->y = y;
821 rect->width = w;
822 rect->height = dy;
bc797f4c 823
83df96d6
JS
824 XFillRectangle(display, window,
825 (GC) dc.GetGC(), rect->x, rect->y, rect->width, rect->height);
bc797f4c 826
83df96d6
JS
827 rect->x = rect->x;
828 rect->y = rect->y;
829 rect->width = rect->width;
830 rect->height = rect->height;
bc797f4c 831
83df96d6
JS
832 updateRects.Append((wxObject*) rect);
833 }
834 else if (dy < 0)
835 {
836 wxRect *rect = new wxRect;
bc797f4c 837
83df96d6
JS
838 rect->x = x;
839 rect->y = y + h + dy;
840 rect->width = w;
841 rect->height = -dy;
bc797f4c 842
83df96d6
JS
843 XFillRectangle(display, window,
844 (GC) dc.GetGC(), rect->x, rect->y, rect->width, rect->height);
bc797f4c 845
83df96d6
JS
846 rect->x = rect->x;
847 rect->y = rect->y;
848 rect->width = rect->width;
849 rect->height = rect->height;
bc797f4c 850
83df96d6
JS
851 updateRects.Append((wxObject*) rect);
852 }
853 dc.SetBrush(wxNullBrush);
bc797f4c 854
83df96d6 855 // Now send expose events
bc797f4c 856
83df96d6
JS
857 wxNode* node = updateRects.First();
858 while (node)
859 {
860 wxRect* rect = (wxRect*) node->Data();
861 XExposeEvent event;
bc797f4c 862
83df96d6
JS
863 event.type = Expose;
864 event.display = display;
865 event.send_event = True;
866 event.window = window;
bc797f4c 867
83df96d6
JS
868 event.x = rect->x;
869 event.y = rect->y;
870 event.width = rect->width;
871 event.height = rect->height;
bc797f4c 872
83df96d6 873 event.count = 0;
bc797f4c 874
83df96d6 875 XSendEvent(display, window, False, ExposureMask, (XEvent *)&event);
bc797f4c 876
83df96d6 877 node = node->Next();
bc797f4c 878
83df96d6 879 }
bc797f4c 880
83df96d6
JS
881 // Delete the update rects
882 node = updateRects.First();
883 while (node)
884 {
885 wxRect* rect = (wxRect*) node->Data();
886 delete rect;
887 node = node->Next();
888 }
bc797f4c
JS
889
890 // TODO
83df96d6 891
bc797f4c 892 // XmUpdateDisplay((Widget) GetMainWidget());
83df96d6
JS
893}
894
895// ---------------------------------------------------------------------------
896// drag and drop
897// ---------------------------------------------------------------------------
898
899#if wxUSE_DRAG_AND_DROP
900
bc797f4c 901void wxWindowX11::SetDropTarget(wxDropTarget * WXUNUSED(pDropTarget))
83df96d6
JS
902{
903 // TODO
904}
905
906#endif
907
908// Old style file-manager drag&drop
bc797f4c 909void wxWindowX11::DragAcceptFiles(bool WXUNUSED(accept))
83df96d6
JS
910{
911 // TODO
912}
913
914// ----------------------------------------------------------------------------
915// tooltips
916// ----------------------------------------------------------------------------
917
918#if wxUSE_TOOLTIPS
919
bc797f4c 920void wxWindowX11::DoSetToolTip(wxToolTip * WXUNUSED(tooltip))
83df96d6
JS
921{
922 // TODO
923}
924
925#endif // wxUSE_TOOLTIPS
926
83df96d6
JS
927// ---------------------------------------------------------------------------
928// moving and resizing
929// ---------------------------------------------------------------------------
930
bc797f4c 931bool wxWindowX11::PreResize()
83df96d6
JS
932{
933 return TRUE;
934}
935
936// Get total size
bc797f4c 937void wxWindowX11::DoGetSize(int *x, int *y) const
83df96d6 938{
bc797f4c
JS
939 // TODO
940#if 0
83df96d6
JS
941 if (m_drawingArea)
942 {
943 CanvasGetSize(x, y);
944 return;
945 }
946
947 Widget widget = (Widget) GetTopWidget();
948 Dimension xx, yy;
949 XtVaGetValues(widget, XmNwidth, &xx, XmNheight, &yy, NULL);
950 if(x) *x = xx; if(y) *y = yy;
bc797f4c 951#endif
83df96d6
JS
952}
953
bc797f4c 954void wxWindowX11::DoGetPosition(int *x, int *y) const
83df96d6 955{
bc797f4c
JS
956 // TODO
957#if 0
83df96d6
JS
958 if (m_drawingArea)
959 {
960 CanvasGetPosition(x, y);
961 return;
962 }
963 Widget widget = (Widget) GetTopWidget();
964 Position xx, yy;
965 XtVaGetValues(widget, XmNx, &xx, XmNy, &yy, NULL);
966
967 // We may be faking the client origin. So a window that's really at (0, 30)
968 // may appear (to wxWin apps) to be at (0, 0).
969 if (GetParent())
970 {
971 wxPoint pt(GetParent()->GetClientAreaOrigin());
972 xx -= pt.x;
973 yy -= pt.y;
974 }
975
976 if(x) *x = xx; if(y) *y = yy;
bc797f4c 977#endif
83df96d6
JS
978}
979
bc797f4c 980void wxWindowX11::DoScreenToClient(int *x, int *y) const
83df96d6 981{
7266b672 982 Display *display = (Display*) wxGetDisplay();
bc797f4c
JS
983 Window rootWindow = RootWindowOfScreen(DefaultScreenOfDisplay(display));
984 Window thisWindow = (Window) GetClientWindow();
83df96d6
JS
985
986 Window childWindow;
987 int xx = *x;
988 int yy = *y;
989 XTranslateCoordinates(display, rootWindow, thisWindow, xx, yy, x, y, &childWindow);
990}
991
bc797f4c 992void wxWindowX11::DoClientToScreen(int *x, int *y) const
83df96d6 993{
7266b672 994 Display *display = (Display*) wxGetDisplay();
bc797f4c
JS
995 Window rootWindow = RootWindowOfScreen(DefaultScreenOfDisplay(display));
996 Window thisWindow = (Window) GetClientWindow();
83df96d6
JS
997
998 Window childWindow;
999 int xx = *x;
1000 int yy = *y;
1001 XTranslateCoordinates(display, thisWindow, rootWindow, xx, yy, x, y, &childWindow);
1002}
1003
1004
1005// Get size *available for subwindows* i.e. excluding menu bar etc.
bc797f4c 1006void wxWindowX11::DoGetClientSize(int *x, int *y) const
83df96d6 1007{
bc797f4c
JS
1008 // TODO
1009#if 0
83df96d6
JS
1010 Widget widget = (Widget) GetClientWidget();
1011 Dimension xx, yy;
1012 XtVaGetValues(widget, XmNwidth, &xx, XmNheight, &yy, NULL);
1013 if(x) *x = xx; if(y) *y = yy;
bc797f4c 1014#endif
83df96d6
JS
1015}
1016
bc797f4c 1017void wxWindowX11::DoSetSize(int x, int y, int width, int height, int sizeFlags)
83df96d6 1018{
bc797f4c
JS
1019 // TODO
1020#if 0
83df96d6
JS
1021 // A bit of optimization to help sort out the flickers.
1022 int oldX, oldY, oldW, oldH;
1023 GetSize(& oldW, & oldH);
1024 GetPosition(& oldX, & oldY);
1025
1026 if ( !(sizeFlags & wxSIZE_ALLOW_MINUS_ONE) )
1027 {
1028 if ( x == -1 )
1029 x = oldX;
1030 if ( y == -1 )
1031 y = oldY;
1032 }
1033
1034 if ( width == -1 )
1035 width = oldW;
1036 if ( height == -1 )
1037 height = oldH;
1038
1039 bool nothingChanged = (x == oldX) && (y == oldY) &&
1040 (width == oldW) && (height == oldH);
1041
1042 if (!wxNoOptimize::CanOptimize())
1043 {
1044 nothingChanged = FALSE;
1045 }
1046
1047 if ( !nothingChanged )
1048 {
1049 if (m_drawingArea)
1050 {
1051 CanvasSetSize(x, y, width, height, sizeFlags);
1052 return;
1053 }
1054
1055 Widget widget = (Widget) GetTopWidget();
1056 if (!widget)
1057 return;
1058
1059 bool managed = XtIsManaged( widget );
1060 if (managed)
1061 XtUnmanageChild(widget);
1062
1063 int xx = x;
1064 int yy = y;
1065 AdjustForParentClientOrigin(xx, yy, sizeFlags);
1066
1067 DoMoveWindow(xx, yy, width, height);
1068
1069 if (managed)
1070 XtManageChild(widget);
1071
83df96d6 1072 }
bc797f4c 1073#endif
83df96d6
JS
1074}
1075
bc797f4c 1076void wxWindowX11::DoSetClientSize(int width, int height)
83df96d6 1077{
bc797f4c
JS
1078 // TODO
1079#if 0
83df96d6
JS
1080 if (m_drawingArea)
1081 {
1082 CanvasSetClientSize(width, height);
1083 return;
1084 }
1085
1086 Widget widget = (Widget) GetTopWidget();
1087
1088 if (width > -1)
1089 XtVaSetValues(widget, XmNwidth, width, NULL);
1090 if (height > -1)
1091 XtVaSetValues(widget, XmNheight, height, NULL);
1092
1093 wxSizeEvent sizeEvent(wxSize(width, height), GetId());
1094 sizeEvent.SetEventObject(this);
1095
1096 GetEventHandler()->ProcessEvent(sizeEvent);
bc797f4c 1097#endif
83df96d6
JS
1098}
1099
1100// For implementation purposes - sometimes decorations make the client area
1101// smaller
bc797f4c 1102wxPoint wxWindowX11::GetClientAreaOrigin() const
83df96d6
JS
1103{
1104 return wxPoint(0, 0);
1105}
1106
1107// Makes an adjustment to the window position (for example, a frame that has
1108// a toolbar that it manages itself).
bc797f4c 1109void wxWindowX11::AdjustForParentClientOrigin(int& x, int& y, int sizeFlags)
83df96d6
JS
1110{
1111 if (((sizeFlags & wxSIZE_NO_ADJUSTMENTS) == 0) && GetParent())
1112 {
1113 wxPoint pt(GetParent()->GetClientAreaOrigin());
1114 x += pt.x; y += pt.y;
1115 }
1116}
1117
bc797f4c 1118void wxWindowX11::SetSizeHints(int minW, int minH, int maxW, int maxH, int incW, int incH)
83df96d6 1119{
bc797f4c
JS
1120 // TODO
1121#if 0
83df96d6
JS
1122 m_minWidth = minW;
1123 m_minHeight = minH;
1124 m_maxWidth = maxW;
1125 m_maxHeight = maxH;
1126
1127 wxFrame *frame = wxDynamicCast(this, wxFrame);
1128 if ( !frame )
1129 {
1130 // TODO what about dialogs?
1131 return;
1132 }
1133
1134 Widget widget = (Widget) frame->GetShellWidget();
1135
1136 if (minW > -1)
1137 XtVaSetValues(widget, XmNminWidth, minW, NULL);
1138 if (minH > -1)
1139 XtVaSetValues(widget, XmNminHeight, minH, NULL);
1140 if (maxW > -1)
1141 XtVaSetValues(widget, XmNmaxWidth, maxW, NULL);
1142 if (maxH > -1)
1143 XtVaSetValues(widget, XmNmaxHeight, maxH, NULL);
1144 if (incW > -1)
1145 XtVaSetValues(widget, XmNwidthInc, incW, NULL);
1146 if (incH > -1)
1147 XtVaSetValues(widget, XmNheightInc, incH, NULL);
bc797f4c 1148#endif
83df96d6
JS
1149}
1150
bc797f4c 1151void wxWindowX11::DoMoveWindow(int x, int y, int width, int height)
83df96d6 1152{
bc797f4c
JS
1153 // TODO
1154#if 0
83df96d6
JS
1155 XtVaSetValues((Widget)GetTopWidget(),
1156 XmNx, x,
1157 XmNy, y,
1158 XmNwidth, width,
1159 XmNheight, height,
1160 NULL);
bc797f4c 1161#endif
83df96d6
JS
1162}
1163
1164// ---------------------------------------------------------------------------
1165// text metrics
1166// ---------------------------------------------------------------------------
1167
bc797f4c 1168int wxWindowX11::GetCharHeight() const
83df96d6
JS
1169{
1170 wxCHECK_MSG( m_font.Ok(), 0, "valid window font needed" );
1171
1172 WXFontStructPtr pFontStruct = m_font.GetFontStruct(1.0, GetXDisplay());
1173
1174 int direction, ascent, descent;
1175 XCharStruct overall;
1176 XTextExtents ((XFontStruct*) pFontStruct, "x", 1, &direction, &ascent,
1177 &descent, &overall);
1178
1179 // return (overall.ascent + overall.descent);
1180 return (ascent + descent);
1181}
1182
bc797f4c 1183int wxWindowX11::GetCharWidth() const
83df96d6
JS
1184{
1185 wxCHECK_MSG( m_font.Ok(), 0, "valid window font needed" );
1186
1187 WXFontStructPtr pFontStruct = m_font.GetFontStruct(1.0, GetXDisplay());
1188
1189 int direction, ascent, descent;
1190 XCharStruct overall;
1191 XTextExtents ((XFontStruct*) pFontStruct, "x", 1, &direction, &ascent,
1192 &descent, &overall);
1193
1194 return overall.width;
1195}
1196
bc797f4c 1197void wxWindowX11::GetTextExtent(const wxString& string,
83df96d6
JS
1198 int *x, int *y,
1199 int *descent, int *externalLeading,
1200 const wxFont *theFont) const
1201{
1202 wxFont *fontToUse = (wxFont *)theFont;
1203 if (!fontToUse)
1204 fontToUse = (wxFont *) & m_font;
1205
1206 wxCHECK_RET( fontToUse->Ok(), "valid window font needed" );
1207
1208 WXFontStructPtr pFontStruct = theFont->GetFontStruct(1.0, GetXDisplay());
1209
1210 int direction, ascent, descent2;
1211 XCharStruct overall;
1212 int slen = string.Len();
1213
1214#if 0
1215 if (use16)
1216 XTextExtents16((XFontStruct*) pFontStruct, (XChar2b *) (char*) (const char*) string, slen, &direction,
1217 &ascent, &descent2, &overall);
1218#endif
1219
1220 XTextExtents((XFontStruct*) pFontStruct, string, slen,
1221 &direction, &ascent, &descent2, &overall);
1222
1223 if ( x )
1224 *x = (overall.width);
1225 if ( y )
1226 *y = (ascent + descent2);
1227 if (descent)
1228 *descent = descent2;
1229 if (externalLeading)
1230 *externalLeading = 0;
1231
1232}
1233
1234// ----------------------------------------------------------------------------
1235// painting
1236// ----------------------------------------------------------------------------
1237
bc797f4c 1238void wxWindowX11::Refresh(bool eraseBack, const wxRect *rect)
83df96d6
JS
1239{
1240 m_needsRefresh = TRUE;
7266b672
JS
1241 Display *display = (Display*) wxGetDisplay();
1242 Window thisWindow = (Window) GetMainWindow();
83df96d6
JS
1243
1244 XExposeEvent dummyEvent;
1245 int width, height;
1246 GetSize(&width, &height);
1247
1248 dummyEvent.type = Expose;
1249 dummyEvent.display = display;
1250 dummyEvent.send_event = True;
1251 dummyEvent.window = thisWindow;
1252 if (rect)
1253 {
1254 dummyEvent.x = rect->x;
1255 dummyEvent.y = rect->y;
1256 dummyEvent.width = rect->width;
1257 dummyEvent.height = rect->height;
1258 }
1259 else
1260 {
1261 dummyEvent.x = 0;
1262 dummyEvent.y = 0;
1263 dummyEvent.width = width;
1264 dummyEvent.height = height;
1265 }
1266 dummyEvent.count = 0;
1267
1268 if (eraseBack)
1269 {
7266b672 1270 wxClientDC dc((wxWindow*) this);
83df96d6
JS
1271 wxBrush backgroundBrush(GetBackgroundColour(), wxSOLID);
1272 dc.SetBackground(backgroundBrush);
1273 if (rect)
1274 dc.Clear(*rect);
1275 else
1276 dc.Clear();
1277 }
1278
1279 XSendEvent(display, thisWindow, False, ExposureMask, (XEvent *)&dummyEvent);
1280}
1281
bc797f4c 1282void wxWindowX11::Clear()
83df96d6 1283{
7266b672 1284 wxClientDC dc((wxWindow*) this);
83df96d6
JS
1285 wxBrush brush(GetBackgroundColour(), wxSOLID);
1286 dc.SetBackground(brush);
1287 dc.Clear();
1288}
1289
bc797f4c 1290void wxWindowX11::ClearUpdateRects()
83df96d6
JS
1291{
1292 wxRectList::Node* node = m_updateRects.GetFirst();
1293 while (node)
1294 {
1295 wxRect* rect = node->GetData();
1296 delete rect;
1297 node = node->GetNext();
1298 }
1299
1300 m_updateRects.Clear();
1301}
1302
bc797f4c 1303void wxWindowX11::DoPaint()
83df96d6 1304{
bc797f4c
JS
1305 // Set an erase event first
1306 wxEraseEvent eraseEvent(GetId());
1307 eraseEvent.SetEventObject(this);
1308 GetEventHandler()->ProcessEvent(eraseEvent);
1309
1310 wxPaintEvent event(GetId());
1311 event.SetEventObject(this);
1312 GetEventHandler()->ProcessEvent(event);
1313
1314 m_needsRefresh = FALSE;
83df96d6
JS
1315}
1316
1317// ----------------------------------------------------------------------------
1318// event handlers
1319// ----------------------------------------------------------------------------
1320
1321// Responds to colour changes: passes event on to children.
bc797f4c 1322void wxWindowX11::OnSysColourChanged(wxSysColourChangedEvent& event)
83df96d6
JS
1323{
1324 wxWindowList::Node *node = GetChildren().GetFirst();
1325 while ( node )
1326 {
1327 // Only propagate to non-top-level windows
1328 wxWindow *win = node->GetData();
1329 if ( win->GetParent() )
1330 {
1331 wxSysColourChangedEvent event2;
1332 event.m_eventObject = win;
1333 win->GetEventHandler()->ProcessEvent(event2);
1334 }
1335
1336 node = node->GetNext();
1337 }
1338}
1339
bc797f4c 1340void wxWindowX11::OnIdle(wxIdleEvent& WXUNUSED(event))
83df96d6
JS
1341{
1342 // This calls the UI-update mechanism (querying windows for
1343 // menu/toolbar/control state information)
1344 UpdateWindowUI();
1345}
1346
1347// ----------------------------------------------------------------------------
1348// accelerators
1349// ----------------------------------------------------------------------------
1350
bc797f4c 1351bool wxWindowX11::ProcessAccelerator(wxKeyEvent& event)
83df96d6
JS
1352{
1353 if (!m_acceleratorTable.Ok())
1354 return FALSE;
1355
7266b672
JS
1356 const wxAcceleratorEntry* entry = m_acceleratorTable.GetEntry(event);
1357 if (entry)
83df96d6 1358 {
83df96d6
JS
1359 // Bingo, we have a match. Now find a control that matches the
1360 // entry command id.
1361
1362 // Need to go up to the top of the window hierarchy, since it might
1363 // be e.g. a menu item
7266b672 1364 wxWindow* parent = (wxWindow*) this;
83df96d6
JS
1365 while ( parent && !parent->IsTopLevel() )
1366 parent = parent->GetParent();
1367
1368 if (!parent)
1369 return FALSE;
1370
1371 wxFrame* frame = wxDynamicCast(parent, wxFrame);
1372 if ( frame )
1373 {
1374 // Try for a menu command
1375 if (frame->GetMenuBar())
1376 {
1377 wxMenuItem* item = frame->GetMenuBar()->FindItem(entry->GetCommand());
1378 if (item)
1379 {
1380 wxCommandEvent commandEvent(wxEVT_COMMAND_MENU_SELECTED, entry->GetCommand());
1381 commandEvent.SetEventObject(frame);
1382
1383 // If ProcessEvent returns TRUE (it was handled), then
1384 // the calling code will skip the event handling.
1385 return frame->GetEventHandler()->ProcessEvent(commandEvent);
1386 }
1387 }
1388 }
1389
1390 // Find a child matching the command id
1391 wxWindow* child = parent->FindWindow(entry->GetCommand());
1392
1393 // No such child
1394 if (!child)
1395 return FALSE;
1396
1397 // Now we process those kinds of windows that we can.
1398 // For now, only buttons.
1399 if ( wxDynamicCast(child, wxButton) )
1400 {
1401 wxCommandEvent commandEvent (wxEVT_COMMAND_BUTTON_CLICKED, child->GetId());
1402 commandEvent.SetEventObject(child);
1403 return child->GetEventHandler()->ProcessEvent(commandEvent);
1404 }
1405
1406 return FALSE;
7266b672
JS
1407
1408 }// if
83df96d6
JS
1409
1410 // We didn't match the key event against an accelerator.
1411 return FALSE;
1412}
1413
1414// ============================================================================
bc797f4c 1415// X11-specific stuff from here on
83df96d6
JS
1416// ============================================================================
1417
1418// ----------------------------------------------------------------------------
1419// function which maintain the global hash table mapping Widgets to wxWindows
1420// ----------------------------------------------------------------------------
1421
bc797f4c 1422bool wxAddWindowToTable(Window w, wxWindow *win)
83df96d6
JS
1423{
1424 wxWindow *oldItem = NULL;
1425 if ((oldItem = (wxWindow *)wxWidgetHashTable->Get ((long) w)))
1426 {
1427 wxLogDebug("Widget table clash: new widget is %ld, %s",
1428 (long)w, win->GetClassInfo()->GetClassName());
1429 return FALSE;
1430 }
1431
1432 wxWidgetHashTable->Put((long) w, win);
1433
bc797f4c 1434 wxLogTrace("widget", "XWindow 0x%08x <-> window %p (%s)",
83df96d6
JS
1435 w, win, win->GetClassInfo()->GetClassName());
1436
1437 return TRUE;
1438}
1439
bc797f4c 1440wxWindow *wxGetWindowFromTable(Window w)
83df96d6
JS
1441{
1442 return (wxWindow *)wxWidgetHashTable->Get((long) w);
1443}
1444
bc797f4c 1445void wxDeleteWindowFromTable(Window w)
83df96d6
JS
1446{
1447 wxWidgetHashTable->Delete((long)w);
1448}
1449
1450// ----------------------------------------------------------------------------
1451// add/remove window from the table
1452// ----------------------------------------------------------------------------
1453
1454// Add to hash table, add event handler
7266b672 1455bool wxWindowX11::AttachWindow (wxWindow* WXUNUSED(parent), WXWindow mainWidget,
bc797f4c 1456 int x, int y, int width, int height)
83df96d6 1457{
7266b672 1458 wxAddWindowToTable((Window ) mainWidget, (wxWindow*) this);
bc797f4c
JS
1459
1460 // TODO
1461#if 0
83df96d6
JS
1462 if (CanAddEventHandler())
1463 {
1464 XtAddEventHandler((Widget) mainWidget,
1465 ButtonPressMask | ButtonReleaseMask | PointerMotionMask, // | KeyPressMask,
1466 False,
1467 wxPanelItemEventHandler,
1468 (XtPointer) this);
1469 }
1470
1471 if (!formWidget)
1472 {
1473 XtTranslations ptr;
1474 XtOverrideTranslations ((Widget) mainWidget,
1475 ptr = XtParseTranslationTable ("<Configure>: resize()"));
1476 XtFree ((char *) ptr);
1477 }
1478
1479 // Some widgets have a parent form widget, e.g. wxRadioBox
1480 if (formWidget)
1481 {
1482 if (!wxAddWindowToTable((Widget) formWidget, this))
1483 return FALSE;
1484
1485 XtTranslations ptr;
1486 XtOverrideTranslations ((Widget) formWidget,
1487 ptr = XtParseTranslationTable ("<Configure>: resize()"));
1488 XtFree ((char *) ptr);
1489 }
bc797f4c 1490#endif
83df96d6
JS
1491 if (x == -1)
1492 x = 0;
1493 if (y == -1)
1494 y = 0;
bc797f4c 1495
83df96d6
JS
1496 SetSize (x, y, width, height);
1497
1498 return TRUE;
1499}
1500
1501// Remove event handler, remove from hash table
7266b672 1502bool wxWindowX11::DetachWindow(WXWindow widget)
83df96d6 1503{
bc797f4c
JS
1504 // TODO
1505#if 0
83df96d6
JS
1506 if (CanAddEventHandler())
1507 {
1508 XtRemoveEventHandler((Widget) widget,
1509 ButtonPressMask | ButtonReleaseMask | PointerMotionMask, // | KeyPressMask,
1510 False,
1511 wxPanelItemEventHandler,
1512 (XtPointer)this);
1513 }
bc797f4c 1514#endif
83df96d6 1515
bc797f4c 1516 wxDeleteWindowFromTable((Window) widget);
83df96d6
JS
1517 return TRUE;
1518}
1519
1520// ----------------------------------------------------------------------------
bc797f4c 1521// X11-specific accessors
83df96d6
JS
1522// ----------------------------------------------------------------------------
1523
1524// Get the underlying X window
bc797f4c 1525WXWindow wxWindowX11::GetXWindow() const
83df96d6 1526{
bc797f4c 1527 return GetMainWindow();
83df96d6
JS
1528}
1529
1530// Get the underlying X display
bc797f4c 1531WXDisplay *wxWindowX11::GetXDisplay() const
83df96d6 1532{
bc797f4c 1533 return wxGetDisplay();
83df96d6
JS
1534}
1535
bc797f4c 1536WXWindow wxWindowX11::GetMainWindow() const
83df96d6
JS
1537{
1538 if (m_drawingArea)
1539 return m_drawingArea;
1540 else
1541 return m_mainWidget;
1542}
1543
7266b672 1544WXWindow wxWindowX11::GetClientWindow() const
83df96d6 1545{
bc797f4c 1546 if (m_drawingArea != (WXWindow) 0)
83df96d6
JS
1547 return m_drawingArea;
1548 else
bc797f4c 1549 return GetMainWindow();
83df96d6
JS
1550}
1551
bc797f4c 1552WXWindow wxWindowX11::GetTopWindow() const
83df96d6 1553{
bc797f4c 1554 return GetMainWindow();
83df96d6
JS
1555}
1556
bc797f4c 1557WXWindow wxWindowX11::GetLabelWindow() const
83df96d6 1558{
bc797f4c 1559 return GetMainWindow();
83df96d6
JS
1560}
1561
1562// ----------------------------------------------------------------------------
bc797f4c 1563// callbacks
83df96d6
JS
1564// ----------------------------------------------------------------------------
1565
1b0fb34b 1566// TODO: implement wxWindow scrollbar, presumably using wxScrollBar
83df96d6 1567#if 0
83df96d6
JS
1568static void wxScrollBarCallback(Widget scrollbar,
1569 XtPointer clientData,
1570 XmScrollBarCallbackStruct *cbs)
1571{
1572 wxWindow *win = wxGetWindowFromTable(scrollbar);
1573 int orientation = (int) clientData;
1574
1575 wxEventType eventType = wxEVT_NULL;
1576 switch (cbs->reason)
1577 {
1578 case XmCR_INCREMENT:
1579 {
1580 eventType = wxEVT_SCROLLWIN_LINEDOWN;
1581 break;
1582 }
1583 case XmCR_DECREMENT:
1584 {
1585 eventType = wxEVT_SCROLLWIN_LINEUP;
1586 break;
1587 }
1588 case XmCR_DRAG:
1589 {
1590 eventType = wxEVT_SCROLLWIN_THUMBTRACK;
1591 break;
1592 }
1593 case XmCR_VALUE_CHANGED:
1594 {
1595 eventType = wxEVT_SCROLLWIN_THUMBRELEASE;
1596 break;
1597 }
1598 case XmCR_PAGE_INCREMENT:
1599 {
1600 eventType = wxEVT_SCROLLWIN_PAGEDOWN;
1601 break;
1602 }
1603 case XmCR_PAGE_DECREMENT:
1604 {
1605 eventType = wxEVT_SCROLLWIN_PAGEUP;
1606 break;
1607 }
1608 case XmCR_TO_TOP:
1609 {
1610 eventType = wxEVT_SCROLLWIN_TOP;
1611 break;
1612 }
1613 case XmCR_TO_BOTTOM:
1614 {
1615 eventType = wxEVT_SCROLLWIN_BOTTOM;
1616 break;
1617 }
1618 default:
1619 {
1620 // Should never get here
1621 wxFAIL_MSG("Unknown scroll event.");
1622 break;
1623 }
1624 }
1625
1626 wxScrollWinEvent event(eventType,
1627 cbs->value,
1628 ((orientation == XmHORIZONTAL) ?
1629 wxHORIZONTAL : wxVERTICAL));
1630 event.SetEventObject( win );
1631 win->GetEventHandler()->ProcessEvent(event);
1632}
bc797f4c 1633#endif
1b0fb34b 1634
bc797f4c 1635
83df96d6
JS
1636// ----------------------------------------------------------------------------
1637// CanvaseXXXSize() functions
1638// ----------------------------------------------------------------------------
1639
1640// SetSize, but as per old wxCanvas (with drawing widget etc.)
bc797f4c 1641void wxWindowX11::CanvasSetSize (int x, int y, int w, int h, int sizeFlags)
83df96d6 1642{
bc797f4c
JS
1643 // TODO
1644#if 0
83df96d6
JS
1645 // A bit of optimization to help sort out the flickers.
1646 int oldX, oldY, oldW, oldH;
1647 GetSize(& oldW, & oldH);
1648 GetPosition(& oldX, & oldY);
1649
1650 bool useOldPos = FALSE;
1651 bool useOldSize = FALSE;
1652
1653 if ((x == -1) && (x == -1) && ((sizeFlags & wxSIZE_ALLOW_MINUS_ONE) == 0))
1654 useOldPos = TRUE;
1655 else if (x == oldX && y == oldY)
1656 useOldPos = TRUE;
1657
1658 if ((w == -1) && (h == -1))
1659 useOldSize = TRUE;
1660 else if (w == oldW && h == oldH)
1661 useOldSize = TRUE;
1662
1663 if (!wxNoOptimize::CanOptimize())
1664 {
1665 useOldSize = FALSE; useOldPos = FALSE;
1666 }
1667
1668 if (useOldPos && useOldSize)
1669 return;
1670
1671 Widget drawingArea = (Widget) m_drawingArea;
1672 bool managed = XtIsManaged(m_borderWidget ? (Widget) m_borderWidget : (Widget) m_scrolledWindow);
1673
1674 if (managed)
1675 XtUnmanageChild (m_borderWidget ? (Widget) m_borderWidget : (Widget) m_scrolledWindow);
1676 XtVaSetValues(drawingArea, XmNresizePolicy, XmRESIZE_ANY, NULL);
1677
1678 int xx = x; int yy = y;
1679 AdjustForParentClientOrigin(xx, yy, sizeFlags);
1680
1681 if (!useOldPos)
1682 {
1683 if (x > -1 || (sizeFlags & wxSIZE_ALLOW_MINUS_ONE))
1684 {
1685 XtVaSetValues (m_borderWidget ? (Widget) m_borderWidget : (Widget) m_scrolledWindow,
1686 XmNx, xx, NULL);
1687 }
1688
1689 if (y > -1 || (sizeFlags & wxSIZE_ALLOW_MINUS_ONE))
1690 {
1691 XtVaSetValues (m_borderWidget ? (Widget) m_borderWidget : (Widget) m_scrolledWindow,
1692 XmNy, yy, NULL);
1693 }
1694 }
1695
1696 if (!useOldSize)
1697 {
1698
1699 if (w > -1)
1700 {
1701 if (m_borderWidget)
1702 {
1703 XtVaSetValues ((Widget) m_borderWidget, XmNwidth, w, NULL);
1704 short thick, margin;
1705 XtVaGetValues ((Widget) m_borderWidget,
1706 XmNshadowThickness, &thick,
1707 XmNmarginWidth, &margin,
1708 NULL);
1709 w -= 2 * (thick + margin);
1710 }
1711
1712 XtVaSetValues ((Widget) m_scrolledWindow, XmNwidth, w, NULL);
1713
1714 Dimension spacing;
1715 Widget sbar;
1716 XtVaGetValues ((Widget) m_scrolledWindow,
1717 XmNspacing, &spacing,
1718 XmNverticalScrollBar, &sbar,
1719 NULL);
1720 Dimension wsbar;
1721 if (sbar)
1722 XtVaGetValues (sbar, XmNwidth, &wsbar, NULL);
1723 else
1724 wsbar = 0;
1725
1726 w -= (spacing + wsbar);
1727
1728#if 0
1729 XtVaSetValues(drawingArea, XmNwidth, w, NULL);
1730#endif // 0
1731 }
1732 if (h > -1)
1733 {
1734 if (m_borderWidget)
1735 {
1736 XtVaSetValues ((Widget) m_borderWidget, XmNheight, h, NULL);
1737 short thick, margin;
1738 XtVaGetValues ((Widget) m_borderWidget,
1739 XmNshadowThickness, &thick,
1740 XmNmarginHeight, &margin,
1741 NULL);
1742 h -= 2 * (thick + margin);
1743 }
1744
1745 XtVaSetValues ((Widget) m_scrolledWindow, XmNheight, h, NULL);
1746
1747 Dimension spacing;
1748 Widget sbar;
1749 XtVaGetValues ((Widget) m_scrolledWindow,
1750 XmNspacing, &spacing,
1751 XmNhorizontalScrollBar, &sbar,
1752 NULL);
1753 Dimension wsbar;
1754 if (sbar)
1755 XtVaGetValues (sbar, XmNheight, &wsbar, NULL);
1756 else
1757 wsbar = 0;
1758
1759 h -= (spacing + wsbar);
1760
1761#if 0
1762 XtVaSetValues(drawingArea, XmNheight, h, NULL);
1763#endif // 0
1764 }
1765 }
1766
1767 if (managed)
1768 XtManageChild (m_borderWidget ? (Widget) m_borderWidget : (Widget) m_scrolledWindow);
1769 XtVaSetValues(drawingArea, XmNresizePolicy, XmRESIZE_NONE, NULL);
bc797f4c
JS
1770#endif
1771 // 0
83df96d6
JS
1772}
1773
bc797f4c 1774void wxWindowX11::CanvasSetClientSize (int w, int h)
83df96d6 1775{
bc797f4c
JS
1776// TODO
1777#if 0
83df96d6
JS
1778 Widget drawingArea = (Widget) m_drawingArea;
1779
1780 XtVaSetValues(drawingArea, XmNresizePolicy, XmRESIZE_ANY, NULL);
1781
1782 if (w > -1)
1783 XtVaSetValues(drawingArea, XmNwidth, w, NULL);
1784 if (h > -1)
1785 XtVaSetValues(drawingArea, XmNheight, h, NULL);
1786
83df96d6 1787 XtVaSetValues(drawingArea, XmNresizePolicy, XmRESIZE_NONE, NULL);
83df96d6
JS
1788#endif // 0
1789}
1790
bc797f4c 1791void wxWindowX11::CanvasGetClientSize (int *w, int *h) const
83df96d6 1792{
bc797f4c
JS
1793// TODO
1794#if 0
83df96d6
JS
1795 // Must return the same thing that was set via SetClientSize
1796 Dimension xx, yy;
1797 XtVaGetValues ((Widget) m_drawingArea, XmNwidth, &xx, XmNheight, &yy, NULL);
1798 *w = xx;
1799 *h = yy;
bc797f4c 1800#endif
83df96d6
JS
1801}
1802
bc797f4c 1803void wxWindowX11::CanvasGetSize (int *w, int *h) const
83df96d6 1804{
bc797f4c
JS
1805// TODO
1806#if 0
83df96d6
JS
1807 Dimension xx, yy;
1808 if ((Widget) m_borderWidget)
1809 XtVaGetValues ((Widget) m_borderWidget, XmNwidth, &xx, XmNheight, &yy, NULL);
1810 else if ((Widget) m_scrolledWindow)
1811 XtVaGetValues ((Widget) m_scrolledWindow, XmNwidth, &xx, XmNheight, &yy, NULL);
1812 else
1813 XtVaGetValues ((Widget) m_drawingArea, XmNwidth, &xx, XmNheight, &yy, NULL);
1814
1815 *w = xx;
1816 *h = yy;
bc797f4c 1817#endif
83df96d6
JS
1818}
1819
bc797f4c 1820void wxWindowX11::CanvasGetPosition (int *x, int *y) const
83df96d6 1821{
bc797f4c
JS
1822// TODO
1823#if 0
83df96d6
JS
1824 Position xx, yy;
1825 XtVaGetValues (m_borderWidget ? (Widget) m_borderWidget : (Widget) m_scrolledWindow, XmNx, &xx, XmNy, &yy, NULL);
1826
1827 // We may be faking the client origin.
1828 // So a window that's really at (0, 30) may appear
1829 // (to wxWin apps) to be at (0, 0).
1830 if (GetParent())
1831 {
1832 wxPoint pt(GetParent()->GetClientAreaOrigin());
1833 xx -= pt.x;
1834 yy -= pt.y;
1835 }
1836
1837 *x = xx;
1838 *y = yy;
bc797f4c 1839#endif
83df96d6
JS
1840}
1841
1842// ----------------------------------------------------------------------------
1843// TranslateXXXEvent() functions
1844// ----------------------------------------------------------------------------
1845
1b0fb34b 1846bool wxTranslateMouseEvent(wxMouseEvent& wxevent, wxWindow *win, Window window, XEvent *xevent)
83df96d6
JS
1847{
1848 switch (xevent->xany.type)
1849 {
1b0fb34b
JS
1850 case EnterNotify:
1851 case LeaveNotify:
83df96d6
JS
1852 case ButtonPress:
1853 case ButtonRelease:
1854 case MotionNotify:
1855 {
1856 wxEventType eventType = wxEVT_NULL;
1857
1b0fb34b 1858 if (xevent->xany.type == EnterNotify)
83df96d6 1859 {
1b0fb34b
JS
1860 //if (local_event.xcrossing.mode!=NotifyNormal)
1861 // return ; // Ignore grab events
1862 eventType = wxEVT_ENTER_WINDOW;
1863 // canvas->GetEventHandler()->OnSetFocus();
1864 }
1865 else if (xevent->xany.type == LeaveNotify)
1866 {
1867 //if (local_event.xcrossingr.mode!=NotifyNormal)
1868 // return ; // Ignore grab events
1869 eventType = wxEVT_LEAVE_WINDOW;
1870 // canvas->GetEventHandler()->OnKillFocus();
83df96d6
JS
1871 }
1872 else if (xevent->xany.type == MotionNotify)
1873 {
1874 eventType = wxEVT_MOTION;
1875 }
1876 else if (xevent->xany.type == ButtonPress)
1877 {
1878 wxevent.SetTimestamp(xevent->xbutton.time);
1879 int button = 0;
1880 if (xevent->xbutton.button == Button1)
1881 {
1882 eventType = wxEVT_LEFT_DOWN;
1883 win->SetButton1(TRUE);
1884 button = 1;
1885 }
1886 else if (xevent->xbutton.button == Button2)
1887 {
1888 eventType = wxEVT_MIDDLE_DOWN;
1889 win->SetButton2(TRUE);
1890 button = 2;
1891 }
1892 else if (xevent->xbutton.button == Button3)
1893 {
1894 eventType = wxEVT_RIGHT_DOWN;
1895 win->SetButton3(TRUE);
1896 button = 3;
1897 }
1898
1899 // check for a double click
1b0fb34b
JS
1900 // TODO: where can we get this value from?
1901 //long dclickTime = XtGetMultiClickTime((Display*) wxGetDisplay());
7266b672 1902 long dclickTime = 200;
83df96d6
JS
1903 long ts = wxevent.GetTimestamp();
1904
1905 int buttonLast = win->GetLastClickedButton();
1906 long lastTS = win->GetLastClickTime();
1907 if ( buttonLast && buttonLast == button && (ts - lastTS) < dclickTime )
1908 {
1909 // I have a dclick
1910 win->SetLastClick(0, ts);
1911 if ( eventType == wxEVT_LEFT_DOWN )
1912 eventType = wxEVT_LEFT_DCLICK;
1913 else if ( eventType == wxEVT_MIDDLE_DOWN )
1914 eventType = wxEVT_MIDDLE_DCLICK;
1915 else if ( eventType == wxEVT_RIGHT_DOWN )
1916 eventType = wxEVT_RIGHT_DCLICK;
1917 }
1918 else
1919 {
1920 // not fast enough or different button
1921 win->SetLastClick(button, ts);
1922 }
1923 }
1924 else if (xevent->xany.type == ButtonRelease)
1925 {
1926 if (xevent->xbutton.button == Button1)
1927 {
1928 eventType = wxEVT_LEFT_UP;
1929 win->SetButton1(FALSE);
1930 }
1931 else if (xevent->xbutton.button == Button2)
1932 {
1933 eventType = wxEVT_MIDDLE_UP;
1934 win->SetButton2(FALSE);
1935 }
1936 else if (xevent->xbutton.button == Button3)
1937 {
1938 eventType = wxEVT_RIGHT_UP;
1939 win->SetButton3(FALSE);
1940 }
1941 else return FALSE;
1942 }
1943 else
1944 {
1945 return FALSE;
1946 }
1947
1948 wxevent.SetEventType(eventType);
1949
1b0fb34b
JS
1950 wxevent.m_x = xevent->xbutton.x;
1951 wxevent.m_y = xevent->xbutton.y;
83df96d6
JS
1952
1953 wxevent.m_leftDown = ((eventType == wxEVT_LEFT_DOWN)
1954 || (event_left_is_down (xevent)
1955 && (eventType != wxEVT_LEFT_UP)));
1956 wxevent.m_middleDown = ((eventType == wxEVT_MIDDLE_DOWN)
1957 || (event_middle_is_down (xevent)
1958 && (eventType != wxEVT_MIDDLE_UP)));
1959 wxevent.m_rightDown = ((eventType == wxEVT_RIGHT_DOWN)
1960 || (event_right_is_down (xevent)
1961 && (eventType != wxEVT_RIGHT_UP)));
1962
1963 wxevent.m_shiftDown = xevent->xbutton.state & ShiftMask;
1964 wxevent.m_controlDown = xevent->xbutton.state & ControlMask;
1965 wxevent.m_altDown = xevent->xbutton.state & Mod3Mask;
1966 wxevent.m_metaDown = xevent->xbutton.state & Mod1Mask;
1967
1968 wxevent.SetId(win->GetId());
1969 wxevent.SetEventObject(win);
1970
1971 return TRUE;
1972 }
1973 }
1974 return FALSE;
1975}
1976
7eaac9f5 1977bool wxTranslateKeyEvent(wxKeyEvent& wxevent, wxWindow *win, Window WXUNUSED(win), XEvent *xevent)
83df96d6
JS
1978{
1979 switch (xevent->xany.type)
1980 {
1981 case KeyPress:
1982 case KeyRelease:
1983 {
1984 char buf[20];
1985
1986 KeySym keySym;
83df96d6
JS
1987 (void) XLookupString ((XKeyEvent *) xevent, buf, 20, &keySym, NULL);
1988 int id = wxCharCodeXToWX (keySym);
1989
1990 if (xevent->xkey.state & ShiftMask)
1991 wxevent.m_shiftDown = TRUE;
1992 if (xevent->xkey.state & ControlMask)
1993 wxevent.m_controlDown = TRUE;
1994 if (xevent->xkey.state & Mod3Mask)
1995 wxevent.m_altDown = TRUE;
1996 if (xevent->xkey.state & Mod1Mask)
1997 wxevent.m_metaDown = TRUE;
1998 wxevent.SetEventObject(win);
1999 wxevent.m_keyCode = id;
2000 wxevent.SetTimestamp(xevent->xkey.time);
2001
2002 wxevent.m_x = xevent->xbutton.x;
2003 wxevent.m_y = xevent->xbutton.y;
2004
2005 if (id > -1)
2006 return TRUE;
2007 else
2008 return FALSE;
2009 break;
2010 }
2011 default:
2012 break;
2013 }
2014 return FALSE;
2015}
2016
2017// ----------------------------------------------------------------------------
2018// Colour stuff
2019// ----------------------------------------------------------------------------
2020
bc797f4c
JS
2021#if 0
2022
83df96d6
JS
2023#define YAllocColor XAllocColor
2024XColor g_itemColors[5];
2025int wxComputeColours (Display *display, wxColour * back, wxColour * fore)
2026{
2027 int result;
2028 static XmColorProc colorProc;
2029
2030 result = wxNO_COLORS;
2031
2032 if (back)
2033 {
2034 g_itemColors[0].red = (((long) back->Red ()) << 8);
2035 g_itemColors[0].green = (((long) back->Green ()) << 8);
2036 g_itemColors[0].blue = (((long) back->Blue ()) << 8);
2037 g_itemColors[0].flags = DoRed | DoGreen | DoBlue;
2038 if (colorProc == (XmColorProc) NULL)
2039 {
2040 // Get a ptr to the actual function
2041 colorProc = XmSetColorCalculation ((XmColorProc) NULL);
2042 // And set it back to motif.
2043 XmSetColorCalculation (colorProc);
2044 }
2045 (*colorProc) (&g_itemColors[wxBACK_INDEX],
2046 &g_itemColors[wxFORE_INDEX],
2047 &g_itemColors[wxSELE_INDEX],
2048 &g_itemColors[wxTOPS_INDEX],
2049 &g_itemColors[wxBOTS_INDEX]);
2050 result = wxBACK_COLORS;
2051 }
2052 if (fore)
2053 {
2054 g_itemColors[wxFORE_INDEX].red = (((long) fore->Red ()) << 8);
2055 g_itemColors[wxFORE_INDEX].green = (((long) fore->Green ()) << 8);
2056 g_itemColors[wxFORE_INDEX].blue = (((long) fore->Blue ()) << 8);
2057 g_itemColors[wxFORE_INDEX].flags = DoRed | DoGreen | DoBlue;
2058 if (result == wxNO_COLORS)
2059 result = wxFORE_COLORS;
2060 }
2061
2062 Display *dpy = display;
2063 Colormap cmap = (Colormap) wxTheApp->GetMainColormap((WXDisplay*) dpy);
2064
2065 if (back)
2066 {
2067 /* 5 Colours to allocate */
2068 for (int i = 0; i < 5; i++)
2069 if (!YAllocColor (dpy, cmap, &g_itemColors[i]))
2070 result = wxNO_COLORS;
2071 }
2072 else if (fore)
2073 {
2074 /* Only 1 colour to allocate */
2075 if (!YAllocColor (dpy, cmap, &g_itemColors[wxFORE_INDEX]))
2076 result = wxNO_COLORS;
2077 }
2078
2079 return (result);
2080
2081}
bc797f4c 2082#endif
83df96d6
JS
2083
2084// Changes the foreground and background colours to be derived from the current
2085// background colour. To change the foreground colour, you must call
2086// SetForegroundColour explicitly.
bc797f4c 2087void wxWindowX11::ChangeBackgroundColour()
83df96d6 2088{
bc797f4c
JS
2089 // TODO
2090#if 0
83df96d6
JS
2091 WXWidget mainWidget = GetMainWidget();
2092 if ( mainWidget )
2093 DoChangeBackgroundColour(mainWidget, m_backgroundColour);
83df96d6
JS
2094#endif
2095}
2096
bc797f4c 2097void wxWindowX11::ChangeForegroundColour()
83df96d6 2098{
bc797f4c
JS
2099 // TODO
2100#if 0
83df96d6
JS
2101 WXWidget mainWidget = GetMainWidget();
2102 if ( mainWidget )
2103 DoChangeForegroundColour(mainWidget, m_foregroundColour);
2104 if ( m_scrolledWindow && mainWidget != m_scrolledWindow )
2105 DoChangeForegroundColour(m_scrolledWindow, m_foregroundColour);
bc797f4c 2106#endif
83df96d6
JS
2107}
2108
2109// Change a widget's foreground and background colours.
bc797f4c 2110void wxWindowX11::DoChangeForegroundColour(WXWindow widget, wxColour& foregroundColour)
83df96d6 2111{
bc797f4c
JS
2112 // TODO
2113#if 0
83df96d6
JS
2114 // When should we specify the foreground, if it's calculated
2115 // by wxComputeColours?
2116 // Solution: say we start with the default (computed) foreground colour.
2117 // If we call SetForegroundColour explicitly for a control or window,
2118 // then the foreground is changed.
2119 // Therefore SetBackgroundColour computes the foreground colour, and
2120 // SetForegroundColour changes the foreground colour. The ordering is
2121 // important.
2122
2123 Widget w = (Widget)widget;
2124 XtVaSetValues(
2125 w,
2126 XmNforeground, foregroundColour.AllocColour(XtDisplay(w)),
2127 NULL
2128 );
bc797f4c 2129#endif
83df96d6
JS
2130}
2131
bc797f4c 2132void wxWindowX11::DoChangeBackgroundColour(WXWindow widget, wxColour& backgroundColour, bool changeArmColour)
83df96d6 2133{
bc797f4c
JS
2134 // TODO
2135#if 0
83df96d6
JS
2136 wxComputeColours (XtDisplay((Widget) widget), & backgroundColour,
2137 (wxColour*) NULL);
2138
2139 XtVaSetValues ((Widget) widget,
2140 XmNbackground, g_itemColors[wxBACK_INDEX].pixel,
2141 XmNtopShadowColor, g_itemColors[wxTOPS_INDEX].pixel,
2142 XmNbottomShadowColor, g_itemColors[wxBOTS_INDEX].pixel,
2143 XmNforeground, g_itemColors[wxFORE_INDEX].pixel,
2144 NULL);
2145
2146 if (changeArmColour)
2147 XtVaSetValues ((Widget) widget,
2148 XmNarmColor, g_itemColors[wxSELE_INDEX].pixel,
2149 NULL);
bc797f4c 2150#endif
83df96d6
JS
2151}
2152
bc797f4c 2153bool wxWindowX11::SetBackgroundColour(const wxColour& col)
83df96d6
JS
2154{
2155 if ( !wxWindowBase::SetBackgroundColour(col) )
2156 return FALSE;
2157
2158 ChangeBackgroundColour();
2159
2160 return TRUE;
2161}
2162
bc797f4c 2163bool wxWindowX11::SetForegroundColour(const wxColour& col)
83df96d6
JS
2164{
2165 if ( !wxWindowBase::SetForegroundColour(col) )
2166 return FALSE;
2167
2168 ChangeForegroundColour();
2169
2170 return TRUE;
2171}
2172
bc797f4c 2173void wxWindowX11::ChangeFont(bool keepOriginalSize)
83df96d6 2174{
bc797f4c
JS
2175 // TODO
2176#if 0
83df96d6
JS
2177 // Note that this causes the widget to be resized back
2178 // to its original size! We therefore have to set the size
2179 // back again. TODO: a better way in Motif?
2180 Widget w = (Widget) GetLabelWidget(); // Usually the main widget
2181 if (w && m_font.Ok())
2182 {
2183 int width, height, width1, height1;
2184 GetSize(& width, & height);
2185
2186 // lesstif 0.87 hangs here
2187#ifndef LESSTIF_VERSION
2188 XtVaSetValues (w,
2189 XmNfontList, (XmFontList) m_font.GetFontList(1.0, XtDisplay(w)),
2190 NULL);
2191#endif
2192
2193 GetSize(& width1, & height1);
2194 if (keepOriginalSize && (width != width1 || height != height1))
2195 {
2196 SetSize(-1, -1, width, height);
2197 }
2198 }
bc797f4c 2199#endif
83df96d6
JS
2200}
2201
2202// ----------------------------------------------------------------------------
2203// global functions
2204// ----------------------------------------------------------------------------
2205
2206wxWindow *wxGetActiveWindow()
2207{
2208 // TODO
2209 wxFAIL_MSG("Not implemented");
2210 return NULL;
2211}
2212
2213/* static */
2214wxWindow *wxWindowBase::GetCapture()
2215{
2216 return (wxWindow *)g_captureWindow;
2217}
2218
2219
2220// Find the wxWindow at the current mouse position, returning the mouse
2221// position.
2222wxWindow* wxFindWindowAtPointer(wxPoint& pt)
2223{
2224 return wxFindWindowAtPoint(wxGetMousePosition());
2225}
2226
2227// Get the current mouse position.
2228wxPoint wxGetMousePosition()
2229{
2230 Display *display = (Display*) wxGetDisplay();
2231 Window rootWindow = RootWindowOfScreen (DefaultScreenOfDisplay(display));
2232 Window rootReturn, childReturn;
2233 int rootX, rootY, winX, winY;
2234 unsigned int maskReturn;
2235
2236 XQueryPointer (display,
2237 rootWindow,
2238 &rootReturn,
2239 &childReturn,
2240 &rootX, &rootY, &winX, &winY, &maskReturn);
2241 return wxPoint(rootX, rootY);
2242}
2243
2244
2245// ----------------------------------------------------------------------------
2246// wxNoOptimize: switch off size optimization
2247// ----------------------------------------------------------------------------
2248
2249int wxNoOptimize::ms_count = 0;
2250