1 /* 2 * Copyright 2006-2008 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 26 package sun.awt.X11; 27 28 import java.awt.Dimension; 29 import java.awt.GraphicsEnvironment; 30 import java.awt.Point; 31 import java.awt.Rectangle; 32 33 import java.util.Collections; 34 import java.util.HashSet; 35 import java.util.Set; 36 37 import sun.awt.X11GraphicsConfig; 38 import sun.awt.X11GraphicsDevice; 39 import sun.awt.X11GraphicsEnvironment; 40 41 /* 42 * This class is a collection of utility methods that operate 43 * with native windows. 44 */ 45 public 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 relative to its parent. 104 */ 105 public static Rectangle getWindowGeometry(long window) { 106 XToolkit.awtLock(); 107 try { 108 return getWindowGeometry(window, XlibWrapper.larg1); 109 } finally { 110 XToolkit.awtUnlock(); 111 } 112 } 113 114 /** 115 * Returns the bounds of the given window relative to its parent. 116 * The unsafe memory pointed to by the rootWindowBuffer will 117 * contain the root window of the given window. 118 * WARNING: DO NOT USE XlibWrapper.larg[2..7] as the rootWindowBuffer! 119 * Only larg1 or larg8 can be used, or some other allocated memory block. 120 */ 121 public static Rectangle getWindowGeometry(long window, long rootWindowBuffer) 122 { 123 XToolkit.awtLock(); 124 try 125 { 126 int res = XlibWrapper.XGetGeometry(XToolkit.getDisplay(), 127 window, 128 rootWindowBuffer, // root_return 129 XlibWrapper.larg2, // x_return 130 XlibWrapper.larg3, // y_return 131 XlibWrapper.larg4, // width_return 132 XlibWrapper.larg5, // height_return 133 XlibWrapper.larg6, // border_width_return 134 XlibWrapper.larg7); // depth_return 135 if (res == 0) 136 { 137 return null; 138 } 139 140 int x = Native.getInt(XlibWrapper.larg2); 141 int y = Native.getInt(XlibWrapper.larg3); 142 long width = Native.getUInt(XlibWrapper.larg4); 143 long height = Native.getUInt(XlibWrapper.larg5); 144 145 return new Rectangle(x, y, (int)width, (int)height); 146 } 147 finally 148 { 149 XToolkit.awtUnlock(); 150 } 151 } 152 153 /** 154 * Translates the given point from one window to another. Returns 155 * null if the translation is failed 156 */ 157 static Point translateCoordinates(long src, long dst, Point p) 158 { 159 Point translated = null; 160 161 XToolkit.awtLock(); 162 try 163 { 164 XTranslateCoordinates xtc = 165 new XTranslateCoordinates(src, dst, p.x, p.y); 166 try 167 { 168 int status = xtc.execute(XErrorHandler.IgnoreBadWindowHandler.getInstance()); 169 if ((status != 0) && 170 ((XToolkit.saved_error == null) || 171 (XToolkit.saved_error.get_error_code() == XConstants.Success))) 172 { 173 translated = new Point(xtc.get_dest_x(), xtc.get_dest_y()); 174 } 175 } 176 finally 177 { 178 xtc.dispose(); 179 } 180 } 181 finally 182 { 183 XToolkit.awtUnlock(); 184 } 185 186 return translated; 187 } 188 189 /** 190 * Translates the given rectangle from one window to another. 191 * Returns null if the translation is failed 192 */ 193 static Rectangle translateCoordinates(long src, long dst, Rectangle r) 194 { 195 Point translatedLoc = translateCoordinates(src, dst, r.getLocation()); 196 if (translatedLoc == null) 197 { 198 return null; 199 } 200 else 201 { 202 return new Rectangle(translatedLoc, r.getSize()); 203 } 204 } 205 206 /** 207 * Returns the parent for the given window 208 */ 209 static long getParentWindow(long window) 210 { 211 XToolkit.awtLock(); 212 try 213 { 214 XBaseWindow bw = XToolkit.windowToXWindow(window); 215 if (bw != null) 216 { 217 XBaseWindow pbw = bw.getParentWindow(); 218 if (pbw != null) 219 { 220 return pbw.getWindow(); 221 } 222 } 223 224 XQueryTree qt = new XQueryTree(window); 225 try 226 { 227 if (qt.execute() == 0) 228 { 229 return XConstants.None; 230 } 231 else 232 { 233 return qt.get_parent(); 234 } 235 } 236 finally 237 { 238 qt.dispose(); 239 } 240 } 241 finally 242 { 243 XToolkit.awtUnlock(); 244 } 245 } 246 247 /** 248 * Returns all the children for the given window 249 */ 250 static Set<Long> getChildWindows(long window) 251 { 252 XToolkit.awtLock(); 253 try 254 { 255 XBaseWindow bw = XToolkit.windowToXWindow(window); 256 if (bw != null) 257 { 258 return bw.getChildren(); 259 } 260 261 XQueryTree xqt = new XQueryTree(window); 262 try 263 { 264 int status = xqt.execute(); 265 if (status == 0) 266 { 267 return Collections.emptySet(); 268 } 269 270 long children = xqt.get_children(); 271 272 if (children == 0) 273 { 274 return Collections.emptySet(); 275 } 276 277 int childrenCount = xqt.get_nchildren(); 278 279 Set<Long> childrenSet = new HashSet<Long>(childrenCount); 280 for (int i = 0; i < childrenCount; i++) 281 { 282 childrenSet.add(Native.getWindow(children, i)); 283 } 284 285 return childrenSet; 286 } 287 finally 288 { 289 xqt.dispose(); 290 } 291 } 292 finally 293 { 294 XToolkit.awtUnlock(); 295 } 296 } 297 298 /** 299 * Checks if the given window is a Java window and is an 300 * instance of XWindowPeer 301 */ 302 static boolean isXAWTToplevelWindow(long window) 303 { 304 return XToolkit.windowToXWindow(window) instanceof XWindowPeer; 305 } 306 307 /** 308 * NOTICE: Right now returns only decorated top-levels (not Window) 309 */ 310 static boolean isToplevelWindow(long window) 311 { 312 if (XToolkit.windowToXWindow(window) instanceof XDecoratedPeer) 313 { 314 return true; 315 } 316 317 XToolkit.awtLock(); 318 try 319 { 320 WindowPropertyGetter wpg = 321 new WindowPropertyGetter(window, XWM.XA_WM_STATE, 0, 1, false, 322 XWM.XA_WM_STATE); 323 try 324 { 325 wpg.execute(XErrorHandler.IgnoreBadWindowHandler.getInstance()); 326 if (wpg.getActualType() == XWM.XA_WM_STATE.getAtom()) 327 { 328 return true; 329 } 330 } 331 finally 332 { 333 wpg.dispose(); 334 } 335 336 return false; 337 } 338 finally 339 { 340 XToolkit.awtUnlock(); 341 } 342 } 343 344 /** 345 * The same as isToplevelWindow(window), but doesn't treat 346 * XEmbeddedFramePeer as toplevel. 347 */ 348 static boolean isTrueToplevelWindow(long window) 349 { 350 if (XToolkit.windowToXWindow(window) instanceof XEmbeddedFramePeer) 351 { 352 return false; 353 } 354 355 return isToplevelWindow(window); 356 } 357 358 static int getWindowMapState(long window) 359 { 360 XToolkit.awtLock(); 361 XWindowAttributes wattr = new XWindowAttributes(); 362 try 363 { 364 XToolkit.WITH_XERROR_HANDLER(XErrorHandler.IgnoreBadWindowHandler.getInstance()); 365 int status = XlibWrapper.XGetWindowAttributes(XToolkit.getDisplay(), 366 window, wattr.pData); 367 XToolkit.RESTORE_XERROR_HANDLER(); 368 if ((status != 0) && 369 ((XToolkit.saved_error == null) || 370 (XToolkit.saved_error.get_error_code() == XConstants.Success))) 371 { 372 return wattr.get_map_state(); 373 } 374 } 375 finally 376 { 377 wattr.dispose(); 378 XToolkit.awtUnlock(); 379 } 380 381 return XConstants.IsUnmapped; 382 } 383 384 /** 385 * XSHAPE extension support. 386 */ 387 388 // The variable is declared static as the XSHAPE extension cannot 389 // be disabled at run-time, and thus is available all the time 390 // once the check is passed. 391 static Boolean isShapingSupported = null; 392 393 /** 394 * Returns whether the XSHAPE extension available 395 * @since 1.7 396 */ 397 static synchronized boolean isShapingSupported() { 398 399 if (isShapingSupported == null) { 400 XToolkit.awtLock(); 401 try { 402 isShapingSupported = 403 XlibWrapper.XShapeQueryExtension( 404 XToolkit.getDisplay(), 405 XlibWrapper.larg1, 406 XlibWrapper.larg2); 407 } finally { 408 XToolkit.awtUnlock(); 409 } 410 } 411 412 return isShapingSupported.booleanValue(); 413 } 414 415 }