1 /* 2 * Copyright (c) 2006, 2008, Oracle and/or its affiliates. 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. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * 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, 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(XErrorHandler.IgnoreBadWindowHandler.getInstance()); 153 if ((status != 0) && 154 ((XToolkit.saved_error == null) || 155 (XToolkit.saved_error.get_error_code() == XConstants.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(XErrorHandler.IgnoreBadWindowHandler.getInstance()); 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(XErrorHandler.IgnoreBadWindowHandler.getInstance()); 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() == XConstants.Success))) 355 { 356 return wattr.get_map_state(); 357 } 358 } 359 finally 360 { 361 wattr.dispose(); 362 XToolkit.awtUnlock(); 363 } 364 365 return XConstants.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 }