blob: b6086ef469bf7562097f22cecc5c1b35a579f033 [file] [log] [blame]
J. Duke319a3b92007-12-01 00:00:00 +00001/*
2 * Copyright 2006-2007 Sun Microsystems, Inc. All Rights Reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Sun designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Sun in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
22 * CA 95054 USA or visit www.sun.com if you need additional information or
23 * have any questions.
24 */
25
26package sun.awt.X11;
27
28import java.awt.Dimension;
29import java.awt.GraphicsEnvironment;
30import java.awt.Point;
31import java.awt.Rectangle;
32
33import java.util.Collections;
34import java.util.HashSet;
35import java.util.Set;
36
37import sun.awt.X11GraphicsConfig;
38import sun.awt.X11GraphicsDevice;
39import sun.awt.X11GraphicsEnvironment;
40
41/*
42 * This class is a collection of utility methods that operate
43 * with native windows.
44 */
45public class XlibUtil
46{
47 /**
48 * The constructor is made private to eliminate any
49 * instances of this class
50 */
51 private XlibUtil()
52 {
53 }
54
55 /**
56 * Xinerama-aware version of XlibWrapper.RootWindow method.
57 */
58 public static long getRootWindow(int screenNumber)
59 {
60 XToolkit.awtLock();
61 try
62 {
63 X11GraphicsEnvironment x11ge = (X11GraphicsEnvironment)
64 GraphicsEnvironment.getLocalGraphicsEnvironment();
65 if (x11ge.runningXinerama())
66 {
67 // all the Xinerama windows share the same root window
68 return XlibWrapper.RootWindow(XToolkit.getDisplay(), 0);
69 }
70 else
71 {
72 return XlibWrapper.RootWindow(XToolkit.getDisplay(), screenNumber);
73 }
74 }
75 finally
76 {
77 XToolkit.awtUnlock();
78 }
79 }
80
81 /**
82 * Checks if the given window is a root window for the given screen
83 */
84 static boolean isRoot(long rootCandidate, long screenNumber)
85 {
86 long root;
87
88 XToolkit.awtLock();
89 try
90 {
91 root = XlibWrapper.RootWindow(XToolkit.getDisplay(),
92 screenNumber);
93 }
94 finally
95 {
96 XToolkit.awtUnlock();
97 }
98
99 return root == rootCandidate;
100 }
101
102 /**
103 * Returns the bounds of the given window, in absolute coordinates
104 */
105 static Rectangle getWindowGeometry(long window)
106 {
107 XToolkit.awtLock();
108 try
109 {
110 int res = XlibWrapper.XGetGeometry(XToolkit.getDisplay(),
111 window,
112 XlibWrapper.larg1, // root_return
113 XlibWrapper.larg2, // x_return
114 XlibWrapper.larg3, // y_return
115 XlibWrapper.larg4, // width_return
116 XlibWrapper.larg5, // height_return
117 XlibWrapper.larg6, // border_width_return
118 XlibWrapper.larg7); // depth_return
119 if (res == 0)
120 {
121 return null;
122 }
123
124 int x = Native.getInt(XlibWrapper.larg2);
125 int y = Native.getInt(XlibWrapper.larg3);
126 long width = Native.getUInt(XlibWrapper.larg4);
127 long height = Native.getUInt(XlibWrapper.larg5);
128
129 return new Rectangle(x, y, (int)width, (int)height);
130 }
131 finally
132 {
133 XToolkit.awtUnlock();
134 }
135 }
136
137 /**
138 * Translates the given point from one window to another. Returns
139 * null if the translation is failed
140 */
141 static Point translateCoordinates(long src, long dst, Point p)
142 {
143 Point translated = null;
144
145 XToolkit.awtLock();
146 try
147 {
148 XTranslateCoordinates xtc =
149 new XTranslateCoordinates(src, dst, p.x, p.y);
150 try
151 {
152 int status = xtc.execute(XToolkit.IgnoreBadWindowHandler);
153 if ((status != 0) &&
154 ((XToolkit.saved_error == null) ||
155 (XToolkit.saved_error.get_error_code() == XlibWrapper.Success)))
156 {
157 translated = new Point(xtc.get_dest_x(), xtc.get_dest_y());
158 }
159 }
160 finally
161 {
162 xtc.dispose();
163 }
164 }
165 finally
166 {
167 XToolkit.awtUnlock();
168 }
169
170 return translated;
171 }
172
173 /**
174 * Translates the given rectangle from one window to another.
175 * Returns null if the translation is failed
176 */
177 static Rectangle translateCoordinates(long src, long dst, Rectangle r)
178 {
179 Point translatedLoc = translateCoordinates(src, dst, r.getLocation());
180 if (translatedLoc == null)
181 {
182 return null;
183 }
184 else
185 {
186 return new Rectangle(translatedLoc, r.getSize());
187 }
188 }
189
190 /**
191 * Returns the parent for the given window
192 */
193 static long getParentWindow(long window)
194 {
195 XToolkit.awtLock();
196 try
197 {
198 XBaseWindow bw = XToolkit.windowToXWindow(window);
199 if (bw != null)
200 {
201 XBaseWindow pbw = bw.getParentWindow();
202 if (pbw != null)
203 {
204 return pbw.getWindow();
205 }
206 }
207
208 XQueryTree qt = new XQueryTree(window);
209 try
210 {
211 if (qt.execute() == 0)
212 {
213 return 0;
214 }
215 else
216 {
217 return qt.get_parent();
218 }
219 }
220 finally
221 {
222 qt.dispose();
223 }
224 }
225 finally
226 {
227 XToolkit.awtUnlock();
228 }
229 }
230
231 /**
232 * Returns all the children for the given window
233 */
234 static Set<Long> getChildWindows(long window)
235 {
236 XToolkit.awtLock();
237 try
238 {
239 XBaseWindow bw = XToolkit.windowToXWindow(window);
240 if (bw != null)
241 {
242 return bw.getChildren();
243 }
244
245 XQueryTree xqt = new XQueryTree(window);
246 try
247 {
248 int status = xqt.execute();
249 if (status == 0)
250 {
251 return Collections.emptySet();
252 }
253
254 long children = xqt.get_children();
255
256 if (children == 0)
257 {
258 return Collections.emptySet();
259 }
260
261 int childrenCount = xqt.get_nchildren();
262
263 Set<Long> childrenSet = new HashSet<Long>(childrenCount);
264 for (int i = 0; i < childrenCount; i++)
265 {
266 childrenSet.add(Native.getWindow(children, i));
267 }
268
269 return childrenSet;
270 }
271 finally
272 {
273 xqt.dispose();
274 }
275 }
276 finally
277 {
278 XToolkit.awtUnlock();
279 }
280 }
281
282 /**
283 * Checks if the given window is a Java window and is an
284 * instance of XWindowPeer
285 */
286 static boolean isXAWTToplevelWindow(long window)
287 {
288 return XToolkit.windowToXWindow(window) instanceof XWindowPeer;
289 }
290
291 /**
292 * NOTICE: Right now returns only decorated top-levels (not Window)
293 */
294 static boolean isToplevelWindow(long window)
295 {
296 if (XToolkit.windowToXWindow(window) instanceof XDecoratedPeer)
297 {
298 return true;
299 }
300
301 XToolkit.awtLock();
302 try
303 {
304 WindowPropertyGetter wpg =
305 new WindowPropertyGetter(window, XWM.XA_WM_STATE, 0, 1, false,
306 XWM.XA_WM_STATE);
307 try
308 {
309 wpg.execute(XToolkit.IgnoreBadWindowHandler);
310 if (wpg.getActualType() == XWM.XA_WM_STATE.getAtom())
311 {
312 return true;
313 }
314 }
315 finally
316 {
317 wpg.dispose();
318 }
319
320 return false;
321 }
322 finally
323 {
324 XToolkit.awtUnlock();
325 }
326 }
327
328 /**
329 * The same as isToplevelWindow(window), but doesn't treat
330 * XEmbeddedFramePeer as toplevel.
331 */
332 static boolean isTrueToplevelWindow(long window)
333 {
334 if (XToolkit.windowToXWindow(window) instanceof XEmbeddedFramePeer)
335 {
336 return false;
337 }
338
339 return isToplevelWindow(window);
340 }
341
342 static int getWindowMapState(long window)
343 {
344 XToolkit.awtLock();
345 XWindowAttributes wattr = new XWindowAttributes();
346 try
347 {
348 XToolkit.WITH_XERROR_HANDLER(XToolkit.IgnoreBadWindowHandler);
349 int status = XlibWrapper.XGetWindowAttributes(XToolkit.getDisplay(),
350 window, wattr.pData);
351 XToolkit.RESTORE_XERROR_HANDLER();
352 if ((status != 0) &&
353 ((XToolkit.saved_error == null) ||
354 (XToolkit.saved_error.get_error_code() == XlibWrapper.Success)))
355 {
356 return wattr.get_map_state();
357 }
358 }
359 finally
360 {
361 wattr.dispose();
362 XToolkit.awtUnlock();
363 }
364
365 return XlibWrapper.IsUnmapped;
366 }
367
368 /**
369 * XSHAPE extension support.
370 */
371
372 // The variable is declared static as the XSHAPE extension cannot
373 // be disabled at run-time, and thus is available all the time
374 // once the check is passed.
375 static Boolean isShapingSupported = null;
376
377 /**
378 * Returns whether the XSHAPE extension available
379 * @since 1.7
380 */
381 static synchronized boolean isShapingSupported() {
382
383 if (isShapingSupported == null) {
384 XToolkit.awtLock();
385 try {
386 isShapingSupported =
387 XlibWrapper.XShapeQueryExtension(
388 XToolkit.getDisplay(),
389 XlibWrapper.larg1,
390 XlibWrapper.larg2);
391 } finally {
392 XToolkit.awtUnlock();
393 }
394 }
395
396 return isShapingSupported.booleanValue();
397 }
398
399}