Put m_statusText.SetCount(number) before wxStatusBarBase::SetFieldsCount(number,...
[wxWidgets.git] / src / x11 / toplevel.cpp
1 ///////////////////////////////////////////////////////////////////////////////
2 // Name: x11/toplevel.cpp
3 // Purpose: implements wxTopLevelWindow for X11
4 // Author: Julian Smart
5 // Modified by:
6 // Created: 24.09.01
7 // RCS-ID: $Id$
8 // Copyright: (c) 2002 Julian Smart
9 // License: wxWindows licence
10 ///////////////////////////////////////////////////////////////////////////////
11
12 // ============================================================================
13 // declarations
14 // ============================================================================
15
16 // ----------------------------------------------------------------------------
17 // headers
18 // ----------------------------------------------------------------------------
19
20 #ifdef __GNUG__
21 #pragma implementation "toplevel.h"
22 #endif
23
24 // For compilers that support precompilation, includes "wx.h".
25 #include "wx/wxprec.h"
26
27 #ifdef __BORLANDC__
28 #pragma hdrstop
29 #endif
30
31 #ifndef WX_PRECOMP
32 #include "wx/app.h"
33 #include "wx/toplevel.h"
34 #include "wx/string.h"
35 #include "wx/log.h"
36 #include "wx/intl.h"
37 #include "wx/frame.h"
38 #endif //WX_PRECOMP
39
40 #include "wx/x11/private.h"
41
42
43 bool wxMWMIsRunning(Window w);
44
45 // ----------------------------------------------------------------------------
46 // wxTopLevelWindowX11 creation
47 // ----------------------------------------------------------------------------
48
49 void wxTopLevelWindowX11::Init()
50 {
51 m_iconized =
52 m_maximizeOnShow = FALSE;
53
54 // unlike (almost?) all other windows, frames are created hidden
55 m_isShown = FALSE;
56
57 // Data to save/restore when calling ShowFullScreen
58 m_fsStyle = 0;
59 m_fsIsMaximized = FALSE;
60 m_fsIsShowing = FALSE;
61 }
62
63 bool wxTopLevelWindowX11::Create(wxWindow *parent,
64 wxWindowID id,
65 const wxString& title,
66 const wxPoint& pos,
67 const wxSize& size,
68 long style,
69 const wxString& name)
70 {
71 // init our fields
72 Init();
73
74 m_windowStyle = style;
75 m_parent = parent;
76
77 SetName(name);
78
79 m_windowId = id == -1 ? NewControlId() : id;
80
81 if (parent)
82 parent->AddChild(this);
83
84 wxTopLevelWindows.Append(this);
85
86 Display *xdisplay = wxGlobalDisplay();
87 int xscreen = DefaultScreen( xdisplay );
88 Visual *xvisual = DefaultVisual( xdisplay, xscreen );
89 Window xparent = RootWindow( xdisplay, xscreen );
90
91 XSetWindowAttributes xattributes;
92 XSizeHints size_hints;
93 XWMHints wm_hints;
94
95 long xattributes_mask =
96 CWOverrideRedirect |
97 CWBorderPixel | CWBackPixel;
98 xattributes.background_pixel = BlackPixel( xdisplay, xscreen );
99 xattributes.border_pixel = BlackPixel( xdisplay, xscreen );
100 xattributes.override_redirect = False;
101
102 Window xwindow = XCreateWindow( xdisplay, xparent, pos.x, pos.y, size.x, size.y,
103 0, DefaultDepth(xdisplay,xscreen), InputOutput, xvisual, xattributes_mask, &xattributes );
104 m_mainWidget = (WXWindow) xwindow;
105
106 XSelectInput( xdisplay, xwindow,
107 ExposureMask | KeyPressMask | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask |
108 ButtonMotionMask | EnterWindowMask | LeaveWindowMask | PointerMotionMask |
109 KeymapStateMask | FocusChangeMask | ColormapChangeMask | StructureNotifyMask |
110 PropertyChangeMask );
111
112 wxAddWindowToTable( xwindow, (wxWindow*) this );
113
114 XSetTransientForHint( xdisplay, xwindow, xparent );
115
116 size_hints.flags = PSize;
117 size_hints.width = size.x;
118 size_hints.height = size.y;
119 XSetWMNormalHints( xdisplay, xwindow, &size_hints);
120
121 wm_hints.flags = InputHint | StateHint /* | WindowGroupHint */;
122 wm_hints.input = True;
123 wm_hints.initial_state = NormalState;
124 XSetWMHints( xdisplay, xwindow, &wm_hints);
125
126 Atom wm_delete_window = XInternAtom( xdisplay, "WM_DELETE_WINDOW", False);
127 XSetWMProtocols( xdisplay, xwindow, &wm_delete_window, 1);
128
129 wxSetWMDecorations((Window) GetMainWindow(), style);
130
131 SetTitle(title);
132
133 return TRUE;
134 }
135
136 wxTopLevelWindowX11::~wxTopLevelWindowX11()
137 {
138 wxTopLevelWindows.DeleteObject(this);
139
140 // If this is the last top-level window, exit.
141 if ( wxTheApp && (wxTopLevelWindows.Number() == 0) )
142 {
143 wxTheApp->SetTopWindow(NULL);
144
145 if (wxTheApp->GetExitOnFrameDelete())
146 {
147 // Signal to the app that we're going to close
148 wxTheApp->ExitMainLoop();
149 }
150 }
151 }
152
153 // ----------------------------------------------------------------------------
154 // wxTopLevelWindowX11 showing
155 // ----------------------------------------------------------------------------
156
157 bool wxTopLevelWindowX11::Show(bool show)
158 {
159 return wxWindowX11::Show(show);
160 }
161
162 // ----------------------------------------------------------------------------
163 // wxTopLevelWindowX11 maximize/minimize
164 // ----------------------------------------------------------------------------
165
166 void wxTopLevelWindowX11::Maximize(bool maximize)
167 {
168 // TODO
169 }
170
171 bool wxTopLevelWindowX11::IsMaximized() const
172 {
173 // TODO
174 return TRUE;
175 }
176
177 void wxTopLevelWindowX11::Iconize(bool iconize)
178 {
179 if (!m_iconized && GetMainWindow())
180 {
181 if (XIconifyWindow(wxGlobalDisplay(),
182 (Window) GetMainWindow(), DefaultScreen(wxGlobalDisplay())) != 0)
183 m_iconized = TRUE;
184 }
185 }
186
187 bool wxTopLevelWindowX11::IsIconized() const
188 {
189 return m_iconized;
190 }
191
192 void wxTopLevelWindowX11::Restore()
193 {
194 // This is the way to deiconify the window, according to the X FAQ
195 if (m_iconized && GetMainWindow())
196 {
197 XMapWindow(wxGlobalDisplay(), (Window) GetMainWindow());
198 m_iconized = FALSE;
199 }
200 }
201
202 // ----------------------------------------------------------------------------
203 // wxTopLevelWindowX11 fullscreen
204 // ----------------------------------------------------------------------------
205
206 bool wxTopLevelWindowX11::ShowFullScreen(bool show, long style)
207 {
208 if (show)
209 {
210 if (IsFullScreen())
211 return FALSE;
212
213 m_fsIsShowing = TRUE;
214 m_fsStyle = style;
215
216 // TODO
217
218 return TRUE;
219 }
220 else
221 {
222 if (!IsFullScreen())
223 return FALSE;
224
225 m_fsIsShowing = FALSE;
226
227 // TODO
228 return TRUE;
229 }
230 }
231
232 // ----------------------------------------------------------------------------
233 // wxTopLevelWindowX11 misc
234 // ----------------------------------------------------------------------------
235
236 void wxTopLevelWindowX11::SetIcon(const wxIcon& icon)
237 {
238 // this sets m_icon
239 wxTopLevelWindowBase::SetIcon(icon);
240
241 if (icon.Ok() && GetMainWindow())
242 {
243 XWMHints *wmHints = XAllocWMHints();
244 wmHints->icon_pixmap = (Pixmap) icon.GetPixmap();
245
246 wmHints->flags = IconPixmapHint;
247
248 if (icon.GetMask())
249 {
250 wmHints->flags |= IconMaskHint;
251 wmHints->icon_mask = (Pixmap) icon.GetMask()->GetPixmap();
252 }
253
254 XSetWMHints(wxGlobalDisplay(), (Window) GetMainWindow(), wmHints);
255 XFree(wmHints);
256 }
257 }
258
259 void wxTopLevelWindowX11::SetTitle(const wxString& title)
260 {
261 m_title = title;
262 if (GetMainWindow())
263 {
264 XStoreName(wxGlobalDisplay(), (Window) GetMainWindow(),
265 (const char*) title);
266 XSetIconName(wxGlobalDisplay(), (Window) GetMainWindow(),
267 (const char*) title);
268
269 // Use this if the platform doesn't supply the above functions.
270 #if 0
271 XTextProperty textProperty;
272 textProperty.value = (unsigned char*) title;
273 textProperty.encoding = XA_STRING;
274 textProperty.format = 8;
275 textProperty.nitems = 1;
276
277 XSetTextProperty(wxGlobalDisplay(), (Window) GetMainWindow(),
278 & textProperty, WM_NAME);
279 #endif
280 }
281 }
282
283 wxString wxTopLevelWindowX11::GetTitle() const
284 {
285 return m_title;
286 }
287
288 #ifndef MWM_DECOR_BORDER
289 /* bit definitions for MwmHints.flags */
290 #define MWM_HINTS_FUNCTIONS (1L << 0)
291 #define MWM_HINTS_DECORATIONS (1L << 1)
292 #define MWM_HINTS_INPUT_MODE (1L << 2)
293 #define MWM_HINTS_STATUS (1L << 3)
294
295 #define MWM_DECOR_ALL (1L << 0)
296 #define MWM_DECOR_BORDER (1L << 1)
297 #define MWM_DECOR_RESIZEH (1L << 2)
298 #define MWM_DECOR_TITLE (1L << 3)
299 #define MWM_DECOR_MENU (1L << 4)
300 #define MWM_DECOR_MINIMIZE (1L << 5)
301 #define MWM_DECOR_MAXIMIZE (1L << 6)
302 #endif
303
304 struct MwmHints {
305 long flags;
306 long functions;
307 long decorations;
308 long input_mode;
309 };
310
311 #define PROP_MOTIF_WM_HINTS_ELEMENTS 5
312
313 // Set the window manager decorations according to the
314 // given wxWindows style
315 bool wxSetWMDecorations(Window w, long style)
316 {
317 if (!wxMWMIsRunning(w))
318 return FALSE;
319
320 Atom mwm_wm_hints = XInternAtom(wxGlobalDisplay(),"_MOTIF_WM_HINTS", False);
321 MwmHints hints;
322 hints.flags = 0;
323 hints.decorations = 0;
324
325 if (style & wxRESIZE_BORDER)
326 {
327 hints.flags |= MWM_HINTS_DECORATIONS;
328 hints.decorations |= MWM_DECOR_RESIZEH;
329 }
330
331 if (style & wxSYSTEM_MENU)
332 {
333 hints.flags |= MWM_HINTS_DECORATIONS;
334 hints.decorations |= MWM_DECOR_MENU;
335 }
336
337 if ((style & wxCAPTION) ||
338 (style & wxTINY_CAPTION_HORIZ) ||
339 (style & wxTINY_CAPTION_VERT))
340 {
341 hints.flags |= MWM_HINTS_DECORATIONS;
342 hints.decorations |= MWM_DECOR_TITLE;
343 }
344
345 if (style & wxTHICK_FRAME)
346 {
347 hints.flags |= MWM_HINTS_DECORATIONS;
348 hints.decorations |= MWM_DECOR_BORDER;
349 }
350
351 if (style & wxTHICK_FRAME)
352 {
353 hints.flags |= MWM_HINTS_DECORATIONS;
354 hints.decorations |= MWM_DECOR_BORDER;
355 }
356
357 if (style & wxMINIMIZE_BOX)
358 {
359 hints.flags |= MWM_HINTS_DECORATIONS;
360 hints.decorations |= MWM_DECOR_MINIMIZE;
361 }
362
363 if (style & wxMAXIMIZE_BOX)
364 {
365 hints.flags |= MWM_HINTS_DECORATIONS;
366 hints.decorations |= MWM_DECOR_MAXIMIZE;
367 }
368
369 XChangeProperty(wxGlobalDisplay(),
370 w,
371 mwm_wm_hints, mwm_wm_hints,
372 32, PropModeReplace,
373 (unsigned char *) &hints, PROP_MOTIF_WM_HINTS_ELEMENTS);
374
375 return TRUE;
376 }
377
378 bool wxMWMIsRunning(Window w)
379 {
380 Display *dpy = (Display*)wxGetDisplay();
381 Atom motifWmInfo = XInternAtom(dpy, "_MOTIF_WM_INFO", False);
382
383 unsigned long length, bytesafter;
384 unsigned char value[20];
385 unsigned char *ptr = &value[0];
386 int ret, format;
387 Atom type;
388
389 type = format = length = 0;
390 value[0] = 0;
391
392 ret = XGetWindowProperty(wxGlobalDisplay(), w, motifWmInfo,
393 0L, 2, False, motifWmInfo,
394 &type, &format, &length, &bytesafter, &ptr);
395
396 return (ret == Success);
397 }
398