]> git.saurik.com Git - wxWidgets.git/blame - src/motif/toplevel.cpp
use unsgined int instead of int for 1 bit bitfields (SGI CC warning fix)
[wxWidgets.git] / src / motif / toplevel.cpp
CommitLineData
0de6dfa7
MB
1/////////////////////////////////////////////////////////////////////////////
2// Name: motif/toplevel.cpp
3// Purpose: wxTopLevelWindow Motif implementation
4// Author: Mattia Barbon
5// Modified by:
6// Created: 12/10/2002
7// RCS-ID: $Id$
8// Copyright: (c) Mattia Barbon
65571936 9// Licence: wxWindows licence
0de6dfa7
MB
10/////////////////////////////////////////////////////////////////////////////
11
12// ============================================================================
13// declarations
14// ============================================================================
15
16// ----------------------------------------------------------------------------
17// headers
18// ----------------------------------------------------------------------------
19
14f355c2 20#if defined(__GNUG__) && !defined(NO_GCC_PRAGMA)
0de6dfa7
MB
21 #pragma implementation "toplevel.h"
22#endif
23
1248b41f
MB
24// For compilers that support precompilation, includes "wx.h".
25#include "wx/wxprec.h"
26
0de6dfa7
MB
27#include "wx/toplevel.h"
28#include "wx/app.h"
29
30#ifdef __VMS__
e004299a
JJ
31#define XtDisplay XTDISPLAY
32#define XtParent XTPARENT
33#define XtScreen XTSCREEN
34#define XtWindow XTWINDOW
35#pragma message disable nosimpint
0de6dfa7
MB
36#endif
37
38#include <Xm/Xm.h>
39#include <X11/Shell.h>
40#include <X11/Core.h>
41#if XmVersion >= 1002
42 #include <Xm/XmAll.h>
43#else
44 #include <Xm/Frame.h>
45#endif
46
47#ifdef __VMS__
48 #pragma message enable nosimpint
49#endif
50
51#include "wx/motif/private.h"
52
53wxList wxModelessWindows; // Frames and modeless dialogs
54
55// ---------------------------------------------------------------------------
56// Callbacks
57// ---------------------------------------------------------------------------
58
59static void wxCloseTLWCallback( Widget widget, XtPointer client_data,
60 XmAnyCallbackStruct *cbs );
61static void wxTLWEventHandler( Widget wid,
62 XtPointer client_data,
63 XEvent* event,
64 Boolean *continueToDispatch );
65
66// ===========================================================================
67// wxTopLevelWindowMotif implementation
68// ===========================================================================
69
2187eef5 70void wxTopLevelWindowMotif::PreDestroy()
0de6dfa7 71{
e964136c
JJ
72#ifdef __VMS
73#pragma message disable codcauunr
74#endif
75 if ( (GetWindowStyleFlag() & wxDIALOG_MODAL) != wxDIALOG_MODAL )
0de6dfa7 76 wxModelessWindows.DeleteObject(this);
e964136c
JJ
77#ifdef __VMS
78#pragma message enable codcauunr
79#endif
0de6dfa7
MB
80
81 m_icons.m_icons.Empty();
82
83 DestroyChildren();
84
85 // MessageDialog and FileDialog do not have a client widget
86 if( GetClientWidget() )
87 {
88 XtRemoveEventHandler( (Widget)GetClientWidget(),
89 ButtonPressMask | ButtonReleaseMask |
90 PointerMotionMask | KeyPressMask,
96be256b 91 False,
0de6dfa7
MB
92 wxTLWEventHandler,
93 (XtPointer)this );
94 }
2187eef5 95}
0de6dfa7 96
2187eef5
MB
97wxTopLevelWindowMotif::~wxTopLevelWindowMotif()
98{
0de6dfa7 99 SetMainWidget( (WXWidget)0 );
0de6dfa7
MB
100}
101
102void wxTopLevelWindowMotif::Init()
103{
96be256b 104 m_isShown = false;
0de6dfa7
MB
105}
106
107bool wxTopLevelWindowMotif::Create( wxWindow *parent, wxWindowID id,
108 const wxString& title,
109 const wxPoint& pos,
110 const wxSize& size,
111 long style,
112 const wxString& name )
113{
114 SetName(name);
115 m_windowStyle = style;
116
117 if ( parent )
118 parent->AddChild(this);
f58585c0 119
0de6dfa7
MB
120 wxTopLevelWindows.Append(this);
121
122 m_windowId = ( id > -1 ) ? id : NewControlId();
123
f58585c0 124 bool retval = XmDoCreateTLW( parent, id, title, pos, size, style, name );
0de6dfa7 125
96be256b 126 if( !retval ) return false;
0de6dfa7
MB
127
128 // Intercept CLOSE messages from the window manager
129 Widget shell = (Widget)GetShellWidget();
130 Atom WM_DELETE_WINDOW = XmInternAtom( XtDisplay( shell ),
131 "WM_DELETE_WINDOW", False );
132
133 // Remove and add WM_DELETE_WINDOW so ours is only handler
134 // This only appears to be necessary for wxDialog, but does not hurt
135 // for wxFrame
136 XmRemoveWMProtocols( shell, &WM_DELETE_WINDOW, 1 );
137 XmAddWMProtocols( shell, &WM_DELETE_WINDOW, 1 );
138 XmActivateWMProtocol( shell, WM_DELETE_WINDOW );
139
140 // Modified Steve Hammes for Motif 2.0
141#if (XmREVISION > 1 || XmVERSION > 1)
142 XmAddWMProtocolCallback( shell, WM_DELETE_WINDOW,
f58585c0 143 (XtCallbackProc)wxCloseTLWCallback,
0de6dfa7
MB
144 (XtPointer)this );
145#elif XmREVISION == 1
146 XmAddWMProtocolCallback( shell, WM_DELETE_WINDOW,
147 (XtCallbackProc)wxCloseTLWCallback,
148 (caddr_t)this );
149#else
150 XmAddWMProtocolCallback( shell, WM_DELETE_WINDOW,
151 (void (*)())wxCloseTLWCallback, (caddr_t)this );
152#endif
153
154 // This patch come from Torsten Liermann lier@lier1.muc.de
155 if( XmIsMotifWMRunning( shell ) )
156 {
157 int decor = 0 ;
8b7b0d67
MB
158 if( !(m_windowStyle & wxNO_BORDER) )
159 decor |= MWM_DECOR_BORDER;
0de6dfa7
MB
160 if( m_windowStyle & wxRESIZE_BORDER )
161 decor |= MWM_DECOR_RESIZEH;
162 if( m_windowStyle & wxSYSTEM_MENU )
163 decor |= MWM_DECOR_MENU;
164 if( ( m_windowStyle & wxCAPTION ) ||
165 ( m_windowStyle & wxTINY_CAPTION_HORIZ ) ||
166 ( m_windowStyle & wxTINY_CAPTION_VERT ) )
167 decor |= MWM_DECOR_TITLE;
168 if( m_windowStyle & wxTHICK_FRAME )
169 decor |= MWM_DECOR_BORDER;
170 if( m_windowStyle & wxMINIMIZE_BOX )
171 decor |= MWM_DECOR_MINIMIZE;
172 if( m_windowStyle & wxMAXIMIZE_BOX )
173 decor |= MWM_DECOR_MAXIMIZE;
174
175 XtVaSetValues( shell,
176 XmNmwmDecorations, decor,
177 NULL );
178 }
179 else
180 {
181 // This allows non-Motif window managers to support at least the
182 // no-decorations case.
183 if( ( m_windowStyle & wxCAPTION ) != wxCAPTION )
184 XtVaSetValues( shell,
96be256b 185 XmNoverrideRedirect, True,
0de6dfa7
MB
186 NULL );
187 }
188
189 XtAddEventHandler( (Widget)GetClientWidget(),
f58585c0 190 ButtonPressMask | ButtonReleaseMask |
0de6dfa7 191 PointerMotionMask | KeyPressMask,
96be256b 192 False,
0de6dfa7
MB
193 wxTLWEventHandler,
194 (XtPointer)this );
195
196 return retval;
197}
198
dad6a47e
MB
199void wxTopLevelWindowMotif::DoGetPosition(int *x, int *y) const
200{
201 Widget top = (Widget) GetTopWidget();
202 Window parent_window = XtWindow((Widget) top),
203 next_parent = XtWindow((Widget) top),
204 root = RootWindowOfScreen(XtScreen((Widget) top));
205
206 // search for the parent that is child of ROOT, because the WM may
207 // reparent twice and notify only the next parent (like FVWM)
208 while (next_parent != root) {
209 Window *theChildren; unsigned int n;
210 parent_window = next_parent;
211 XQueryTree(XtDisplay((Widget) top), parent_window, &root,
212 &next_parent, &theChildren, &n);
213 XFree(theChildren); // not needed
214 }
215 int xx, yy; unsigned int dummy;
216 XGetGeometry(XtDisplay((Widget) top), parent_window, &root,
217 &xx, &yy, &dummy, &dummy, &dummy, &dummy);
218 if (x) *x = xx;
219 if (y) *y = yy;
220}
221
0de6dfa7
MB
222void wxTopLevelWindowMotif::Raise()
223{
224 Widget top = (Widget) GetTopWidget();
225 Window parent_window = XtWindow( top ),
226 next_parent = XtWindow( top ),
227 root = RootWindowOfScreen( XtScreen( top ) );
228 // search for the parent that is child of ROOT, because the WM may
229 // reparent twice and notify only the next parent (like FVWM)
230 while( next_parent != root )
231 {
232 Window *theChildren;
233 unsigned int n;
234
235 parent_window = next_parent;
236 XQueryTree( XtDisplay( top ), parent_window, &root,
237 &next_parent, &theChildren, &n );
238 XFree( theChildren ); // not needed
239 }
240 XRaiseWindow( XtDisplay( top ), parent_window );
241}
242
243void wxTopLevelWindowMotif::Lower()
244{
245 Widget top = (Widget) GetTopWidget();
246 Window parent_window = XtWindow( top ),
247 next_parent = XtWindow( top ),
248 root = RootWindowOfScreen( XtScreen( top ) );
249 // search for the parent that is child of ROOT, because the WM may
250 // reparent twice and notify only the next parent (like FVWM)
251 while( next_parent != root )
252 {
253 Window *theChildren;
254 unsigned int n;
255
256 parent_window = next_parent;
257 XQueryTree( XtDisplay( top ), parent_window, &root,
258 &next_parent, &theChildren, &n );
259 XFree( theChildren ); // not needed
260 }
261 XLowerWindow( XtDisplay( top ), parent_window );
262}
263
264static inline Widget GetShell( const wxTopLevelWindowMotif* tlw )
265{
266 Widget main = (Widget) tlw->GetMainWidget();
267 if( !main ) return (Widget) NULL;
268
269 return XtParent( main );
270}
271
272WXWidget wxTopLevelWindowMotif::GetShellWidget() const
273{
274 return (WXWidget) GetShell( this );
275}
276
277bool wxTopLevelWindowMotif::ShowFullScreen( bool show,
0ec6fd04 278 long style )
0de6dfa7
MB
279{
280 // TODO, see wxGTK
96be256b 281 return false;
0de6dfa7
MB
282}
283
284bool wxTopLevelWindowMotif::IsFullScreen() const
285{
286 // TODO, see wxGTK
96be256b 287 return false;
0de6dfa7
MB
288}
289
290void wxTopLevelWindowMotif::Restore()
291{
292 Widget shell = GetShell( this );
293
294 if( shell )
295 XtVaSetValues( shell,
96be256b 296 XmNiconic, False,
0de6dfa7
MB
297 NULL );
298}
299
0ec6fd04 300void wxTopLevelWindowMotif::Iconize( bool iconize )
0de6dfa7
MB
301{
302 Widget shell = GetShell( this );
303 if( !shell ) return;
304
305 if( !iconize )
96be256b 306 Show( true );
0de6dfa7
MB
307
308 XtVaSetValues( shell,
309 XmNiconic, (Boolean)iconize,
310 NULL );
311}
312
313bool wxTopLevelWindowMotif::IsIconized() const
314{
315 Widget shell = GetShell( this );
316
317 if( !shell )
96be256b 318 return false;
0de6dfa7
MB
319
320 Boolean iconic;
321 XtVaGetValues( shell,
322 XmNiconic, &iconic,
323 NULL );
324
325 return iconic;
326}
327
0ec6fd04 328void wxTopLevelWindowMotif::Maximize( bool maximize )
0de6dfa7 329{
96be256b 330 Show( true );
0de6dfa7
MB
331
332 if( maximize )
333 Restore();
334}
335
336bool wxTopLevelWindowMotif::IsMaximized() const
337{
96be256b 338 return false;
0de6dfa7
MB
339}
340
024f89f9
VS
341void wxTopLevelWindowMotif::DoSetSizeHints( int minW, int minH,
342 int maxW, int maxH,
343 int incW, int incH )
66f8b9ac 344{
024f89f9 345 wxTopLevelWindowBase::DoSetSizeHints( minW, minH, maxW, maxH, incW, incH );
66f8b9ac
MB
346
347 int count = 0;
348 Arg args[6];
349
350 if( minW > -1 ) { XtSetArg( args[count], XmNminWidth, minW ); ++count; }
351 if( minH > -1 ) { XtSetArg( args[count], XmNminHeight, minH ); ++count; }
352 if( maxW > -1 ) { XtSetArg( args[count], XmNmaxWidth, maxW ); ++count; }
353 if( maxH > -1 ) { XtSetArg( args[count], XmNmaxHeight, maxH ); ++count; }
354 if( incW > -1 ) { XtSetArg( args[count], XmNwidthInc, incW ); ++count; }
355 if( incH > -1 ) { XtSetArg( args[count], XmNheightInc, incH ); ++count; }
356
f58585c0 357 XtSetValues( (Widget)GetShellWidget(), args, count );
66f8b9ac
MB
358}
359
f7f78039
MB
360bool wxTopLevelWindowMotif::SetShape( const wxRegion& region )
361{
362 return wxDoSetShape( (Display*)GetXDisplay(),
363 XtWindow( (Widget)GetShellWidget() ),
364 region );
365}
366
0de6dfa7
MB
367// ---------------------------------------------------------------------------
368// Callback definition
369// ---------------------------------------------------------------------------
370
371// Handle a close event from the window manager
372static void wxCloseTLWCallback( Widget WXUNUSED(widget), XtPointer client_data,
373 XmAnyCallbackStruct *WXUNUSED(cbs) )
374{
375 wxTopLevelWindowMotif* tlw = (wxTopLevelWindowMotif*)client_data;
376 wxCloseEvent closeEvent( wxEVT_CLOSE_WINDOW, tlw->GetId() );
377 closeEvent.SetEventObject( tlw );
378
379 // May delete the dialog (with delayed deletion)
380 tlw->GetEventHandler()->ProcessEvent(closeEvent);
381}
382
383void wxTLWEventHandler( Widget wid,
384 XtPointer WXUNUSED(client_data),
385 XEvent* event,
386 Boolean* continueToDispatch)
387{
388 wxTopLevelWindowMotif* tlw =
389 (wxTopLevelWindowMotif*)wxGetWindowFromTable( wid );
390
391 if( tlw )
392 {
393 wxMouseEvent wxevent( wxEVT_NULL );
394
395 if( wxTranslateMouseEvent( wxevent, tlw, wid, event ) )
396 {
397 wxevent.SetEventObject( tlw );
398 wxevent.SetId( tlw->GetId() );
399 tlw->GetEventHandler()->ProcessEvent( wxevent );
400 }
401 else
402 {
403 // An attempt to implement OnCharHook by calling OnCharHook first;
96be256b 404 // if this returns true, set continueToDispatch to False
0de6dfa7
MB
405 // (don't continue processing).
406 // Otherwise set it to True and call OnChar.
407 wxKeyEvent keyEvent( wxEVT_CHAR );
408 if( wxTranslateKeyEvent( keyEvent, tlw, wid, event ))
409 {
410 keyEvent.SetEventObject( tlw );
411 keyEvent.SetId( tlw->GetId() );
412 keyEvent.SetEventType( wxEVT_CHAR_HOOK );
413 if( tlw->GetEventHandler()->ProcessEvent( keyEvent ) )
414 {
415 *continueToDispatch = False;
416 return;
417 }
418 else
419 {
420 // For simplicity, OnKeyDown is the same as OnChar
421 // TODO: filter modifier key presses from OnChar
422 keyEvent.SetEventType( wxEVT_KEY_DOWN );
423
424 // Only process OnChar if OnKeyDown didn't swallow it
425 if( !tlw->GetEventHandler()->ProcessEvent( keyEvent ) )
426 {
427 keyEvent.SetEventType( wxEVT_CHAR );
428 tlw->GetEventHandler()->ProcessEvent( keyEvent );
429 }
430 }
431 }
432 }
433 }
434
435 *continueToDispatch = True;
436}
437