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