]>
git.saurik.com Git - wxWidgets.git/blob - src/motif/toplevel.cpp
a1df9f3b1058aa338faf7d50b8361ef4c49661a4
   1 ///////////////////////////////////////////////////////////////////////////// 
   2 // Name:        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 #if defined(__GNUG__) && !defined(NO_GCC_PRAGMA) 
  21     #pragma implementation "toplevel.h" 
  24 // For compilers that support precompilation, includes "wx.h". 
  25 #include "wx/wxprec.h" 
  27 #include "wx/toplevel.h" 
  31 #define XtDisplay XTDISPLAY 
  32 #define XtParent XTPARENT 
  33 #define XtScreen XTSCREEN 
  34 #define XtWindow XTWINDOW 
  35 #pragma message disable nosimpint 
  39 #include <X11/Shell.h> 
  48     #pragma message enable nosimpint 
  51 #include "wx/motif/private.h" 
  53 wxList wxModelessWindows
;  // Frames and modeless dialogs 
  55 // --------------------------------------------------------------------------- 
  57 // --------------------------------------------------------------------------- 
  59 static void wxCloseTLWCallback( Widget widget
, XtPointer client_data
, 
  60                                 XmAnyCallbackStruct 
*cbs 
); 
  61 static void wxTLWEventHandler( Widget wid
, 
  62                                XtPointer client_data
, 
  64                                Boolean 
*continueToDispatch 
); 
  66 // =========================================================================== 
  67 // wxTopLevelWindowMotif implementation 
  68 // =========================================================================== 
  70 void wxTopLevelWindowMotif::PreDestroy() 
  73 #pragma message disable codcauunr 
  75    if ( (GetWindowStyleFlag() & wxDIALOG_MODAL
) != wxDIALOG_MODAL 
) 
  76         wxModelessWindows
.DeleteObject(this); 
  78 #pragma message enable codcauunr 
  81     m_icons
