]>
git.saurik.com Git - wxWidgets.git/blob - src/motif/toplevel.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/motif/toplevel.cpp
3 // Purpose: wxTopLevelWindow Motif implementation
4 // Author: Mattia Barbon
8 // Copyright: (c) Mattia Barbon
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
12 // ============================================================================
14 // ============================================================================
16 // ----------------------------------------------------------------------------
18 // ----------------------------------------------------------------------------
20 // For compilers that support precompilation, includes "wx.h".
21 #include "wx/wxprec.h"
23 #include "wx/toplevel.h"
24 #include "wx/settings.h"
32 #define XtDisplay XTDISPLAY
33 #define XtParent XTPARENT
34 #define XtScreen XTSCREEN
35 #define XtWindow XTWINDOW
36 #pragma message disable nosimpint
40 #include <X11/Shell.h>
49 #pragma message enable nosimpint
52 #include "wx/motif/private.h"
54 wxList wxModelessWindows
; // Frames and modeless dialogs
56 // ---------------------------------------------------------------------------
58 // ---------------------------------------------------------------------------
60 static void wxCloseTLWCallback( Widget widget
, XtPointer client_data
,
61 XmAnyCallbackStruct
*cbs
);
62 static void wxTLWEventHandler( Widget wid
,
63 XtPointer client_data
,
65 Boolean
*continueToDispatch
);
67 // ===========================================================================
68 // wxTopLevelWindowMotif implementation
69 // ===========================================================================
71 void wxTopLevelWindowMotif::PreDestroy()
73 wxModelessWindows
.DeleteObject(this);
77 // MessageDialog and FileDialog do not have a client widget
78 if( GetClientWidget() )
80 XtRemoveEventHandler( (Widget
)GetClientWidget(),
81 ButtonPressMask
| ButtonReleaseMask
|
82 PointerMotionMask
| KeyPressMask
,
89 wxTopLevelWindowMotif::~wxTopLevelWindowMotif()
91 SetMainWidget( (WXWidget
)0 );
94 void wxTopLevelWindowMotif::Init()
99 bool wxTopLevelWindowMotif::Create( wxWindow
*parent
, wxWindowID id
,
100 const wxString
& title
,
104 const wxString
& name
)
107 m_windowStyle
= style
;
110 parent
->AddChild(this);
112 wxTopLevelWindows
.Append(this);
114 m_windowId
= ( id
> -1 ) ? id
: NewControlId();
115 // MBN: More backward compatible, but uglier
116 m_font
= wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT
);
117 m_inheritFont
= true;
119 bool retval
= XmDoCreateTLW( parent
, id
, title
, pos
, size
, style
, name
);
121 if( !retval
) return false;
123 // Intercept CLOSE messages from the window manager
124 Widget shell
= (Widget
)GetShellWidget();
125 Atom WM_DELETE_WINDOW
= XmInternAtom( XtDisplay( shell
),
126 "WM_DELETE_WINDOW", False
);
128 // Remove and add WM_DELETE_WINDOW so ours is only handler
129 // This only appears to be necessary for wxDialog, but does not hurt
131 XmRemoveWMProtocols( shell
, &WM_DELETE_WINDOW
, 1 );
132 XmAddWMProtocols( shell
, &WM_DELETE_WINDOW
, 1 );
133 XmActivateWMProtocol( shell
, WM_DELETE_WINDOW
);
135 // Modified Steve Hammes for Motif 2.0
136 #if (XmREVISION > 1 || XmVERSION > 1)
137 XmAddWMProtocolCallback( shell
, WM_DELETE_WINDOW
,
138 (XtCallbackProc
)wxCloseTLWCallback
,
140 #elif XmREVISION == 1
141 XmAddWMProtocolCallback( shell
, WM_DELETE_WINDOW
,
142 (XtCallbackProc
)wxCloseTLWCallback
,
145 XmAddWMProtocolCallback( shell
, WM_DELETE_WINDOW
,
146 (void (*)())wxCloseTLWCallback
, (caddr_t
)this );
149 // This patch come from Torsten Liermann lier@lier1.muc.de
150 if( XmIsMotifWMRunning( shell
) )
153 if( !(m_windowStyle
& wxNO_BORDER
) )
154 decor
|= MWM_DECOR_BORDER
;
155 if( m_windowStyle
& wxRESIZE_BORDER
)
156 decor
|= MWM_DECOR_RESIZEH
;
157 if( m_windowStyle
& wxSYSTEM_MENU
)
158 decor
|= MWM_DECOR_MENU
;
159 if( ( m_windowStyle
& wxCAPTION
) ||
160 ( m_windowStyle
& wxTINY_CAPTION_HORIZ
) ||
161 ( m_windowStyle
& wxTINY_CAPTION_VERT
) )
162 decor
|= MWM_DECOR_TITLE
;
163 if( m_windowStyle
& wxRESIZE_BORDER
)
164 decor
|= MWM_DECOR_BORDER
;
165 if( m_windowStyle
& wxMINIMIZE_BOX
)
166 decor
|= MWM_DECOR_MINIMIZE
;
167 if( m_windowStyle
& wxMAXIMIZE_BOX
)
168 decor
|= MWM_DECOR_MAXIMIZE
;
170 XtVaSetValues( shell
,
171 XmNmwmDecorations
, decor
,
176 // This allows non-Motif window managers to support at least the
177 // no-decorations case.
178 if( ( m_windowStyle
& wxCAPTION
) != wxCAPTION
)
179 XtVaSetValues( shell
,
180 XmNoverrideRedirect
, True
,
184 XtAddEventHandler( (Widget
)GetClientWidget(),
185 ButtonPressMask
| ButtonReleaseMask
|
186 PointerMotionMask
| KeyPressMask
,
194 void wxTopLevelWindowMotif::DoGetPosition(int *x
, int *y
) const
196 Widget top
= (Widget
) GetTopWidget();
197 Window parent_window
= XtWindow((Widget
) top
),
198 next_parent
= XtWindow((Widget
) top
),
199 root
= RootWindowOfScreen(XtScreen((Widget
) top
));
201 // search for the parent that is child of ROOT, because the WM may
202 // reparent twice and notify only the next parent (like FVWM)
203 while (next_parent
!= root
) {
204 Window
*theChildren
; unsigned int n
;
205 parent_window
= next_parent
;
206 XQueryTree(XtDisplay((Widget
) top
), parent_window
, &root
,
207 &next_parent
, &theChildren
, &n
);
208 XFree(theChildren
); // not needed
210 int xx
, yy
; unsigned int dummy
;
211 XGetGeometry(XtDisplay((Widget
) top
), parent_window
, &root
,
212 &xx
, &yy
, &dummy
, &dummy
, &dummy
, &dummy
);
217 void wxTopLevelWindowMotif::Raise()
219 Widget top
= (Widget
) GetTopWidget();
220 Window parent_window
= XtWindow( top
),
221 next_parent
= XtWindow( top
),
222 root
= RootWindowOfScreen( XtScreen( top
) );
223 // search for the parent that is child of ROOT, because the WM may
224 // reparent twice and notify only the next parent (like FVWM)
225 while( next_parent
!= root
)
230 parent_window
= next_parent
;
231 XQueryTree( XtDisplay( top
), parent_window
, &root
,
232 &next_parent
, &theChildren
, &n
);
233 XFree( theChildren
); // not needed
235 XRaiseWindow( XtDisplay( top
), parent_window
);
238 void wxTopLevelWindowMotif::Lower()
240 Widget top
= (Widget
) GetTopWidget();
241 Window parent_window
= XtWindow( top
),
242 next_parent
= XtWindow( top
),
243 root
= RootWindowOfScreen( XtScreen( top
) );
244 // search for the parent that is child of ROOT, because the WM may
245 // reparent twice and notify only the next parent (like FVWM)
246 while( next_parent
!= root
)
251 parent_window
= next_parent
;
252 XQueryTree( XtDisplay( top
), parent_window
, &root
,
253 &next_parent
, &theChildren
, &n
);
254 XFree( theChildren
); // not needed
256 XLowerWindow( XtDisplay( top
), parent_window
);
259 static inline Widget
GetShell( const wxTopLevelWindowMotif
* tlw
)
261 Widget main
= (Widget
) tlw
->GetMainWidget();
262 if( !main
) return (Widget
) NULL
;
264 return XtParent( main
);
267 WXWidget
wxTopLevelWindowMotif::GetShellWidget() const
269 return (WXWidget
) GetShell( this );
272 bool wxTopLevelWindowMotif::ShowFullScreen( bool WXUNUSED(show
),
273 long WXUNUSED(style
) )
279 bool wxTopLevelWindowMotif::IsFullScreen() const
285 void wxTopLevelWindowMotif::Restore()
287 Widget shell
= GetShell( this );
290 XtVaSetValues( shell
,
295 void wxTopLevelWindowMotif::Iconize( bool iconize
)
297 Widget shell
= GetShell( this );
303 XtVaSetValues( shell
,
304 XmNiconic
, (Boolean
)iconize
,
308 bool wxTopLevelWindowMotif::IsIconized() const
310 Widget shell
= GetShell( this );
316 XtVaGetValues( shell
,
320 return (iconic
== True
);
323 void wxTopLevelWindowMotif::Maximize( bool maximize
)
331 bool wxTopLevelWindowMotif::IsMaximized() const
336 void wxTopLevelWindowMotif::DoSetSizeHints( int minW
, int minH
,
340 wxTopLevelWindowBase::DoSetSizeHints( minW
, minH
, maxW
, maxH
, incW
, incH
);
345 if( minW
> -1 ) { XtSetArg( args
[count
], XmNminWidth
, minW
); ++count
; }
346 if( minH
> -1 ) { XtSetArg( args
[count
], XmNminHeight
, minH
); ++count
; }
347 if( maxW
> -1 ) { XtSetArg( args
[count
], XmNmaxWidth
, maxW
); ++count
; }
348 if( maxH
> -1 ) { XtSetArg( args
[count
], XmNmaxHeight
, maxH
); ++count
; }
349 if( incW
> -1 ) { XtSetArg( args
[count
], XmNwidthInc
, incW
); ++count
; }
350 if( incH
> -1 ) { XtSetArg( args
[count
], XmNheightInc
, incH
); ++count
; }
352 XtSetValues( (Widget
)GetShellWidget(), args
, count
);
355 bool wxTopLevelWindowMotif::SetShape( const wxRegion
& region
)
357 return wxDoSetShape( (Display
*)GetXDisplay(),
358 XtWindow( (Widget
)GetShellWidget() ),
362 // ---------------------------------------------------------------------------
363 // Callback definition
364 // ---------------------------------------------------------------------------
366 // Handle a close event from the window manager
367 static void wxCloseTLWCallback( Widget
WXUNUSED(widget
), XtPointer client_data
,
368 XmAnyCallbackStruct
*WXUNUSED(cbs
) )
370 wxTopLevelWindowMotif
* tlw
= (wxTopLevelWindowMotif
*)client_data
;
371 wxCloseEvent
closeEvent( wxEVT_CLOSE_WINDOW
, tlw
->GetId() );
372 closeEvent
.SetEventObject( tlw
);
374 // May delete the dialog (with delayed deletion)
375 tlw
->GetEventHandler()->ProcessEvent(closeEvent
);
378 void wxTLWEventHandler( Widget wid
,
379 XtPointer
WXUNUSED(client_data
),
381 Boolean
* continueToDispatch
)
383 wxTopLevelWindowMotif
* tlw
=
384 (wxTopLevelWindowMotif
*)wxGetWindowFromTable( wid
);
388 wxMouseEvent
wxevent( wxEVT_NULL
);
390 if( wxTranslateMouseEvent( wxevent
, tlw
, wid
, event
) )
392 wxevent
.SetEventObject( tlw
);
393 wxevent
.SetId( tlw
->GetId() );
394 tlw
->GetEventHandler()->ProcessEvent( wxevent
);
398 // An attempt to implement OnCharHook by calling OnCharHook first;
399 // if this returns true, set continueToDispatch to False
400 // (don't continue processing).
401 // Otherwise set it to True and call OnChar.
402 wxKeyEvent
keyEvent( wxEVT_CHAR
);
403 if( wxTranslateKeyEvent( keyEvent
, tlw
, wid
, event
))
405 keyEvent
.SetEventObject( tlw
);
406 keyEvent
.SetId( tlw
->GetId() );
407 keyEvent
.SetEventType( wxEVT_CHAR_HOOK
);
408 if( tlw
->GetEventHandler()->ProcessEvent( keyEvent
) )
410 *continueToDispatch
= False
;
415 // For simplicity, OnKeyDown is the same as OnChar
416 // TODO: filter modifier key presses from OnChar
417 keyEvent
.SetEventType( wxEVT_KEY_DOWN
);
419 // Only process OnChar if OnKeyDown didn't swallow it
420 if( !tlw
->GetEventHandler()->ProcessEvent( keyEvent
) )
422 keyEvent
.SetEventType( wxEVT_CHAR
);
423 tlw
->GetEventHandler()->ProcessEvent( keyEvent
);
430 *continueToDispatch
= True
;