1 /////////////////////////////////////////////////////////////////////////////// 
   2 // Name:        x11/toplevel.cpp 
   3 // Purpose:     implements wxTopLevelWindow for X11 
   4 // Author:      Julian Smart 
   8 // Copyright:   (c) 2002 Julian Smart 
   9 // License:     wxWindows licence 
  10 /////////////////////////////////////////////////////////////////////////////// 
  12 // ============================================================================ 
  14 // ============================================================================ 
  16 // ---------------------------------------------------------------------------- 
  18 // ---------------------------------------------------------------------------- 
  21     #pragma implementation "toplevel.h" 
  24 // For compilers that support precompilation, includes "wx.h". 
  25 #include "wx/wxprec.h" 
  33     #include "wx/toplevel.h" 
  34     #include "wx/string.h" 
  39     #include "wx/statusbr.h" 
  42 #include "wx/settings.h" 
  43 #include "wx/x11/private.h" 
  44 #include "X11/Xutil.h" 
  46 bool wxMWMIsRunning(Window w
); 
  48 // ---------------------------------------------------------------------------- 
  49 // wxTopLevelWindowX11 creation 
  50 // ---------------------------------------------------------------------------- 
  52 void wxTopLevelWindowX11::Init() 
  55     m_maximizeOnShow 
= FALSE
; 
  57     // unlike (almost?) all other windows, frames are created hidden 
  60     // Data to save/restore when calling ShowFullScreen 
  62     m_fsIsMaximized 
= FALSE
; 
  63     m_fsIsShowing 
