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