]> git.saurik.com Git - wxWidgets.git/blame - src/motif/frame.cpp
wxMSW update for CW, wxMac updated
[wxWidgets.git] / src / motif / frame.cpp
CommitLineData
4bb6408c 1/////////////////////////////////////////////////////////////////////////////
1c4f8f8d 2// Name: motif/frame.cpp
4bb6408c
JS
3// Purpose: wxFrame
4// Author: Julian Smart
5// Modified by:
6// Created: 17/09/98
7// RCS-ID: $Id$
8// Copyright: (c) Julian Smart
9// Licence: wxWindows licence
10/////////////////////////////////////////////////////////////////////////////
11
1c4f8f8d
VZ
12// ============================================================================
13// declarations
14// ============================================================================
15
16// ----------------------------------------------------------------------------
17// headers
18// ----------------------------------------------------------------------------
19
4bb6408c 20#ifdef __GNUG__
1c4f8f8d 21 #pragma implementation "frame.h"
4bb6408c
JS
22#endif
23
24#include "wx/frame.h"
25#include "wx/statusbr.h"
26#include "wx/toolbar.h"
27#include "wx/menuitem.h"
28#include "wx/menu.h"
29#include "wx/dcclient.h"
30#include "wx/dialog.h"
31#include "wx/settings.h"
32#include "wx/app.h"
33#include "wx/utils.h"
34
338dd992 35#ifdef __VMS__
1c4f8f8d 36 #pragma message disable nosimpint
338dd992 37#endif
1c4f8f8d 38
4bb6408c 39#if defined(__ultrix) || defined(__sgi)
1c4f8f8d 40 #include <Xm/Frame.h>
4bb6408c
JS
41#endif
42
43#include <Xm/Xm.h>
44#include <X11/Shell.h>
45#if XmVersion >= 1002
1c4f8f8d 46 #include <Xm/XmAll.h>
4bb6408c 47#else
1c4f8f8d 48 #include <Xm/Frame.h>
4bb6408c
JS
49#endif
50#include <Xm/MwmUtil.h>
51#include <Xm/BulletinB.h>
52#include <Xm/Form.h>
53#include <Xm/MainW.h>
54#include <Xm/RowColumn.h>
55#include <Xm/Label.h>
56#include <Xm/AtomMgr.h>
57#include <Xm/LabelG.h>
58#include <Xm/Frame.h>
59#if XmVersion > 1000
1c4f8f8d 60 #include <Xm/Protocols.h>
4bb6408c 61#endif
1c4f8f8d 62
338dd992 63#ifdef __VMS__
1c4f8f8d 64 #pragma message enable nosimpint
338dd992 65#endif
4bb6408c
JS
66
67#include "wx/motif/private.h"
68
1c4f8f8d
VZ
69// ----------------------------------------------------------------------------
70// private functions
71// ----------------------------------------------------------------------------
72
73static void wxCloseFrameCallback(Widget, XtPointer, XmAnyCallbackStruct *cbs);
74static void wxFrameFocusProc(Widget workArea, XtPointer clientData,
75 XmAnyCallbackStruct *cbs);
dfe1eee3 76static void wxFrameMapProc(Widget frameShell, XtPointer clientData,
2d120f83 77 XCrossingEvent * event);
4bb6408c 78
1c4f8f8d
VZ
79// ----------------------------------------------------------------------------
80// globals
81// ----------------------------------------------------------------------------
82
4bb6408c
JS
83extern wxList wxModelessWindows;
84extern wxList wxPendingDelete;
85
86// TODO: this should be tidied so that any frame can be the
87// top frame
88static bool wxTopLevelUsed = FALSE;
89
1c4f8f8d
VZ
90// ----------------------------------------------------------------------------
91// wxWin macros
92// ----------------------------------------------------------------------------
93
4bb6408c 94#if !USE_SHARED_LIBRARY
1c4f8f8d
VZ
95BEGIN_EVENT_TABLE(wxFrame, wxFrameBase)
96 EVT_ACTIVATE(wxFrame::OnActivate)
97 EVT_SYS_COLOUR_CHANGED(wxFrame::OnSysColourChanged)
4bb6408c
JS
98END_EVENT_TABLE()
99
c0854a08 100IMPLEMENT_DYNAMIC_CLASS(wxFrame, wxWindow)
4bb6408c
JS
101#endif
102
1c4f8f8d
VZ
103// ============================================================================
104// implementation
105// ============================================================================
1ccbb61a 106
1c4f8f8d
VZ
107// ----------------------------------------------------------------------------
108// frame construction
109// ----------------------------------------------------------------------------
dfe1eee3 110
1c4f8f8d
VZ
111void wxFrame::Init()
112{
4bb6408c 113 m_iconized = FALSE;
dfe1eee3 114
4bb6408c
JS
115 //// Motif-specific
116 m_frameShell = (WXWidget) NULL;
117 m_frameWidget = (WXWidget) NULL;;
118 m_workArea = (WXWidget) NULL;;
119 m_clientArea = (WXWidget) NULL;;
120 m_visibleStatus = TRUE;
4bb6408c
JS
121}
122
123bool wxFrame::Create(wxWindow *parent,
2d120f83
JS
124 wxWindowID id,
125 const wxString& title,
126 const wxPoint& pos,
127 const wxSize& size,
128 long style,
129 const wxString& name)
4bb6408c 130{
1c4f8f8d
VZ
131 if ( parent )
132 AddChild(this);
133 else
2d120f83 134 wxTopLevelWindows.Append(this);
dfe1eee3 135
1c4f8f8d
VZ
136 wxModelessWindows.Append(this);
137
2d120f83 138 SetName(name);
dfe1eee3 139
2d120f83 140 m_windowStyle = style;
dfe1eee3 141
2d120f83
JS
142 m_backgroundColour = wxSystemSettings::GetSystemColour(wxSYS_COLOUR_APPWORKSPACE);
143 m_foregroundColour = *wxBLACK;
da175b2c 144 m_font = wxSystemSettings::GetSystemFont(wxSYS_DEFAULT_GUI_FONT);
dfe1eee3 145
2d120f83
JS
146 if ( id > -1 )
147 m_windowId = id;
148 else
149 m_windowId = (int)NewControlId();
dfe1eee3 150
447a039f
MB
151 int x = pos.x, y = pos.y;
152 int width = size.x, height = size.y;
da8bed9b
VZ
153
154 // Set reasonable values for position and size if defaults have been
155 // requested
447a039f 156 //
da8bed9b
VZ
157 // MB TODO: something better than these arbitrary values ?
158 // VZ should use X resources for this...
159 if ( width == -1 )
160 width = 400;
161 if ( height == -1 )
162 height = 400;
447a039f
MB
163
164 int displayW, displayH;
165 wxDisplaySize( &displayW, &displayH );
166
167 if ( x == -1 )
168 {
169 x = (displayW - width) / 2;
170 if (x < 10) x = 10;
171 }
172 if ( y == -1 )
173 {
174 y = (displayH - height) / 2;
da8bed9b 175 if (y < 10) y = 10;
447a039f 176 }
da8bed9b 177
1c4f8f8d 178 // VZ: what does this do??
2d120f83 179 if (wxTopLevelUsed)
31528cd3 180 {
2d120f83 181 // Change suggested by Matthew Flatt
31528cd3
VZ
182 m_frameShell = (WXWidget)XtAppCreateShell
183 (
184 name,
185 wxTheApp->GetClassName(),
186 topLevelShellWidgetClass,
187 (Display*) wxGetDisplay(),
188 NULL,
189 0
190 );
191 }
2d120f83
JS
192 else
193 {
194 m_frameShell = wxTheApp->GetTopLevelWidget();
195 wxTopLevelUsed = TRUE;
196 }
dfe1eee3
VZ
197
198 XtVaSetValues((Widget) m_frameShell,
2d120f83
JS
199 // Allows menu to resize
200 XmNallowShellResize, True,
201 XmNdeleteResponse, XmDO_NOTHING,
202 XmNmappedWhenManaged, False,
203 XmNiconic, (style & wxICONIZE) ? TRUE : FALSE,
204 NULL);
dfe1eee3 205
1c4f8f8d 206 if (!title.IsEmpty())
dfe1eee3 207 XtVaSetValues((Widget) m_frameShell,
1c4f8f8d 208 XmNtitle, title.c_str(),
2d120f83 209 NULL);
dfe1eee3 210
2d120f83
JS
211 m_frameWidget = (WXWidget) XtVaCreateManagedWidget("main_window",
212 xmMainWindowWidgetClass, (Widget) m_frameShell,
213 XmNresizePolicy, XmRESIZE_NONE,
214 NULL);
dfe1eee3 215
2d120f83
JS
216 m_workArea = (WXWidget) XtVaCreateWidget("form",
217 xmFormWidgetClass, (Widget) m_frameWidget,
218 XmNresizePolicy, XmRESIZE_NONE,
219 NULL);
dfe1eee3 220
2d120f83
JS
221 m_clientArea = (WXWidget) XtVaCreateWidget("client",
222 xmBulletinBoardWidgetClass, (Widget) m_workArea,
223 XmNmarginWidth, 0,
224 XmNmarginHeight, 0,
225 XmNrightAttachment, XmATTACH_FORM,
226 XmNleftAttachment, XmATTACH_FORM,
227 XmNtopAttachment, XmATTACH_FORM,
228 XmNbottomAttachment, XmATTACH_FORM,
229 // XmNresizePolicy, XmRESIZE_ANY,
230 NULL);
0492c5a0 231
1c4f8f8d
VZ
232 wxLogTrace(wxTRACE_Messages,
233 "Created frame (0x%08x) with work area 0x%08x and client "
31528cd3
VZ
234 "area 0x%08x", m_frameWidget, m_workArea, m_clientArea);
235
2e35f56f
JS
236 XtAddEventHandler((Widget) m_clientArea, ExposureMask,FALSE,
237 wxUniversalRepaintProc, (XtPointer) this);
dfe1eee3 238
2d120f83
JS
239 XtVaSetValues((Widget) m_frameWidget,
240 XmNworkWindow, (Widget) m_workArea,
241 NULL);
dfe1eee3 242
2d120f83
JS
243 XtManageChild((Widget) m_clientArea);
244 XtManageChild((Widget) m_workArea);
dfe1eee3 245
2d120f83 246 wxAddWindowToTable((Widget) m_workArea, this);
dfe1eee3 247
1c4f8f8d 248 XtTranslations ptr;
dfe1eee3 249
2d120f83
JS
250 XtOverrideTranslations((Widget) m_workArea,
251 ptr = XtParseTranslationTable("<Configure>: resize()"));
dfe1eee3 252
2d120f83 253 XtFree((char *)ptr);
dfe1eee3
VZ
254
255 XtAddCallback((Widget) m_workArea, XmNfocusCallback,
2d120f83 256 (XtCallbackProc)wxFrameFocusProc, (XtPointer)this);
dfe1eee3 257
2d120f83
JS
258 /* Part of show-&-hide fix */
259 XtAddEventHandler((Widget) m_frameShell, StructureNotifyMask,
260 False, (XtEventHandler)wxFrameMapProc,
261 (XtPointer)m_workArea);
dfe1eee3 262
2d120f83
JS
263 if (x > -1)
264 XtVaSetValues((Widget) m_frameShell, XmNx, x, NULL);
265 if (y > -1)
266 XtVaSetValues((Widget) m_frameShell, XmNy, y, NULL);
267 if (width > -1)
268 XtVaSetValues((Widget) m_frameShell, XmNwidth, width, NULL);
269 if (height > -1)
270 XtVaSetValues((Widget) m_frameShell, XmNheight, height, NULL);
dfe1eee3 271
2d120f83 272 m_mainWidget = m_frameWidget;
dfe1eee3 273
2d120f83 274 ChangeFont(FALSE);
dfe1eee3 275
2d120f83
JS
276 // This patch comes from Torsten Liermann lier@lier1.muc.de
277 if (XmIsMotifWMRunning( (Widget) m_frameShell ))
278 {
1c4f8f8d 279 int decor = 0;
2d120f83 280 if (style & wxRESIZE_BORDER)
1c4f8f8d 281 decor |= MWM_DECOR_RESIZEH;
2d120f83
JS
282 if (style & wxSYSTEM_MENU)
283 decor |= MWM_DECOR_MENU;
284 if ((style & wxCAPTION) ||
285 (style & wxTINY_CAPTION_HORIZ) ||
286 (style & wxTINY_CAPTION_VERT))
287 decor |= MWM_DECOR_TITLE;
288 if (style & wxTHICK_FRAME)
289 decor |= MWM_DECOR_BORDER;
290 if (style & wxTHICK_FRAME)
291 decor |= MWM_DECOR_BORDER;
292 if (style & wxMINIMIZE_BOX)
293 decor |= MWM_DECOR_MINIMIZE;
294 if (style & wxMAXIMIZE_BOX)
295 decor |= MWM_DECOR_MAXIMIZE;
1c4f8f8d 296 XtVaSetValues((Widget) m_frameShell,XmNmwmDecorations,decor,NULL);
2d120f83
JS
297 }
298 // This allows non-Motif window managers to support at least the
299 // no-decorations case.
300 else
301 {
302 if (style == 0)
303 XtVaSetValues((Widget) m_frameShell,XmNoverrideRedirect,TRUE,NULL);
304 }
305 XtRealizeWidget((Widget) m_frameShell);
dfe1eee3 306
2d120f83
JS
307 // Intercept CLOSE messages from the window manager
308 Atom WM_DELETE_WINDOW = XmInternAtom(XtDisplay((Widget) m_frameShell), "WM_DELETE_WINDOW", False);
4bb6408c 309#if (XmREVISION > 1 || XmVERSION > 1)
2d120f83 310 XmAddWMProtocolCallback((Widget) m_frameShell, WM_DELETE_WINDOW, (XtCallbackProc) wxCloseFrameCallback, (XtPointer)this);
4bb6408c
JS
311#else
312#if XmREVISION == 1
2d120f83 313 XmAddWMProtocolCallback((Widget) m_frameShell, WM_DELETE_WINDOW, (XtCallbackProc) wxCloseFrameCallback, (caddr_t)this);
4bb6408c 314#else
2d120f83 315 XmAddWMProtocolCallback((Widget) m_frameShell, WM_DELETE_WINDOW, (void (*)())wxCloseFrameCallback, (caddr_t)this);
4bb6408c
JS
316#endif
317#endif
dfe1eee3 318
2d120f83 319 ChangeBackgroundColour();
dfe1eee3 320
2d120f83 321 PreResize();
dfe1eee3 322
2d120f83
JS
323 wxSizeEvent sizeEvent(wxSize(width, height), GetId());
324 sizeEvent.SetEventObject(this);
dfe1eee3 325
2d120f83 326 GetEventHandler()->ProcessEvent(sizeEvent);
dfe1eee3 327
2d120f83 328 return TRUE;
4bb6408c
JS
329}
330
331wxFrame::~wxFrame()
332{
3ab377bd 333 m_isBeingDeleted = TRUE;
da8bed9b 334
2e35f56f
JS
335 if (m_clientArea)
336 XtRemoveEventHandler((Widget) m_clientArea, ExposureMask, FALSE,
337 wxUniversalRepaintProc, (XtPointer) this);
338
2d120f83
JS
339 if (GetMainWidget())
340 Show(FALSE);
0492c5a0 341
2d120f83
JS
342 if (m_frameMenuBar)
343 {
344 m_frameMenuBar->DestroyMenuBar();
dfe1eee3 345
2d120f83 346 // Hack to stop core dump on Ultrix, OSF, for some strange reason.
4bb6408c 347#if MOTIF_MENUBAR_DELETE_FIX
2d120f83 348 GetMenuBar()->SetMainWidget((WXWidget) NULL);
4bb6408c 349#endif
2d120f83
JS
350 delete m_frameMenuBar;
351 m_frameMenuBar = NULL;
352 }
dfe1eee3 353
2d120f83
JS
354 wxTopLevelWindows.DeleteObject(this);
355 wxModelessWindows.DeleteObject(this);
dfe1eee3 356
2d120f83 357 if (m_frameStatusBar)
1c4f8f8d 358 {
2d120f83 359 delete m_frameStatusBar;
1c4f8f8d
VZ
360 m_frameStatusBar = NULL;
361 }
dfe1eee3 362
2d120f83 363 DestroyChildren();
dfe1eee3 364
2d120f83 365 if (m_workArea)
4bb6408c 366 {
2d120f83 367 wxDeleteWindowFromTable((Widget) m_workArea);
dfe1eee3 368
2d120f83 369 XtDestroyWidget ((Widget) m_workArea);
4bb6408c 370 }
dfe1eee3 371
2d120f83
JS
372 if (m_frameWidget)
373 {
374 wxDeleteWindowFromTable((Widget) m_frameWidget);
375 XtDestroyWidget ((Widget) m_frameWidget);
376 }
dfe1eee3 377
2d120f83
JS
378 if (m_frameShell)
379 XtDestroyWidget ((Widget) m_frameShell);
dfe1eee3 380
2d120f83 381 SetMainWidget((WXWidget) NULL);
dfe1eee3 382
2d120f83 383 /* Check if it's the last top-level window */
dfe1eee3 384
2d120f83
JS
385 if (wxTheApp && (wxTopLevelWindows.Number() == 0))
386 {
387 wxTheApp->SetTopWindow(NULL);
dfe1eee3 388
2d120f83
JS
389 if (wxTheApp->GetExitOnFrameDelete())
390 {
391 // Signal to the app that we're going to close
392 wxTheApp->ExitMainLoop();
393 }
394 }
4bb6408c
JS
395}
396
397// Get size *available for subwindows* i.e. excluding menu bar, toolbar etc.
449f38b5 398void wxFrame::DoGetClientSize(int *x, int *y) const
4bb6408c 399{
2d120f83
JS
400 Dimension xx, yy;
401 XtVaGetValues((Widget) m_workArea, XmNwidth, &xx, XmNheight, &yy, NULL);
dfe1eee3 402
2d120f83
JS
403 if (m_frameStatusBar)
404 {
405 int sbw, sbh;
406 m_frameStatusBar->GetSize(& sbw, & sbh);
407 yy -= sbh;
408 }
1ccbb61a 409#if wxUSE_TOOLBAR
2d120f83
JS
410 if (m_frameToolBar)
411 {
412 int tbw, tbh;
413 m_frameToolBar->GetSize(& tbw, & tbh);
414 if (m_frameToolBar->GetWindowStyleFlag() & wxTB_VERTICAL)
415 xx -= tbw;
416 else
417 yy -= tbh;
418 }
1ccbb61a 419#endif // wxUSE_TOOLBAR
2d120f83
JS
420 /*
421 if (GetMenuBar() != (wxMenuBar*) NULL)
422 {
4bb6408c
JS
423 // it seems that if a frame holds a panel, the menu bar size
424 // gets automatically taken care of --- grano@cs.helsinki.fi 4.4.95
425 bool hasSubPanel = FALSE;
c0ed460c 426 for(wxNode* node = GetChildren().First(); node; node = node->Next())
4bb6408c 427 {
2d120f83
JS
428 wxWindow *win = (wxWindow *)node->Data();
429 hasSubPanel = (win->IsKindOf(CLASSINFO(wxPanel)) && !win->IsKindOf(CLASSINFO(wxDialog)));
dfe1eee3 430
4bb6408c 431 if (hasSubPanel)
2d120f83
JS
432 break;
433 }
434 if (! hasSubPanel) {
4bb6408c
JS
435 Dimension ys;
436 XtVaGetValues((Widget) GetMenuBarWidget(), XmNheight, &ys, NULL);
437 yy -= ys;
2d120f83
JS
438 }
439 }
440 */
dfe1eee3 441
2d120f83 442 *x = xx; *y = yy;
4bb6408c
JS
443}
444
445// Set the client size (i.e. leave the calculation of borders etc.
446// to wxWindows)
bfc6fde4 447void wxFrame::DoSetClientSize(int width, int height)
4bb6408c 448{
2d120f83
JS
449 // Calculate how large the new main window should be
450 // by finding the difference between the client area and the
451 // main window area, and adding on to the new client area
452 if (width > -1)
453 XtVaSetValues((Widget) m_workArea, XmNwidth, width, NULL);
dfe1eee3 454
2d120f83 455 if (height > -1)
a4294b78 456 {
2d120f83
JS
457 if (m_frameStatusBar)
458 {
459 int sbw, sbh;
460 m_frameStatusBar->GetSize(& sbw, & sbh);
461 height += sbh;
462 }
1ccbb61a 463#if wxUSE_TOOLBAR
2d120f83
JS
464 if (m_frameToolBar)
465 {
466 int tbw, tbh;
467 m_frameToolBar->GetSize(& tbw, & tbh);
468 if (m_frameToolBar->GetWindowStyleFlag() & wxTB_VERTICAL)
469 width += tbw;
470 else
471 height += tbh;
472 }
1ccbb61a 473#endif // wxUSE_TOOLBAR
dfe1eee3 474
2d120f83 475 XtVaSetValues((Widget) m_workArea, XmNheight, height, NULL);
a4294b78 476 }
2d120f83 477 PreResize();
dfe1eee3 478
2d120f83
JS
479 wxSizeEvent sizeEvent(wxSize(width, height), GetId());
480 sizeEvent.SetEventObject(this);
dfe1eee3 481
2d120f83 482 GetEventHandler()->ProcessEvent(sizeEvent);
dfe1eee3 483
4bb6408c
JS
484}
485
449f38b5 486void wxFrame::DoGetSize(int *width, int *height) const
4bb6408c 487{
2d120f83
JS
488 Dimension xx, yy;
489 XtVaGetValues((Widget) m_frameShell, XmNwidth, &xx, XmNheight, &yy, NULL);
490 *width = xx; *height = yy;
4bb6408c
JS
491}
492
449f38b5 493void wxFrame::DoGetPosition(int *x, int *y) const
4bb6408c
JS
494{
495 Window parent_window = XtWindow((Widget) m_frameShell),
2d120f83
JS
496 next_parent = XtWindow((Widget) m_frameShell),
497 root = RootWindowOfScreen(XtScreen((Widget) m_frameShell));
dfe1eee3 498
4bb6408c
JS
499 // search for the parent that is child of ROOT, because the WM may
500 // reparent twice and notify only the next parent (like FVWM)
501 while (next_parent != root) {
2d120f83
JS
502 Window *theChildren; unsigned int n;
503 parent_window = next_parent;
504 XQueryTree(XtDisplay((Widget) m_frameShell), parent_window, &root,
505 &next_parent, &theChildren, &n);
506 XFree(theChildren); // not needed
4bb6408c
JS
507 }
508 int xx, yy; unsigned int dummy;
509 XGetGeometry(XtDisplay((Widget) m_frameShell), parent_window, &root,
2d120f83 510 &xx, &yy, &dummy, &dummy, &dummy, &dummy);
4bb6408c
JS
511 if (x) *x = xx;
512 if (y) *y = yy;
513}
514
af111fc3 515void wxFrame::DoSetSize(int x, int y, int width, int height, int WXUNUSED(sizeFlags))
4bb6408c 516{
2d120f83
JS
517 if (x > -1)
518 XtVaSetValues((Widget) m_frameShell, XmNx, x, NULL);
519 if (y > -1)
520 XtVaSetValues((Widget) m_frameShell, XmNy, y, NULL);
521 if (width > -1)
522 XtVaSetValues((Widget) m_frameWidget, XmNwidth, width, NULL);
523 if (height > -1)
524 XtVaSetValues((Widget) m_frameWidget, XmNheight, height, NULL);
dfe1eee3 525
2d120f83
JS
526 if (!(height == -1 && width == -1))
527 {
528 PreResize();
dfe1eee3 529
2d120f83
JS
530 wxSizeEvent sizeEvent(wxSize(width, height), GetId());
531 sizeEvent.SetEventObject(this);
dfe1eee3 532
2d120f83
JS
533 GetEventHandler()->ProcessEvent(sizeEvent);
534 }
4bb6408c
JS
535}
536
537bool wxFrame::Show(bool show)
538{
2d120f83
JS
539 if (!m_frameShell)
540 return wxWindow::Show(show);
dfe1eee3 541
2d120f83 542 m_visibleStatus = show; /* show-&-hide fix */
dfe1eee3 543
2d120f83
JS
544 m_isShown = show;
545 if (show) {
546 XtMapWidget((Widget) m_frameShell);
547 XRaiseWindow(XtDisplay((Widget) m_frameShell), XtWindow((Widget) m_frameShell));
548 } else {
549 XtUnmapWidget((Widget) m_frameShell);
550 // XmUpdateDisplay(wxTheApp->topLevel); // Experimental: may be responsible for crashes
551 }
552 return TRUE;
4bb6408c
JS
553}
554
555void wxFrame::Iconize(bool iconize)
556{
2d120f83
JS
557 if (!iconize)
558 Show(TRUE);
dfe1eee3 559
2d120f83
JS
560 if (m_frameShell)
561 XtVaSetValues((Widget) m_frameShell, XmNiconic, (Boolean)iconize, NULL);
4bb6408c
JS
562}
563
1c4f8f8d
VZ
564void wxFrame::Restore()
565{
566 if ( m_frameShell )
567 XtVaSetValues((Widget) m_frameShell, XmNiconic, FALSE, NULL);
568}
569
4bb6408c
JS
570void wxFrame::Maximize(bool maximize)
571{
2d120f83 572 Show(TRUE);
dfe1eee3 573
1c4f8f8d
VZ
574 if ( maximize )
575 Restore();
4bb6408c
JS
576}
577
578bool wxFrame::IsIconized() const
579{
2d120f83
JS
580 if (!m_frameShell)
581 return FALSE;
dfe1eee3 582
2d120f83
JS
583 Boolean iconic;
584 XtVaGetValues((Widget) m_frameShell, XmNiconic, &iconic, NULL);
585 return iconic;
4bb6408c
JS
586}
587
6f63ec3f 588// Is it maximized?
1c4f8f8d 589bool wxFrame::IsMaximized() const
6f63ec3f
JS
590{
591 // No maximizing in Motif (?)
592 return FALSE;
593}
594
4bb6408c
JS
595void wxFrame::SetTitle(const wxString& title)
596{
2d120f83
JS
597 if (title == m_title)
598 return;
dfe1eee3 599
2d120f83 600 m_title = title;
dfe1eee3 601
2d120f83 602 if (!title.IsNull())
dfe1eee3 603 XtVaSetValues((Widget) m_frameShell,
1c4f8f8d
VZ
604 XmNtitle, title.c_str(),
605 XmNiconName, title.c_str(),
2d120f83 606 NULL);
4bb6408c
JS
607}
608
609void wxFrame::SetIcon(const wxIcon& icon)
610{
2d120f83 611 m_icon = icon;
dfe1eee3 612
2d120f83
JS
613 if (!m_frameShell)
614 return;
dfe1eee3 615
2d120f83
JS
616 if (!icon.Ok() || !icon.GetPixmap())
617 return;
dfe1eee3 618
2d120f83 619 XtVaSetValues((Widget) m_frameShell, XtNiconPixmap, icon.GetPixmap(), NULL);
4bb6408c
JS
620}
621
4bb6408c
JS
622void wxFrame::PositionStatusBar()
623{
50414e24 624 if (!m_frameStatusBar)
2d120f83 625 return;
dfe1eee3 626
4bb6408c
JS
627 int w, h;
628 GetClientSize(&w, &h);
629 int sw, sh;
630 m_frameStatusBar->GetSize(&sw, &sh);
dfe1eee3 631
4bb6408c
JS
632 // Since we wish the status bar to be directly under the client area,
633 // we use the adjusted sizes without using wxSIZE_NO_ADJUSTMENTS.
89c7e962 634 m_frameStatusBar->SetSize(0, h, w, sh);
4bb6408c
JS
635}
636
637WXWidget wxFrame::GetMenuBarWidget() const
638{
2d120f83
JS
639 if (GetMenuBar())
640 return GetMenuBar()->GetMainWidget();
641 else
642 return (WXWidget) NULL;
4bb6408c
JS
643}
644
645void wxFrame::SetMenuBar(wxMenuBar *menuBar)
646{
647 if (!menuBar)
648 {
649 m_frameMenuBar = NULL;
650 return;
651 }
dfe1eee3 652
4bb6408c 653 // Currently can't set it twice
2d120f83 654 // wxASSERT_MSG( (m_frameMenuBar == (wxMenuBar*) NULL), "Cannot set the menubar more than once");
dfe1eee3 655
621793f4 656 if (m_frameMenuBar)
4bb6408c 657 {
621793f4
JS
658 m_frameMenuBar->DestroyMenuBar();
659 delete m_frameMenuBar;
4bb6408c 660 }
dfe1eee3 661
621793f4
JS
662 m_frameMenuBar = menuBar;
663 m_frameMenuBar->CreateMenuBar(this);
4bb6408c
JS
664}
665
4bb6408c
JS
666// Responds to colour changes, and passes event on to children.
667void wxFrame::OnSysColourChanged(wxSysColourChangedEvent& event)
668{
669 SetBackgroundColour(wxSystemSettings::GetSystemColour(wxSYS_COLOUR_APPWORKSPACE));
670 Refresh();
dfe1eee3 671
4bb6408c
JS
672 if ( m_frameStatusBar )
673 {
674 wxSysColourChangedEvent event2;
675 event2.SetEventObject( m_frameStatusBar );
676 m_frameStatusBar->ProcessEvent(event2);
677 }
dfe1eee3 678
4bb6408c
JS
679 // Propagate the event to the non-top-level children
680 wxWindow::OnSysColourChanged(event);
681}
682
4bb6408c
JS
683// Default activation behaviour - set the focus for the first child
684// subwindow found.
685void wxFrame::OnActivate(wxActivateEvent& event)
686{
af111fc3
JS
687 if (!event.GetActive())
688 return;
689
2d120f83 690 for(wxNode *node = GetChildren().First(); node; node = node->Next())
4bb6408c 691 {
2d120f83
JS
692 // Find a child that's a subwindow, but not a dialog box.
693 wxWindow *child = (wxWindow *)node->Data();
694 if (!child->IsKindOf(CLASSINFO(wxFrame)) &&
695 !child->IsKindOf(CLASSINFO(wxDialog)))
696 {
697 child->SetFocus();
698 return;
699 }
4bb6408c 700 }
4bb6408c
JS
701}
702
1ccbb61a 703#if wxUSE_TOOLBAR
dfe1eee3 704
1c4f8f8d
VZ
705wxToolBar* wxFrame::CreateToolBar(long style,
706 wxWindowID id,
707 const wxString& name)
4bb6408c 708{
1c4f8f8d 709 if ( wxFrameBase::CreateToolBar(style, id, name) )
4bb6408c 710 {
4bb6408c 711 PositionToolBar();
4bb6408c 712 }
4bb6408c 713
1ccbb61a
VZ
714 return m_frameToolBar;
715}
716
4bb6408c
JS
717void wxFrame::PositionToolBar()
718{
4bb6408c
JS
719 if (GetToolBar())
720 {
1c4f8f8d
VZ
721 int cw, ch;
722 GetClientSize(& cw, &ch);
723
4bb6408c
JS
724 int tw, th;
725 GetToolBar()->GetSize(& tw, & th);
dfe1eee3 726
4bb6408c
JS
727 if (GetToolBar()->GetWindowStyleFlag() & wxTB_VERTICAL)
728 {
729 // Use the 'real' position. wxSIZE_NO_ADJUSTMENTS
730 // means, pretend we don't have toolbar/status bar, so we
731 // have the original client size.
a4294b78 732 GetToolBar()->SetSize(0, 0, tw, ch + th, wxSIZE_NO_ADJUSTMENTS);
4bb6408c
JS
733 }
734 else
735 {
736 // Use the 'real' position
737 GetToolBar()->SetSize(0, 0, cw, th, wxSIZE_NO_ADJUSTMENTS);
738 }
739 }
740}
1ccbb61a 741#endif // wxUSE_TOOLBAR
4bb6408c 742
1c4f8f8d 743void wxFrame::Raise()
4bb6408c
JS
744{
745 Window parent_window = XtWindow((Widget) m_frameShell),
2d120f83
JS
746 next_parent = XtWindow((Widget) m_frameShell),
747 root = RootWindowOfScreen(XtScreen((Widget) m_frameShell));
4bb6408c
JS
748 // search for the parent that is child of ROOT, because the WM may
749 // reparent twice and notify only the next parent (like FVWM)
750 while (next_parent != root) {
2d120f83
JS
751 Window *theChildren; unsigned int n;
752 parent_window = next_parent;
753 XQueryTree(XtDisplay((Widget) m_frameShell), parent_window, &root,
754 &next_parent, &theChildren, &n);
755 XFree(theChildren); // not needed
4bb6408c
JS
756 }
757 XRaiseWindow(XtDisplay((Widget) m_frameShell), parent_window);
758}
759
1c4f8f8d 760void wxFrame::Lower()
4bb6408c
JS
761{
762 Window parent_window = XtWindow((Widget) m_frameShell),
2d120f83
JS
763 next_parent = XtWindow((Widget) m_frameShell),
764 root = RootWindowOfScreen(XtScreen((Widget) m_frameShell));
4bb6408c
JS
765 // search for the parent that is child of ROOT, because the WM may
766 // reparent twice and notify only the next parent (like FVWM)
767 while (next_parent != root) {
2d120f83
JS
768 Window *theChildren; unsigned int n;
769 parent_window = next_parent;
770 XQueryTree(XtDisplay((Widget) m_frameShell), parent_window, &root,
771 &next_parent, &theChildren, &n);
772 XFree(theChildren); // not needed
4bb6408c
JS
773 }
774 XLowerWindow(XtDisplay((Widget) m_frameShell), parent_window);
775}
776
af111fc3
JS
777void wxFrameFocusProc(Widget WXUNUSED(workArea), XtPointer WXUNUSED(clientData),
778 XmAnyCallbackStruct *WXUNUSED(cbs))
4bb6408c 779{
2d120f83
JS
780 // wxDebugMsg("focus proc from frame %ld\n",(long)frame);
781 // TODO
dfe1eee3
VZ
782 // wxFrame *frame = (wxFrame *)clientData;
783 // frame->GetEventHandler()->OnSetFocus();
4bb6408c
JS
784}
785
786/* MATTEW: Used to insure that hide-&-show within an event cycle works */
dfe1eee3 787static void wxFrameMapProc(Widget frameShell, XtPointer clientData,
2d120f83 788 XCrossingEvent * event)
4bb6408c 789{
dfe1eee3
VZ
790 wxFrame *frame = (wxFrame *)wxGetWindowFromTable((Widget)clientData);
791
2d120f83
JS
792 if (frame) {
793 XEvent *e = (XEvent *)event;
dfe1eee3 794
2d120f83
JS
795 if (e->xany.type == MapNotify)
796 {
797 // Iconize fix
798 XtVaSetValues(frameShell, XmNiconic, (Boolean)False, NULL);
799 if (!frame->GetVisibleStatus())
800 {
801 /* We really wanted this to be hidden! */
802 XtUnmapWidget((Widget) frame->GetShellWidget());
803 }
804 }
805 else if (e->xany.type == UnmapNotify)
806 // Iconize fix
807 XtVaSetValues(frameShell, XmNiconic, (Boolean)True, NULL);
4bb6408c 808 }
4bb6408c
JS
809}
810
811//// Motif-specific
812bool wxFrame::PreResize()
813{
1ccbb61a 814#if wxUSE_TOOLBAR
2d120f83 815 PositionToolBar();
1ccbb61a 816#endif // wxUSE_TOOLBAR
1c4f8f8d
VZ
817
818#if wxUSE_STATUSBAR
2d120f83 819 PositionStatusBar();
1c4f8f8d
VZ
820#endif // wxUSE_STATUSBAR
821
2d120f83 822 return TRUE;
4bb6408c
JS
823}
824
50414e24
JS
825WXWidget wxFrame::GetClientWidget() const
826{
2d120f83 827 return m_clientArea;
50414e24
JS
828}
829
af111fc3 830void wxFrame::ChangeFont(bool WXUNUSED(keepOriginalSize))
0d57be45
JS
831{
832 // TODO
833}
834
835void wxFrame::ChangeBackgroundColour()
836{
621793f4
JS
837 if (GetClientWidget())
838 DoChangeBackgroundColour(GetClientWidget(), m_backgroundColour);
0d57be45
JS
839}
840
841void wxFrame::ChangeForegroundColour()
842{
621793f4
JS
843 if (GetClientWidget())
844 DoChangeForegroundColour(GetClientWidget(), m_foregroundColour);
0d57be45
JS
845}
846
af111fc3 847void wxCloseFrameCallback(Widget WXUNUSED(widget), XtPointer client_data, XmAnyCallbackStruct *WXUNUSED(cbs))
4bb6408c 848{
2d120f83 849 wxFrame *frame = (wxFrame *)client_data;
dfe1eee3 850
2d120f83
JS
851 wxCloseEvent closeEvent(wxEVT_CLOSE_WINDOW, frame->GetId());
852 closeEvent.SetEventObject(frame);
dfe1eee3 853
2d120f83
JS
854 // May delete the frame (with delayed deletion)
855 frame->GetEventHandler()->ProcessEvent(closeEvent);
4bb6408c 856}
0d57be45 857