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