1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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 .
26 #include <X11/Xutil.h>
27 #include <X11/Xatom.h>
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.
58 WMSupportsFWS (Display
*display
, int screen
)
64 unsigned long propItems
;
65 unsigned long propBytesAfter
;
66 unsigned char *propData
;
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
)
94 if (propFormat
!= 32 ||
98 #if OSL_DEBUG_LEVEL > 1
99 fprintf (stderr
, "Bad FWS_COMM_WINDOW property on root window.\n");
105 fwsCommWindow
= *(Window
*) propData
;
106 #if OSL_DEBUG_LEVEL > 1
107 fprintf (stderr
, "Using fwsCommWindow = 0x%lx.\n", fwsCommWindow
);
111 if (XGetWindowProperty (display
, DefaultRootWindow (display
),
112 FWS_PROTOCOLS
, 0, 10,
113 False
, AnyPropertyType
, &propType
,
114 &propFormat
, &propItems
,
115 &propBytesAfter
, &propData
) != Success
)
120 if (propFormat
!= 32 ||
123 #if OSL_DEBUG_LEVEL > 1
124 fprintf (stderr
, "Bad FWS_PROTOCOLS property on root window.\n");
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");
141 if (protocol
== FWS_PARK_ICONS
)
144 #if OSL_DEBUG_LEVEL > 1
145 fprintf (stderr
, "Using fwsParkIcons.\n");
149 if (protocol
== FWS_PASSES_INPUT
)
151 fwsPassesInput
= True
;
152 #if OSL_DEBUG_LEVEL > 1
153 fprintf (stderr
, "Using fwsPassesInput.\n");
157 if (protocol
== FWS_HANDLES_FOCUS
)
159 fwsHandlesFocus
= True
;
160 #if OSL_DEBUG_LEVEL > 1
161 fprintf (stderr
, "Using fwsHandlesFocus.\n");
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.
175 static Bool badWindowFound
;
176 static int (* oldHandler
) (Display
*, XErrorEvent
*);
179 newHandler (Display
*display
, XErrorEvent
*xerror
)
181 if (xerror
->error_code
!= BadWindow
)
182 (*oldHandler
)(display
, xerror
);
184 badWindowFound
= True
;
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.
196 RegisterFwsWindow (Display
*display
, Window window
)
198 XClientMessageEvent msg
;
200 msg
.type
= ClientMessage
;
201 msg
.window
= fwsCommWindow
;
202 msg
.message_type
= FWS_REGISTER_WINDOW
;
204 msg
.data
.l
[0] = window
;
206 XSync (display
, False
);
207 badWindowFound
= False
;
208 oldHandler
= XSetErrorHandler (newHandler
);
210 XSendEvent (display
, fwsCommWindow
, False
, NoEventMask
,
212 XSync (display
, False
);
214 XSetErrorHandler (oldHandler
);
215 #if OSL_DEBUG_LEVEL > 1
217 fprintf (stderr
, "No FWS client window to register with.\n");
220 return !badWindowFound
;
223 // Add the FWS protocol atoms to the WMProtocols property for the window.
225 AddFwsProtocols (Display
*display
, Window window
)
227 #define MAX_FWS_PROTOS 10
229 Atom fwsProtocols
[ MAX_FWS_PROTOS
];
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: */