]> git.saurik.com Git - wxWidgets.git/blame - src/motif/window.cpp
compilation fix
[wxWidgets.git] / src / motif / window.cpp
CommitLineData
4bb6408c
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
34636400 9// Licence: wxWindows licence
4bb6408c
JS
10/////////////////////////////////////////////////////////////////////////////
11
34636400
VZ
12// ============================================================================
13// declarations
14// ============================================================================
15
16// ----------------------------------------------------------------------------
17// headers
18// ----------------------------------------------------------------------------
19
4bb6408c 20#ifdef __GNUG__
34636400 21 #pragma implementation "window.h"
4bb6408c
JS
22#endif
23
4dff3400
JJ
24#ifdef __VMS
25#define XtDisplay XTDISPLAY
bcd055ae
JJ
26#define XtWindow XTWINDOW
27#define XtScreen XTSCREEN
4dff3400
JJ
28#endif
29
4bb6408c
JS
30#include "wx/setup.h"
31#include "wx/menu.h"
32#include "wx/dc.h"
33#include "wx/dcclient.h"
34#include "wx/utils.h"
35#include "wx/app.h"
4bb6408c 36#include "wx/layout.h"
4bb6408c
JS
37#include "wx/button.h"
38#include "wx/settings.h"
4bb6408c 39#include "wx/frame.h"
a91b47e8 40#include "wx/scrolwin.h"
33caefb3 41#include "wx/module.h"
4bb6408c
JS
42#include "wx/menuitem.h"
43#include "wx/log.h"
7e1bcfa8 44#include "wx/evtloop.h"
ed39ff57 45#include "wx/hash.h"
4bb6408c 46
47d67540 47#if wxUSE_DRAG_AND_DROP
34636400 48 #include "wx/dnd.h"
4bb6408c
JS
49#endif
50
fc7ca9b3 51// DoSetSizeIntr and DoMoveWindowIntr
37c997b4
MB
52// PROBLEM:
53// under Motif composite controls (such as wxCalendarCtrl or generic wxSpinCtrl
fc7ca9b3 54// did nott work and/or segfaulted because
37c997b4
MB
55// 1) wxWindow::Create calls SetSize,
56// which results in a call to DoSetSize much earlier than in the other ports
57// 2) if wxWindow::Create is called (wxControl::Create calls it)
58// then DoSetSize is never called, causing layout problems in composite
59// controls
60//
61// SOLUTION:
62// 1) don't call SetSize, DoSetSize, DoMoveWindow, DoGetPosition,
63// DoSetPosition directly or indirectly from wxWindow::Create
fc7ca9b3 64// 2) call DoMoveWindow from DoSetSize, allowing controls to override it
37c997b4 65
338dd992
JJ
66#ifdef __VMS__
67#pragma message disable nosimpint
68#endif
4bb6408c 69#include <Xm/Xm.h>
50414e24
JS
70
71#include <Xm/DrawingA.h>
72#include <Xm/ScrolledW.h>
73#include <Xm/ScrollBar.h>
74#include <Xm/Frame.h>
75#include <Xm/Label.h>
ee31c392 76#include <Xm/RowColumn.h> // for XmMenuPosition
338dd992
JJ
77#ifdef __VMS__
78#pragma message enable nosimpint
79#endif
50414e24 80
4bb6408c
JS
81#include "wx/motif/private.h"
82
83#include <string.h>
84
34636400
VZ
85// ----------------------------------------------------------------------------
86// constants
87// ----------------------------------------------------------------------------
88
89static const int SCROLL_MARGIN = 4;
90
91// ----------------------------------------------------------------------------
92// global variables for this module
93// ----------------------------------------------------------------------------
94
33caefb3 95extern wxHashTable *wxWidgetHashTable;
9806a47c
JS
96static wxWindow* g_captureWindow = NULL;
97
34636400
VZ
98
99// ----------------------------------------------------------------------------
100// private functions
101// ----------------------------------------------------------------------------
102
103static void wxCanvasRepaintProc(Widget, XtPointer, XmDrawingAreaCallbackStruct * cbs);
104static void wxCanvasInputEvent(Widget drawingArea, XtPointer data, XmDrawingAreaCallbackStruct * cbs);
105static void wxCanvasMotionEvent(Widget, XButtonEvent * event);
106static void wxCanvasEnterLeave(Widget drawingArea, XtPointer clientData, XCrossingEvent * event);
8aa04e8b 107static void wxScrollBarCallback(Widget widget, XtPointer clientData,
311227c3 108 XmScrollBarCallbackStruct *cbs);
34636400
VZ
109static void wxPanelItemEventHandler(Widget wid,
110 XtPointer client_data,
111 XEvent* event,
112 Boolean *continueToDispatch);
113
114// unused for now
115#if 0
116
117// Helper function for 16-bit fonts
118static int str16len(const char *s)
119{
120 int count = 0;
121
122 while (s[0] && s[1]) {
123 count++;
124 s += 2;
125 }
126
127 return count;
128}
129
130#endif // 0
131
132// ----------------------------------------------------------------------------
133// macros
134// ----------------------------------------------------------------------------
50414e24
JS
135
136#define event_left_is_down(x) ((x)->xbutton.state & Button1Mask)
137#define event_middle_is_down(x) ((x)->xbutton.state & Button2Mask)
138#define event_right_is_down(x) ((x)->xbutton.state & Button3Mask)
139
34636400
VZ
140// ----------------------------------------------------------------------------
141// event tables
142// ----------------------------------------------------------------------------
4bb6408c 143
8e877c19 144 IMPLEMENT_DYNAMIC_CLASS(wxWindow, wxWindowBase)
4bb6408c 145
8e877c19 146 BEGIN_EVENT_TABLE(wxWindow, wxWindowBase)
34636400
VZ
147 EVT_SYS_COLOUR_CHANGED(wxWindow::OnSysColourChanged)
148 EVT_IDLE(wxWindow::OnIdle)
149 END_EVENT_TABLE()
4bb6408c 150
34636400
VZ
151// ============================================================================
152// implementation
153// ============================================================================
4bb6408c 154
34636400
VZ
155// ----------------------------------------------------------------------------
156// helper functions
157// ----------------------------------------------------------------------------
4bb6408c 158
34636400 159void wxWindow::UnmanageAndDestroy(WXWidget widget)
4bb6408c 160{
34636400
VZ
161 Widget w = (Widget)widget;
162 if ( w )
4bb6408c 163 {
34636400
VZ
164 XtUnmanageChild(w);
165 XtDestroyWidget(w);
4bb6408c 166 }
4bb6408c
JS
167}
168
b9ecc16a 169bool wxWindow::MapOrUnmap(WXWidget widget, bool domap)
4bb6408c 170{
34636400
VZ
171 Widget w = (Widget)widget;
172 if ( !w )
173 return FALSE;
174
882b1d8d
MB
175 // Rationale: a lot of common operations (including but not
176 // limited to moving, resizing and appending items to a listbox)
177 // unmamange the widget, do their work, then manage it again.
178 // This means that, for example adding an item to a listbox will show it,
179 // or that most controls are shown every time they are moved or resized!
180 XtSetMappedWhenManaged( w, domap );
181
28169f14
MB
182 // if the widget is not unmanaged, it still intercepts
183 // mouse events, even if it is not mapped (and hence invisible)
b9ecc16a 184 if ( domap )
28169f14
MB
185 {
186 XtManageChild(w);
882b1d8d 187 // XtMapWidget(w);
28169f14 188 }
34636400 189 else
28169f14 190 {
28169f14 191 XtUnmanageChild(w);
882b1d8d 192 // XtUnmapWidget(w);
28169f14 193 }
34636400 194
4bb6408c
JS
195 return TRUE;
196}
197
34636400
VZ
198// ----------------------------------------------------------------------------
199// constructors
200// ----------------------------------------------------------------------------
201
202void wxWindow::Init()
4bb6408c 203{
34636400
VZ
204 // generic initializations first
205 InitBase();
206
50414e24 207 // Motif-specific
a91b47e8 208 m_needsRefresh = TRUE;
50414e24 209 m_mainWidget = (WXWidget) 0;
34636400 210
50414e24 211 m_winCaptured = FALSE;
34636400 212
50414e24 213 m_isShown = TRUE;
3ab377bd
MB
214 m_isBeingDeleted = FALSE;
215
34636400
VZ
216 m_hScrollBar =
217 m_vScrollBar =
218 m_borderWidget =
219 m_scrolledWindow =
50414e24 220 m_drawingArea = (WXWidget) 0;
34636400 221
34636400
VZ
222 m_scrollPosX =
223 m_scrollPosY = 0;
224
50414e24 225 m_backingPixmap = (WXPixmap) 0;
34636400 226 m_pixmapWidth =
50414e24 227 m_pixmapHeight = 0;
34636400
VZ
228
229 m_pixmapOffsetX =
50414e24 230 m_pixmapOffsetY = 0;
34636400
VZ
231
232 m_lastTS = 0;
233 m_lastButton = 0;
34636400
VZ
234}
235
236// real construction (Init() must have been called before!)
237bool wxWindow::Create(wxWindow *parent, wxWindowID id,
238 const wxPoint& pos,
239 const wxSize& size,
240 long style,
241 const wxString& name)
242{
243 wxCHECK_MSG( parent, FALSE, "can't create wxWindow without parent" );
244
813c20a6 245 CreateBase(parent, id, pos, size, style, wxDefaultValidator, name);
34636400
VZ
246
247 parent->AddChild(this);
248
a756f210 249 m_backgroundColour = wxSystemSettings::GetColour(wxSYS_COLOUR_3DFACE);
4bb6408c 250 m_foregroundColour = *wxBLACK;
34636400 251
50414e24
JS
252 //// TODO: we should probably optimize by only creating a
253 //// a drawing area if we have one or more scrollbars (wxVSCROLL/wxHSCROLL).
254 //// But for now, let's simplify things by always creating the
255 //// drawing area, since otherwise the translations are different.
34636400 256
2d120f83 257 // New translations for getting mouse motion feedback
34636400
VZ
258 static const String translations =
259"<Btn1Motion>: wxCanvasMotionEvent() DrawingAreaInput() ManagerGadgetButtonMotion()\n\
2d120f83
JS
260<Btn2Motion>: wxCanvasMotionEvent() DrawingAreaInput() ManagerGadgetButtonMotion()\n\
261<Btn3Motion>: wxCanvasMotionEvent() DrawingAreaInput() ManagerGadgetButtonMotion()\n\
262<BtnMotion>: wxCanvasMotionEvent() DrawingAreaInput() ManagerGadgetButtonMotion()\n\
263<Btn1Down>: DrawingAreaInput() ManagerGadgetArm()\n\
264<Btn2Down>: DrawingAreaInput() ManagerGadgetArm()\n\
265<Btn3Down>: DrawingAreaInput() ManagerGadgetArm()\n\
266<Btn1Up>: DrawingAreaInput() ManagerGadgetActivate()\n\
267<Btn2Up>: DrawingAreaInput() ManagerGadgetActivate()\n\
268<Btn3Up>: DrawingAreaInput() ManagerGadgetActivate()\n\
269<Motion>: wxCanvasMotionEvent() DrawingAreaInput()\n\
270<EnterWindow>: wxCanvasMotionEvent() DrawingAreaInput()\n\
271<LeaveWindow>: wxCanvasMotionEvent() DrawingAreaInput()\n\
272<Key>: DrawingAreaInput()";
34636400 273
2d120f83
JS
274 XtActionsRec actions[1];
275 actions[0].string = "wxCanvasMotionEvent";
276 actions[0].proc = (XtActionProc) wxCanvasMotionEvent;
277 XtAppAddActions ((XtAppContext) wxTheApp->GetAppContext(), actions, 1);
34636400
VZ
278
279 Widget parentWidget = (Widget) parent->GetClientWidget();
6769d0cb 280 m_borderWidget = wxCreateBorderWidget( (WXWidget)parentWidget, style );
34636400
VZ
281
282 m_scrolledWindow = (WXWidget)XtVaCreateManagedWidget
283 (
284 "scrolledWindow",
285 xmScrolledWindowWidgetClass,
286 m_borderWidget ? (Widget) m_borderWidget
287 : parentWidget,
288 XmNresizePolicy, XmRESIZE_NONE,
289 XmNspacing, 0,
290 XmNscrollingPolicy, XmAPPLICATION_DEFINED,
291 //XmNscrollBarDisplayPolicy, XmAS_NEEDED,
292 NULL
293 );
294
295 XtTranslations ptr = XtParseTranslationTable(translations);
296 m_drawingArea = (WXWidget)XtVaCreateWidget
297 (
298 name,
299 xmDrawingAreaWidgetClass, (Widget) m_scrolledWindow,
300 XmNunitType, XmPIXELS,
301 // XmNresizePolicy, XmRESIZE_ANY,
302 XmNresizePolicy, XmRESIZE_NONE,
303 XmNmarginHeight, 0,
304 XmNmarginWidth, 0,
305 XmNtranslations, ptr,
306 NULL
307 );
308 XtFree((char *) ptr);
309
310#if 0
311 if (GetWindowStyleFlag() & wxOVERRIDE_KEY_TRANSLATIONS)
312 {
2d120f83
JS
313 ptr = XtParseTranslationTable ("<Key>: DrawingAreaInput()");
314 XtOverrideTranslations ((Widget) m_drawingArea, ptr);
315 XtFree ((char *) ptr);
34636400
VZ
316 }
317#endif // 0
318
2d120f83
JS
319 wxAddWindowToTable((Widget) m_drawingArea, this);
320 wxAddWindowToTable((Widget) m_scrolledWindow, this);
34636400
VZ
321
322 // This order is very important in Motif 1.2.1
2d120f83
JS
323 XtRealizeWidget ((Widget) m_scrolledWindow);
324 XtRealizeWidget ((Widget) m_drawingArea);
325 XtManageChild ((Widget) m_drawingArea);
34636400
VZ
326
327 ptr = XtParseTranslationTable("<Configure>: resize()");
328 XtOverrideTranslations((Widget) m_drawingArea, ptr);
50414e24 329 XtFree ((char *) ptr);
34636400 330
2d120f83
JS
331 XtAddCallback ((Widget) m_drawingArea, XmNexposeCallback, (XtCallbackProc) wxCanvasRepaintProc, (XtPointer) this);
332 XtAddCallback ((Widget) m_drawingArea, XmNinputCallback, (XtCallbackProc) wxCanvasInputEvent, (XtPointer) this);
34636400 333
34636400
VZ
334 XtAddEventHandler(
335 (Widget)m_drawingArea,
336 PointerMotionHintMask | EnterWindowMask |
337 LeaveWindowMask | FocusChangeMask,
338 False,
339 (XtEventHandler) wxCanvasEnterLeave,
340 (XtPointer) this
341 );
342
343 // Scrolled widget needs to have its colour changed or we get a little blue
344 // square where the scrollbars abutt
a756f210 345 wxColour backgroundColour = wxSystemSettings::GetColour(wxSYS_COLOUR_3DFACE);
a8680e3e
MB
346 wxDoChangeBackgroundColour(m_scrolledWindow, backgroundColour, TRUE);
347 wxDoChangeBackgroundColour(m_drawingArea, backgroundColour, TRUE);
34636400
VZ
348
349 XmScrolledWindowSetAreas(
350 (Widget)m_scrolledWindow,
351 (Widget) 0, (Widget) 0,
352 (Widget) m_drawingArea);
353
34636400
VZ
354 // Without this, the cursor may not be restored properly (e.g. in splitter
355 // sample).
2d120f83 356 SetCursor(*wxSTANDARD_CURSOR);
a756f210 357 SetFont(wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT));
37c997b4 358 DoSetSizeIntr(pos.x, pos.y, size.x,size.y, wxSIZE_AUTO, TRUE);
2d120f83 359 return TRUE;
88150e60
JS
360}
361
34636400
VZ
362// Destructor
363wxWindow::~wxWindow()
364{
9806a47c 365 if (g_captureWindow == this)
2b5f62a0 366 g_captureWindow = NULL;
9806a47c 367
3ab377bd
MB
368 m_isBeingDeleted = TRUE;
369
34636400
VZ
370 // Motif-specific actions first
371 WXWidget wMain = GetMainWidget();
372 if ( wMain )
373 {
374 // Removes event handlers
375 DetachWidget(wMain);
376 }
377
ee31c392
VZ
378 if ( m_parent )
379 m_parent->RemoveChild( this );
380
34636400
VZ
381 // If m_drawingArea, we're a fully-fledged window with drawing area,
382 // scrollbars etc. (what wxCanvas used to be)
383 if ( m_drawingArea )
384 {
385 // Destroy children before destroying self
386 DestroyChildren();
387
388 if (m_backingPixmap)
389 XFreePixmap (XtDisplay ((Widget) GetMainWidget()), (Pixmap) m_backingPixmap);
390
391 Widget w = (Widget) m_drawingArea;
392 wxDeleteWindowFromTable(w);
393
394 if (w)
395 {
396 XtDestroyWidget(w);
2b5f62a0 397 m_drawingArea = (WXWidget) 0;
34636400
VZ
398 }
399
34636400
VZ
400 // Only if we're _really_ a canvas (not a dialog box/panel)
401 if (m_scrolledWindow)
402 {
403 wxDeleteWindowFromTable((Widget) m_scrolledWindow);
404 }
405
311227c3
MB
406 if (m_hScrollBar)
407 {
408 wxDeleteWindowFromTable((Widget) m_hScrollBar);
2b5f62a0 409 XtUnmanageChild((Widget) m_hScrollBar);
311227c3
MB
410 }
411 if (m_vScrollBar)
412 {
413 wxDeleteWindowFromTable((Widget) m_vScrollBar);
2b5f62a0 414 XtUnmanageChild((Widget) m_vScrollBar);
311227c3
MB
415 }
416
f0d5fc50 417 if (m_hScrollBar)
2b5f62a0 418 XtDestroyWidget((Widget) m_hScrollBar);
f0d5fc50 419 if (m_vScrollBar)
2b5f62a0 420 XtDestroyWidget((Widget) m_vScrollBar);
f0d5fc50 421
34636400
VZ
422 UnmanageAndDestroy(m_scrolledWindow);
423
424 if (m_borderWidget)
425 {
426 XtDestroyWidget ((Widget) m_borderWidget);
427 m_borderWidget = (WXWidget) 0;
428 }
429 }
7b28757f
JS
430 else // Why wasn't this here before? JACS 8/3/2000
431 DestroyChildren();
432
34636400
VZ
433
434 // Destroy the window
435 if (GetMainWidget())
436 {
437 // If this line (XtDestroyWidget) causes a crash, you may comment it out.
438 // Child widgets will get destroyed automatically when a frame
439 // or dialog is destroyed, but before that you may get some memory
440 // leaks and potential layout problems if you delete and then add
441 // child windows.
bdeca1d1
GRG
442
443 // GRG, Feb/2000: commented this out when adding support for
444 // wxSCROLL[WIN]_THUMBRELEASE events. Also it was reported
445 // that this call crashed wxMotif under OS/2, so it seems
446 // that leaving it out is the right thing to do.
b3ef4fb5
SN
447 // SN, Feb/2000: newgrid/griddemo shows why it is needed :-(
448 XtDestroyWidget((Widget) GetMainWidget());
34636400
VZ
449 SetMainWidget((WXWidget) NULL);
450 }
451}
452
453// ----------------------------------------------------------------------------
454// scrollbar management
455// ----------------------------------------------------------------------------
456
148b44a1
MB
457WXWidget wxWindow::DoCreateScrollBar(WXWidget parent,
458 wxOrientation orientation,
459 void (*callback)())
460{
461 int orient = ( orientation & wxHORIZONTAL ) ? XmHORIZONTAL : XmVERTICAL;
462 Widget sb =
463 XtVaCreateManagedWidget( "scrollBarWidget",
464 xmScrollBarWidgetClass, (Widget)parent,
465 XmNorientation, orient,
466 XmNincrement, 1,
467 XmNvalue, 0,
468 NULL );
469
470 XtPointer o = (XtPointer)orientation;
471 XtCallbackProc cb = (XtCallbackProc)callback;
472
473 XtAddCallback( sb, XmNvalueChangedCallback, cb, o );
474 XtAddCallback( sb, XmNdragCallback, cb, o );
475 XtAddCallback( sb, XmNincrementCallback, cb, o );
476 XtAddCallback( sb, XmNdecrementCallback, cb, o );
477 XtAddCallback( sb, XmNpageIncrementCallback, cb, o );
478 XtAddCallback( sb, XmNpageDecrementCallback, cb, o );
479 XtAddCallback( sb, XmNtoTopCallback, cb, o );
480 XtAddCallback( sb, XmNtoBottomCallback, cb, o );
481
482 return (WXWidget)sb;
483}
484
88150e60 485// Helper function
af0bb3b1 486void wxWindow::CreateScrollbar(wxOrientation orientation)
88150e60 487{
34636400
VZ
488 wxCHECK_RET( m_drawingArea, "this window can't have scrollbars" );
489
148b44a1
MB
490 XtVaSetValues( (Widget) m_scrolledWindow,
491 XmNresizePolicy, XmRESIZE_NONE,
492 NULL );
34636400 493
148b44a1 494 wxColour backgroundColour = wxSystemSettings::GetColour(wxSYS_COLOUR_3DFACE);
2d120f83
JS
495 // Add scrollbars if required
496 if (orientation == wxHORIZONTAL)
497 {
148b44a1
MB
498 m_hScrollBar = DoCreateScrollBar( m_scrolledWindow, wxHORIZONTAL,
499 (void (*)())wxScrollBarCallback );
34636400 500
a8680e3e 501 wxDoChangeBackgroundColour(m_hScrollBar, backgroundColour, TRUE);
34636400 502
148b44a1 503 XtRealizeWidget( (Widget)m_hScrollBar );
34636400 504
2d120f83
JS
505 XtVaSetValues((Widget) m_scrolledWindow,
506 XmNhorizontalScrollBar, (Widget) m_hScrollBar,
507 NULL);
34636400 508
148b44a1 509 wxAddWindowToTable( (Widget)m_hScrollBar, this );
2d120f83 510 }
148b44a1 511 else if (orientation == wxVERTICAL)
2d120f83 512 {
148b44a1
MB
513 m_vScrollBar = DoCreateScrollBar( m_scrolledWindow, wxVERTICAL,
514 (void (*)())wxScrollBarCallback );
34636400 515
a8680e3e 516 wxDoChangeBackgroundColour(m_vScrollBar, backgroundColour, TRUE);
34636400 517
148b44a1 518 XtRealizeWidget((Widget)m_vScrollBar);
34636400 519
2d120f83
JS
520 XtVaSetValues((Widget) m_scrolledWindow,
521 XmNverticalScrollBar, (Widget) m_vScrollBar,
522 NULL);
34636400 523
148b44a1 524 wxAddWindowToTable( (Widget)m_vScrollBar, this );
2d120f83 525 }
34636400 526
148b44a1
MB
527 XtVaSetValues( (Widget) m_scrolledWindow,
528 XmNresizePolicy, XmRESIZE_ANY,
529 NULL );
88150e60 530}
34636400 531
af0bb3b1 532void wxWindow::DestroyScrollbar(wxOrientation orientation)
88150e60 533{
34636400
VZ
534 wxCHECK_RET( m_drawingArea, "this window can't have scrollbars" );
535
148b44a1
MB
536 XtVaSetValues((Widget) m_scrolledWindow,
537 XmNresizePolicy, XmRESIZE_NONE,
538 NULL);
539 String stringSB = orientation == wxHORIZONTAL ?
540 XmNhorizontalScrollBar : XmNverticalScrollBar;
541 WXWidget* widgetSB = orientation == wxHORIZONTAL ?
542 &m_hScrollBar : &m_vScrollBar;
34636400 543
148b44a1 544 if( *widgetSB )
2d120f83 545 {
148b44a1
MB
546 wxDeleteWindowFromTable( (Widget)*widgetSB );
547 XtDestroyWidget( (Widget)*widgetSB );
548 *widgetSB = (WXWidget)NULL;
549 }
34636400 550
148b44a1
MB
551 XtVaSetValues( (Widget)m_scrolledWindow,
552 stringSB, (Widget) 0,
553 NULL );
34636400 554
148b44a1
MB
555 XtVaSetValues((Widget) m_scrolledWindow,
556 XmNresizePolicy, XmRESIZE_ANY,
557 NULL);
4bb6408c
JS
558}
559
34636400
VZ
560// ---------------------------------------------------------------------------
561// basic operations
562// ---------------------------------------------------------------------------
563
4bb6408c
JS
564void wxWindow::SetFocus()
565{
34636400
VZ
566 Widget wMain = (Widget) GetMainWidget();
567 XmProcessTraversal(wMain, XmTRAVERSE_CURRENT);
2d120f83 568 XmProcessTraversal((Widget) GetMainWidget(), XmTRAVERSE_CURRENT);
4bb6408c
JS
569}
570
34636400 571// Get the window with the focus
af0bb3b1 572wxWindow *wxWindowBase::FindFocus()
4bb6408c 573{
34636400
VZ
574 // TODO Problems:
575 // (1) Can there be multiple focussed widgets in an application?
576 // In which case we need to find the top-level window that's
577 // currently active.
578 // (2) The widget with the focus may not be in the widget table
579 // depending on which widgets I put in the table
580 wxWindow *winFocus = (wxWindow *)NULL;
581 for ( wxWindowList::Node *node = wxTopLevelWindows.GetFirst();
582 node;
583 node = node->GetNext() )
2d120f83 584 {
34636400
VZ
585 wxWindow *win = node->GetData();
586
587 Widget w = XmGetFocusWidget ((Widget) win->GetTopWidget());
588
589 if (w != (Widget) NULL)
590 {
591 winFocus = wxGetWindowFromTable(w);
592 if ( winFocus )
593 break;
594 }
2d120f83 595 }
4bb6408c 596
34636400 597 return winFocus;
4bb6408c
JS
598}
599
af0bb3b1 600bool wxWindow::Enable(bool enable)
4bb6408c 601{
34636400
VZ
602 if ( !wxWindowBase::Enable(enable) )
603 return FALSE;
4bb6408c 604
af0bb3b1 605 Widget wMain = (Widget)GetMainWidget();
34636400
VZ
606 if ( wMain )
607 {
608 XtSetSensitive(wMain, enable);
609 XmUpdateDisplay(wMain);
610 }
611
612 return TRUE;
4bb6408c
JS
613}
614
34636400 615bool wxWindow::Show(bool show)
4bb6408c 616{
34636400
VZ
617 if ( !wxWindowBase::Show(show) )
618 return FALSE;
619
620 if (m_borderWidget || m_scrolledWindow)
2d120f83 621 {
34636400 622 MapOrUnmap(m_borderWidget ? m_borderWidget : m_scrolledWindow, show);
882b1d8d 623 // MapOrUnmap(m_drawingArea, show);
2d120f83
JS
624 }
625 else
34636400
VZ
626 {
627 if ( !MapOrUnmap(GetTopWidget(), show) )
628 MapOrUnmap(GetMainWidget(), show);
629 }
630
34636400
VZ
631 return TRUE;
632}
4bb6408c 633
34636400
VZ
634// Raise the window to the top of the Z order
635void wxWindow::Raise()
4bb6408c 636{
34636400
VZ
637 Widget wTop = (Widget) GetTopWidget();
638 Window window = XtWindow(wTop);
639 XRaiseWindow(XtDisplay(wTop), window);
4bb6408c
JS
640}
641
34636400
VZ
642// Lower the window to the bottom of the Z order
643void wxWindow::Lower()
644{
645 Widget wTop = (Widget) GetTopWidget();
646 Window window = XtWindow(wTop);
647 XLowerWindow(XtDisplay(wTop), window);
648}
4bb6408c 649
af0bb3b1 650void wxWindow::SetTitle(const wxString& title)
4bb6408c 651{
af0bb3b1 652 XtVaSetValues((Widget)GetMainWidget(), XmNtitle, title.c_str(), NULL);
4bb6408c
JS
653}
654
34636400 655wxString wxWindow::GetTitle() const
4bb6408c 656{
af0bb3b1
VZ
657 char *title;
658 XtVaGetValues((Widget)GetMainWidget(), XmNtitle, &title, NULL);
659
660 return wxString(title);
4bb6408c
JS
661}
662
4116c221 663void wxWindow::DoCaptureMouse()
4bb6408c 664{
9806a47c 665 g_captureWindow = this;
34636400 666 if ( m_winCaptured )
a4294b78 667 return;
34636400 668
af0bb3b1 669 Widget wMain = (Widget)GetMainWidget();
34636400
VZ
670 if ( wMain )
671 XtAddGrab(wMain, TRUE, FALSE);
672
673 m_winCaptured = TRUE;
4bb6408c
JS
674}
675
4116c221 676void wxWindow::DoReleaseMouse()
4bb6408c 677{
9806a47c 678 g_captureWindow = NULL;
34636400
VZ
679 if ( !m_winCaptured )
680 return;
681
af0bb3b1 682 Widget wMain = (Widget)GetMainWidget();
34636400
VZ
683 if ( wMain )
684 XtRemoveGrab(wMain);
685
686 m_winCaptured = FALSE;
4bb6408c
JS
687}
688
34636400 689bool wxWindow::SetFont(const wxFont& font)
4bb6408c 690{
34636400
VZ
691 if ( !wxWindowBase::SetFont(font) )
692 {
693 // nothing to do
694 return FALSE;
695 }
696
697 ChangeFont();
698
699 return TRUE;
4bb6408c
JS
700}
701
34636400 702bool wxWindow::SetCursor(const wxCursor& cursor)
4bb6408c 703{
34636400 704 if ( !wxWindowBase::SetCursor(cursor) )
2d120f83 705 {
34636400
VZ
706 // no change
707 return FALSE;
2d120f83 708 }
4bb6408c 709
f6bcfd97
BP
710 // wxASSERT_MSG( m_cursor.Ok(),
711 // wxT("cursor must be valid after call to the base version"));
712 wxCursor* cursor2 = NULL;
713 if (m_cursor.Ok())
714 cursor2 = & m_cursor;
715 else
716 cursor2 = wxSTANDARD_CURSOR;
4bb6408c 717
34636400 718 WXDisplay *dpy = GetXDisplay();
f6bcfd97 719 WXCursor x_cursor = cursor2->GetXCursor(dpy);
34636400
VZ
720
721 Widget w = (Widget) GetMainWidget();
722 Window win = XtWindow(w);
723 XDefineCursor((Display*) dpy, win, (Cursor) x_cursor);
af0bb3b1
VZ
724
725 return TRUE;
34636400
VZ
726}
727
728// Coordinates relative to the window
729void wxWindow::WarpPointer (int x, int y)
4bb6408c 730{
34636400
VZ
731 Widget wClient = (Widget)GetClientWidget();
732
733 XWarpPointer(XtDisplay(wClient), None, XtWindow(wClient), 0, 0, 0, 0, x, y);
4bb6408c
JS
734}
735
34636400
VZ
736// ---------------------------------------------------------------------------
737// scrolling stuff
738// ---------------------------------------------------------------------------
739
740int wxWindow::GetScrollPos(int orient) const
4bb6408c 741{
34636400
VZ
742 if (orient == wxHORIZONTAL)
743 return m_scrollPosX;
744 else
745 return m_scrollPosY;
746
747#if 0
748 Widget scrollBar = (Widget) ((orient == wxHORIZONTAL) ? m_hScrollBar : m_vScrollBar);
749 if (scrollBar)
2d120f83 750 {
34636400
VZ
751 int pos;
752 XtVaGetValues(scrollBar, XmNvalue, &pos, NULL);
753 return pos;
2d120f83 754 }
34636400
VZ
755 else
756 return 0;
757#endif // 0
2d120f83 758}
7fe7d506 759
34636400
VZ
760// This now returns the whole range, not just the number of positions that we
761// can scroll.
762int wxWindow::GetScrollRange(int orient) const
2d120f83 763{
af0bb3b1 764 Widget scrollBar = (Widget)GetScrollbar((wxOrientation)orient);
34636400
VZ
765 wxCHECK_MSG( scrollBar, 0, "no such scrollbar" );
766
c4cb3d0f
JS
767 int range = 0;
768 if (scrollBar)
769 XtVaGetValues(scrollBar, XmNmaximum, &range, NULL);
34636400 770 return range;
2d120f83 771}
4bb6408c 772
34636400 773int wxWindow::GetScrollThumb(int orient) const
4bb6408c 774{
af0bb3b1 775 Widget scrollBar = (Widget)GetScrollbar((wxOrientation)orient);
34636400
VZ
776 wxCHECK_MSG( scrollBar, 0, "no such scrollbar" );
777
778 int thumb;
779 XtVaGetValues(scrollBar, XmNsliderSize, &thumb, NULL);
780 return thumb;
4bb6408c
JS
781}
782
34636400 783void wxWindow::SetScrollPos(int orient, int pos, bool WXUNUSED(refresh))
4bb6408c 784{
af0bb3b1 785 Widget scrollBar = (Widget)GetScrollbar((wxOrientation)orient);
34636400
VZ
786
787 if ( scrollBar )
4bb6408c 788 {
34636400 789 XtVaSetValues (scrollBar, XmNvalue, pos, NULL);
4bb6408c 790 }
34636400 791
af0bb3b1 792 SetInternalScrollPos((wxOrientation)orient, pos);
4bb6408c
JS
793}
794
34636400
VZ
795// New function that will replace some of the above.
796void wxWindow::SetScrollbar(int orient, int pos, int thumbVisible,
797 int range, bool WXUNUSED(refresh))
4bb6408c 798{
34636400
VZ
799 int oldW, oldH;
800 GetSize(& oldW, & oldH);
801
802 if (range == 0)
803 range = 1;
804 if (thumbVisible == 0)
805 thumbVisible = 1;
806
807 if (thumbVisible > range)
808 thumbVisible = range;
809
810 // Save the old state to see if it changed
af0bb3b1 811 WXWidget oldScrollBar = GetScrollbar((wxOrientation)orient);
34636400
VZ
812
813 if (orient == wxHORIZONTAL)
50414e24 814 {
34636400 815 if (thumbVisible == range)
2d120f83 816 {
34636400
VZ
817 if (m_hScrollBar)
818 DestroyScrollbar(wxHORIZONTAL);
2d120f83
JS
819 }
820 else
821 {
34636400
VZ
822 if (!m_hScrollBar)
823 CreateScrollbar(wxHORIZONTAL);
2d120f83 824 }
50414e24 825 }
34636400 826 if (orient == wxVERTICAL)
50414e24 827 {
34636400 828 if (thumbVisible == range)
2d120f83 829 {
34636400
VZ
830 if (m_vScrollBar)
831 DestroyScrollbar(wxVERTICAL);
2d120f83
JS
832 }
833 else
834 {
34636400
VZ
835 if (!m_vScrollBar)
836 CreateScrollbar(wxVERTICAL);
2d120f83 837 }
50414e24 838 }
af0bb3b1 839 WXWidget newScrollBar = GetScrollbar((wxOrientation)orient);
4bb6408c 840
88150e60 841 if (oldScrollBar != newScrollBar)
28ab302b 842 {
34636400 843 // This is important! Without it, scrollbars misbehave badly.
2d120f83
JS
844 XtUnrealizeWidget((Widget) m_scrolledWindow);
845 XmScrolledWindowSetAreas ((Widget) m_scrolledWindow, (Widget) m_hScrollBar, (Widget) m_vScrollBar, (Widget) m_drawingArea);
846 XtRealizeWidget((Widget) m_scrolledWindow);
847 XtManageChild((Widget) m_scrolledWindow);
28ab302b 848 }
34636400 849
88150e60 850 if (newScrollBar)
34636400 851 {
2d120f83
JS
852 XtVaSetValues((Widget) newScrollBar,
853 XmNvalue, pos,
854 XmNminimum, 0,
855 XmNmaximum, range,
856 XmNsliderSize, thumbVisible,
857 NULL);
34636400
VZ
858 }
859
af0bb3b1 860 SetInternalScrollPos((wxOrientation)orient, pos);
34636400 861
88150e60
JS
862 int newW, newH;
863 GetSize(& newW, & newH);
34636400 864
88150e60
JS
865 // Adjusting scrollbars can resize the canvas accidentally
866 if (newW != oldW || newH != oldH)
867 SetSize(-1, -1, oldW, oldH);
4bb6408c
JS
868}
869
870// Does a physical scroll
16e93305 871void wxWindow::ScrollWindow(int dx, int dy, const wxRect *rect)
4bb6408c 872{
2d120f83
JS
873 int x, y, w, h;
874 if (rect)
875 {
876 // Use specified rectangle
877 x = rect->x; y = rect->y; w = rect->width; h = rect->height;
878 }
879 else
880 {
881 // Use whole client area
882 x = 0; y = 0;
883 GetClientSize(& w, & h);
884 }
34636400
VZ
885
886 int x1 = (dx >= 0) ? x : x - dx;
2d120f83
JS
887 int y1 = (dy >= 0) ? y : y - dy;
888 int w1 = w - abs(dx);
889 int h1 = h - abs(dy);
890 int x2 = (dx >= 0) ? x + dx : x;
891 int y2 = (dy >= 0) ? y + dy : y;
34636400 892
2d120f83 893 wxClientDC dc(this);
34636400 894
2d120f83 895 dc.SetLogicalFunction (wxCOPY);
34636400 896
2d120f83
JS
897 Widget widget = (Widget) GetMainWidget();
898 Window window = XtWindow(widget);
899 Display* display = XtDisplay(widget);
34636400
VZ
900
901 XCopyArea(display, window, window, (GC) dc.GetGC(),
902 x1, y1, w1, h1, x2, y2);
903
2d120f83
JS
904 dc.SetAutoSetting(TRUE);
905 wxBrush brush(GetBackgroundColour(), wxSOLID);
34636400
VZ
906 dc.SetBrush(brush); // FIXME: needed?
907
fc7ca9b3
MB
908 wxWindowList::Node *cnode = m_children.GetFirst();
909 while (cnode)
910 {
911 wxWindow *child = cnode->GetData();
912 int sx = 0;
913 int sy = 0;
914 child->GetSize( &sx, &sy );
915 wxPoint pos( child->GetPosition() );
916 child->SetSize( pos.x + dx, pos.y + dy, sx, sy, wxSIZE_ALLOW_MINUS_ONE );
917 cnode = cnode->GetNext();
918 }
919
34636400
VZ
920 // We'll add rectangles to the list of update rectangles according to which
921 // bits we've exposed.
2d120f83 922 wxList updateRects;
34636400 923
2d120f83
JS
924 if (dx > 0)
925 {
926 wxRect *rect = new wxRect;
927 rect->x = x;
928 rect->y = y;
929 rect->width = dx;
930 rect->height = h;
34636400 931
2d120f83
JS
932 XFillRectangle(display, window,
933 (GC) dc.GetGC(), rect->x, rect->y, rect->width, rect->height);
34636400 934
2d120f83
JS
935 rect->x = rect->x;
936 rect->y = rect->y;
937 rect->width = rect->width;
938 rect->height = rect->height;
34636400 939
2d120f83
JS
940 updateRects.Append((wxObject*) rect);
941 }
942 else if (dx < 0)
943 {
944 wxRect *rect = new wxRect;
34636400 945
2d120f83
JS
946 rect->x = x + w + dx;
947 rect->y = y;
948 rect->width = -dx;
949 rect->height = h;
34636400 950
2d120f83
JS
951 XFillRectangle(display, window,
952 (GC) dc.GetGC(), rect->x, rect->y, rect->width,
953 rect->height);
34636400 954
2d120f83
JS
955 rect->x = rect->x;
956 rect->y = rect->y;
957 rect->width = rect->width;
958 rect->height = rect->height;
34636400 959
2d120f83
JS
960 updateRects.Append((wxObject*) rect);
961 }
962 if (dy > 0)
963 {
964 wxRect *rect = new wxRect;
34636400 965
2d120f83
JS
966 rect->x = x;
967 rect->y = y;
968 rect->width = w;
969 rect->height = dy;
34636400 970
2d120f83
JS
971 XFillRectangle(display, window,
972 (GC) dc.GetGC(), rect->x, rect->y, rect->width, rect->height);
34636400 973
2d120f83
JS
974 rect->x = rect->x;
975 rect->y = rect->y;
976 rect->width = rect->width;
977 rect->height = rect->height;
34636400 978
2d120f83
JS
979 updateRects.Append((wxObject*) rect);
980 }
981 else if (dy < 0)
982 {
983 wxRect *rect = new wxRect;
34636400 984
2d120f83
JS
985 rect->x = x;
986 rect->y = y + h + dy;
987 rect->width = w;
988 rect->height = -dy;
34636400 989
2d120f83
JS
990 XFillRectangle(display, window,
991 (GC) dc.GetGC(), rect->x, rect->y, rect->width, rect->height);
34636400 992
2d120f83
JS
993 rect->x = rect->x;
994 rect->y = rect->y;
995 rect->width = rect->width;
996 rect->height = rect->height;
34636400 997
2d120f83
JS
998 updateRects.Append((wxObject*) rect);
999 }
1000 dc.SetBrush(wxNullBrush);
34636400 1001
2d120f83 1002 // Now send expose events
34636400 1003
1bc822df 1004 wxList::Node* node = updateRects.GetFirst();
2d120f83
JS
1005 while (node)
1006 {
1bc822df 1007 wxRect* rect = (wxRect*) node->GetData();
2d120f83 1008 XExposeEvent event;
34636400 1009
2d120f83
JS
1010 event.type = Expose;
1011 event.display = display;
1012 event.send_event = True;
1013 event.window = window;
34636400 1014
2d120f83
JS
1015 event.x = rect->x;
1016 event.y = rect->y;
1017 event.width = rect->width;
1018 event.height = rect->height;
34636400 1019
2d120f83 1020 event.count = 0;
34636400 1021
2d120f83 1022 XSendEvent(display, window, False, ExposureMask, (XEvent *)&event);
34636400 1023
1bc822df 1024 node = node->GetNext();
34636400 1025
2d120f83 1026 }
34636400 1027
2d120f83 1028 // Delete the update rects
1bc822df 1029 node = updateRects.GetFirst();
2d120f83
JS
1030 while (node)
1031 {
1bc822df 1032 wxRect* rect = (wxRect*) node->GetData();
2d120f83 1033 delete rect;
1bc822df 1034 node = node->GetNext();
2d120f83 1035 }
a91b47e8
JS
1036
1037 XmUpdateDisplay((Widget) GetMainWidget());
4bb6408c
JS
1038}
1039
34636400
VZ
1040// ---------------------------------------------------------------------------
1041// drag and drop
1042// ---------------------------------------------------------------------------
4ce81a75 1043
34636400 1044#if wxUSE_DRAG_AND_DROP
4ce81a75 1045
34636400 1046void wxWindow::SetDropTarget(wxDropTarget * WXUNUSED(pDropTarget))
4ce81a75 1047{
34636400 1048 // TODO
4bb6408c
JS
1049}
1050
34636400
VZ
1051#endif
1052
1053// Old style file-manager drag&drop
1054void wxWindow::DragAcceptFiles(bool WXUNUSED(accept))
4bb6408c 1055{
34636400 1056 // TODO
4bb6408c
JS
1057}
1058
34636400
VZ
1059// ----------------------------------------------------------------------------
1060// tooltips
1061// ----------------------------------------------------------------------------
1062
1063#if wxUSE_TOOLTIPS
1064
1065void wxWindow::DoSetToolTip(wxToolTip * WXUNUSED(tooltip))
4bb6408c 1066{
34636400 1067 // TODO
4bb6408c
JS
1068}
1069
34636400
VZ
1070#endif // wxUSE_TOOLTIPS
1071
ee31c392
VZ
1072// ----------------------------------------------------------------------------
1073// popup menus
1074// ----------------------------------------------------------------------------
1075
7e1bcfa8
MB
1076#if wxUSE_MENUS
1077
ee31c392
VZ
1078bool wxWindow::DoPopupMenu(wxMenu *menu, int x, int y)
1079{
1080 Widget widget = (Widget) GetMainWidget();
1081
1082 /* The menuId field seems to be usused, so we'll use it to
1083 indicate whether a menu is popped up or not:
1084 0: Not currently created as a popup
1085 -1: Created as a popup, but not active
1086 1: Active popup.
1087 */
1088
1089 if (menu->GetParent() && (menu->GetId() != -1))
1090 return FALSE;
1091
7e1bcfa8
MB
1092 if (menu->GetMainWidget())
1093 {
ee31c392
VZ
1094 menu->DestroyMenu(TRUE);
1095 }
1096
1097 menu->SetId(1); /* Mark as popped-up */
1098 menu->CreateMenu(NULL, widget, menu);
1099 menu->SetInvokingWindow(this);
1100
1101 menu->UpdateUI();
1102
1103 // menu->SetParent(parent);
1104 // parent->children->Append(menu); // Store menu for later deletion
1105
1106 Widget menuWidget = (Widget) menu->GetMainWidget();
1107
1108 int rootX = 0;
1109 int rootY = 0;
1110
1111 int deviceX = x;
1112 int deviceY = y;
1113 /*
1114 if (this->IsKindOf(CLASSINFO(wxCanvas)))
1115 {
1116 wxCanvas *canvas = (wxCanvas *) this;
1117 deviceX = canvas->GetDC ()->LogicalToDeviceX (x);
1118 deviceY = canvas->GetDC ()->LogicalToDeviceY (y);
1119 }
1120 */
1121
1122 Display *display = XtDisplay (widget);
1123 Window rootWindow = RootWindowOfScreen (XtScreen((Widget)widget));
1124 Window thisWindow = XtWindow (widget);
1125 Window childWindow;
1126 XTranslateCoordinates (display, thisWindow, rootWindow, (int) deviceX, (int) deviceY,
1127 &rootX, &rootY, &childWindow);
1128
1129 XButtonPressedEvent event;
1130 event.type = ButtonPress;
1131 event.button = 1;
1132
1133 event.x = deviceX;
1134 event.y = deviceY;
1135
1136 event.x_root = rootX;
1137 event.y_root = rootY;
1138
1139 XmMenuPosition (menuWidget, &event);
1140 XtManageChild (menuWidget);
1141
2b5f62a0 1142 // The ID of a pop-up menu is 1 when active, and is set to 0 by the
e41e1385 1143 // idle-time destroy routine.
2b5f62a0 1144 // Waiting until this ID changes causes this function to block until
e41e1385
JS
1145 // the menu has been dismissed and the widgets cleaned up.
1146 // In other words, once this routine returns, it is safe to delete
1147 // the menu object.
1148 // Ian Brown <ian.brown@printsoft.de>
e41e1385 1149
7e1bcfa8 1150 wxEventLoop evtLoop;
e41e1385 1151
7e1bcfa8
MB
1152 while (menu->GetId() == 1)
1153 {
1154 wxDoEventLoopIteration( evtLoop );
e41e1385 1155 }
7e1bcfa8 1156
ee31c392
VZ
1157 return TRUE;
1158}
1159
7e1bcfa8
MB
1160#endif
1161
34636400
VZ
1162// ---------------------------------------------------------------------------
1163// moving and resizing
1164// ---------------------------------------------------------------------------
4bb6408c 1165
34636400 1166bool wxWindow::PreResize()
4bb6408c 1167{
2d120f83 1168 return TRUE;
4bb6408c
JS
1169}
1170
34636400 1171// Get total size
af0bb3b1 1172void wxWindow::DoGetSize(int *x, int *y) const
4bb6408c 1173{
fc7ca9b3
MB
1174 Widget widget = (Widget)( !m_drawingArea ? GetTopWidget() :
1175 ( m_borderWidget ? m_borderWidget :
1176 m_scrolledWindow ? m_scrolledWindow :
1177 m_drawingArea ) );
34636400 1178 Dimension xx, yy;
fc7ca9b3
MB
1179
1180 XtVaGetValues( widget,
1181 XmNwidth, &xx,
1182 XmNheight, &yy,
1183 NULL );
1184 if(x) *x = xx;
1185 if(y) *y = yy;
4bb6408c
JS
1186}
1187
af0bb3b1 1188void wxWindow::DoGetPosition(int *x, int *y) const
4bb6408c 1189{
fc7ca9b3
MB
1190 Widget widget = (Widget)
1191 ( m_drawingArea ?
1192 ( m_borderWidget ? m_borderWidget : m_scrolledWindow ) :
1193 GetTopWidget() );
1194
34636400
VZ
1195 Position xx, yy;
1196 XtVaGetValues(widget, XmNx, &xx, XmNy, &yy, NULL);
b59bf2db 1197
34636400
VZ
1198 // We may be faking the client origin. So a window that's really at (0, 30)
1199 // may appear (to wxWin apps) to be at (0, 0).
1200 if (GetParent())
b59bf2db 1201 {
34636400
VZ
1202 wxPoint pt(GetParent()->GetClientAreaOrigin());
1203 xx -= pt.x;
1204 yy -= pt.y;
b59bf2db 1205 }
34636400 1206
fc7ca9b3
MB
1207 if(x) *x = xx;
1208 if(y) *y = yy;
4bb6408c
JS
1209}
1210
af0bb3b1 1211void wxWindow::DoScreenToClient(int *x, int *y) const
4bb6408c 1212{
34636400
VZ
1213 Widget widget = (Widget) GetClientWidget();
1214 Display *display = XtDisplay((Widget) GetMainWidget());
1215 Window rootWindow = RootWindowOfScreen(XtScreen(widget));
1216 Window thisWindow = XtWindow(widget);
1217
1218 Window childWindow;
1219 int xx = *x;
1220 int yy = *y;
1221 XTranslateCoordinates(display, rootWindow, thisWindow, xx, yy, x, y, &childWindow);
4bb6408c
JS
1222}
1223
af0bb3b1 1224void wxWindow::DoClientToScreen(int *x, int *y) const
4bb6408c 1225{
34636400
VZ
1226 Widget widget = (Widget) GetClientWidget();
1227 Display *display = XtDisplay(widget);
1228 Window rootWindow = RootWindowOfScreen(XtScreen(widget));
1229 Window thisWindow = XtWindow(widget);
1230
1231 Window childWindow;
1232 int xx = *x;
1233 int yy = *y;
1234 XTranslateCoordinates(display, thisWindow, rootWindow, xx, yy, x, y, &childWindow);
4bb6408c
JS
1235}
1236
34636400
VZ
1237
1238// Get size *available for subwindows* i.e. excluding menu bar etc.
af0bb3b1 1239void wxWindow::DoGetClientSize(int *x, int *y) const
4fabb575 1240{
34636400
VZ
1241 Widget widget = (Widget) GetClientWidget();
1242 Dimension xx, yy;
1243 XtVaGetValues(widget, XmNwidth, &xx, XmNheight, &yy, NULL);
f6fb552e 1244 if(x) *x = xx; if(y) *y = yy;
4fabb575
JS
1245}
1246
34636400 1247void wxWindow::DoSetSize(int x, int y, int width, int height, int sizeFlags)
37c997b4
MB
1248{
1249 DoSetSizeIntr(x, y, width, height, sizeFlags, FALSE);
1250}
1251
1252void wxWindow::DoSetSizeIntr(int x, int y, int width, int height,
1253 int sizeFlags, bool fromCtor)
4bb6408c 1254{
34636400 1255 // A bit of optimization to help sort out the flickers.
bf5c9d34 1256 int oldX = -1, oldY = -1, oldW = -1, oldH = -1;
37c997b4
MB
1257 if( !fromCtor )
1258 {
1259 GetSize(& oldW, & oldH);
1260 GetPosition(& oldX, & oldY);
1261 }
34636400 1262
9d9b7755
VZ
1263 if ( !(sizeFlags & wxSIZE_ALLOW_MINUS_ONE) )
1264 {
1265 if ( x == -1 )
1266 x = oldX;
1267 if ( y == -1 )
1268 y = oldY;
1269 }
34636400 1270
fc7ca9b3 1271 wxSize size(-1, -1);
7e1bcfa8 1272 if ( width <= 0 )
fc7ca9b3 1273 {
66f8b9ac 1274 if ( ( sizeFlags & wxSIZE_AUTO_WIDTH ) && !fromCtor )
fc7ca9b3
MB
1275 {
1276 size = DoGetBestSize();
1277 width = size.x;
1278 }
1279 else
1280 {
1281 width = oldW;
1282 }
1283 }
34636400 1284
fc7ca9b3 1285 if ( height == -1 )
02800301 1286 {
66f8b9ac 1287 if( ( sizeFlags & wxSIZE_AUTO_HEIGHT ) && !fromCtor )
fc7ca9b3
MB
1288 {
1289 if( size.x == -1 ) size = DoGetBestSize();
1290 height = size.y;
1291 }
1292 else
1293 {
1294 height = oldH;
1295 }
34636400
VZ
1296 }
1297
fc7ca9b3
MB
1298 if ( x != oldX || y != oldY || width != oldW || height != oldH
1299 || !wxNoOptimize::CanOptimize() )
34636400 1300 {
9d9b7755
VZ
1301 if (m_drawingArea)
1302 {
fc7ca9b3
MB
1303 int flags = 0;
1304
1305 if (x > -1 || (sizeFlags & wxSIZE_ALLOW_MINUS_ONE))
1306 flags |= wxMOVE_X;
1307
1308 if (y > -1 || (sizeFlags & wxSIZE_ALLOW_MINUS_ONE))
1309 flags |= wxMOVE_Y;
1310
1311 if (width > 0)
1312 flags |= wxMOVE_WIDTH;
1313
1314 if (height > 0)
1315 flags |= wxMOVE_HEIGHT;
1316
1317 int xx = x; int yy = y;
1318 AdjustForParentClientOrigin(xx, yy, sizeFlags);
1319 if( !fromCtor )
1320 DoMoveWindow( xx, yy, width, height );
1321 else
1322 DoMoveWindowIntr( xx, yy, width, height, flags );
1323
9d9b7755
VZ
1324 return;
1325 }
34636400 1326
9d9b7755
VZ
1327 Widget widget = (Widget) GetTopWidget();
1328 if (!widget)
1329 return;
34636400 1330
9d9b7755
VZ
1331 bool managed = XtIsManaged( widget );
1332 if (managed)
1333 XtUnmanageChild(widget);
34636400 1334
9d9b7755
VZ
1335 int xx = x;
1336 int yy = y;
1337 AdjustForParentClientOrigin(xx, yy, sizeFlags);
1338
1339 DoMoveWindow(xx, yy, width, height);
34636400 1340
9d9b7755
VZ
1341 if (managed)
1342 XtManageChild(widget);
9d9b7755 1343 }
4bb6408c
JS
1344}
1345
34636400 1346void wxWindow::DoSetClientSize(int width, int height)
4bb6408c 1347{
34636400 1348 if (m_drawingArea)
4bb6408c 1349 {
fc7ca9b3
MB
1350 Widget drawingArea = (Widget) m_drawingArea;
1351
1352 XtVaSetValues(drawingArea, XmNresizePolicy, XmRESIZE_ANY, NULL);
1353
1354 if (width > -1)
1355 XtVaSetValues(drawingArea, XmNwidth, width, NULL);
1356 if (height > -1)
1357 XtVaSetValues(drawingArea, XmNheight, height, NULL);
1358
1359 XtVaSetValues(drawingArea, XmNresizePolicy, XmRESIZE_NONE, NULL);
34636400 1360 return;
4bb6408c 1361 }
34636400
VZ
1362
1363 Widget widget = (Widget) GetTopWidget();
1364
1365 if (width > -1)
1366 XtVaSetValues(widget, XmNwidth, width, NULL);
1367 if (height > -1)
1368 XtVaSetValues(widget, XmNheight, height, NULL);
4bb6408c
JS
1369}
1370
34636400
VZ
1371// For implementation purposes - sometimes decorations make the client area
1372// smaller
1373wxPoint wxWindow::GetClientAreaOrigin() const
02e8b2f9 1374{
34636400 1375 return wxPoint(0, 0);
02e8b2f9
JS
1376}
1377
fc7ca9b3
MB
1378void wxWindow::DoMoveWindowIntr(int xx, int yy, int w, int h,
1379 int flags)
9d9b7755 1380{
37c997b4 1381 if (m_drawingArea)
fc7ca9b3
MB
1382 {
1383 Widget drawingArea = (Widget) m_drawingArea;
1384 Widget borderOrScrolled = m_borderWidget ?
1385 (Widget) m_borderWidget :
1386 (Widget) m_scrolledWindow;
1387
1388 bool managed = XtIsManaged(borderOrScrolled);
fc7ca9b3
MB
1389 if (managed)
1390 XtUnmanageChild (borderOrScrolled);
1391 XtVaSetValues(drawingArea, XmNresizePolicy, XmRESIZE_ANY, NULL);
1392
1393 if (flags & wxMOVE_X)
1394 XtVaSetValues (borderOrScrolled,
1395 XmNx, xx,
1396 NULL);
1397 if (flags & wxMOVE_Y)
1398 XtVaSetValues (borderOrScrolled,
1399 XmNy, yy,
1400 NULL);
1401
1402 if (flags & wxMOVE_WIDTH)
1403 {
1404 if (m_borderWidget)
1405 {
1406 XtVaSetValues ((Widget) m_borderWidget, XmNwidth, w, NULL);
1407 short thick, margin;
1408 XtVaGetValues ((Widget) m_borderWidget,
1409 XmNshadowThickness, &thick,
1410 XmNmarginWidth, &margin,
1411 NULL);
1412 w -= 2 * (thick + margin);
1413 }
37c997b4 1414
fc7ca9b3
MB
1415 XtVaSetValues ((Widget) m_scrolledWindow, XmNwidth, w, NULL);
1416 }
d9d3622e 1417
fc7ca9b3
MB
1418 if (flags & wxMOVE_HEIGHT)
1419 {
1420 if (m_borderWidget)
1421 {
1422 XtVaSetValues ((Widget) m_borderWidget, XmNheight, h, NULL);
1423 short thick, margin;
1424 XtVaGetValues ((Widget) m_borderWidget,
1425 XmNshadowThickness, &thick,
1426 XmNmarginHeight, &margin,
1427 NULL);
1428 h -= 2 * (thick + margin);
1429 }
1430
1431 XtVaSetValues ((Widget) m_scrolledWindow, XmNheight, h, NULL);
1432 }
1433
1434 if (managed)
1435 XtManageChild (borderOrScrolled);
1436 XtVaSetValues(drawingArea, XmNresizePolicy, XmRESIZE_NONE, NULL);
1437 }
1438 else
1439 {
1440 if( w < 1 ) w = 1;
1441 if( h < 1 ) h = 1;
1442
1443 XtVaSetValues((Widget)GetTopWidget(),
1444 XmNx, xx,
1445 XmNy, yy,
1446 XmNwidth, w,
1447 XmNheight, h,
1448 NULL);
1449 }
1450}
1451
1452void wxWindow::DoMoveWindow(int x, int y, int width, int height)
1453{
1454 DoMoveWindowIntr (x, y, width, height,
1455 wxMOVE_X|wxMOVE_Y|wxMOVE_WIDTH|wxMOVE_HEIGHT);
9d9b7755
VZ
1456}
1457
34636400
VZ
1458// ---------------------------------------------------------------------------
1459// text metrics
1460// ---------------------------------------------------------------------------
1461
1462int wxWindow::GetCharHeight() const
4bb6408c 1463{
af0bb3b1 1464 wxCHECK_MSG( m_font.Ok(), 0, "valid window font needed" );
34636400 1465
af0bb3b1 1466 WXFontStructPtr pFontStruct = m_font.GetFontStruct(1.0, GetXDisplay());
34636400
VZ
1467
1468 int direction, ascent, descent;
1469 XCharStruct overall;
1470 XTextExtents ((XFontStruct*) pFontStruct, "x", 1, &direction, &ascent,
1471 &descent, &overall);
1472
1473 // return (overall.ascent + overall.descent);
1474 return (ascent + descent);
4bb6408c
JS
1475}
1476
34636400 1477int wxWindow::GetCharWidth() const
4bb6408c 1478{
af0bb3b1 1479 wxCHECK_MSG( m_font.Ok(), 0, "valid window font needed" );
34636400 1480
af0bb3b1 1481 WXFontStructPtr pFontStruct = m_font.GetFontStruct(1.0, GetXDisplay());
34636400
VZ
1482
1483 int direction, ascent, descent;
1484 XCharStruct overall;
1485 XTextExtents ((XFontStruct*) pFontStruct, "x", 1, &direction, &ascent,
1486 &descent, &overall);
1487
1488 return overall.width;
4bb6408c
JS
1489}
1490
34636400
VZ
1491void wxWindow::GetTextExtent(const wxString& string,
1492 int *x, int *y,
1493 int *descent, int *externalLeading,
1494 const wxFont *theFont) const
4bb6408c 1495{
34636400
VZ
1496 wxFont *fontToUse = (wxFont *)theFont;
1497 if (!fontToUse)
af0bb3b1 1498 fontToUse = (wxFont *) & m_font;
34636400 1499
af0bb3b1 1500 wxCHECK_RET( fontToUse->Ok(), "valid window font needed" );
8e877c19 1501
37c997b4 1502 WXFontStructPtr pFontStruct = fontToUse->GetFontStruct(1.0, GetXDisplay());
34636400
VZ
1503
1504 int direction, ascent, descent2;
1505 XCharStruct overall;
8e877c19 1506 int slen = string.Len();
34636400
VZ
1507
1508#if 0
1509 if (use16)
1510 XTextExtents16((XFontStruct*) pFontStruct, (XChar2b *) (char*) (const char*) string, slen, &direction,
1511 &ascent, &descent2, &overall);
1512#endif
1513
1514 XTextExtents((XFontStruct*) pFontStruct, string, slen,
1515 &direction, &ascent, &descent2, &overall);
1516
1517 if ( x )
1518 *x = (overall.width);
1519 if ( y )
1520 *y = (ascent + descent2);
1521 if (descent)
1522 *descent = descent2;
1523 if (externalLeading)
1524 *externalLeading = 0;
8e877c19 1525
4bb6408c
JS
1526}
1527
34636400
VZ
1528// ----------------------------------------------------------------------------
1529// painting
1530// ----------------------------------------------------------------------------
4bb6408c 1531
148b44a1
MB
1532void wxWindow::AddUpdateRect(int x, int y, int w, int h)
1533{
1534 m_updateRegion.Union( x, y, w, h );
1535}
1536
34636400 1537void wxWindow::Refresh(bool eraseBack, const wxRect *rect)
4bb6408c 1538{
34636400
VZ
1539 m_needsRefresh = TRUE;
1540 Display *display = XtDisplay((Widget) GetMainWidget());
1541 Window thisWindow = XtWindow((Widget) GetMainWidget());
1542
1543 XExposeEvent dummyEvent;
1544 int width, height;
1545 GetSize(&width, &height);
1546
1547 dummyEvent.type = Expose;
1548 dummyEvent.display = display;
1549 dummyEvent.send_event = True;
1550 dummyEvent.window = thisWindow;
1551 if (rect)
2d120f83 1552 {
34636400
VZ
1553 dummyEvent.x = rect->x;
1554 dummyEvent.y = rect->y;
1555 dummyEvent.width = rect->width;
1556 dummyEvent.height = rect->height;
2d120f83
JS
1557 }
1558 else
1559 {
34636400
VZ
1560 dummyEvent.x = 0;
1561 dummyEvent.y = 0;
1562 dummyEvent.width = width;
1563 dummyEvent.height = height;
2d120f83 1564 }
34636400 1565 dummyEvent.count = 0;
4bb6408c 1566
34636400 1567 if (eraseBack)
2d120f83 1568 {
34636400
VZ
1569 wxClientDC dc(this);
1570 wxBrush backgroundBrush(GetBackgroundColour(), wxSOLID);
1571 dc.SetBackground(backgroundBrush);
1572 if (rect)
1573 dc.Clear(*rect);
1574 else
1575 dc.Clear();
2d120f83 1576 }
4bb6408c 1577
34636400 1578 XSendEvent(display, thisWindow, False, ExposureMask, (XEvent *)&dummyEvent);
4bb6408c
JS
1579}
1580
34636400 1581void wxWindow::Clear()
4bb6408c 1582{
34636400
VZ
1583 wxClientDC dc(this);
1584 wxBrush brush(GetBackgroundColour(), wxSOLID);
1585 dc.SetBackground(brush);
1586 dc.Clear();
4bb6408c
JS
1587}
1588
34636400 1589void wxWindow::DoPaint()
4bb6408c 1590{
34636400
VZ
1591 //TODO : make a temporary gc so we can do the XCopyArea below
1592 if (m_backingPixmap && !m_needsRefresh)
4bb6408c 1593 {
34636400 1594 wxPaintDC dc(this);
4bb6408c 1595
34636400 1596 GC tempGC = (GC) dc.GetBackingGC();
4bb6408c 1597
34636400 1598 Widget widget = (Widget) GetMainWidget();
4bb6408c 1599
34636400
VZ
1600 int scrollPosX = 0;
1601 int scrollPosY = 0;
4bb6408c 1602
34636400
VZ
1603 // We have to test whether it's a wxScrolledWindow (hack!) because
1604 // otherwise we don't know how many pixels have been scrolled. We might
1605 // solve this in the future by defining virtual wxWindow functions to get
1606 // the scroll position in pixels. Or, each kind of scrolled window has to
1607 // implement backing stores itself, using generic wxWindows code.
1608 wxScrolledWindow* scrolledWindow = wxDynamicCast(this, wxScrolledWindow);
1609 if ( scrolledWindow )
1610 {
1611 int x, y;
1612 scrolledWindow->CalcScrolledPosition(0, 0, &x, &y);
1613
1614 scrollPosX = - x;
1615 scrollPosY = - y;
1616 }
1617
1618 // TODO: This could be optimized further by only copying the areas in the
1619 // current update region.
1620
1621 // Only blit the part visible in the client area. The backing pixmap
1622 // always starts at 0, 0 but we may be looking at only a portion of it.
1623 wxSize clientArea = GetClientSize();
1624 int toBlitX = m_pixmapWidth - scrollPosX;
1625 int toBlitY = m_pixmapHeight - scrollPosY;
1626
1627 // Copy whichever is samller, the amount of pixmap we have to copy,
1628 // or the size of the client area.
1629 toBlitX = wxMin(toBlitX, clientArea.x);
1630 toBlitY = wxMin(toBlitY, clientArea.y);
1631
1632 // Make sure we're not negative
1633 toBlitX = wxMax(0, toBlitX);
1634 toBlitY = wxMax(0, toBlitY);
1635
1636 XCopyArea
1637 (
1638 XtDisplay(widget),
1639 (Pixmap) m_backingPixmap,
1640 XtWindow (widget),
1641 tempGC,
1642 scrollPosX, scrollPosY, // Start at the scroll position
1643 toBlitX, toBlitY, // How much of the pixmap to copy
1644 0, 0 // Destination
1645 );
1646 }
1647 else
4bb6408c 1648 {
fc7ca9b3 1649 wxWindowDC dc(this);
34636400 1650 // Set an erase event first
fc7ca9b3 1651 wxEraseEvent eraseEvent(GetId(), &dc);
34636400
VZ
1652 eraseEvent.SetEventObject(this);
1653 GetEventHandler()->ProcessEvent(eraseEvent);
1654
1655 wxPaintEvent event(GetId());
1656 event.SetEventObject(this);
1657 GetEventHandler()->ProcessEvent(event);
1658
1659 m_needsRefresh = FALSE;
4bb6408c 1660 }
4bb6408c
JS
1661}
1662
34636400
VZ
1663// ----------------------------------------------------------------------------
1664// event handlers
1665// ----------------------------------------------------------------------------
1666
1667// Responds to colour changes: passes event on to children.
1668void wxWindow::OnSysColourChanged(wxSysColourChangedEvent& event)
4bb6408c 1669{
34636400
VZ
1670 wxWindowList::Node *node = GetChildren().GetFirst();
1671 while ( node )
4bb6408c 1672 {
34636400
VZ
1673 // Only propagate to non-top-level windows
1674 wxWindow *win = node->GetData();
1675 if ( win->GetParent() )
2d120f83 1676 {
34636400
VZ
1677 wxSysColourChangedEvent event2;
1678 event.m_eventObject = win;
1679 win->GetEventHandler()->ProcessEvent(event2);
2d120f83 1680 }
4bb6408c 1681
34636400 1682 node = node->GetNext();
2d120f83 1683 }
4bb6408c
JS
1684}
1685
af111fc3 1686void wxWindow::OnIdle(wxIdleEvent& WXUNUSED(event))
4bb6408c 1687{
34636400
VZ
1688 // This calls the UI-update mechanism (querying windows for
1689 // menu/toolbar/control state information)
0b30bb0b
JS
1690 if (wxUpdateUIEvent::CanUpdate())
1691 UpdateWindowUI();
4bb6408c
JS
1692}
1693
34636400
VZ
1694// ----------------------------------------------------------------------------
1695// accelerators
1696// ----------------------------------------------------------------------------
4bb6408c 1697
34636400 1698bool wxWindow::ProcessAccelerator(wxKeyEvent& event)
4bb6408c 1699{
7e1bcfa8 1700#if wxUSE_ACCEL
34636400
VZ
1701 if (!m_acceleratorTable.Ok())
1702 return FALSE;
4bb6408c 1703
34636400
VZ
1704 int count = m_acceleratorTable.GetCount();
1705 wxAcceleratorEntry* entries = m_acceleratorTable.GetEntries();
1706 int i;
1707 for (i = 0; i < count; i++)
2d120f83 1708 {
34636400
VZ
1709 wxAcceleratorEntry* entry = & (entries[i]);
1710 if (entry->MatchesEvent(event))
1711 {
f6045f99 1712 // Bingo, we have a match. Now find a control that matches the
2b5f62a0 1713 // entry command id.
4bb6408c 1714
34636400
VZ
1715 // Need to go up to the top of the window hierarchy, since it might
1716 // be e.g. a menu item
1717 wxWindow* parent = this;
1718 while ( parent && !parent->IsTopLevel() )
1719 parent = parent->GetParent();
4bb6408c 1720
34636400
VZ
1721 if (!parent)
1722 return FALSE;
4bb6408c 1723
34636400
VZ
1724 wxFrame* frame = wxDynamicCast(parent, wxFrame);
1725 if ( frame )
1726 {
7e1bcfa8 1727#if wxUSE_MENUS
34636400
VZ
1728 // Try for a menu command
1729 if (frame->GetMenuBar())
1730 {
c71830c3 1731 wxMenuItem* item = frame->GetMenuBar()->FindItem(entry->GetCommand());
34636400
VZ
1732 if (item)
1733 {
1734 wxCommandEvent commandEvent(wxEVT_COMMAND_MENU_SELECTED, entry->GetCommand());
1735 commandEvent.SetEventObject(frame);
4bb6408c 1736
34636400
VZ
1737 // If ProcessEvent returns TRUE (it was handled), then
1738 // the calling code will skip the event handling.
1739 return frame->GetEventHandler()->ProcessEvent(commandEvent);
1740 }
1741 }
7e1bcfa8 1742#endif
34636400 1743 }
3dd4e4e0 1744
34636400
VZ
1745 // Find a child matching the command id
1746 wxWindow* child = parent->FindWindow(entry->GetCommand());
3dd4e4e0 1747
34636400
VZ
1748 // No such child
1749 if (!child)
1750 return FALSE;
3dd4e4e0 1751
34636400
VZ
1752 // Now we process those kinds of windows that we can.
1753 // For now, only buttons.
1754 if ( wxDynamicCast(child, wxButton) )
1755 {
1756 wxCommandEvent commandEvent (wxEVT_COMMAND_BUTTON_CLICKED, child->GetId());
1757 commandEvent.SetEventObject(child);
1758 return child->GetEventHandler()->ProcessEvent(commandEvent);
1759 }
3dd4e4e0 1760
34636400
VZ
1761 return FALSE;
1762 } // matches event
1763 }// for
7e1bcfa8 1764#endif
4bb6408c 1765
34636400
VZ
1766 // We didn't match the key event against an accelerator.
1767 return FALSE;
4bb6408c
JS
1768}
1769
34636400
VZ
1770// ============================================================================
1771// Motif-specific stuff from here on
1772// ============================================================================
1773
1774// ----------------------------------------------------------------------------
1775// function which maintain the global hash table mapping Widgets to wxWindows
1776// ----------------------------------------------------------------------------
1777
1778bool wxAddWindowToTable(Widget w, wxWindow *win)
4bb6408c 1779{
34636400 1780 wxWindow *oldItem = NULL;
33caefb3 1781 if ((oldItem = (wxWindow *)wxWidgetHashTable->Get ((long) w)))
2d120f83 1782 {
34636400
VZ
1783 wxLogDebug("Widget table clash: new widget is %ld, %s",
1784 (long)w, win->GetClassInfo()->GetClassName());
1785 return FALSE;
2d120f83 1786 }
4bb6408c 1787
33caefb3 1788 wxWidgetHashTable->Put((long) w, win);
4bb6408c 1789
1bc822df
MB
1790 wxLogTrace("widget", "Widget 0x%p <-> window %p (%s)",
1791 (WXWidget)w, win, win->GetClassInfo()->GetClassName());
31528cd3 1792
34636400 1793 return TRUE;
4bb6408c
JS
1794}
1795
34636400 1796wxWindow *wxGetWindowFromTable(Widget w)
4bb6408c 1797{
33caefb3 1798 return (wxWindow *)wxWidgetHashTable->Get((long) w);
4bb6408c
JS
1799}
1800
34636400 1801void wxDeleteWindowFromTable(Widget w)
4bb6408c 1802{
fc7ca9b3
MB
1803 wxLogTrace("widget", "Widget 0x%p", (WXWidget)w);
1804
33caefb3 1805 wxWidgetHashTable->Delete((long)w);
4bb6408c
JS
1806}
1807
34636400
VZ
1808// ----------------------------------------------------------------------------
1809// add/remove window from the table
1810// ----------------------------------------------------------------------------
4bb6408c 1811
34636400 1812// Add to hash table, add event handler
af111fc3 1813bool wxWindow::AttachWidget (wxWindow* WXUNUSED(parent), WXWidget mainWidget,
34636400 1814 WXWidget formWidget, int x, int y, int width, int height)
4bb6408c 1815{
34636400 1816 wxAddWindowToTable((Widget) mainWidget, this);
a8680e3e
MB
1817 XtAddEventHandler( (Widget) mainWidget,
1818 ButtonPressMask | ButtonReleaseMask
1819 | PointerMotionMask,
1820 False,
1821 wxPanelItemEventHandler,
1822 (XtPointer) this);
4bb6408c 1823
34636400
VZ
1824 if (!formWidget)
1825 {
1826 XtTranslations ptr;
1827 XtOverrideTranslations ((Widget) mainWidget,
1828 ptr = XtParseTranslationTable ("<Configure>: resize()"));
1829 XtFree ((char *) ptr);
1830 }
4bb6408c 1831
34636400
VZ
1832 // Some widgets have a parent form widget, e.g. wxRadioBox
1833 if (formWidget)
1834 {
1835 if (!wxAddWindowToTable((Widget) formWidget, this))
1836 return FALSE;
4bb6408c 1837
34636400
VZ
1838 XtTranslations ptr;
1839 XtOverrideTranslations ((Widget) formWidget,
1840 ptr = XtParseTranslationTable ("<Configure>: resize()"));
1841 XtFree ((char *) ptr);
1842 }
4bb6408c 1843
34636400
VZ
1844 if (x == -1)
1845 x = 0;
1846 if (y == -1)
1847 y = 0;
1848 SetSize (x, y, width, height);
4bb6408c 1849
34636400 1850 return TRUE;
4bb6408c
JS
1851}
1852
34636400
VZ
1853// Remove event handler, remove from hash table
1854bool wxWindow::DetachWidget(WXWidget widget)
4bb6408c 1855{
a8680e3e
MB
1856 XtRemoveEventHandler( (Widget) widget,
1857 ButtonPressMask | ButtonReleaseMask
1858 | PointerMotionMask,
1859 False,
1860 wxPanelItemEventHandler,
1861 (XtPointer)this);
4bb6408c 1862
34636400 1863 wxDeleteWindowFromTable((Widget) widget);
2d120f83 1864 return TRUE;
4bb6408c
JS
1865}
1866
34636400
VZ
1867// ----------------------------------------------------------------------------
1868// Motif-specific accessors
1869// ----------------------------------------------------------------------------
2d120f83 1870
34636400 1871// Get the underlying X window
4bb6408c
JS
1872WXWindow wxWindow::GetXWindow() const
1873{
af0bb3b1 1874 Widget wMain = (Widget)GetMainWidget();
34636400
VZ
1875 if ( wMain )
1876 return (WXWindow) XtWindow(wMain);
ad813b00
JS
1877 else
1878 return (WXWindow) 0;
4bb6408c
JS
1879}
1880
34636400 1881// Get the underlying X display
4bb6408c
JS
1882WXDisplay *wxWindow::GetXDisplay() const
1883{
af0bb3b1 1884 Widget wMain = (Widget)GetMainWidget();
34636400
VZ
1885 if ( wMain )
1886 return (WXDisplay*) XtDisplay(wMain);
ad813b00
JS
1887 else
1888 return (WXDisplay*) NULL;
4bb6408c
JS
1889}
1890
1891WXWidget wxWindow::GetMainWidget() const
1892{
50414e24 1893 if (m_drawingArea)
2d120f83 1894 return m_drawingArea;
50414e24 1895 else
2d120f83 1896 return m_mainWidget;
50414e24
JS
1897}
1898
1899WXWidget wxWindow::GetClientWidget() const
1900{
1901 if (m_drawingArea != (WXWidget) 0)
1902 return m_drawingArea;
1903 else
02e8b2f9
JS
1904 return GetMainWidget();
1905}
1906
1907WXWidget wxWindow::GetTopWidget() const
1908{
1909 return GetMainWidget();
4bb6408c
JS
1910}
1911
34636400
VZ
1912WXWidget wxWindow::GetLabelWidget() const
1913{
1914 return GetMainWidget();
1915}
1916
1917// ----------------------------------------------------------------------------
1918// Motif callbacks
1919// ----------------------------------------------------------------------------
1920
1921// All widgets should have this as their resize proc.
1922// OnSize sent to wxWindow via client data.
66f8b9ac
MB
1923void wxWidgetResizeProc(Widget w, XConfigureEvent *WXUNUSED(event),
1924 String WXUNUSED(args)[], int *WXUNUSED(num_args))
34636400
VZ
1925{
1926 wxWindow *win = wxGetWindowFromTable(w);
1927 if (!win)
1928 return;
1929
1930 if (win->PreResize())
1931 {
1932 int width, height;
1933 win->GetSize(&width, &height);
1934 wxSizeEvent sizeEvent(wxSize(width, height), win->GetId());
1935 sizeEvent.SetEventObject(win);
1936 win->GetEventHandler()->ProcessEvent(sizeEvent);
1937 }
1938}
1939
1940static void wxCanvasRepaintProc(Widget drawingArea,
1941 XtPointer clientData,
1942 XmDrawingAreaCallbackStruct * cbs)
50414e24 1943{
34636400 1944 if (!wxGetWindowFromTable(drawingArea))
2d120f83 1945 return;
34636400 1946
50414e24 1947 XEvent * event = cbs->event;
55acd85e 1948 wxWindow * win = (wxWindow *) clientData;
34636400 1949
50414e24
JS
1950 switch (event->type)
1951 {
2d120f83 1952 case Expose:
55acd85e 1953 {
6970c7b9
MB
1954 win->AddUpdateRect(event->xexpose.x, event->xexpose.y,
1955 event->xexpose.width, event->xexpose.height);
148b44a1 1956
55acd85e
JS
1957 if (event -> xexpose.count == 0)
1958 {
a91b47e8 1959 win->DoPaint();
55acd85e
JS
1960 }
1961 break;
1962 }
50414e24 1963 }
50414e24
JS
1964}
1965
1966// Unable to deal with Enter/Leave without a separate EventHandler (Motif 1.1.4)
34636400 1967static void wxCanvasEnterLeave(Widget drawingArea,
af111fc3 1968 XtPointer WXUNUSED(clientData),
34636400 1969 XCrossingEvent * event)
50414e24 1970{
2d120f83
JS
1971 XmDrawingAreaCallbackStruct cbs;
1972 XEvent ev;
34636400 1973
2d120f83 1974 ((XCrossingEvent &) ev) = *event;
34636400 1975
2d120f83
JS
1976 cbs.reason = XmCR_INPUT;
1977 cbs.event = &ev;
34636400
VZ
1978
1979 wxCanvasInputEvent(drawingArea, (XtPointer) NULL, &cbs);
50414e24
JS
1980}
1981
1982// Fix to make it work under Motif 1.0 (!)
da494b40
MB
1983static void wxCanvasMotionEvent (Widget WXUNUSED(drawingArea),
1984 XButtonEvent *WXUNUSED(event))
50414e24 1985{
34636400 1986#if XmVersion <= 1000
2d120f83
JS
1987 XmDrawingAreaCallbackStruct cbs;
1988 XEvent ev;
34636400 1989
2d120f83
JS
1990 ev = *((XEvent *) event);
1991 cbs.reason = XmCR_INPUT;
1992 cbs.event = &ev;
34636400 1993
2d120f83 1994 wxCanvasInputEvent (drawingArea, (XtPointer) NULL, &cbs);
34636400 1995#endif // XmVersion <= 1000
50414e24
JS
1996}
1997
34636400 1998static void wxCanvasInputEvent(Widget drawingArea,
af111fc3 1999 XtPointer WXUNUSED(data),
34636400 2000 XmDrawingAreaCallbackStruct * cbs)
50414e24 2001{
34636400 2002 wxWindow *canvas = wxGetWindowFromTable(drawingArea);
2d120f83 2003 XEvent local_event;
34636400 2004
2d120f83 2005 if (canvas==NULL)
34636400
VZ
2006 return;
2007
2d120f83
JS
2008 if (cbs->reason != XmCR_INPUT)
2009 return;
34636400
VZ
2010
2011 local_event = *(cbs->event); // We must keep a copy!
2012
2d120f83 2013 switch (local_event.xany.type)
50414e24
JS
2014 {
2015 case EnterNotify:
2016 case LeaveNotify:
2017 case ButtonPress:
2018 case ButtonRelease:
2019 case MotionNotify:
a8680e3e
MB
2020 {
2021 wxMouseEvent wxevent;
2022 if(wxTranslateMouseEvent(wxevent, canvas, drawingArea, &local_event))
2d120f83 2023 {
a8680e3e
MB
2024 canvas->GetEventHandler()->ProcessEvent(wxevent);
2025 }
2026 break;
2027 }
50414e24 2028 case KeyPress:
50414e24 2029 {
2b5f62a0
VZ
2030 wxKeyEvent event (wxEVT_CHAR);
2031 if (wxTranslateKeyEvent (event, canvas, (Widget) 0, &local_event))
2d120f83
JS
2032 {
2033 // Implement wxFrame::OnCharHook by checking ancestor.
66f8b9ac
MB
2034 wxWindow *parent = canvas;
2035 while (parent && !parent->IsTopLevel())
2d120f83 2036 parent = parent->GetParent();
34636400 2037
2d120f83
JS
2038 if (parent)
2039 {
2040 event.SetEventType(wxEVT_CHAR_HOOK);
2041 if (parent->GetEventHandler()->ProcessEvent(event))
2042 return;
2d120f83 2043 }
a91b47e8
JS
2044
2045 // For simplicity, OnKeyDown is the same as OnChar
2046 // TODO: filter modifier key presses from OnChar
2047 event.SetEventType(wxEVT_KEY_DOWN);
2048
2049 // Only process OnChar if OnKeyDown didn't swallow it
2050 if (!canvas->GetEventHandler()->ProcessEvent (event))
2051 {
66f8b9ac
MB
2052 event.SetEventType(wxEVT_CHAR);
2053 canvas->GetEventHandler()->ProcessEvent (event);
2054 }
2d120f83
JS
2055 }
2056 break;
2057 }
2058 case KeyRelease:
2059 {
2d120f83 2060 wxKeyEvent event (wxEVT_KEY_UP);
2b5f62a0 2061 if (wxTranslateKeyEvent (event, canvas, (Widget) 0, &local_event))
2d120f83
JS
2062 {
2063 canvas->GetEventHandler()->ProcessEvent (event);
2064 }
2065 break;
50414e24 2066 }
50414e24 2067 case FocusIn:
2d120f83
JS
2068 {
2069 if (local_event.xfocus.detail != NotifyPointer)
2070 {
2071 wxFocusEvent event(wxEVT_SET_FOCUS, canvas->GetId());
2072 event.SetEventObject(canvas);
2073 canvas->GetEventHandler()->ProcessEvent(event);
2074 }
2075 break;
50414e24 2076 }
50414e24 2077 case FocusOut:
2d120f83
JS
2078 {
2079 if (local_event.xfocus.detail != NotifyPointer)
2080 {
2081 wxFocusEvent event(wxEVT_KILL_FOCUS, canvas->GetId());
2082 event.SetEventObject(canvas);
2083 canvas->GetEventHandler()->ProcessEvent(event);
2084 }
2085 break;
2086 }
50414e24 2087 default:
2d120f83 2088 break;
50414e24
JS
2089 }
2090}
2091
34636400 2092static void wxPanelItemEventHandler(Widget wid,
af111fc3 2093 XtPointer WXUNUSED(client_data),
34636400
VZ
2094 XEvent* event,
2095 Boolean *continueToDispatch)
50414e24 2096{
34636400 2097 // Widget can be a label or the actual widget.
a91b47e8 2098
af0bb3b1 2099 wxWindow *window = wxGetWindowFromTable(wid);
34636400
VZ
2100 if (window)
2101 {
2102 wxMouseEvent wxevent(0);
2103 if (wxTranslateMouseEvent(wxevent, window, wid, event))
2104 {
2105 window->GetEventHandler()->ProcessEvent(wxevent);
2106 }
2107 }
a91b47e8 2108
34636400
VZ
2109 // TODO: probably the key to allowing default behaviour to happen. Say we
2110 // set a m_doDefault flag to FALSE at the start of this function. Then in
2111 // e.g. wxWindow::OnMouseEvent we can call Default() which sets this flag to
2112 // TRUE, indicating that default processing can happen. Thus, behaviour can
2113 // appear to be overridden just by adding an event handler and not calling
2114 // wxWindow::OnWhatever. ALSO, maybe we can use this instead of the current
2115 // way of handling drawing area events, to simplify things.
2116 *continueToDispatch = True;
2117}
a91b47e8 2118
34636400
VZ
2119static void wxScrollBarCallback(Widget scrollbar,
2120 XtPointer clientData,
311227c3 2121 XmScrollBarCallbackStruct *cbs)
34636400 2122{
34636400 2123 wxWindow *win = wxGetWindowFromTable(scrollbar);
148b44a1 2124 wxOrientation orientation = (wxOrientation)(int)clientData;
a91b47e8 2125
34636400
VZ
2126 wxEventType eventType = wxEVT_NULL;
2127 switch (cbs->reason)
2128 {
2129 case XmCR_INCREMENT:
2130 {
311227c3 2131 eventType = wxEVT_SCROLLWIN_LINEDOWN;
34636400
VZ
2132 break;
2133 }
2134 case XmCR_DECREMENT:
2135 {
311227c3 2136 eventType = wxEVT_SCROLLWIN_LINEUP;
34636400
VZ
2137 break;
2138 }
2139 case XmCR_DRAG:
2140 {
311227c3 2141 eventType = wxEVT_SCROLLWIN_THUMBTRACK;
34636400
VZ
2142 break;
2143 }
2144 case XmCR_VALUE_CHANGED:
2145 {
bdeca1d1 2146 eventType = wxEVT_SCROLLWIN_THUMBRELEASE;
34636400
VZ
2147 break;
2148 }
2149 case XmCR_PAGE_INCREMENT:
2150 {
311227c3 2151 eventType = wxEVT_SCROLLWIN_PAGEDOWN;
34636400
VZ
2152 break;
2153 }
2154 case XmCR_PAGE_DECREMENT:
2155 {
311227c3 2156 eventType = wxEVT_SCROLLWIN_PAGEUP;
34636400
VZ
2157 break;
2158 }
2159 case XmCR_TO_TOP:
2160 {
311227c3 2161 eventType = wxEVT_SCROLLWIN_TOP;
34636400
VZ
2162 break;
2163 }
2164 case XmCR_TO_BOTTOM:
2165 {
311227c3 2166 eventType = wxEVT_SCROLLWIN_BOTTOM;
34636400
VZ
2167 break;
2168 }
2169 default:
2170 {
2171 // Should never get here
2172 wxFAIL_MSG("Unknown scroll event.");
2173 break;
2174 }
2175 }
a91b47e8 2176
311227c3
MB
2177 wxScrollWinEvent event(eventType,
2178 cbs->value,
148b44a1 2179 orientation);
311227c3 2180 event.SetEventObject( win );
34636400
VZ
2181 win->GetEventHandler()->ProcessEvent(event);
2182}
a91b47e8 2183
34636400
VZ
2184// For repainting arbitrary windows
2185void wxUniversalRepaintProc(Widget w, XtPointer WXUNUSED(c_data), XEvent *event, char *)
2186{
2187 Window window;
2188 Display *display;
a91b47e8 2189
34636400
VZ
2190 wxWindow* win = wxGetWindowFromTable(w);
2191 if (!win)
2192 return;
a91b47e8 2193
34636400 2194 switch(event -> type)
50414e24 2195 {
af0bb3b1 2196 case Expose:
34636400
VZ
2197 {
2198 window = (Window) win -> GetXWindow();
2199 display = (Display *) win -> GetXDisplay();
a91b47e8 2200
148b44a1
MB
2201 win->AddUpdateRect(event->xexpose.x, event->xexpose.y,
2202 event->xexpose.width, event->xexpose.height);
2203
34636400
VZ
2204 if (event -> xexpose.count == 0)
2205 {
2206 win->DoPaint();
af0bb3b1
VZ
2207 }
2208
34636400
VZ
2209 break;
2210 }
50414e24
JS
2211 }
2212}
2213
34636400
VZ
2214// ----------------------------------------------------------------------------
2215// TranslateXXXEvent() functions
2216// ----------------------------------------------------------------------------
2217
a8680e3e
MB
2218bool wxTranslateMouseEvent(wxMouseEvent& wxevent, wxWindow *win,
2219 Widget widget, XEvent *xevent)
02e8b2f9 2220{
2d120f83
JS
2221 switch (xevent->xany.type)
2222 {
a8680e3e
MB
2223 case EnterNotify:
2224 case LeaveNotify:
2225#if 0
2226 fprintf(stderr, "Widget 0x%p <-> window %p (%s), %s\n",
2227 (WXWidget)widget, win, win->GetClassInfo()->GetClassName(),
2228 (xevent->xany.type == EnterNotify ? "ENTER" : "LEAVE"));
2229#endif
1e8abce5
MB
2230 case ButtonPress:
2231 case ButtonRelease:
2232 case MotionNotify:
02e8b2f9 2233 {
2d120f83 2234 wxEventType eventType = wxEVT_NULL;
34636400 2235
2d120f83
JS
2236 if (xevent->xany.type == LeaveNotify)
2237 {
a8680e3e
MB
2238 eventType = wxEVT_LEAVE_WINDOW;
2239 }
2240 if (xevent->xany.type == EnterNotify)
2241 {
2242 eventType = wxEVT_ENTER_WINDOW;
2d120f83
JS
2243 }
2244 else if (xevent->xany.type == MotionNotify)
2245 {
2246 eventType = wxEVT_MOTION;
2247 }
2248 else if (xevent->xany.type == ButtonPress)
2249 {
1e8abce5
MB
2250 wxevent.SetTimestamp(xevent->xbutton.time);
2251 int button = 0;
2d120f83
JS
2252 if (xevent->xbutton.button == Button1)
2253 {
2254 eventType = wxEVT_LEFT_DOWN;
1e8abce5 2255 button = 1;
2d120f83
JS
2256 }
2257 else if (xevent->xbutton.button == Button2)
2258 {
2259 eventType = wxEVT_MIDDLE_DOWN;
1e8abce5 2260 button = 2;
2d120f83
JS
2261 }
2262 else if (xevent->xbutton.button == Button3)
2263 {
2264 eventType = wxEVT_RIGHT_DOWN;
1e8abce5
MB
2265 button = 3;
2266 }
2267
2268 // check for a double click
2269 //
eb6fa4b4 2270 long dclickTime = XtGetMultiClickTime(xevent->xany.display);
1e8abce5
MB
2271 long ts = wxevent.GetTimestamp();
2272
2273 int buttonLast = win->GetLastClickedButton();
2274 long lastTS = win->GetLastClickTime();
a8680e3e
MB
2275 if ( buttonLast && buttonLast == button &&
2276 (ts - lastTS) < dclickTime )
1e8abce5
MB
2277 {
2278 // I have a dclick
2279 win->SetLastClick(0, ts);
205c0389
VZ
2280 if ( eventType == wxEVT_LEFT_DOWN )
2281 eventType = wxEVT_LEFT_DCLICK;
2282 else if ( eventType == wxEVT_MIDDLE_DOWN )
2283 eventType = wxEVT_MIDDLE_DCLICK;
2284 else if ( eventType == wxEVT_RIGHT_DOWN )
2285 eventType = wxEVT_RIGHT_DCLICK;
1e8abce5
MB
2286 }
2287 else
2288 {
2289 // not fast enough or different button
2290 win->SetLastClick(button, ts);
2d120f83
JS
2291 }
2292 }
2293 else if (xevent->xany.type == ButtonRelease)
2294 {
2295 if (xevent->xbutton.button == Button1)
2296 {
2297 eventType = wxEVT_LEFT_UP;
2d120f83
JS
2298 }
2299 else if (xevent->xbutton.button == Button2)
2300 {
2301 eventType = wxEVT_MIDDLE_UP;
2d120f83
JS
2302 }
2303 else if (xevent->xbutton.button == Button3)
2304 {
2305 eventType = wxEVT_RIGHT_UP;
2d120f83 2306 }
a8680e3e
MB
2307 else
2308 return FALSE;
2d120f83 2309 }
af0bb3b1
VZ
2310 else
2311 {
2312 return FALSE;
2313 }
34636400 2314
2d120f83 2315 wxevent.SetEventType(eventType);
34636400 2316
2d120f83
JS
2317 Position x1, y1;
2318 XtVaGetValues(widget, XmNx, &x1, XmNy, &y1, NULL);
34636400 2319
2d120f83
JS
2320 int x2, y2;
2321 win->GetPosition(&x2, &y2);
34636400 2322
2d120f83
JS
2323 // The button x/y must be translated to wxWindows
2324 // window space - the widget might be a label or button,
2325 // within a form.
2326 int dx = 0;
2327 int dy = 0;
2328 if (widget != (Widget)win->GetMainWidget())
2329 {
2330 dx = x1;
2331 dy = y1;
2332 }
34636400 2333
2d120f83
JS
2334 wxevent.m_x = xevent->xbutton.x + dx;
2335 wxevent.m_y = xevent->xbutton.y + dy;
34636400 2336
2d120f83 2337 wxevent.m_leftDown = ((eventType == wxEVT_LEFT_DOWN)
34636400 2338 || (event_left_is_down (xevent)
2d120f83
JS
2339 && (eventType != wxEVT_LEFT_UP)));
2340 wxevent.m_middleDown = ((eventType == wxEVT_MIDDLE_DOWN)
34636400 2341 || (event_middle_is_down (xevent)
2d120f83
JS
2342 && (eventType != wxEVT_MIDDLE_UP)));
2343 wxevent.m_rightDown = ((eventType == wxEVT_RIGHT_DOWN)
34636400 2344 || (event_right_is_down (xevent)
2d120f83 2345 && (eventType != wxEVT_RIGHT_UP)));
34636400 2346
2d120f83
JS
2347 wxevent.m_shiftDown = xevent->xbutton.state & ShiftMask;
2348 wxevent.m_controlDown = xevent->xbutton.state & ControlMask;
1e8abce5
MB
2349 wxevent.m_altDown = xevent->xbutton.state & Mod3Mask;
2350 wxevent.m_metaDown = xevent->xbutton.state & Mod1Mask;
2351
2352 wxevent.SetId(win->GetId());
2353 wxevent.SetEventObject(win);
2354
2d120f83
JS
2355 return TRUE;
2356 }
02e8b2f9 2357 }
2d120f83 2358 return FALSE;
02e8b2f9
JS
2359}
2360
fc7ca9b3
MB
2361bool wxTranslateKeyEvent(wxKeyEvent& wxevent, wxWindow *win,
2362 Widget WXUNUSED(widget), XEvent *xevent)
02e8b2f9 2363{
2d120f83
JS
2364 switch (xevent->xany.type)
2365 {
02e8b2f9 2366 case KeyPress:
4a041f2f 2367 case KeyRelease:
2d120f83
JS
2368 {
2369 char buf[20];
34636400 2370
2d120f83 2371 KeySym keySym;
fc7ca9b3 2372 (void) XLookupString((XKeyEvent *)xevent, buf, 20, &keySym, NULL);
2d120f83 2373 int id = wxCharCodeXToWX (keySym);
2b5f62a0
VZ
2374 // id may be WXK_xxx code - these are outside ASCII range, so we
2375 // can't just use toupper() on id
2376 if (id >= 'a' && id <= 'z')
2377 id = toupper(id);
34636400 2378
2d120f83
JS
2379 if (xevent->xkey.state & ShiftMask)
2380 wxevent.m_shiftDown = TRUE;
2381 if (xevent->xkey.state & ControlMask)
2382 wxevent.m_controlDown = TRUE;
2383 if (xevent->xkey.state & Mod3Mask)
2384 wxevent.m_altDown = TRUE;
2385 if (xevent->xkey.state & Mod1Mask)
2386 wxevent.m_metaDown = TRUE;
2387 wxevent.SetEventObject(win);
2388 wxevent.m_keyCode = id;
2389 wxevent.SetTimestamp(xevent->xkey.time);
34636400 2390
2d120f83
JS
2391 wxevent.m_x = xevent->xbutton.x;
2392 wxevent.m_y = xevent->xbutton.y;
34636400 2393
2d120f83
JS
2394 if (id > -1)
2395 return TRUE;
2396 else
2397 return FALSE;
2398 break;
2399 }
02e8b2f9 2400 default:
2d120f83
JS
2401 break;
2402 }
2403 return FALSE;
02e8b2f9
JS
2404}
2405
34636400
VZ
2406// ----------------------------------------------------------------------------
2407// Colour stuff
2408// ----------------------------------------------------------------------------
2409
02e8b2f9 2410#define YAllocColor XAllocColor
0d57be45
JS
2411XColor g_itemColors[5];
2412int wxComputeColours (Display *display, wxColour * back, wxColour * fore)
02e8b2f9 2413{
2d120f83
JS
2414 int result;
2415 static XmColorProc colorProc;
34636400 2416
2d120f83 2417 result = wxNO_COLORS;
34636400 2418
2d120f83 2419 if (back)
02e8b2f9 2420 {
2d120f83
JS
2421 g_itemColors[0].red = (((long) back->Red ()) << 8);
2422 g_itemColors[0].green = (((long) back->Green ()) << 8);
2423 g_itemColors[0].blue = (((long) back->Blue ()) << 8);
2424 g_itemColors[0].flags = DoRed | DoGreen | DoBlue;
2425 if (colorProc == (XmColorProc) NULL)
2426 {
2427 // Get a ptr to the actual function
2428 colorProc = XmSetColorCalculation ((XmColorProc) NULL);
2429 // And set it back to motif.
2430 XmSetColorCalculation (colorProc);
2431 }
2432 (*colorProc) (&g_itemColors[wxBACK_INDEX],
2433 &g_itemColors[wxFORE_INDEX],
2434 &g_itemColors[wxSELE_INDEX],
2435 &g_itemColors[wxTOPS_INDEX],
2436 &g_itemColors[wxBOTS_INDEX]);
2437 result = wxBACK_COLORS;
02e8b2f9 2438 }
2d120f83 2439 if (fore)
02e8b2f9 2440 {
2d120f83
JS
2441 g_itemColors[wxFORE_INDEX].red = (((long) fore->Red ()) << 8);
2442 g_itemColors[wxFORE_INDEX].green = (((long) fore->Green ()) << 8);
2443 g_itemColors[wxFORE_INDEX].blue = (((long) fore->Blue ()) << 8);
2444 g_itemColors[wxFORE_INDEX].flags = DoRed | DoGreen | DoBlue;
2445 if (result == wxNO_COLORS)
2446 result = wxFORE_COLORS;
02e8b2f9 2447 }
34636400 2448
2d120f83
JS
2449 Display *dpy = display;
2450 Colormap cmap = (Colormap) wxTheApp->GetMainColormap((WXDisplay*) dpy);
34636400 2451
2d120f83 2452 if (back)
02e8b2f9 2453 {
2d120f83
JS
2454 /* 5 Colours to allocate */
2455 for (int i = 0; i < 5; i++)
2456 if (!YAllocColor (dpy, cmap, &g_itemColors[i]))
2457 result = wxNO_COLORS;
02e8b2f9 2458 }
2d120f83 2459 else if (fore)
02e8b2f9 2460 {
2d120f83
JS
2461 /* Only 1 colour to allocate */
2462 if (!YAllocColor (dpy, cmap, &g_itemColors[wxFORE_INDEX]))
2463 result = wxNO_COLORS;
02e8b2f9 2464 }
34636400 2465
fc7ca9b3 2466 return result;
02e8b2f9
JS
2467}
2468
34636400
VZ
2469// Changes the foreground and background colours to be derived from the current
2470// background colour. To change the foreground colour, you must call
2471// SetForegroundColour explicitly.
0d57be45 2472void wxWindow::ChangeBackgroundColour()
02e8b2f9 2473{
34636400
VZ
2474 WXWidget mainWidget = GetMainWidget();
2475 if ( mainWidget )
a8680e3e 2476 wxDoChangeBackgroundColour(mainWidget, m_backgroundColour);
0d57be45 2477}
02e8b2f9 2478
0d57be45
JS
2479void wxWindow::ChangeForegroundColour()
2480{
34636400
VZ
2481 WXWidget mainWidget = GetMainWidget();
2482 if ( mainWidget )
a8680e3e 2483 wxDoChangeForegroundColour(mainWidget, m_foregroundColour);
34636400 2484 if ( m_scrolledWindow && mainWidget != m_scrolledWindow )
a8680e3e 2485 wxDoChangeForegroundColour(m_scrolledWindow, m_foregroundColour);
02e8b2f9
JS
2486}
2487
af0bb3b1 2488bool wxWindow::SetBackgroundColour(const wxColour& col)
02e8b2f9 2489{
af0bb3b1
VZ
2490 if ( !wxWindowBase::SetBackgroundColour(col) )
2491 return FALSE;
2492
0d57be45 2493 ChangeBackgroundColour();
af0bb3b1
VZ
2494
2495 return TRUE;
0d57be45
JS
2496}
2497
af0bb3b1 2498bool wxWindow::SetForegroundColour(const wxColour& col)
0d57be45 2499{
af0bb3b1
VZ
2500 if ( !wxWindowBase::SetForegroundColour(col) )
2501 return FALSE;
2502
0d57be45 2503 ChangeForegroundColour();
af0bb3b1
VZ
2504
2505 return TRUE;
0d57be45
JS
2506}
2507
4b5f3fe6 2508void wxWindow::ChangeFont(bool keepOriginalSize)
0d57be45
JS
2509{
2510 // Note that this causes the widget to be resized back
2511 // to its original size! We therefore have to set the size
2512 // back again. TODO: a better way in Motif?
0d57be45 2513 Widget w = (Widget) GetLabelWidget(); // Usually the main widget
af0bb3b1 2514 if (w && m_font.Ok())
0d57be45
JS
2515 {
2516 int width, height, width1, height1;
2517 GetSize(& width, & height);
34636400 2518
e1aae528 2519 wxDoChangeFont( GetLabelWidget(), m_font );
34636400 2520
0d57be45 2521 GetSize(& width1, & height1);
4b5f3fe6 2522 if (keepOriginalSize && (width != width1 || height != height1))
0d57be45
JS
2523 {
2524 SetSize(-1, -1, width, height);
2525 }
2526 }
02e8b2f9 2527}
0d57be45 2528
34636400
VZ
2529// ----------------------------------------------------------------------------
2530// global functions
2531// ----------------------------------------------------------------------------
0d57be45 2532
34636400 2533wxWindow *wxGetActiveWindow()
1f112209
JS
2534{
2535 // TODO
9b8f6fa2 2536 wxFAIL_MSG("Not implemented");
34636400 2537 return NULL;
1f112209
JS
2538}
2539
9806a47c
JS
2540/* static */
2541wxWindow *wxWindowBase::GetCapture()
2542{
2543 return (wxWindow *)g_captureWindow;
2544}
2545
2546
3723b7b1
JS
2547// Find the wxWindow at the current mouse position, returning the mouse
2548// position.
2549wxWindow* wxFindWindowAtPointer(wxPoint& pt)
2550{
57591e0e 2551 return wxFindWindowAtPoint(wxGetMousePosition());
3723b7b1
JS
2552}
2553
2554// Get the current mouse position.
2555wxPoint wxGetMousePosition()
2556{
eb6fa4b4 2557 Display *display = wxGlobalDisplay();
59a12e90
JS
2558 Window rootWindow = RootWindowOfScreen (DefaultScreenOfDisplay(display));
2559 Window rootReturn, childReturn;
2560 int rootX, rootY, winX, winY;
2561 unsigned int maskReturn;
2562
2563 XQueryPointer (display,
2b5f62a0
VZ
2564 rootWindow,
2565 &rootReturn,
59a12e90
JS
2566 &childReturn,
2567 &rootX, &rootY, &winX, &winY, &maskReturn);
2568 return wxPoint(rootX, rootY);
3723b7b1
JS
2569}
2570
9806a47c 2571
34636400
VZ
2572// ----------------------------------------------------------------------------
2573// wxNoOptimize: switch off size optimization
2574// ----------------------------------------------------------------------------
88150e60 2575
af0bb3b1 2576int wxNoOptimize::ms_count = 0;
311227c3 2577