Linking now
[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 if ( !wxWindowBase::Show(show) )
160 return FALSE;
161
162 return wxWindowX11::Show(show);
163 }
164
165 // ----------------------------------------------------------------------------
166 // wxTopLevelWindowX11 maximize/minimize
167 // ----------------------------------------------------------------------------
168
169 void wxTopLevelWindowX11::Maximize(bool maximize)
170 {
171 // TODO
172 }
173
174 bool wxTopLevelWindowX11::IsMaximized() const
175 {
176 // TODO
177 return TRUE;
178 }
179
180 void wxTopLevelWindowX11::Iconize(bool iconize)
181 {
182 if (!m_iconized && GetMainWindow())
183 {
184 if (XIconifyWindow(wxGlobalDisplay(),
185 (Window) GetMainWindow(), DefaultScreen(wxGlobalDisplay())) != 0)
186 m_iconized = TRUE;
187 }
188 }
189
190 bool wxTopLevelWindowX11::IsIconized() const
191 {
192 return m_iconized;
193 }
194
195 void wxTopLevelWindowX11::Restore()
196 {
197 // This is the way to deiconify the window, according to the X FAQ
198 if (m_iconized && GetMainWindow())
199 {
200 XMapWindow(wxGlobalDisplay(), (Window) GetMainWindow());
201 m_iconized = FALSE;
202 }
203 }
204
205 // ----------------------------------------------------------------------------
206 // wxTopLevelWindowX11 fullscreen
207 // ----------------------------------------------------------------------------
208
209 bool wxTopLevelWindowX11::ShowFullScreen(bool show, long style)
210 {
211 if (show)
212 {
213 if (IsFullScreen())
214 return FALSE;
215
216 m_fsIsShowing = TRUE;
217 m_fsStyle = style;
218
219 // TODO
220
221 return TRUE;
222 }
223 else
224 {
225 if (!IsFullScreen())
226 return FALSE;
227
228 m_fsIsShowing = FALSE;
229
230 // TODO
231 return TRUE;
232 }
233 }
234
235 // ----------------------------------------------------------------------------
236 // wxTopLevelWindowX11 misc
237 // ----------------------------------------------------------------------------
238
239 void wxTopLevelWindowX11::SetIcon(const wxIcon& icon)
240 {
241 // this sets m_icon
242 wxTopLevelWindowBase::SetIcon(icon);
243
244 if (icon.Ok() && GetMainWindow())
245 {
246 XWMHints *wmHints = XAllocWMHints();
247 wmHints->icon_pixmap = (Pixmap) icon.GetPixmap();
248
249 wmHints->flags = IconPixmapHint;
250
251 if (icon.GetMask())
252 {
253 wmHints->flags |= IconMaskHint;
254 wmHints->icon_mask = (Pixmap) icon.GetMask()->GetPixmap();
255 }
256
257 XSetWMHints(wxGlobalDisplay(), (Window) GetMainWindow(), wmHints);
258 XFree(wmHints);
259 }
260 }
261
262 void wxTopLevelWindowX11::SetTitle(const wxString& title)
263 {
264 m_title = title;
265 if (GetMainWindow())
266 {
267 XStoreName(wxGlobalDisplay(), (Window) GetMainWindow(),
268 (const char*) title);
269 XSetIconName(wxGlobalDisplay(), (Window) GetMainWindow(),
270 (const char*) title);
271
272 // Use this if the platform doesn't supply the above functions.
273 #if 0
274 XTextProperty textProperty;
275 textProperty.value = (unsigned char*) title;
276 textProperty.encoding = XA_STRING;
277 textProperty.format = 8;
278 textProperty.nitems = 1;
279
280 XSetTextProperty(wxGlobalDisplay(), (Window) GetMainWindow(),
281 & textProperty, WM_NAME);
282 #endif
283 }
284 }
285
286 wxString wxTopLevelWindowX11::GetTitle() const
287 {
288 return m_title;
289 }
290
291 #ifndef MWM_DECOR_BORDER
292 /* bit definitions for MwmHints.flags */
293 #define MWM_HINTS_FUNCTIONS (1L << 0)
294 #define MWM_HINTS_DECORATIONS (1L << 1)
295 #define MWM_HINTS_INPUT_MODE (1L << 2)
296 #define MWM_HINTS_STATUS (1L << 3)
297
298 #define MWM_DECOR_ALL (1L << 0)
299 #define MWM_DECOR_BORDER (1L << 1)
300 #define MWM_DECOR_RESIZEH (1L << 2)
301 #define MWM_DECOR_TITLE (1L << 3)
302 #define MWM_DECOR_MENU (1L << 4)
303 #define MWM_DECOR_MINIMIZE (1L << 5)
304 #define MWM_DECOR_MAXIMIZE (1L << 6)
305 #endif
306
307 struct MwmHints {
308 long flags;
309 long functions;
310 long decorations;
311 long input_mode;
312 };
313
314 #define PROP_MOTIF_WM_HINTS_ELEMENTS 5
315
316 // Set the window manager decorations according to the
317 // given wxWindows style
318 bool wxSetWMDecorations(Window w, long style)
319 {
320 if (!wxMWMIsRunning(w))
321 return FALSE;
322
323 Atom mwm_wm_hints = XInternAtom(wxGlobalDisplay(),"_MOTIF_WM_HINTS", False);
324 MwmHints hints;
325 hints.flags = 0;
326 hints.decorations = 0;
327
328 if (style & wxRESIZE_BORDER)
329 {
330 hints.flags |= MWM_HINTS_DECORATIONS;
331 hints.decorations |= MWM_DECOR_RESIZEH;
332 }
333
334 if (style & wxSYSTEM_MENU)
335 {
336 hints.flags |= MWM_HINTS_DECORATIONS;
337 hints.decorations |= MWM_DECOR_MENU;
338 }
339
340 if ((style & wxCAPTION) ||
341 (style & wxTINY_CAPTION_HORIZ) ||
342 (style & wxTINY_CAPTION_VERT))
343 {
344 hints.flags |= MWM_HINTS_DECORATIONS;
345 hints.decorations |= MWM_DECOR_TITLE;
346 }
347
348 if (style & wxTHICK_FRAME)
349 {
350 hints.flags |= MWM_HINTS_DECORATIONS;
351 hints.decorations |= MWM_DECOR_BORDER;
352 }
353
354 if (style & wxTHICK_FRAME)
355 {
356 hints.flags |= MWM_HINTS_DECORATIONS;
357 hints.decorations |= MWM_DECOR_BORDER;
358 }
359
360 if (style & wxMINIMIZE_BOX)
361 {
362 hints.flags |= MWM_HINTS_DECORATIONS;
363 hints.decorations |= MWM_DECOR_MINIMIZE;
364 }
365
366 if (style & wxMAXIMIZE_BOX)
367 {
368 hints.flags |= MWM_HINTS_DECORATIONS;
369 hints.decorations |= MWM_DECOR_MAXIMIZE;
370 }
371
372 XChangeProperty(wxGlobalDisplay(),
373 w,
374 mwm_wm_hints, mwm_wm_hints,
375 32, PropModeReplace,
376 (unsigned char *) &hints, PROP_MOTIF_WM_HINTS_ELEMENTS);
377
378 return TRUE;
379 }
380
381 bool wxMWMIsRunning(Window w)
382 {
383 Display *dpy = (Display*)wxGetDisplay();
384 Atom motifWmInfo = XInternAtom(dpy, "_MOTIF_WM_INFO", False);
385
386 unsigned long length, bytesafter;
387 unsigned char value[20];
388 unsigned char *ptr = &value[0];
389 int ret, format;
390 Atom type;
391
392 type = format = length = 0;
393 value[0] = 0;
394
395 ret = XGetWindowProperty(wxGlobalDisplay(), w, motifWmInfo,
396 0L, 2, False, motifWmInfo,
397 &type, &format, &length, &bytesafter, &ptr);
398
399 return (ret == Success);
400 }
401