]>
git.saurik.com Git - wxWidgets.git/blob - src/motif/toplevel.cpp
01342c5b9b9c0bddab92f4f118e4017d59a0bdef
   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
;