]>
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"
27 #define XtDisplay XTDISPLAY
28 #define XtParent XTPARENT
29 #define XtScreen XTSCREEN
30 #define XtWindow XTWINDOW
31 #pragma message disable nosimpint
35 #include <X11/Shell.h>
44 #pragma message enable nosimpint
47 #include "wx/motif/private.h"
49 wxList wxModelessWindows
; // Frames and modeless dialogs
51 // ---------------------------------------------------------------------------
53 // ---------------------------------------------------------------------------
55 static void wxCloseTLWCallback( Widget widget
, XtPointer client_data
,
56 XmAnyCallbackStruct
*cbs
);
57 static void wxTLWEventHandler( Widget wid
,
58 XtPointer client_data
,
60 Boolean
*continueToDispatch
);
62 // ===========================================================================
63 // wxTopLevelWindowMotif implementation
64 // ===========================================================================
66 void wxTopLevelWindowMotif::PreDestroy()
69 #pragma message disable codcauunr
71 if ( (GetWindowStyleFlag() & wxDIALOG_MODAL
) != wxDIALOG_MODAL
)
72 wxModelessWindows
.DeleteObject(this);
74 #pragma message enable codcauunr
77 m_icons
.m_icons
.Empty();
81 // MessageDialog and FileDialog do not have a client widget
82 if( GetClientWidget() )
84 XtRemoveEventHandler( (Widget
)GetClientWidget(),
85 ButtonPressMask
| ButtonReleaseMask
|
86 PointerMotionMask
| KeyPressMask
,
93 wxTopLevelWindowMotif::~wxTopLevelWindowMotif()
95 SetMainWidget( (WXWidget
)0 );
98 void wxTopLevelWindowMotif::Init()
103 bool wxTopLevelWindowMotif::Create( wxWindow
*parent
, wxWindowID id
,
104 const wxString
& title
,
108 const wxString
& name
)
111 m_windowStyle
= style
;
114 parent
->AddChild(this);
116 wxTopLevelWindows
.Append(this);
118 m_windowId
= ( id
> -1 ) ? id
: NewControlId();
120 bool retval
= XmDoCreateTLW( parent
, id
, title
, pos
, size
, style
, name
);
122 if( !retval
) return false;
124 // Intercept CLOSE messages from the window manager
125 Widget shell
= (Widget
)GetShellWidget();
126 Atom WM_DELETE_WINDOW
= XmInternAtom( XtDisplay( shell
),
127 "WM_DELETE_WINDOW", False
);
129 // Remove and add WM_DELETE_WINDOW so ours is only handler
130 // This only appears to be necessary for wxDialog, but does not hurt
132 XmRemoveWMProtocols( shell
, &WM_DELETE_WINDOW
, 1 );
133 XmAddWMProtocols( shell
, &WM_DELETE_WINDOW
, 1 );
134 XmActivateWMProtocol( shell
, WM_DELETE_WINDOW
);
136 // Modified Steve Hammes for Motif 2.0
137 #if (XmREVISION > 1 || XmVERSION > 1)
138 XmAddWMProtocolCallback( shell
, WM_DELETE_WINDOW
,
139 (XtCallbackProc
)wxCloseTLWCallback
,
141 #elif XmREVISION == 1
142 XmAddWMProtocolCallback( shell
, WM_DELETE_WINDOW
,
143 (XtCallbackProc
)wxCloseTLWCallback
,
146 XmAddWMProtocolCallback( shell
, WM_DELETE_WINDOW
,
147 (void (*)())wxCloseTLWCallback
, (caddr_t
)this );
150 // This patch come from Torsten Liermann lier@lier1.muc.de
151 if( XmIsMotifWMRunning( shell
) )
154 if( !(m_windowStyle
& wxNO_BORDER
) )
155 decor
|= MWM_DECOR_BORDER
;
156 if( m_windowStyle
& wxRESIZE_BORDER
)
157 decor
|= MWM_DECOR_RESIZEH
;
158 if( m_windowStyle
& wxSYSTEM_MENU
)
159 decor
|= MWM_DECOR_MENU
;
160 if( ( m_windowStyle
& wxCAPTION
) ||
161 ( m_windowStyle
& wxTINY_CAPTION_HORIZ
) ||
162 ( m_windowStyle
& wxTINY_CAPTION_VERT
) )
163 decor
|= MWM_DECOR_TITLE
;
164 if( m_windowStyle
& wxTHICK_FRAME
)
165 decor
|= MWM_DECOR_BORDER
;
166 if( m_windowStyle
& wxMINIMIZE_BOX
)
167 decor
|= MWM_DECOR_MINIMIZE
;
168 if( m_windowStyle
& wxMAXIMIZE_BOX
)
169 decor
|= MWM_DECOR_MAXIMIZE
;
171 XtVaSetValues( shell
,
172 XmNmwmDecorations
, decor
,
177 // This allows non-Motif window managers to support at least the
178 // no-decorations case.
179 if( ( m_windowStyle
& wxCAPTION
) != wxCAPTION
)
180 XtVaSetValues( shell
,
181 XmNoverrideRedirect
, True
,
185 XtAddEventHandler( (Widget
)GetClientWidget(),
186 ButtonPressMask
| ButtonReleaseMask
|
187 PointerMotionMask
| KeyPressMask
,
195 void wxTopLevelWindowMotif::DoGetPosition(int *x
, int *y
) const
197 Widget top
= (Widget
) GetTopWidget();
198 Window parent_window
= XtWindow((Widget
) top
),
199 next_parent
= XtWindow((Widget
) top
),
200 root
= RootWindowOfScreen(XtScreen((Widget
) top
));
202 // search for the parent that is child of ROOT, because the WM may
203 // reparent twice and notify only the next parent (like FVWM)
204 while (next_parent
!= root
) {
205 Window
*theChildren
; unsigned int n
;
206 parent_window
= next_parent
;
207 XQueryTree(XtDisplay((Widget
) top
), parent_window
, &root
,
208 &next_parent
, &theChildren
, &n
);
209 XFree(theChildren
); // not needed
211 int xx
, yy
; unsigned int dummy
;
212 XGetGeometry(XtDisplay((Widget
) top
), parent_window
, &root
,
213 &xx
, &yy
, &dummy
, &dummy
, &dummy
, &dummy
);
218 void wxTopLevelWindowMotif::Raise()
220 Widget top
= (Widget
) GetTopWidget();
221 Window parent_window
= XtWindow( top
),
222 next_parent
= XtWindow( top
),
223 root
= RootWindowOfScreen( XtScreen( top
) );
224 // search for the parent that is child of ROOT, because the WM may
225 // reparent twice and notify only the next parent (like FVWM)
226 while( next_parent
!= root
)
231 parent_window
= next_parent
;
232 XQueryTree( XtDisplay( top
), parent_window
, &root
,
233 &next_parent
, &theChildren
, &n
);
234 XFree( theChildren
); // not needed
236 XRaiseWindow( XtDisplay( top
), parent_window
);
239 void wxTopLevelWindowMotif::Lower()
241 Widget top
= (Widget
) GetTopWidget();
242 Window parent_window
= XtWindow( top
),
243 next_parent
= XtWindow( top
),
244 root
= RootWindowOfScreen( XtScreen( top
) );
245 // search for the parent that is child of ROOT, because the WM may
246 // reparent twice and notify only the next parent (like FVWM)
247 while( next_parent
!= root
)
252 parent_window
= next_parent
;
253 XQueryTree( XtDisplay( top
), parent_window
, &root
,
254 &next_parent
, &theChildren
, &n
);
255 XFree( theChildren
); // not needed
257 XLowerWindow( XtDisplay( top
), parent_window
);
260 static inline Widget
GetShell( const wxTopLevelWindowMotif
* tlw
)
262 Widget main
= (Widget
) tlw
->GetMainWidget();
263 if( !main
) return (Widget
) NULL
;
265 return XtParent( main
);
268 WXWidget
wxTopLevelWindowMotif::GetShellWidget() const
270 return (WXWidget
) GetShell( this );
273 bool wxTopLevelWindowMotif::ShowFullScreen( bool WXUNUSED(show
),
274 long WXUNUSED(style
) )
280 bool wxTopLevelWindowMotif::IsFullScreen() const
286 void wxTopLevelWindowMotif::Restore()
288 Widget shell
= GetShell( this );
291 XtVaSetValues( shell
,
296 void wxTopLevelWindowMotif::Iconize( bool iconize
)
298 Widget shell
= GetShell( this );
304 XtVaSetValues( shell
,
305 XmNiconic
, (Boolean
)iconize
,
309 bool wxTopLevelWindowMotif::IsIconized() const
311 Widget shell
= GetShell( this );
317 XtVaGetValues( shell
,
321 return (iconic
== True
);
324 void wxTopLevelWindowMotif::Maximize( bool maximize
)
332 bool wxTopLevelWindowMotif::IsMaximized() const
337 void wxTopLevelWindowMotif::DoSetSizeHints( int minW
, int minH
,
341 wxTopLevelWindowBase::DoSetSizeHints( minW
, minH
, maxW
, maxH
, incW
, incH
);
346 if( minW
> -1 ) { XtSetArg( args
[count
], XmNminWidth
, minW
); ++count
; }
347 if( minH
> -1 ) { XtSetArg( args
[count
], XmNminHeight
, minH
); ++count
; }
348 if( maxW
> -1 ) { XtSetArg( args
[count
], XmNmaxWidth
, maxW
); ++count
; }
349 if( maxH
> -1 ) { XtSetArg( args
[count
], XmNmaxHeight
, maxH
); ++count
; }
350 if( incW
> -1 ) { XtSetArg( args
[count
], XmNwidthInc
, incW
); ++count
; }
351 if( incH
> -1 ) { XtSetArg( args
[count
], XmNheightInc
, incH
); ++count
; }
353 XtSetValues( (Widget
)GetShellWidget(), args
, count
);
356 bool wxTopLevelWindowMotif::SetShape( const wxRegion
& region
)
358 return wxDoSetShape( (Display
*)GetXDisplay(),
359 XtWindow( (Widget
)GetShellWidget() ),
363 // ---------------------------------------------------------------------------
364 // Callback definition
365 // ---------------------------------------------------------------------------
367 // Handle a close event from the window manager
368 static void wxCloseTLWCallback( Widget
WXUNUSED(widget
), XtPointer client_data
,
369 XmAnyCallbackStruct
*WXUNUSED(cbs
) )
371 wxTopLevelWindowMotif
* tlw
= (wxTopLevelWindowMotif
*)client_data
;
372 wxCloseEvent
closeEvent( wxEVT_CLOSE_WINDOW
, tlw
->GetId() );
373 closeEvent
.SetEventObject( tlw
);
375 // May delete the dialog (with delayed deletion)
376 tlw
->GetEventHandler()->ProcessEvent(closeEvent
);
379 void wxTLWEventHandler( Widget wid
,
380 XtPointer
WXUNUSED(client_data
),
382 Boolean
* continueToDispatch
)
384 wxTopLevelWindowMotif
* tlw
=
385 (wxTopLevelWindowMotif
*)wxGetWindowFromTable( wid
);
389 wxMouseEvent
wxevent( wxEVT_NULL
);
391 if( wxTranslateMouseEvent( wxevent
, tlw
, wid
, event
) )
393 wxevent
.SetEventObject( tlw
);
394 wxevent
.SetId( tlw
->GetId() );
395 tlw
->GetEventHandler()->ProcessEvent( wxevent
);
399 // An attempt to implement OnCharHook by calling OnCharHook first;
400 // if this returns true, set continueToDispatch to False
401 // (don't continue processing).
402 // Otherwise set it to True and call OnChar.
403 wxKeyEvent
keyEvent( wxEVT_CHAR
);
404 if( wxTranslateKeyEvent( keyEvent
, tlw
, wid
, event
))
406 keyEvent
.SetEventObject( tlw
);
407 keyEvent
.SetId( tlw
->GetId() );
408 keyEvent
.SetEventType( wxEVT_CHAR_HOOK
);
409 if( tlw
->GetEventHandler()->ProcessEvent( keyEvent
) )
411 *continueToDispatch
= False
;
416 // For simplicity, OnKeyDown is the same as OnChar
417 // TODO: filter modifier key presses from OnChar
418 keyEvent
.SetEventType( wxEVT_KEY_DOWN
);
420 // Only process OnChar if OnKeyDown didn't swallow it
421 if( !tlw
->GetEventHandler()->ProcessEvent( keyEvent
) )
423 keyEvent
.SetEventType( wxEVT_CHAR
);
424 tlw
->GetEventHandler()->ProcessEvent( keyEvent
);
431 *continueToDispatch
= True
;