= FALSE
; 
  66 bool wxTopLevelWindowX11::Create(wxWindow 
*parent
, 
  68                                  const wxString
& title
, 
  77     m_windowStyle 
= style
; 
  82     m_windowId 
= id 
== -1 ? NewControlId() : id
; 
  85         parent
->AddChild(this); 
  87     wxTopLevelWindows
.Append(this); 
  89     Display 
*xdisplay 
= wxGlobalDisplay(); 
  90     int xscreen 
= DefaultScreen( xdisplay 
); 
  91     Visual 
*xvisual 
= DefaultVisual( xdisplay
, xscreen 
); 
  92     Window xparent 
= RootWindow( xdisplay
, xscreen 
); 
  93     Colormap cm 
= DefaultColormap( xdisplay
, xscreen 
); 
  95     // TODO: For dialogs, this should be wxSYS_COLOUR_3DFACE 
  96     m_backgroundColour 
= wxSystemSettings::GetColour(wxSYS_COLOUR_APPWORKSPACE
); 
  97     m_backgroundColour
.CalcPixel( (WXColormap
) cm 
); 
 100     XSetWindowAttributes xattributes
; 
 101     XSizeHints size_hints
; 
 104     long xattributes_mask 
= 
 106         CWBorderPixel 
| CWBackPixel
; 
 107     xattributes
.background_pixel 
= m_backgroundColour
.GetPixel(); 
 108     xattributes
.border_pixel 
= BlackPixel( xdisplay
, xscreen 
); 
 109     xattributes
.override_redirect 
= False
; 
 111     Window xwindow 
= XCreateWindow( xdisplay
, xparent
, pos
.x
, pos
.y
, size
.x
, size
.y
,  
 112        0, DefaultDepth(xdisplay
,xscreen
), InputOutput
, xvisual
, xattributes_mask
, &xattributes 
); 
 113     m_mainWidget 
= (WXWindow
) xwindow
; 
 115     XSelectInput( xdisplay
, xwindow
, 
 116         ExposureMask 
| KeyPressMask 
| KeyReleaseMask 
| ButtonPressMask 
| ButtonReleaseMask 
| 
 117         ButtonMotionMask 
| EnterWindowMask 
| LeaveWindowMask 
| PointerMotionMask 
| 
 118         KeymapStateMask 
| FocusChangeMask 
| ColormapChangeMask 
| StructureNotifyMask 
| 
 119         PropertyChangeMask 
); 
 121     wxAddWindowToTable( xwindow
, (wxWindow
*) this ); 
 123     XSetTransientForHint( xdisplay
, xwindow
, xparent 
); 
 125     size_hints
.flags 
= PSize
; 
 126     size_hints
.width 
= size
.x
; 
 127     size_hints
.height 
= size
.y
; 
 128     XSetWMNormalHints( xdisplay
, xwindow
, &size_hints
); 
 130     wm_hints
.flags 
= InputHint 
| StateHint 
/* | WindowGroupHint */; 
 131     wm_hints
.input 
= True
; 
 132     wm_hints
.initial_state 
= NormalState
; 
 133     XSetWMHints( xdisplay
, xwindow
, &wm_hints
); 
 135     Atom wm_delete_window 
= XInternAtom( xdisplay
, "WM_DELETE_WINDOW", False
); 
 136     XSetWMProtocols( xdisplay
, xwindow
, &wm_delete_window
, 1); 
 138     wxSetWMDecorations((Window
) GetMainWindow(), style
); 
 145 wxTopLevelWindowX11::~wxTopLevelWindowX11() 
 147     wxTopLevelWindows
.DeleteObject(this); 
 149     // If this is the last top-level window, exit. 
 150     if ( wxTheApp 
&& (wxTopLevelWindows
.Number() == 0) ) 
 152         wxTheApp
->SetTopWindow(NULL
); 
 154         if (wxTheApp
->GetExitOnFrameDelete()) 
 156             // Signal to the app that we're going to close 
 157             wxTheApp
->ExitMainLoop(); 
 162 // ---------------------------------------------------------------------------- 
 163 // wxTopLevelWindowX11 showing 
 164 // ---------------------------------------------------------------------------- 
 166 bool wxTopLevelWindowX11::Show(bool show
) 
 168     return wxWindowX11::Show(show
); 
 171 // ---------------------------------------------------------------------------- 
 172 // wxTopLevelWindowX11 maximize/minimize 
 173 // ---------------------------------------------------------------------------- 
 175 void wxTopLevelWindowX11::Maximize(bool maximize
) 
 180 bool wxTopLevelWindowX11::IsMaximized() const 
 186 void wxTopLevelWindowX11::Iconize(bool iconize
) 
 188     if (!m_iconized 
&& GetMainWindow()) 
 190         if (XIconifyWindow(wxGlobalDisplay(), 
 191             (Window
) GetMainWindow(), DefaultScreen(wxGlobalDisplay())) != 0) 
 196 bool wxTopLevelWindowX11::IsIconized() const 
 201 void wxTopLevelWindowX11::Restore() 
 203     // This is the way to deiconify the window, according to the X FAQ 
 204     if (m_iconized 
&& GetMainWindow()) 
 206         XMapWindow(wxGlobalDisplay(), (Window
) GetMainWindow()); 
 211 // ---------------------------------------------------------------------------- 
 212 // wxTopLevelWindowX11 fullscreen 
 213 // ---------------------------------------------------------------------------- 
 215 bool wxTopLevelWindowX11::ShowFullScreen(bool show
, long style
) 
 222         m_fsIsShowing 
= TRUE
; 
 234         m_fsIsShowing 
= FALSE
; 
 241 // ---------------------------------------------------------------------------- 
 242 // wxTopLevelWindowX11 misc 
 243 // ---------------------------------------------------------------------------- 
 245 void wxTopLevelWindowX11::SetIcon(const wxIcon
& icon
) 
 248     wxTopLevelWindowBase::SetIcon(icon
); 
 250     if (icon
.Ok() && GetMainWindow()) 
 252         XWMHints 
*wmHints 
= XAllocWMHints(); 
 253         wmHints
->icon_pixmap 
= (Pixmap
) icon
.GetPixmap(); 
 255         wmHints
->flags 
= IconPixmapHint
; 
 259             wmHints
->flags 
|= IconMaskHint
; 
 260             wmHints
->icon_mask 
= (Pixmap
) icon
.GetMask()->GetPixmap(); 
 263         XSetWMHints(wxGlobalDisplay(), (Window
) GetMainWindow(), wmHints
); 
 268 void wxTopLevelWindowX11::SetTitle(const wxString
& title
) 
 273         XStoreName(wxGlobalDisplay(), (Window
) GetMainWindow(), 
 274             (const char*) title
); 
 275         XSetIconName(wxGlobalDisplay(), (Window
) GetMainWindow(), 
 276             (const char*) title
); 
 278         // Use this if the platform doesn't supply the above functions. 
 280         XTextProperty textProperty
; 
 281         textProperty
.value 
= (unsigned char*) title
; 
 282         textProperty
.encoding 
= XA_STRING
; 
 283         textProperty
.format 
= 8; 
 284         textProperty
.nitems 
= 1; 
 286         XSetTextProperty(wxGlobalDisplay(), (Window
) GetMainWindow(), 
 287             & textProperty
, WM_NAME
); 
 292 wxString 
wxTopLevelWindowX11::GetTitle() const 
 297 #ifndef MWM_DECOR_BORDER 
 298 /* bit definitions for MwmHints.flags */ 
 299 #define MWM_HINTS_FUNCTIONS (1L << 0) 
 300 #define MWM_HINTS_DECORATIONS (1L << 1) 
 301 #define MWM_HINTS_INPUT_MODE (1L << 2) 
 302 #define MWM_HINTS_STATUS (1L << 3) 
 304 #define MWM_DECOR_ALL           (1L << 0) 
 305 #define MWM_DECOR_BORDER        (1L << 1) 
 306 #define MWM_DECOR_RESIZEH       (1L << 2) 
 307 #define MWM_DECOR_TITLE         (1L << 3) 
 308 #define MWM_DECOR_MENU          (1L << 4) 
 309 #define MWM_DECOR_MINIMIZE      (1L << 5) 
 310 #define MWM_DECOR_MAXIMIZE      (1L << 6) 
 320 #define PROP_MOTIF_WM_HINTS_ELEMENTS 5 
 322 // Set the window manager decorations according to the 
 323 // given wxWindows style 
 324 bool wxSetWMDecorations(Window w
, long style
) 
 326     if (!wxMWMIsRunning(w
)) 
 329     Atom mwm_wm_hints 
= XInternAtom(wxGlobalDisplay(),"_MOTIF_WM_HINTS", False
); 
 332     hints
.decorations 
= 0; 
 334     if (style 
& wxRESIZE_BORDER
) 
 336         hints
.flags 
|= MWM_HINTS_DECORATIONS
; 
 337         hints
.decorations 
|= MWM_DECOR_RESIZEH
; 
 340     if (style 
& wxSYSTEM_MENU
) 
 342         hints
.flags 
|= MWM_HINTS_DECORATIONS
; 
 343         hints
.decorations 
|= MWM_DECOR_MENU
; 
 346     if ((style 
& wxCAPTION
) || 
 347         (style 
& wxTINY_CAPTION_HORIZ
) || 
 348         (style 
& wxTINY_CAPTION_VERT
)) 
 350         hints
.flags 
|= MWM_HINTS_DECORATIONS
; 
 351         hints
.decorations 
|= MWM_DECOR_TITLE
; 
 354     if (style 
& wxTHICK_FRAME
) 
 356         hints
.flags 
|= MWM_HINTS_DECORATIONS
; 
 357         hints
.decorations 
|= MWM_DECOR_BORDER
; 
 360     if (style 
& wxTHICK_FRAME
) 
 362         hints
.flags 
|= MWM_HINTS_DECORATIONS
; 
 363         hints
.decorations 
|= MWM_DECOR_BORDER
; 
 366     if (style 
& wxMINIMIZE_BOX
) 
 368         hints
.flags 
|= MWM_HINTS_DECORATIONS
; 
 369         hints
.decorations 
|= MWM_DECOR_MINIMIZE
; 
 372     if (style 
& wxMAXIMIZE_BOX
) 
 374         hints
.flags 
|= MWM_HINTS_DECORATIONS
; 
 375         hints
.decorations 
|= MWM_DECOR_MAXIMIZE
; 
 378     XChangeProperty(wxGlobalDisplay(), 
 380                     mwm_wm_hints
, mwm_wm_hints
, 
 382                     (unsigned char *) &hints
, PROP_MOTIF_WM_HINTS_ELEMENTS
); 
 387 bool wxMWMIsRunning(Window w
) 
 389     Display 
*dpy 
= (Display
*)wxGetDisplay(); 
 390     Atom motifWmInfo 
= XInternAtom(dpy
, "_MOTIF_WM_INFO", False
); 
 392     unsigned long length
, bytesafter
; 
 393     unsigned char value
[20]; 
 394     unsigned char *ptr 
= &value
[0]; 
 398     type 
= format 
= length 
= 0; 
 401     ret 
= XGetWindowProperty(wxGlobalDisplay(), w
, motifWmInfo
, 
 402             0L, 2, False
, motifWmInfo
,  
 403             &type
, &format
, &length
, &bytesafter
, &ptr
); 
 405     return (ret 
== Success
); 
 408 // For implementation purposes - sometimes decorations make the client area 
 410 wxPoint 
wxTopLevelWindowX11::GetClientAreaOrigin() const 
 412     // In fact wxFrame::GetClientAreaOrigin 
 413     // does the required calculation already. 
 415     if (this->IsKindOf(CLASSINFO(wxFrame
))) 
 417         wxFrame
* frame 
= (wxFrame
*) this; 
 418         if (frame
->GetMenuBar()) 
 419             return wxPoint(0, frame
->GetMenuBar()->GetSize().y
); 
 422     return wxPoint(0, 0); 
 425 void wxTopLevelWindowX11::DoGetClientSize( int *width
, int *height 
) const 
 427     wxWindowX11::DoGetClientSize(width
, height
); 
 428     // Done by wxTopLevelWindow 
 430     if (this->IsKindOf(CLASSINFO(wxFrame
))) 
 432         wxFrame
* frame 
= (wxFrame
*) this; 
 433         if (frame
->GetMenuBar()) 
 434             (*height
) -= frame
->GetMenuBar()->GetSize().y
; 
 435         if (frame
->GetStatusBar()) 
 436             (*height
) -= frame
->GetStatusBar()->GetSize().y
; 
 441 void wxTopLevelWindowX11::DoSetClientSize(int width
, int height
) 
 443     wxWindowX11::DoSetClientSize(width
, height
); 
 445     if (!GetMainWindow()) 
 448     XWindowChanges windowChanges
; 
 453         windowChanges
.width 
= width 
; 
 454         valueMask 
|= CWWidth
; 
 458         windowChanges
.height 
= height 
; 
 459         valueMask 
|= CWHeight
; 
 461     XConfigureWindow(wxGlobalDisplay(), (Window
) GetMainWindow(), 
 462         valueMask
, & windowChanges
);