.m_icons
.Empty(); 
  85     // MessageDialog and FileDialog do not have a client widget 
  86     if( GetClientWidget() ) 
  88         XtRemoveEventHandler( (Widget
)GetClientWidget(), 
  89                               ButtonPressMask 
| ButtonReleaseMask 
| 
  90                               PointerMotionMask 
| KeyPressMask
, 
  97 wxTopLevelWindowMotif::~wxTopLevelWindowMotif() 
  99     SetMainWidget( (WXWidget
)0 ); 
 102 void wxTopLevelWindowMotif::Init() 
 107 bool wxTopLevelWindowMotif::Create( wxWindow 
*parent
, wxWindowID id
, 
 108                                     const wxString
& title
, 
 112                                     const wxString
& name 
) 
 115     m_windowStyle 
= style
; 
 118         parent
->AddChild(this); 
 120     wxTopLevelWindows
.Append(this); 
 122     m_windowId 
= ( id 
> -1 ) ? id 
: NewControlId(); 
 124     bool retval 
= DoCreate( parent
, id
, title
, pos
, size
, style
, name 
); 
 126     if( !retval 
) return false; 
 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 
); 
 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 
 136     XmRemoveWMProtocols( shell
, &WM_DELETE_WINDOW
, 1 ); 
 137     XmAddWMProtocols( shell
, &WM_DELETE_WINDOW
, 1 ); 
 138     XmActivateWMProtocol( shell
, WM_DELETE_WINDOW 
); 
 140     // Modified Steve Hammes for Motif 2.0 
 141 #if (XmREVISION > 1 || XmVERSION > 1) 
 142     XmAddWMProtocolCallback( shell
, WM_DELETE_WINDOW
, 
 143                              (XtCallbackProc
)wxCloseTLWCallback
, 
 145 #elif XmREVISION == 1 
 146     XmAddWMProtocolCallback( shell
, WM_DELETE_WINDOW
, 
 147                              (XtCallbackProc
)wxCloseTLWCallback
, 
 150     XmAddWMProtocolCallback( shell
, WM_DELETE_WINDOW
, 
 151                              (void (*)())wxCloseTLWCallback
, (caddr_t
)this ); 
 154     // This patch come from Torsten Liermann lier@lier1.muc.de 
 155     if( XmIsMotifWMRunning( shell 
) ) 
 158         if( !(m_windowStyle 
& wxNO_BORDER
) ) 
 159             decor 
|= MWM_DECOR_BORDER
; 
 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
; 
 175         XtVaSetValues( shell
, 
 176                        XmNmwmDecorations
, decor
, 
 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
, 
 185                            XmNoverrideRedirect
, True
, 
 189     XtAddEventHandler( (Widget
)GetClientWidget(), 
 190                        ButtonPressMask 
| ButtonReleaseMask 
| 
 191                        PointerMotionMask 
| KeyPressMask
, 
 199 void wxTopLevelWindowMotif::DoGetPosition(int *x
, int *y
) const 
 201     Widget top 
= (Widget
) GetTopWidget(); 
 202     Window parent_window 
= XtWindow((Widget
) top
), 
 203         next_parent   
= XtWindow((Widget
) top
), 
 204         root          
= RootWindowOfScreen(XtScreen((Widget
) top
)); 
 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 
 215     int xx
, yy
; unsigned int dummy
; 
 216     XGetGeometry(XtDisplay((Widget
) top
), parent_window
, &root
, 
 217         &xx
, &yy
, &dummy
, &dummy
, &dummy
, &dummy
); 
 222 void wxTopLevelWindowMotif::Raise() 
 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 
) 
 235         parent_window 
= next_parent
; 
 236         XQueryTree( XtDisplay( top 
), parent_window
, &root
, 
 237             &next_parent
, &theChildren
, &n 
); 
 238         XFree( theChildren 
); // not needed 
 240     XRaiseWindow( XtDisplay( top 
), parent_window 
); 
 243 void wxTopLevelWindowMotif::Lower() 
 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 
) 
 256         parent_window 
= next_parent
; 
 257         XQueryTree( XtDisplay( top 
), parent_window
, &root
, 
 258             &next_parent
, &theChildren
, &n 
); 
 259         XFree( theChildren 
); // not needed 
 261     XLowerWindow( XtDisplay( top 
), parent_window 
); 
 264 static inline Widget 
GetShell( const wxTopLevelWindowMotif
* tlw 
) 
 266     Widget main 
= (Widget
) tlw
->GetMainWidget(); 
 267     if( !main 
) return (Widget
) NULL
; 
 269     return XtParent( main 
); 
 272 WXWidget 
wxTopLevelWindowMotif::GetShellWidget() const 
 274     return (WXWidget
) GetShell( this ); 
 277 bool wxTopLevelWindowMotif::ShowFullScreen( bool show
, 
 284 bool wxTopLevelWindowMotif::IsFullScreen() const 
 290 void wxTopLevelWindowMotif::Restore() 
 292     Widget shell 
= GetShell( this ); 
 295         XtVaSetValues( shell
, 
 300 void wxTopLevelWindowMotif::Iconize( bool iconize 
) 
 302     Widget shell 
= GetShell( this ); 
 308     XtVaSetValues( shell
, 
 309                    XmNiconic
, (Boolean
)iconize
, 
 313 bool wxTopLevelWindowMotif::IsIconized() const 
 315     Widget shell 
= GetShell( this ); 
 321     XtVaGetValues( shell
, 
 328 void wxTopLevelWindowMotif::Maximize( bool maximize 
) 
 336 bool wxTopLevelWindowMotif::IsMaximized() const 
 341 void wxTopLevelWindowMotif::DoSetSizeHints( int minW
, int minH
, 
 345     wxTopLevelWindowBase::DoSetSizeHints( minW
, minH
, maxW
, maxH
, incW
, incH 
); 
 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
; } 
 357     XtSetValues( (Widget
)GetShellWidget(), args
, count 
); 
 360 bool wxTopLevelWindowMotif::SetShape( const wxRegion
& region 
) 
 362     return wxDoSetShape( (Display
*)GetXDisplay(), 
 363                          XtWindow( (Widget
)GetShellWidget() ), 
 367 // --------------------------------------------------------------------------- 
 368 // Callback definition 
 369 // --------------------------------------------------------------------------- 
 371 // Handle a close event from the window manager 
 372 static void wxCloseTLWCallback( Widget 
WXUNUSED(widget
), XtPointer client_data
, 
 373                                 XmAnyCallbackStruct 
*WXUNUSED(cbs
) ) 
 375     wxTopLevelWindowMotif
* tlw 
= (wxTopLevelWindowMotif
*)client_data
; 
 376     wxCloseEvent 
closeEvent( wxEVT_CLOSE_WINDOW
, tlw
->GetId() ); 
 377     closeEvent
.SetEventObject( tlw 
); 
 379     // May delete the dialog (with delayed deletion) 
 380     tlw
->GetEventHandler()->ProcessEvent(closeEvent
); 
 383 void wxTLWEventHandler( Widget wid
, 
 384                         XtPointer 
WXUNUSED(client_data
), 
 386                         Boolean
* continueToDispatch
) 
 388     wxTopLevelWindowMotif
* tlw 
= 
 389         (wxTopLevelWindowMotif
*)wxGetWindowFromTable( wid 
); 
 393         wxMouseEvent 
wxevent( wxEVT_NULL 
); 
 395         if( wxTranslateMouseEvent( wxevent
, tlw
, wid
, event 
) ) 
 397             wxevent
.SetEventObject( tlw 
); 
 398             wxevent
.SetId( tlw
->GetId() ); 
 399             tlw
->GetEventHandler()->ProcessEvent( wxevent 
); 
 403             // An attempt to implement OnCharHook by calling OnCharHook first; 
 404             // if this returns true, set continueToDispatch to False 
 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 
)) 
 410                 keyEvent
.SetEventObject( tlw 
); 
 411                 keyEvent
.SetId( tlw
->GetId() ); 
 412                 keyEvent
.SetEventType( wxEVT_CHAR_HOOK 
); 
 413                 if( tlw
->GetEventHandler()->ProcessEvent( keyEvent 
) ) 
 415                     *continueToDispatch 
= False
; 
 420                     // For simplicity, OnKeyDown is the same as OnChar 
 421                     // TODO: filter modifier key presses from OnChar 
 422                     keyEvent
.SetEventType( wxEVT_KEY_DOWN 
); 
 424                     // Only process OnChar if OnKeyDown didn't swallow it 
 425                     if( !tlw
->GetEventHandler()->ProcessEvent( keyEvent 
) ) 
 427                         keyEvent
.SetEventType( wxEVT_CHAR 
); 
 428                         tlw
->GetEventHandler()->ProcessEvent( keyEvent 
); 
 435     *continueToDispatch 
= True
;