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