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