Version 4.3.0.0.beta1, tag libreoffice-4.3.0.0.beta1
[LibreOffice.git] / vcl / unx / generic / window / FWS.cxx
bloba2dbdae3da16041c02d3458c2a27269d8427c0c3
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <stdio.h>
21 #include <stdlib.h>
22 #include <string.h>
23 #include <unistd.h>
25 #include <X11/Xlib.h>
26 #include <X11/Xutil.h>
27 #include <X11/Xatom.h>
28 #include "FWS.hxx"
30 static Atom fwsIconAtom;
32 static Atom FWS_CLIENT;
33 static Atom FWS_COMM_WINDOW;
34 static Atom FWS_PROTOCOLS;
35 static Atom FWS_STACK_UNDER;
36 static Atom FWS_PARK_ICONS;
37 static Atom FWS_PASS_ALL_INPUT;
38 static Atom FWS_PASSES_INPUT;
39 static Atom FWS_HANDLES_FOCUS;
41 static Atom FWS_REGISTER_WINDOW;
42 static Atom FWS_STATE_CHANGE;
43 static Atom FWS_UNSEEN_STATE;
44 static Atom FWS_NORMAL_STATE;
45 static Atom WM_PROTOCOLS;
46 static Atom WM_CHANGE_STATE;
48 static Bool fwsStackUnder;
49 static Bool fwsParkIcons;
50 static Bool fwsPassesInput;
51 static Bool fwsHandlesFocus;
53 static Window fwsCommWindow;
55 // Initialize our atoms and determine if the current window manager is
56 // providing FWS extension support.
57 Bool
58 WMSupportsFWS (Display *display, int screen)
60 unsigned int i;
61 Atom protocol;
62 Atom propType;
63 int propFormat;
64 unsigned long propItems;
65 unsigned long propBytesAfter;
66 unsigned char *propData;
67 char propName[64];
69 FWS_CLIENT = XInternAtom(display, "_SUN_FWS_CLIENT", False);
70 FWS_COMM_WINDOW = XInternAtom(display, "_SUN_FWS_COMM_WINDOW", False);
71 FWS_PROTOCOLS = XInternAtom(display, "_SUN_FWS_PROTOCOLS", False);
72 FWS_STACK_UNDER = XInternAtom(display, "_SUN_FWS_STACK_UNDER", False);
73 FWS_PARK_ICONS = XInternAtom(display, "_SUN_FWS_PARK_ICONS", False);
74 FWS_PASS_ALL_INPUT = XInternAtom(display, "_SUN_FWS_PASS_ALL_INPUT", False);
75 FWS_PASSES_INPUT = XInternAtom(display, "_SUN_FWS_PASSES_INPUT", False);
76 FWS_HANDLES_FOCUS = XInternAtom(display, "_SUN_FWS_HANDLES_FOCUS", False);
77 FWS_REGISTER_WINDOW= XInternAtom(display, "_SUN_FWS_REGISTER_WINDOW",False);
78 FWS_STATE_CHANGE = XInternAtom(display, "_SUN_FWS_STATE_CHANGE", False);
79 FWS_UNSEEN_STATE = XInternAtom(display, "_SUN_FWS_UNSEEN_STATE", False);
80 FWS_NORMAL_STATE = XInternAtom(display, "_SUN_FWS_NORMAL_STATE", False);
81 WM_PROTOCOLS = XInternAtom(display, "WM_PROTOCOLS", False);
82 WM_CHANGE_STATE = XInternAtom(display, "WM_CHANGE_STATE", False);
84 snprintf (propName, sizeof(propName), "_SUN_FWS_NEXT_ICON_%d", screen);
85 fwsIconAtom = XInternAtom(display, propName, False);
87 if (XGetWindowProperty (display, DefaultRootWindow (display),
88 FWS_COMM_WINDOW, 0, 1,
89 False, AnyPropertyType, &propType,
90 &propFormat, &propItems,
91 &propBytesAfter, &propData) != Success)
92 return False;
94 if (propFormat != 32 ||
95 propItems != 1 ||
96 propBytesAfter != 0)
98 #if OSL_DEBUG_LEVEL > 1
99 fprintf (stderr, "Bad FWS_COMM_WINDOW property on root window.\n");
100 #endif
101 XFree (propData);
102 return False;
105 fwsCommWindow = *(Window *) propData;
106 #if OSL_DEBUG_LEVEL > 1
107 fprintf (stderr, "Using fwsCommWindow = 0x%lx.\n", fwsCommWindow);
108 #endif
109 XFree (propData);
111 if (XGetWindowProperty (display, DefaultRootWindow (display),
112 FWS_PROTOCOLS, 0, 10,
113 False, AnyPropertyType, &propType,
114 &propFormat, &propItems,
115 &propBytesAfter, &propData) != Success)
117 return False;
120 if (propFormat != 32 ||
121 propBytesAfter != 0)
123 #if OSL_DEBUG_LEVEL > 1
124 fprintf (stderr, "Bad FWS_PROTOCOLS property on root window.\n");
125 #endif
126 XFree (propData);
127 return False;
130 for (i = 0; i < propItems; ++i)
132 protocol = ((Atom *) propData)[i];
133 if (protocol == FWS_STACK_UNDER)
135 fwsStackUnder = True;
136 #if OSL_DEBUG_LEVEL > 1
137 fprintf (stderr, "Using fwsStackUnder.\n");
138 #endif
140 else
141 if (protocol == FWS_PARK_ICONS)
143 fwsParkIcons = True;
144 #if OSL_DEBUG_LEVEL > 1
145 fprintf (stderr, "Using fwsParkIcons.\n");
146 #endif
148 else
149 if (protocol == FWS_PASSES_INPUT)
151 fwsPassesInput = True;
152 #if OSL_DEBUG_LEVEL > 1
153 fprintf (stderr, "Using fwsPassesInput.\n");
154 #endif
156 else
157 if (protocol == FWS_HANDLES_FOCUS)
159 fwsHandlesFocus = True;
160 #if OSL_DEBUG_LEVEL > 1
161 fprintf (stderr, "Using fwsHandlesFocus.\n");
162 #endif
166 XFree (propData);
167 return True;
170 // Handle X errors (temporarily) to record the occurrence of BadWindow
171 // errors without crashing. Used to detect the FWS_COMM_WINDOW root window
172 // property containing an old or obsolete window id.
173 extern "C" {
175 static Bool badWindowFound;
176 static int (* oldHandler) (Display *, XErrorEvent *);
178 static int
179 newHandler (Display *display, XErrorEvent *xerror)
181 if (xerror->error_code != BadWindow)
182 (*oldHandler)(display, xerror);
183 else
184 badWindowFound = True;
186 return 0;
191 // Send a client message to the FWS_COMM_WINDOW indicating the existence
192 // of a new FWS client window. Be careful to avoid BadWindow errors on
193 // the XSendEvent in case the FWS_COMM_WINDOW root window property had
194 // old/obsolete junk in it.
195 Bool
196 RegisterFwsWindow (Display *display, Window window)
198 XClientMessageEvent msg;
200 msg.type = ClientMessage;
201 msg.window = fwsCommWindow;
202 msg.message_type = FWS_REGISTER_WINDOW;
203 msg.format = 32;
204 msg.data.l[0] = window;
206 XSync (display, False);
207 badWindowFound = False;
208 oldHandler = XSetErrorHandler (newHandler);
210 XSendEvent (display, fwsCommWindow, False, NoEventMask,
211 (XEvent *) &msg);
212 XSync (display, False);
214 XSetErrorHandler (oldHandler);
215 #if OSL_DEBUG_LEVEL > 1
216 if (badWindowFound)
217 fprintf (stderr, "No FWS client window to register with.\n");
218 #endif
220 return !badWindowFound;
223 // Add the FWS protocol atoms to the WMProtocols property for the window.
224 void
225 AddFwsProtocols (Display *display, Window window)
227 #define MAX_FWS_PROTOS 10
229 Atom fwsProtocols[ MAX_FWS_PROTOS ];
230 int nProtos = 0;
232 fwsProtocols[ nProtos++ ] = FWS_CLIENT;
233 fwsProtocols[ nProtos++ ] = FWS_STACK_UNDER;
234 fwsProtocols[ nProtos++ ] = FWS_STATE_CHANGE;
235 fwsProtocols[ nProtos++ ] = FWS_PASS_ALL_INPUT;
236 XChangeProperty (display, window, WM_PROTOCOLS,
237 XA_ATOM, 32, PropModeAppend,
238 (unsigned char *) fwsProtocols, nProtos);
241 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */