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