1 /*
   2  * Copyright (c) 2003, 2007, 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.*;
  29 import sun.awt.*;
  30 import java.util.logging.*;
  31 import java.util.*;
  32 
  33 public class XBaseWindow implements XConstants, XUtilConstants {
  34     private static final Logger log = Logger.getLogger("sun.awt.X11.XBaseWindow");
  35     private static final Logger insLog = Logger.getLogger("sun.awt.X11.insets.XBaseWindow");
  36     private static final Logger eventLog = Logger.getLogger("sun.awt.X11.event.XBaseWindow");
  37     private static final Logger focusLog = Logger.getLogger("sun.awt.X11.focus.XBaseWindow");
  38     private static final Logger grabLog = Logger.getLogger("sun.awt.X11.grab.XBaseWindow");
  39 
  40     public static final String
  41         PARENT_WINDOW = "parent window", // parent window, Long
  42         BOUNDS = "bounds", // bounds of the window, Rectangle
  43         OVERRIDE_REDIRECT = "overrideRedirect", // override_redirect setting, Boolean
  44         EVENT_MASK = "event mask", // event mask, Integer
  45         VALUE_MASK = "value mask", // value mask, Long
  46         BORDER_PIXEL = "border pixel", // border pixel value, Integer
  47         COLORMAP = "color map", // color map, Long
  48         DEPTH = "visual depth", // depth, Integer
  49         VISUAL_CLASS = "visual class", // visual class, Integer
  50         VISUAL = "visual", // visual, Long
  51         EMBEDDED = "embedded", // is embedded?, Boolean
  52         DELAYED = "delayed", // is creation delayed?, Boolean
  53         PARENT = "parent", // parent peer
  54         BACKGROUND_PIXMAP = "pixmap", // background pixmap
  55         VISIBLE = "visible", // whether it is visible by default
  56         SAVE_UNDER = "save under", // save content under this window
  57         BACKING_STORE = "backing store", // enables double buffering
  58         BIT_GRAVITY = "bit gravity"; // copy old content on geometry change
  59     private XCreateWindowParams delayedParams;
  60 
  61     Set<Long> children = new HashSet<Long>();
  62     long window;
  63     boolean visible;
  64     boolean mapped;
  65     boolean embedded;
  66     Rectangle maxBounds;
  67     volatile XBaseWindow parentWindow;
  68 
  69     private boolean disposed;
  70 
  71     private long screen;
  72     private XSizeHints hints;
  73     private XWMHints wmHints;
  74 
  75     final static int MIN_SIZE = 1;
  76     final static int DEF_LOCATION = 1;
  77 
  78     private static XAtom wm_client_leader;
  79 
  80     static enum InitialiseState {
  81         INITIALISING,
  82         NOT_INITIALISED,
  83         INITIALISED,
  84         FAILED_INITIALISATION
  85     };
  86 
  87     private InitialiseState initialising;
  88 
  89     int x;
  90     int y;
  91     int width;
  92     int height;
  93 
  94     void awtLock() {
  95         XToolkit.awtLock();
  96     }
  97 
  98     void awtUnlock() {
  99         XToolkit.awtUnlock();
 100     }
 101 
 102     void awtLockNotifyAll() {
 103         XToolkit.awtLockNotifyAll();
 104     }
 105 
 106     void awtLockWait() throws InterruptedException {
 107         XToolkit.awtLockWait();
 108     }
 109 
 110     // To prevent errors from overriding obsolete methods
 111     protected final void init(long parentWindow, Rectangle bounds) {}
 112     protected final void preInit() {}
 113     protected final void postInit() {}
 114 
 115     // internal lock for synchronizing state changes and paint calls, initialized in preInit.
 116     // the order with other locks: AWTLock -> stateLock
 117     static class StateLock extends Object { }
 118     protected StateLock state_lock;
 119 
 120     /**
 121      * Called for delayed inits during construction
 122      */
 123     void instantPreInit(XCreateWindowParams params) {
 124         state_lock = new StateLock();
 125         initialising = InitialiseState.NOT_INITIALISED;
 126     }
 127 
 128     /**
 129      * Called before window creation, descendants should override to initialize the data,
 130      * initialize params.
 131      */
 132     void preInit(XCreateWindowParams params) {
 133         state_lock = new StateLock();
 134         initialising = InitialiseState.NOT_INITIALISED;
 135         embedded = Boolean.TRUE.equals(params.get(EMBEDDED));
 136         visible = Boolean.TRUE.equals(params.get(VISIBLE));
 137 
 138         Object parent = params.get(PARENT);
 139         if (parent instanceof XBaseWindow) {
 140             parentWindow = (XBaseWindow)parent;
 141         } else {
 142             Long parentWindowID = (Long)params.get(PARENT_WINDOW);
 143             if (parentWindowID != null) {
 144                 parentWindow = XToolkit.windowToXWindow(parentWindowID);
 145             }
 146         }
 147 
 148         Long eventMask = (Long)params.get(EVENT_MASK);
 149         if (eventMask != null) {
 150             long mask = eventMask.longValue();
 151             mask |= SubstructureNotifyMask;
 152             params.put(EVENT_MASK, mask);
 153         }
 154 
 155         screen = -1;
 156     }
 157 
 158     /**
 159      * Called after window creation, descendants should override to initialize Window
 160      * with class-specific values and perform post-initialization actions.
 161      */
 162     void postInit(XCreateWindowParams params) {
 163         if (log.isLoggable(Level.FINE)) {
 164             log.fine("WM name is " + getWMName());
 165         }
 166         updateWMName();
 167 
 168         // Set WM_CLIENT_LEADER property
 169         initClientLeader();
 170     }
 171 
 172     /**
 173      * Creates window using parameters <code>params</code>
 174      * If params contain flag DELAYED doesn't do anything.
 175      * Note: Descendants can call this method to create the window
 176      * at the time different to instance construction.
 177      */
 178     protected final void init(XCreateWindowParams params) {
 179         awtLock();
 180         initialising = InitialiseState.INITIALISING;
 181         awtUnlock();
 182 
 183         try {
 184             if (!Boolean.TRUE.equals(params.get(DELAYED))) {
 185                 preInit(params);
 186                 create(params);
 187                 postInit(params);
 188             } else {
 189                 instantPreInit(params);
 190                 delayedParams = params;
 191             }
 192             awtLock();
 193             initialising = InitialiseState.INITIALISED;
 194             awtLockNotifyAll();
 195             awtUnlock();
 196         } catch (RuntimeException re) {
 197             awtLock();
 198             initialising = InitialiseState.FAILED_INITIALISATION;
 199             awtLockNotifyAll();
 200             awtUnlock();
 201             throw re;
 202         } catch (Throwable t) {
 203             if (log.isLoggable(Level.WARNING)) {
 204                 log.log(Level.WARNING, "Exception during peer initialization", t);
 205             }
 206             awtLock();
 207             initialising = InitialiseState.FAILED_INITIALISATION;
 208             awtLockNotifyAll();
 209             awtUnlock();
 210         }
 211     }
 212 
 213     public boolean checkInitialised() {
 214         awtLock();
 215         try {
 216             switch (initialising) {
 217               case INITIALISED:
 218                   return true;
 219               case INITIALISING:
 220                   try {
 221                       while (initialising != InitialiseState.INITIALISED) {
 222                           awtLockWait();
 223                       }
 224                   } catch (InterruptedException ie) {
 225                       return false;
 226                   }
 227                   return true;
 228               case NOT_INITIALISED:
 229               case FAILED_INITIALISATION:
 230                   return false;
 231               default:
 232                   return false;
 233             }
 234         } finally {
 235             awtUnlock();
 236         }
 237     }
 238 
 239     /*
 240      * Creates an invisible InputOnly window without an associated Component.
 241      */
 242     XBaseWindow() {
 243         this(new XCreateWindowParams());
 244     }
 245 
 246     /**
 247      * Creates normal child window
 248      */
 249     XBaseWindow(long parentWindow, Rectangle bounds) {
 250         this(new XCreateWindowParams(new Object[] {
 251             BOUNDS, bounds,
 252             PARENT_WINDOW, Long.valueOf(parentWindow)}));
 253     }
 254 
 255     /**
 256      * Creates top-level window
 257      */
 258     XBaseWindow(Rectangle bounds) {
 259         this(new XCreateWindowParams(new Object[] {
 260             BOUNDS, bounds
 261         }));
 262     }
 263 
 264     public XBaseWindow (XCreateWindowParams params) {
 265         init(params);
 266     }
 267 
 268     /* This create is used by the XEmbeddedFramePeer since it has to create the window
 269        as a child of the netscape window. This netscape window is passed in as wid */
 270     XBaseWindow(long parentWindow) {
 271         this(new XCreateWindowParams(new Object[] {
 272             PARENT_WINDOW, Long.valueOf(parentWindow),
 273             EMBEDDED, Boolean.TRUE
 274         }));
 275     }
 276 
 277     /**
 278      * Verifies that all required parameters are set. If not, sets them to default values.
 279      * Verifies values of critical parameters, adjust their values when needed.
 280      * @throws IllegalArgumentException if params is null
 281      */
 282     protected void checkParams(XCreateWindowParams params) {
 283         if (params == null) {
 284             throw new IllegalArgumentException("Window creation parameters are null");
 285         }
 286         params.putIfNull(PARENT_WINDOW, Long.valueOf(XToolkit.getDefaultRootWindow()));
 287         params.putIfNull(BOUNDS, new Rectangle(DEF_LOCATION, DEF_LOCATION, MIN_SIZE, MIN_SIZE));
 288         params.putIfNull(DEPTH, Integer.valueOf((int)XlibWrapper.CopyFromParent));
 289         params.putIfNull(VISUAL, Long.valueOf(XlibWrapper.CopyFromParent));
 290         params.putIfNull(VISUAL_CLASS, Integer.valueOf((int)XlibWrapper.InputOnly));
 291         params.putIfNull(VALUE_MASK, Long.valueOf(XlibWrapper.CWEventMask));
 292         Rectangle bounds = (Rectangle)params.get(BOUNDS);
 293         bounds.width = Math.max(MIN_SIZE, bounds.width);
 294         bounds.height = Math.max(MIN_SIZE, bounds.height);
 295 
 296         Long eventMaskObj = (Long)params.get(EVENT_MASK);
 297         long eventMask = eventMaskObj != null ? eventMaskObj.longValue() : 0;
 298         // We use our own synthetic grab see XAwtState.getGrabWindow()
 299         // (see X vol. 1, 8.3.3.2)
 300         eventMask |= PropertyChangeMask | OwnerGrabButtonMask;
 301         params.put(EVENT_MASK, Long.valueOf(eventMask));
 302     }
 303 
 304     /**
 305      * Creates window with parameters specified by <code>params</code>
 306      * @see #init
 307      */
 308     private final void create(XCreateWindowParams params) {
 309         XToolkit.awtLock();
 310         try {
 311             XSetWindowAttributes xattr = new XSetWindowAttributes();
 312             try {
 313                 checkParams(params);
 314 
 315                 long value_mask = ((Long)params.get(VALUE_MASK)).longValue();
 316 
 317                 Long eventMask = (Long)params.get(EVENT_MASK);
 318                 xattr.set_event_mask(eventMask.longValue());
 319                 value_mask |= XlibWrapper.CWEventMask;
 320 
 321                 Long border_pixel = (Long)params.get(BORDER_PIXEL);
 322                 if (border_pixel != null) {
 323                     xattr.set_border_pixel(border_pixel.longValue());
 324                     value_mask |= XlibWrapper.CWBorderPixel;
 325                 }
 326 
 327                 Long colormap = (Long)params.get(COLORMAP);
 328                 if (colormap != null) {
 329                     xattr.set_colormap(colormap.longValue());
 330                     value_mask |= XlibWrapper.CWColormap;
 331                 }
 332                 Long background_pixmap = (Long)params.get(BACKGROUND_PIXMAP);
 333                 if (background_pixmap != null) {
 334                     xattr.set_background_pixmap(background_pixmap.longValue());
 335                     value_mask |= XlibWrapper.CWBackPixmap;
 336                 }
 337 
 338                 Long parentWindow = (Long)params.get(PARENT_WINDOW);
 339                 Rectangle bounds = (Rectangle)params.get(BOUNDS);
 340                 Integer depth = (Integer)params.get(DEPTH);
 341                 Integer visual_class = (Integer)params.get(VISUAL_CLASS);
 342                 Long visual = (Long)params.get(VISUAL);
 343                 Boolean overrideRedirect = (Boolean)params.get(OVERRIDE_REDIRECT);
 344                 if (overrideRedirect != null) {
 345                     xattr.set_override_redirect(overrideRedirect.booleanValue());
 346                     value_mask |= XlibWrapper.CWOverrideRedirect;
 347                 }
 348 
 349                 Boolean saveUnder = (Boolean)params.get(SAVE_UNDER);
 350                 if (saveUnder != null) {
 351                     xattr.set_save_under(saveUnder.booleanValue());
 352                     value_mask |= XlibWrapper.CWSaveUnder;
 353                 }
 354 
 355                 Integer backingStore = (Integer)params.get(BACKING_STORE);
 356                 if (backingStore != null) {
 357                     xattr.set_backing_store(backingStore.intValue());
 358                     value_mask |= XlibWrapper.CWBackingStore;
 359                 }
 360 
 361                 Integer bitGravity = (Integer)params.get(BIT_GRAVITY);
 362                 if (bitGravity != null) {
 363                     xattr.set_bit_gravity(bitGravity.intValue());
 364                     value_mask |= XlibWrapper.CWBitGravity;
 365                 }
 366 
 367                 if (log.isLoggable(Level.FINE)) {
 368                     log.fine("Creating window for " + this + " with the following attributes: \n" + params);
 369                 }
 370                 window = XlibWrapper.XCreateWindow(XToolkit.getDisplay(),
 371                                    parentWindow.longValue(),
 372                                    bounds.x, bounds.y, // location
 373                                    bounds.width, bounds.height, // size
 374                                    0, // border
 375                                    depth.intValue(), // depth
 376                                    visual_class.intValue(), // class
 377                                    visual.longValue(), // visual
 378                                    value_mask,  // value mask
 379                                    xattr.pData); // attributes
 380 
 381                 if (window == 0) {
 382                     throw new IllegalStateException("Couldn't create window because of wrong parameters. Run with NOISY_AWT to see details");
 383                 }
 384                 XToolkit.addToWinMap(window, this);
 385             } finally {
 386                 xattr.dispose();
 387             }
 388         } finally {
 389             XToolkit.awtUnlock();
 390         }
 391     }
 392 
 393     public XCreateWindowParams getDelayedParams() {
 394         return delayedParams;
 395     }
 396 
 397     protected String getWMName() {
 398         return XToolkit.getCorrectXIDString(getClass().getName());
 399     }
 400 
 401     protected void initClientLeader() {
 402         XToolkit.awtLock();
 403         try {
 404             if (wm_client_leader == null) {
 405                 wm_client_leader = XAtom.get("WM_CLIENT_LEADER");
 406             }
 407             wm_client_leader.setWindowProperty(this, getXAWTRootWindow());
 408         } finally {
 409             XToolkit.awtUnlock();
 410         }
 411     }
 412 
 413     static XRootWindow getXAWTRootWindow() {
 414         return XRootWindow.getInstance();
 415     }
 416 
 417     void destroy() {
 418         XToolkit.awtLock();
 419         try {
 420             if (hints != null) {
 421                 XlibWrapper.XFree(hints.pData);
 422                 hints = null;
 423             }
 424             XToolkit.removeFromWinMap(getWindow(), this);
 425             XlibWrapper.XDestroyWindow(XToolkit.getDisplay(), getWindow());
 426             if (XPropertyCache.isCachingSupported()) {
 427                 XPropertyCache.clearCache(window);
 428             }
 429             window = -1;
 430             if( !isDisposed() ) {
 431                 setDisposed( true );
 432             }
 433 
 434             XAwtState.getGrabWindow(); // Magic - getGrabWindow clear state if grabbing window is disposed of.
 435         } finally {
 436             XToolkit.awtUnlock();
 437         }
 438     }
 439 
 440     void flush() {
 441         XToolkit.awtLock();
 442         try {
 443             XlibWrapper.XFlush(XToolkit.getDisplay());
 444         } finally {
 445             XToolkit.awtUnlock();
 446         }
 447     }
 448 
 449     /**
 450      * Helper function to set W
 451      */
 452     public final void setWMHints(XWMHints hints) {
 453         XToolkit.awtLock();
 454         try {
 455             XlibWrapper.XSetWMHints(XToolkit.getDisplay(), getWindow(), hints.pData);
 456         } finally {
 457             XToolkit.awtUnlock();
 458         }
 459     }
 460 
 461     public XWMHints getWMHints() {
 462         if (wmHints == null) {
 463             wmHints = new XWMHints(XlibWrapper.XAllocWMHints());
 464 //              XlibWrapper.XGetWMHints(XToolkit.getDisplay(),
 465 //                                      getWindow(),
 466 //                                      wmHints.pData);
 467         }
 468         return wmHints;
 469     }
 470 
 471 
 472     /*
 473      * Call this method under AWTLock.
 474      * The lock should be acquired untill all operations with XSizeHints are completed.
 475      */
 476     public XSizeHints getHints() {
 477         if (hints == null) {
 478             long p_hints = XlibWrapper.XAllocSizeHints();
 479             hints = new XSizeHints(p_hints);
 480 //              XlibWrapper.XGetWMNormalHints(XToolkit.getDisplay(), getWindow(), p_hints, XlibWrapper.larg1);
 481             // TODO: Shouldn't we listen for WM updates on this property?
 482         }
 483         return hints;
 484     }
 485 
 486     public void setSizeHints(long flags, int x, int y, int width, int height) {
 487         if (insLog.isLoggable(Level.FINER)) {
 488             insLog.finer("Setting hints, flags " + XlibWrapper.hintsToString(flags));
 489         }
 490         XToolkit.awtLock();
 491         try {
 492             XSizeHints hints = getHints();
 493             // Note: if PPosition is not set in flags this means that
 494             // we want to reset PPosition in hints.  This is necessary
 495             // for locationByPlatform functionality
 496             if ((flags & XlibWrapper.PPosition) != 0) {
 497                 hints.set_x(x);
 498                 hints.set_y(y);
 499             }
 500             if ((flags & XlibWrapper.PSize) != 0) {
 501                 hints.set_width(width);
 502                 hints.set_height(height);
 503             } else if ((hints.get_flags() & XlibWrapper.PSize) != 0) {
 504                 flags |= XlibWrapper.PSize;
 505             }
 506             if ((flags & XlibWrapper.PMinSize) != 0) {
 507                 hints.set_min_width(width);
 508                 hints.set_min_height(height);
 509             } else if ((hints.get_flags() & XlibWrapper.PMinSize) != 0) {
 510                 flags |= XlibWrapper.PMinSize;
 511                 //Fix for 4320050: Minimum size for java.awt.Frame is not being enforced.
 512                 //We don't need to reset minimum size if it's already set
 513             }
 514             if ((flags & XlibWrapper.PMaxSize) != 0) {
 515                 if (maxBounds != null) {
 516                     if (maxBounds.width != Integer.MAX_VALUE) {
 517                         hints.set_max_width(maxBounds.width);
 518                     } else {
 519                         hints.set_max_width(XToolkit.getDefaultScreenWidth());
 520                     }
 521                     if (maxBounds.height != Integer.MAX_VALUE) {
 522                         hints.set_max_height(maxBounds.height);
 523                     } else {
 524                         hints.set_max_height(XToolkit.getDefaultScreenHeight());
 525                     }
 526                 } else {
 527                     hints.set_max_width(width);
 528                     hints.set_max_height(height);
 529                 }
 530             } else if ((hints.get_flags() & XlibWrapper.PMaxSize) != 0) {
 531                 flags |= XlibWrapper.PMaxSize;
 532                 if (maxBounds != null) {
 533                     if (maxBounds.width != Integer.MAX_VALUE) {
 534                         hints.set_max_width(maxBounds.width);
 535                     } else {
 536                         hints.set_max_width(XToolkit.getDefaultScreenWidth());
 537                     }
 538                     if (maxBounds.height != Integer.MAX_VALUE) {
 539                         hints.set_max_height(maxBounds.height);
 540                     } else {
 541                         hints.set_max_height(XToolkit.getDefaultScreenHeight());
 542                     }
 543                 } else {
 544                     // Leave intact
 545                 }
 546             }
 547             flags |= XlibWrapper.PWinGravity;
 548             hints.set_flags(flags);
 549             hints.set_win_gravity((int)XlibWrapper.NorthWestGravity);
 550             if (insLog.isLoggable(Level.FINER)) {
 551                 insLog.finer("Setting hints, resulted flags " + XlibWrapper.hintsToString(flags) +
 552                              ", values " + hints);
 553             }
 554             XlibWrapper.XSetWMNormalHints(XToolkit.getDisplay(), getWindow(), hints.pData);
 555         } finally {
 556             XToolkit.awtUnlock();
 557         }
 558     }
 559 
 560     public boolean isMinSizeSet() {
 561         XSizeHints hints = getHints();
 562         long flags = hints.get_flags();
 563         return ((flags & XlibWrapper.PMinSize) == XlibWrapper.PMinSize);
 564     }
 565 
 566     /**
 567      * This lock object can be used to protect instance data from concurrent access
 568      * by two threads. If both state lock and AWT lock are taken, AWT Lock should be taken first.
 569      */
 570     Object getStateLock() {
 571         return state_lock;
 572     }
 573 
 574     public long getWindow() {
 575         return window;
 576     }
 577     public long getContentWindow() {
 578         return window;
 579     }
 580 
 581     public XBaseWindow getContentXWindow() {
 582         return XToolkit.windowToXWindow(getContentWindow());
 583     }
 584 
 585     public Rectangle getBounds() {
 586         return new Rectangle(x, y, width, height);
 587     }
 588     public Dimension getSize() {
 589         return new Dimension(width, height);
 590     }
 591 
 592 
 593     public void toFront() {
 594         XToolkit.awtLock();
 595         try {
 596             XlibWrapper.XRaiseWindow(XToolkit.getDisplay(), getWindow());
 597         } finally {
 598             XToolkit.awtUnlock();
 599         }
 600     }
 601     public void xRequestFocus(long time) {
 602         XToolkit.awtLock();
 603         try {
 604             if (focusLog.isLoggable(Level.FINER)) {
 605                 focusLog.finer("XSetInputFocus on " + Long.toHexString(getWindow()) + " with time " + time);
 606             }
 607             XlibWrapper.XSetInputFocus2(XToolkit.getDisplay(), getWindow(), time);
 608         } finally {
 609             XToolkit.awtUnlock();
 610         }
 611     }
 612     public void xRequestFocus() {
 613         XToolkit.awtLock();
 614         try {
 615             if (focusLog.isLoggable(Level.FINER)) {
 616                 focusLog.finer("XSetInputFocus on " + Long.toHexString(getWindow()));
 617             }
 618             XlibWrapper.XSetInputFocus(XToolkit.getDisplay(), getWindow());
 619         } finally {
 620             XToolkit.awtUnlock();
 621         }
 622     }
 623 
 624     public static long xGetInputFocus() {
 625         XToolkit.awtLock();
 626         try {
 627             return XlibWrapper.XGetInputFocus(XToolkit.getDisplay());
 628         } finally {
 629             XToolkit.awtUnlock();
 630         }
 631     }
 632 
 633     public void xSetVisible(boolean visible) {
 634         if (log.isLoggable(Level.FINE)) {
 635             log.fine("Setting visible on " + this + " to " + visible);
 636         }
 637         XToolkit.awtLock();
 638         try {
 639             this.visible = visible;
 640             if (visible) {
 641                 XlibWrapper.XMapWindow(XToolkit.getDisplay(), getWindow());
 642             }
 643             else {
 644                 XlibWrapper.XUnmapWindow(XToolkit.getDisplay(), getWindow());
 645             }
 646             XlibWrapper.XFlush(XToolkit.getDisplay());
 647         } finally {
 648             XToolkit.awtUnlock();
 649         }
 650     }
 651 
 652     boolean isMapped() {
 653         return mapped;
 654     }
 655 
 656     void updateWMName() {
 657         String name = getWMName();
 658         XToolkit.awtLock();
 659         try {
 660             if (name == null) {
 661                 name = " ";
 662             }
 663             XAtom nameAtom = XAtom.get(XAtom.XA_WM_NAME);
 664             nameAtom.setProperty(getWindow(), name);
 665             XAtom netNameAtom = XAtom.get("_NET_WM_NAME");
 666             netNameAtom.setPropertyUTF8(getWindow(), name);
 667         } finally {
 668             XToolkit.awtUnlock();
 669         }
 670     }
 671     void setWMClass(String[] cl) {
 672         if (cl.length != 2) {
 673             throw new IllegalArgumentException("WM_CLASS_NAME consists of exactly two strings");
 674         }
 675         XToolkit.awtLock();
 676         try {
 677             XAtom xa = XAtom.get(XAtom.XA_WM_CLASS);
 678             xa.setProperty8(getWindow(), cl[0] + '\0' + cl[1]);
 679         } finally {
 680             XToolkit.awtUnlock();
 681         }
 682     }
 683 
 684     boolean isVisible() {
 685         return visible;
 686     }
 687 
 688     static long getScreenOfWindow(long window) {
 689         XToolkit.awtLock();
 690         try {
 691             return XlibWrapper.getScreenOfWindow(XToolkit.getDisplay(), window);
 692         } finally {
 693             XToolkit.awtUnlock();
 694         }
 695     }
 696     long getScreenNumber() {
 697         XToolkit.awtLock();
 698         try {
 699             return XlibWrapper.XScreenNumberOfScreen(getScreen());
 700         } finally {
 701             XToolkit.awtUnlock();
 702         }
 703     }
 704 
 705     long getScreen() {
 706         if (screen == -1) { // Not initialized
 707             screen = getScreenOfWindow(window);
 708         }
 709         return screen;
 710     }
 711 
 712     public void xSetBounds(Rectangle bounds) {
 713         xSetBounds(bounds.x, bounds.y, bounds.width, bounds.height);
 714     }
 715 
 716     public void xSetBounds(int x, int y, int width, int height) {
 717         if (getWindow() == 0) {
 718             insLog.warning("Attempt to resize uncreated window");
 719             throw new IllegalStateException("Attempt to resize uncreated window");
 720         }
 721         if (insLog.isLoggable(Level.FINE)) {
 722             insLog.fine("Setting bounds on " + this + " to (" + x + ", " + y + "), " + width + "x" + height);
 723         }
 724         if (width <= 0) {
 725             width = 1;
 726         }
 727         if (height <= 0) {
 728             height = 1;
 729         }
 730         XToolkit.awtLock();
 731         try {
 732              XlibWrapper.XMoveResizeWindow(XToolkit.getDisplay(), getWindow(), x,y,width,height);
 733         } finally {
 734             XToolkit.awtUnlock();
 735         }
 736     }
 737 
 738     /**
 739      * Translate coordinates from one window into another.  Optimized
 740      * for XAWT - uses cached data when possible.  Preferable over
 741      * pure XTranslateCoordinates.
 742      * @return coordinates relative to dst, or null if error happened
 743      */
 744     static Point toOtherWindow(long src, long dst, int x, int y) {
 745         Point rpt = new Point(0, 0);
 746 
 747         // Check if both windows belong to XAWT - then no X calls are necessary
 748 
 749         XBaseWindow srcPeer = XToolkit.windowToXWindow(src);
 750         XBaseWindow dstPeer = XToolkit.windowToXWindow(dst);
 751 
 752         if (srcPeer != null && dstPeer != null) {
 753             // (x, y) is relative to src
 754             rpt.x = x + srcPeer.getAbsoluteX() - dstPeer.getAbsoluteX();
 755             rpt.y = y + srcPeer.getAbsoluteY() - dstPeer.getAbsoluteY();
 756         } else if (dstPeer != null && XlibUtil.isRoot(src, dstPeer.getScreenNumber())) {
 757             // from root into peer
 758             rpt.x = x - dstPeer.getAbsoluteX();
 759             rpt.y = y - dstPeer.getAbsoluteY();
 760         } else if (srcPeer != null && XlibUtil.isRoot(dst, srcPeer.getScreenNumber())) {
 761             // from peer into root
 762             rpt.x = x + srcPeer.getAbsoluteX();
 763             rpt.y = y + srcPeer.getAbsoluteY();
 764         } else {
 765             rpt = XlibUtil.translateCoordinates(src, dst, new Point(x, y));
 766         }
 767         return rpt;
 768     }
 769 
 770     /*
 771      * Convert to global coordinates.
 772      */
 773     Rectangle toGlobal(Rectangle rec) {
 774         Point p = toGlobal(rec.getLocation());
 775         Rectangle newRec = new Rectangle(rec);
 776         if (p != null) {
 777             newRec.setLocation(p);
 778         }
 779         return newRec;
 780     }
 781 
 782     Point toGlobal(Point pt) {
 783         Point p = toGlobal(pt.x, pt.y);
 784         if (p != null) {
 785             return p;
 786         } else {
 787             return new Point(pt);
 788         }
 789     }
 790 
 791     Point toGlobal(int x, int y) {
 792         long root;
 793         XToolkit.awtLock();
 794         try {
 795             root = XlibWrapper.RootWindow(XToolkit.getDisplay(),
 796                     getScreenNumber());
 797         } finally {
 798             XToolkit.awtUnlock();
 799         }
 800         Point p = toOtherWindow(getContentWindow(), root, x, y);
 801         if (p != null) {
 802             return p;
 803         } else {
 804             return new Point(x, y);
 805         }
 806     }
 807 
 808     /*
 809      * Convert to local coordinates.
 810      */
 811     Point toLocal(Point pt) {
 812         Point p = toLocal(pt.x, pt.y);
 813         if (p != null) {
 814             return p;
 815         } else {
 816             return new Point(pt);
 817         }
 818     }
 819 
 820     Point toLocal(int x, int y) {
 821         long root;
 822         XToolkit.awtLock();
 823         try {
 824             root = XlibWrapper.RootWindow(XToolkit.getDisplay(),
 825                     getScreenNumber());
 826         } finally {
 827             XToolkit.awtUnlock();
 828         }
 829         Point p = toOtherWindow(root, getContentWindow(), x, y);
 830         if (p != null) {
 831             return p;
 832         } else {
 833             return new Point(x, y);
 834         }
 835     }
 836 
 837     /**
 838      * We should always grab both keyboard and pointer to control event flow
 839      * on popups. This also simplifies synthetic grab implementation.
 840      * The active grab overrides activated automatic grab.
 841      */
 842     public boolean grabInput() {
 843         if (grabLog.isLoggable(Level.FINE)) {
 844             grabLog.log(Level.FINE, "Grab input on {0}", new Object[] {String.valueOf(this)});
 845         }
 846 
 847         XToolkit.awtLock();
 848         try {
 849             if (XAwtState.getGrabWindow() == this &&
 850                 XAwtState.isManualGrab())
 851             {
 852                 grabLog.fine("    Already Grabbed");
 853                 return true;
 854             }
 855             //6273031: PIT. Choice drop down does not close once it is right clicked to show a popup menu
 856             //remember previous window having grab and if it's not null ungrab it.
 857             XBaseWindow prevGrabWindow = XAwtState.getGrabWindow();
 858             final int eventMask = (int) (ButtonPressMask | ButtonReleaseMask
 859                 | EnterWindowMask | LeaveWindowMask | PointerMotionMask
 860                 | ButtonMotionMask);
 861             final int ownerEvents = 1;
 862 
 863             int ptrGrab = XlibWrapper.XGrabPointer(XToolkit.getDisplay(),
 864                 getContentWindow(), ownerEvents, eventMask, GrabModeAsync,
 865                 GrabModeAsync, None, (XWM.isMotif() ? XToolkit.arrowCursor : None),
 866                 CurrentTime);
 867             // Check grab results to be consistent with X server grab
 868             if (ptrGrab != GrabSuccess) {
 869                 XlibWrapper.XUngrabPointer(XToolkit.getDisplay(), CurrentTime);
 870                 XAwtState.setGrabWindow(null);
 871                 grabLog.fine("    Grab Failure - mouse");
 872                 return false;
 873             }
 874 
 875             int keyGrab = XlibWrapper.XGrabKeyboard(XToolkit.getDisplay(),
 876                 getContentWindow(), ownerEvents, GrabModeAsync, GrabModeAsync,
 877                 CurrentTime);
 878             if (keyGrab != GrabSuccess) {
 879                 XlibWrapper.XUngrabPointer(XToolkit.getDisplay(), CurrentTime);
 880                 XlibWrapper.XUngrabKeyboard(XToolkit.getDisplay(), CurrentTime);
 881                 XAwtState.setGrabWindow(null);
 882                 grabLog.fine("    Grab Failure - keyboard");
 883                 return false;
 884             }
 885             if (prevGrabWindow != null) {
 886                 prevGrabWindow.ungrabInputImpl();
 887             }
 888             XAwtState.setGrabWindow(this);
 889             grabLog.fine("    Grab - success");
 890             return true;
 891         } finally {
 892             XToolkit.awtUnlock();
 893         }
 894     }
 895 
 896     static void ungrabInput() {
 897         XToolkit.awtLock();
 898         try {
 899             XBaseWindow grabWindow = XAwtState.getGrabWindow();
 900             if (grabLog.isLoggable(Level.FINE)) {
 901                 grabLog.log(Level.FINE, "UnGrab input on {0}",
 902                             new Object[] {String.valueOf(grabWindow)});
 903             }
 904             if (grabWindow != null) {
 905                 grabWindow.ungrabInputImpl();
 906                 XlibWrapper.XUngrabPointer(XToolkit.getDisplay(), CurrentTime);
 907                 XlibWrapper.XUngrabKeyboard(XToolkit.getDisplay(), CurrentTime);
 908                 XAwtState.setGrabWindow(null);
 909                 // we need to call XFlush() here to force ungrab
 910                 // see 6384219 for details
 911                 XlibWrapper.XFlush(XToolkit.getDisplay());
 912             }
 913         } finally {
 914             XToolkit.awtUnlock();
 915         }
 916     }
 917 
 918     // called from ungrabInput, used in popup windows to hide theirselfs in ungrabbing
 919     void ungrabInputImpl() {
 920     }
 921 
 922     static void checkSecurity() {
 923         if (XToolkit.isSecurityWarningEnabled() && XToolkit.isToolkitThread()) {
 924             StackTraceElement stack[] = (new Throwable()).getStackTrace();
 925             if (log.isLoggable(Level.WARNING)) {
 926                 log.warning(stack[1] + ": Security violation: calling user code on toolkit thread");
 927             }
 928         }
 929     }
 930 
 931     public Set<Long> getChildren() {
 932         synchronized (getStateLock()) {
 933             return new HashSet<Long>(children);
 934         }
 935     }
 936 
 937     // -------------- Event handling ----------------
 938     public void handleMapNotifyEvent(XEvent xev) {
 939         mapped = true;
 940     }
 941     public void handleUnmapNotifyEvent(XEvent xev) {
 942         mapped = false;
 943     }
 944     public void handleReparentNotifyEvent(XEvent xev) {
 945         if (eventLog.isLoggable(Level.FINER)) {
 946             XReparentEvent msg = xev.get_xreparent();
 947             eventLog.finer(msg.toString());
 948         }
 949     }
 950     public void handlePropertyNotify(XEvent xev) {
 951         XPropertyEvent msg = xev.get_xproperty();
 952         if (XPropertyCache.isCachingSupported()) {
 953             XPropertyCache.clearCache(window, XAtom.get(msg.get_atom()));
 954         }
 955         if (eventLog.isLoggable(Level.FINER)) {
 956             eventLog.log(Level.FINER, "{0}", new Object[] {String.valueOf(msg)});
 957         }
 958     }
 959 
 960     public void handleDestroyNotify(XEvent xev) {
 961         XAnyEvent xany = xev.get_xany();
 962         if (xany.get_window() == getWindow()) {
 963             XToolkit.removeFromWinMap(getWindow(), this);
 964             if (XPropertyCache.isCachingSupported()) {
 965                 XPropertyCache.clearCache(getWindow());
 966             }
 967         }
 968         if (xany.get_window() != getWindow()) {
 969             synchronized (getStateLock()) {
 970                 children.remove(xany.get_window());
 971             }
 972         }
 973     }
 974 
 975     public void handleCreateNotify(XEvent xev) {
 976         XAnyEvent xany = xev.get_xany();
 977         if (xany.get_window() != getWindow()) {
 978             synchronized (getStateLock()) {
 979                 children.add(xany.get_window());
 980             }
 981         }
 982     }
 983 
 984     public void handleClientMessage(XEvent xev) {
 985         if (eventLog.isLoggable(Level.FINER)) {
 986             XClientMessageEvent msg = xev.get_xclient();
 987             eventLog.finer(msg.toString());
 988         }
 989     }
 990 
 991     public void handleVisibilityEvent(XEvent xev) {
 992     }
 993     public void handleKeyPress(XEvent xev) {
 994     }
 995     public void handleKeyRelease(XEvent xev) {
 996     }
 997     public void handleExposeEvent(XEvent xev) {
 998     }
 999     /**
1000      * Activate automatic grab on first ButtonPress,
1001      * deactivate on full mouse release
1002      */
1003     public void handleButtonPressRelease(XEvent xev) {
1004         XButtonEvent xbe = xev.get_xbutton();
1005         final int buttonState = xbe.get_state() & (Button1Mask | Button2Mask
1006             | Button3Mask | Button4Mask | Button5Mask);
1007         switch (xev.get_type()) {
1008         case ButtonPress:
1009             if (buttonState == 0) {
1010                 XAwtState.setAutoGrabWindow(this);
1011             }
1012             break;
1013         case ButtonRelease:
1014             if (isFullRelease(buttonState, xbe.get_button())) {
1015                 XAwtState.setAutoGrabWindow(null);
1016             }
1017             break;
1018         }
1019     }
1020     public void handleMotionNotify(XEvent xev) {
1021     }
1022     public void handleXCrossingEvent(XEvent xev) {
1023     }
1024     public void handleConfigureNotifyEvent(XEvent xev) {
1025         XConfigureEvent xe = xev.get_xconfigure();
1026         if (insLog.isLoggable(Level.FINER)) {
1027             insLog.log(Level.FINER, "Configure, {0}",
1028                        new Object[] {String.valueOf(xe)});
1029         }
1030         x = xe.get_x();
1031         y = xe.get_y();
1032         width = xe.get_width();
1033         height = xe.get_height();
1034     }
1035     /**
1036      * Checks ButtonRelease released all Mouse buttons
1037      */
1038     static boolean isFullRelease(int buttonState, int button) {
1039         switch (button) {
1040         case Button1:
1041             return buttonState == Button1Mask;
1042         case Button2:
1043             return buttonState == Button2Mask;
1044         case Button3:
1045             return buttonState == Button3Mask;
1046         case Button4:
1047             return buttonState == Button4Mask;
1048         case Button5:
1049             return buttonState == Button5Mask;
1050         }
1051         return buttonState == 0;
1052     }
1053 
1054     static boolean isGrabbedEvent(XEvent ev, XBaseWindow target) {
1055         switch (ev.get_type()) {
1056           case ButtonPress:
1057           case ButtonRelease:
1058           case MotionNotify:
1059           case KeyPress:
1060           case KeyRelease:
1061               return true;
1062           case LeaveNotify:
1063           case EnterNotify:
1064               // We shouldn't dispatch this events to the grabbed components (see 6317481)
1065               // But this logic is important if the grabbed component is top-level (see realSync)
1066               return (target instanceof XWindowPeer);
1067           default:
1068               return false;
1069         }
1070     }
1071     /**
1072      * Dispatches event to the grab Window or event source window depending
1073      * on whether the grab is active and on the event type
1074      */
1075     static void dispatchToWindow(XEvent ev) {
1076         XBaseWindow target = XAwtState.getGrabWindow();
1077         if (target == null || !isGrabbedEvent(ev, target)) {
1078             target = XToolkit.windowToXWindow(ev.get_xany().get_window());
1079         }
1080         if (target != null && target.checkInitialised()) {
1081             target.dispatchEvent(ev);
1082         }
1083     }
1084 
1085     public void dispatchEvent(XEvent xev) {
1086         if (eventLog.isLoggable(Level.FINEST)) {
1087             eventLog.finest(xev.toString());
1088         }
1089         int type = xev.get_type();
1090 
1091         if (isDisposed()) {
1092             return;
1093         }
1094 
1095         switch (type)
1096         {
1097           case VisibilityNotify:
1098               handleVisibilityEvent(xev);
1099               break;
1100           case ClientMessage:
1101               handleClientMessage(xev);
1102               break;
1103           case Expose :
1104           case GraphicsExpose :
1105               handleExposeEvent(xev);
1106               break;
1107           case ButtonPress:
1108           case ButtonRelease:
1109               handleButtonPressRelease(xev);
1110               break;
1111 
1112           case MotionNotify:
1113               handleMotionNotify(xev);
1114               break;
1115           case KeyPress:
1116               handleKeyPress(xev);
1117               break;
1118           case KeyRelease:
1119               handleKeyRelease(xev);
1120               break;
1121           case EnterNotify:
1122           case LeaveNotify:
1123               handleXCrossingEvent(xev);
1124               break;
1125           case ConfigureNotify:
1126               handleConfigureNotifyEvent(xev);
1127               break;
1128           case MapNotify:
1129               handleMapNotifyEvent(xev);
1130               break;
1131           case UnmapNotify:
1132               handleUnmapNotifyEvent(xev);
1133               break;
1134           case ReparentNotify:
1135               handleReparentNotifyEvent(xev);
1136               break;
1137           case PropertyNotify:
1138               handlePropertyNotify(xev);
1139               break;
1140           case DestroyNotify:
1141               handleDestroyNotify(xev);
1142               break;
1143           case CreateNotify:
1144               handleCreateNotify(xev);
1145               break;
1146         }
1147     }
1148     protected boolean isEventDisabled(XEvent e) {
1149         return false;
1150     }
1151 
1152     int getX() {
1153         return x;
1154     }
1155 
1156     int getY() {
1157         return y;
1158     }
1159 
1160     int getWidth() {
1161         return width;
1162     }
1163 
1164     int getHeight() {
1165         return height;
1166     }
1167 
1168     void setDisposed(boolean d) {
1169         disposed = d;
1170     }
1171 
1172     boolean isDisposed() {
1173         return disposed;
1174     }
1175 
1176     public int getAbsoluteX() {
1177         XBaseWindow pw = getParentWindow();
1178         if (pw != null) {
1179             return pw.getAbsoluteX() + getX();
1180         } else {
1181             // Overridden for top-levels as their (x,y) is Java (x, y), not native location
1182             return getX();
1183         }
1184     }
1185 
1186     public int getAbsoluteY() {
1187         XBaseWindow pw = getParentWindow();
1188         if (pw != null) {
1189             return pw.getAbsoluteY() + getY();
1190         } else {
1191             return getY();
1192         }
1193     }
1194 
1195     public XBaseWindow getParentWindow() {
1196         return parentWindow;
1197     }
1198 
1199     public XWindowPeer getToplevelXWindow() {
1200         XBaseWindow bw = this;
1201         while (bw != null && !(bw instanceof XWindowPeer)) {
1202             bw = bw.getParentWindow();
1203         }
1204         return (XWindowPeer)bw;
1205     }
1206     public String toString() {
1207         return super.toString() + "(" + Long.toString(getWindow(), 16) + ")";
1208     }
1209 
1210     /**
1211      * Returns whether the given point is inside of the window.  Coordinates are local.
1212      */
1213     public boolean contains(int x, int y) {
1214         return x >= 0 && y >= 0 && x < getWidth() && y < getHeight();
1215     }
1216 
1217     /**
1218      * Returns whether the given point is inside of the window.  Coordinates are global.
1219      */
1220     public boolean containsGlobal(int x, int y) {
1221         return x >= getAbsoluteX() && y >= getAbsoluteY() && x < (getAbsoluteX()+getWidth()) && y < (getAbsoluteY()+getHeight());
1222     }
1223 
1224 }