1 /************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2000, 2010 Oracle and/or its affiliates. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * This file is part of OpenOffice.org. 10 * 11 * OpenOffice.org is free software: you can redistribute it and/or modify 12 * it under the terms of the GNU Lesser General Public License version 3 13 * only, as published by the Free Software Foundation. 14 * 15 * OpenOffice.org is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU Lesser General Public License version 3 for more details 19 * (a copy is included in the LICENSE file that accompanied this code). 20 * 21 * You should have received a copy of the GNU Lesser General Public License 22 * version 3 along with OpenOffice.org. If not, see 23 * <http://www.openoffice.org/license.html> 24 * for a copy of the LGPLv3 License. 25 * 26 ************************************************************************/ 27 28 // MARKER(update_precomp.py): autogen include statement, do not remove 29 #include "precompiled_vcl.hxx" 30 31 #include <stdio.h> 32 #include <stdlib.h> 33 #include <string.h> 34 #include <unistd.h> 35 36 #include <X11/Xlib.h> 37 #include <X11/Xutil.h> 38 #include <X11/Xatom.h> 39 #include "FWS.hxx" 40 41 static Atom fwsIconAtom; 42 43 static Atom FWS_CLIENT; 44 static Atom FWS_COMM_WINDOW; 45 static Atom FWS_PROTOCOLS; 46 static Atom FWS_STACK_UNDER; 47 static Atom FWS_PARK_ICONS; 48 static Atom FWS_PASS_ALL_INPUT; 49 static Atom FWS_PASSES_INPUT; 50 static Atom FWS_HANDLES_FOCUS; 51 52 static Atom FWS_REGISTER_WINDOW; 53 static Atom FWS_STATE_CHANGE; 54 static Atom FWS_UNSEEN_STATE; 55 static Atom FWS_NORMAL_STATE; 56 static Atom WM_PROTOCOLS; 57 static Atom WM_CHANGE_STATE; 58 59 static Bool fwsStackUnder; 60 static Bool fwsParkIcons; 61 static Bool fwsPassesInput; 62 static Bool fwsHandlesFocus; 63 64 static Window fwsCommWindow; 65 66 /*************************************<->*********************************** 67 * 68 * WMSupportsFWS() - 69 * 70 * Initialize our atoms and determine if the current window manager is 71 * providing FWS extension support. 72 * 73 *************************************<->***********************************/ 74 75 Bool 76 WMSupportsFWS (Display *display, int screen) 77 { 78 unsigned int i; 79 Atom protocol; 80 Atom propType; 81 int propFormat; 82 unsigned long propItems; 83 unsigned long propBytesAfter; 84 unsigned char *propData; 85 char propName[64]; 86 87 FWS_CLIENT = XInternAtom(display, "_SUN_FWS_CLIENT", False); 88 FWS_COMM_WINDOW = XInternAtom(display, "_SUN_FWS_COMM_WINDOW", False); 89 FWS_PROTOCOLS = XInternAtom(display, "_SUN_FWS_PROTOCOLS", False); 90 FWS_STACK_UNDER = XInternAtom(display, "_SUN_FWS_STACK_UNDER", False); 91 FWS_PARK_ICONS = XInternAtom(display, "_SUN_FWS_PARK_ICONS", False); 92 FWS_PASS_ALL_INPUT = XInternAtom(display, "_SUN_FWS_PASS_ALL_INPUT", False); 93 FWS_PASSES_INPUT = XInternAtom(display, "_SUN_FWS_PASSES_INPUT", False); 94 FWS_HANDLES_FOCUS = XInternAtom(display, "_SUN_FWS_HANDLES_FOCUS", False); 95 FWS_REGISTER_WINDOW= XInternAtom(display, "_SUN_FWS_REGISTER_WINDOW",False); 96 FWS_STATE_CHANGE = XInternAtom(display, "_SUN_FWS_STATE_CHANGE", False); 97 FWS_UNSEEN_STATE = XInternAtom(display, "_SUN_FWS_UNSEEN_STATE", False); 98 FWS_NORMAL_STATE = XInternAtom(display, "_SUN_FWS_NORMAL_STATE", False); 99 WM_PROTOCOLS = XInternAtom(display, "WM_PROTOCOLS", False); 100 WM_CHANGE_STATE = XInternAtom(display, "WM_CHANGE_STATE", False); 101 102 snprintf (propName, sizeof(propName), "_SUN_FWS_NEXT_ICON_%d", screen); 103 fwsIconAtom = XInternAtom(display, propName, False); 104 105 if (XGetWindowProperty (display, DefaultRootWindow (display), 106 FWS_COMM_WINDOW, 0, 1, 107 False, AnyPropertyType, &propType, 108 &propFormat, &propItems, 109 &propBytesAfter, &propData) != Success) 110 return False; 111 112 if (propFormat != 32 || 113 propItems != 1 || 114 propBytesAfter != 0) 115 { 116 #if OSL_DEBUG_LEVEL > 1 117 fprintf (stderr, "Bad FWS_COMM_WINDOW property on root window.\n"); 118 #endif 119 XFree (propData); 120 return False; 121 } 122 123 fwsCommWindow = *(Window *) propData; 124 #if OSL_DEBUG_LEVEL > 1 125 fprintf (stderr, "Using fwsCommWindow = 0x%lx.\n", fwsCommWindow); 126 #endif 127 XFree (propData); 128 129 130 if (XGetWindowProperty (display, DefaultRootWindow (display), 131 FWS_PROTOCOLS, 0, 10, 132 False, AnyPropertyType, &propType, 133 &propFormat, &propItems, 134 &propBytesAfter, &propData) != Success) 135 { 136 return False; 137 } 138 139 if (propFormat != 32 || 140 propBytesAfter != 0) 141 { 142 #if OSL_DEBUG_LEVEL > 1 143 fprintf (stderr, "Bad FWS_PROTOCOLS property on root window.\n"); 144 #endif 145 XFree (propData); 146 return False; 147 } 148 149 for (i = 0; i < propItems; ++i) 150 { 151 protocol = ((Atom *) propData)[i]; 152 if (protocol == FWS_STACK_UNDER) 153 { 154 fwsStackUnder = True; 155 #if OSL_DEBUG_LEVEL > 1 156 fprintf (stderr, "Using fwsStackUnder.\n"); 157 #endif 158 } 159 else 160 if (protocol == FWS_PARK_ICONS) 161 { 162 fwsParkIcons = True; 163 #if OSL_DEBUG_LEVEL > 1 164 fprintf (stderr, "Using fwsParkIcons.\n"); 165 #endif 166 } 167 else 168 if (protocol == FWS_PASSES_INPUT) 169 { 170 fwsPassesInput = True; 171 #if OSL_DEBUG_LEVEL > 1 172 fprintf (stderr, "Using fwsPassesInput.\n"); 173 #endif 174 } 175 else 176 if (protocol == FWS_HANDLES_FOCUS) 177 { 178 fwsHandlesFocus = True; 179 #if OSL_DEBUG_LEVEL > 1 180 fprintf (stderr, "Using fwsHandlesFocus.\n"); 181 #endif 182 } 183 } 184 185 XFree (propData); 186 return True; 187 } 188 189 /*************************************<->*********************************** 190 * 191 * newHandler() - 192 * 193 * Handle X errors (temporarily) to record the occurance of BadWindow 194 * errors without crashing. Used to detect the FWS_COMM_WINDOW root window 195 * property containing an old or obsolete window id. 196 * 197 *************************************<->***********************************/ 198 199 extern "C" { 200 201 static Bool badWindowFound; 202 static int (* oldHandler) (Display *, XErrorEvent *); 203 204 static int 205 newHandler (Display *display, XErrorEvent *xerror) 206 { 207 if (xerror->error_code != BadWindow) 208 (*oldHandler)(display, xerror); 209 else 210 badWindowFound = True; 211 212 return 0; 213 } 214 215 } 216 217 /*************************************<->*********************************** 218 * 219 * RegisterFwsWindow() - 220 * 221 * Send a client message to the FWS_COMM_WINDOW indicating the existance 222 * of a new FWS client window. Be careful to avoid BadWindow errors on 223 * the XSendEvent in case the FWS_COMM_WINDOW root window property had 224 * old/obsolete junk in it. 225 * 226 *************************************<->***********************************/ 227 228 Bool 229 RegisterFwsWindow (Display *display, Window window) 230 { 231 XClientMessageEvent msg; 232 233 msg.type = ClientMessage; 234 msg.window = fwsCommWindow; 235 msg.message_type = FWS_REGISTER_WINDOW; 236 msg.format = 32; 237 msg.data.l[0] = window; 238 239 XSync (display, False); 240 badWindowFound = False; 241 oldHandler = XSetErrorHandler (newHandler); 242 243 XSendEvent (display, fwsCommWindow, False, NoEventMask, 244 (XEvent *) &msg); 245 XSync (display, False); 246 247 XSetErrorHandler (oldHandler); 248 #if OSL_DEBUG_LEVEL > 1 249 if (badWindowFound) 250 fprintf (stderr, "No FWS client window to register with.\n"); 251 #endif 252 253 return !badWindowFound; 254 } 255 256 /*************************************<->*********************************** 257 * 258 * AddFwsProtocols - 259 * 260 * Add the FWS protocol atoms to the WMProtocols property for the window. 261 * 262 *************************************<->***********************************/ 263 264 void 265 AddFwsProtocols (Display *display, Window window) 266 { 267 #define MAX_FWS_PROTOS 10 268 269 Atom fwsProtocols[ MAX_FWS_PROTOS ]; 270 int nProtos = 0; 271 272 fwsProtocols[ nProtos++ ] = FWS_CLIENT; 273 fwsProtocols[ nProtos++ ] = FWS_STACK_UNDER; 274 fwsProtocols[ nProtos++ ] = FWS_STATE_CHANGE; 275 fwsProtocols[ nProtos++ ] = FWS_PASS_ALL_INPUT; 276 XChangeProperty (display, window, WM_PROTOCOLS, 277 XA_ATOM, 32, PropModeAppend, 278 (unsigned char *) fwsProtocols, nProtos); 279 } 280 281