More X11 code
[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 #include "X11/Xatom.h"
42 #include "X11/Xutil.h"
43
44 // Set the window manager decorations according to the
45 // given wxWindows style
46 static bool SetWMDecorations(Widget w, long style);
47 static bool MWMIsRunning(Window w);
48
49
50 // ----------------------------------------------------------------------------
51 // globals
52 // ----------------------------------------------------------------------------
53
54 // list of all frames and modeless dialogs
55 // wxWindowList wxModelessWindows;
56
57 // ----------------------------------------------------------------------------
58 // wxTopLevelWindowX11 creation
59 // ----------------------------------------------------------------------------
60
61 void wxTopLevelWindowX11::Init()
62 {
63 m_iconized =
64 m_maximizeOnShow = FALSE;
65
66 // unlike (almost?) all other windows, frames are created hidden
67 m_isShown = FALSE;
68
69 // Data to save/restore when calling ShowFullScreen
70 m_fsStyle = 0;
71 m_fsIsMaximized = FALSE;
72 m_fsIsShowing = FALSE;
73 }
74
75 bool wxTopLevelWindowX11::CreateDialog(const wxString& title,
76 const wxPoint& pos,
77 const wxSize& size)
78 {
79 // TODO
80 return FALSE;
81 }
82
83 bool wxTopLevelWindowX11::CreateFrame(const wxString& title,
84 const wxPoint& pos,
85 const wxSize& size)
86 {
87 // TODO
88 return FALSE;
89 }
90
91 bool wxTopLevelWindowX11::Create(wxWindow *parent,
92 wxWindowID id,
93 const wxString& title,
94 const wxPoint& pos,
95 const wxSize& size,
96 long style,
97 const wxString& name)
98 {
99 // init our fields
100 Init();
101
102 m_windowStyle = style;
103
104 SetName(name);
105
106 m_windowId = id == -1 ? NewControlId() : id;
107
108 wxTopLevelWindows.Append(this);
109
110 Atom wm_delete_window = XInternAtom(wxGlobalDisplay(), "WM_DELETE_WINDOW", False);
111
112 XSetWMProtocols(wxGlobalDisplay(), (Window) GetMainWindow(), &wm_delete_window, 1);
113 SetWMDecorations((Window) GetMainWindow(), style);
114
115 SetTitle(title);
116
117 if ( GetExtraStyle() & wxTOPLEVEL_EX_DIALOG )
118 {
119 return CreateDialog(title, pos, size);
120 }
121 else // !dialog
122 {
123 return CreateFrame(title, pos, size);
124 }
125 }
126
127 wxTopLevelWindowX11::~wxTopLevelWindowX11()
128 {
129 wxTopLevelWindows.DeleteObject(this);
130
131 if ( wxModelessWindows.Find(this) )
132 wxModelessWindows.DeleteObject(this);
133
134 // If this is the last top-level window, exit.
135 if ( wxTheApp && (wxTopLevelWindows.Number() == 0) )
136 {
137 wxTheApp->SetTopWindow(NULL);
138
139 if (wxTheApp->GetExitOnFrameDelete())
140 {
141 // Signal to the app that we're going to close
142 wxTheApp->ExitMainLoop();
143 }
144 }
145 }
146
147 // ----------------------------------------------------------------------------
148 // wxTopLevelWindowX11 showing
149 // ----------------------------------------------------------------------------
150
151 bool wxTopLevelWindowX11::Show(bool show)
152 {
153 if ( !wxWindowBase::Show(show) )
154 return FALSE;
155
156 return wxWindowX11::Show(show);
157 }
158
159 // ----------------------------------------------------------------------------
160 // wxTopLevelWindowX11 maximize/minimize
161 // ----------------------------------------------------------------------------
162
163 void wxTopLevelWindowX11::Maximize(bool maximize)
164 {
165 // TODO
166 }
167
168 bool wxTopLevelWindowX11::IsMaximized() const
169 {
170 // TODO
171 return TRUE;
172 }
173
174 void wxTopLevelWindowX11::Iconize(bool iconize)
175 {
176 if (!m_iconized && GetMainWindow())
177 {
178 if (XIconifyWindow(wxGlobalDisplay(),
179 (Window) GetMainWindow(), DefaultScreen(wxGlobalDisplay())) != 0)
180 m_iconized = TRUE;
181 }
182 }
183
184 bool wxTopLevelWindowX11::IsIconized() const
185 {
186 return m_iconized;
187 }
188
189 void wxTopLevelWindowX11::Restore()
190 {
191 // This is the way to deiconify the window, according to the X FAQ
192 if (m_iconized && GetMainWindow())
193 {
194 XMapWindow(wxGlobalDisplay(), (Window) GetMainWindow());
195 m_iconized = FALSE;
196 }
197 }
198
199 // ----------------------------------------------------------------------------
200 // wxTopLevelWindowX11 fullscreen
201 // ----------------------------------------------------------------------------
202
203 bool wxTopLevelWindowX11::ShowFullScreen(bool show, long style)
204 {
205 if (show)
206 {
207 if (IsFullScreen())
208 return FALSE;
209
210 m_fsIsShowing = TRUE;
211 m_fsStyle = style;
212
213 // TODO
214
215 return TRUE;
216 }
217 else
218 {
219 if (!IsFullScreen())
220 return FALSE;
221
222 m_fsIsShowing = FALSE;
223
224 // TODO
225 return TRUE;
226 }
227 }
228
229 // ----------------------------------------------------------------------------
230 // wxTopLevelWindowX11 misc
231 // ----------------------------------------------------------------------------
232
233 void wxTopLevelWindowX11::SetIcon(const wxIcon& icon)
234 {
235 // this sets m_icon
236 wxTopLevelWindowBase::SetIcon(icon);
237
238 if (icon.Ok() && GetMainWindow())
239 {
240 XWMHints *wmHints = XAllocWMHints();
241 wmHints.icon_pixmap = (Pixmap) icon.GetPixmap();
242
243 wmHints.flags = IconPixmapHint;
244
245 if (icon.GetMask())
246 {
247 wmHints.flags |= IconMaskHint;
248 wmHints.icon_mask = (Pixmap) icon.GetMask()->GetPixmap();
249 }
250
251 XSetWMHints(wxGlobalDisplay(), (Window) GetMainWindow(),
252 wmHints);
253 XFree(wmHints);
254 }
255 }
256
257 void wxTopLevelWindowX11::SetTitle(const wxString& title)
258 {
259 m_title = title;
260 if (GetMainWindow())
261 {
262 XStoreName(wxGlobalDisplay(), (Window) GetMainWindow(),
263 (const char*) title);
264 XSetIconName(wxGlobalDisplay(), (Window) GetMainWindow(),
265 (const char*) title);
266 #if 0
267 XTextProperty textProperty;
268 textProperty.value = (unsigned char*) title;
269 textProperty.encoding = XA_STRING;
270 textProperty.format = 8;
271 textProperty.nitems = 1;
272
273 XSetTextProperty(wxGlobalDisplay(), (Window) GetMainWindow(),
274 & textProperty, WM_NAME);
275 #endif
276 }
277 }
278
279 wxString wxTopLevelWindowX11::GetTitle() const
280 {
281 return m_title;
282 }
283
284 #ifndef MWM_DECOR_BORDER
285 /* bit definitions for MwmHints.flags */
286 #define MWM_HINTS_FUNCTIONS (1L << 0)
287 #define MWM_HINTS_DECORATIONS (1L << 1)
288 #define MWM_HINTS_INPUT_MODE (1L << 2)
289 #define MWM_HINTS_STATUS (1L << 3)
290
291 #define MWM_DECOR_ALL (1L << 0)
292 #define MWM_DECOR_BORDER (1L << 1)
293 #define MWM_DECOR_RESIZEH (1L << 2)
294 #define MWM_DECOR_TITLE (1L << 3)
295 #define MWM_DECOR_MENU (1L << 4)
296 #define MWM_DECOR_MINIMIZE (1L << 5)
297 #define MWM_DECOR_MAXIMIZE (1L << 6)
298 #endif
299
300 struct MwmHints {
301 long flags;
302 long functions;
303 long decorations;
304 long input_mode;
305 };
306
307 #define PROP_MOTIF_WM_HINTS_ELEMENTS 5
308
309 // Set the window manager decorations according to the
310 // given wxWindows style
311 static bool SetWMDecorations(Widget w, long style)
312 {
313 if (!MWMIsRunning(w))
314 return FALSE;
315
316 Atom mwm_wm_hints = XInternAtom(wxGlobalDisplay(),"_MOTIF_WM_HINTS", False);
317 MwmHints hints;
318 hints.flags = 0;
319 hints.decorations = 0;
320
321 if (style & wxRESIZE_BORDER)
322 {
323 hints.flags |= MWM_HINTS_DECORATIONS;
324 hints.decorations |= MWM_DECOR_RESIZEH;
325 }
326
327 if (style & wxSYSTEM_MENU)
328 {
329 hints.flags |= MWM_HINTS_DECORATIONS;
330 hints.decorations |= MWM_DECOR_MENU;
331 }
332
333 if ((style & wxCAPTION) ||
334 (style & wxTINY_CAPTION_HORIZ) ||
335 (style & wxTINY_CAPTION_VERT))
336 {
337 hints.flags |= MWM_HINTS_DECORATIONS;
338 hints.decorations |= MWM_DECOR_TITLE;
339 }
340
341 if (style & wxTHICK_FRAME)
342 {
343 hints.flags |= MWM_HINTS_DECORATIONS;
344 hints.decorations |= MWM_DECOR_BORDER;
345 }
346
347 if (style & wxTHICK_FRAME)
348 {
349 hints.flags |= MWM_HINTS_DECORATIONS;
350 hints.decorations |= MWM_DECOR_BORDER;
351 }
352
353 if (style & wxMINIMIZE_BOX)
354 {
355 hints.flags |= MWM_HINTS_DECORATIONS;
356 hints.decorations |= MWM_DECOR_MINIMIZE;
357 }
358
359 if (style & wxMAXIMIZE_BOX)
360 {
361 hints.flags |= MWM_HINTS_DECORATIONS;
362 hints.decorations |= MWM_DECOR_MAXIMIZE;
363 }
364
365 XChangeProperty(wxGlobalDisplay(),
366 w,
367 mwm_wm_hints, mem_wm_hints,
368 32, PropModeReplace,
369 (unsigned char *) &hints, PROP_MOTIF_WM_HINTS_ELEMENTS);
370
371 return TRUE;
372 }
373
374 static bool MWMIsRunning(Window w)
375 {
376 Atom motifWmInfo = XInternAtom(dpy, "_MOTIF_WM_INFO", False);
377
378 unsigned long length, bytesafter;
379 unsigned char value[20];
380 int ret, type, format;
381
382 type = format = length = 0;
383 value = 0;
384
385 ret = XGetWindowProperty(wxGlobalDisplay(), w, motifWmInfo,
386 0L, 2, False, motifWmInfo,
387 &type, &format, &length, &bytesafter, &value);
388
389 return (ret == Success);
390 }
391