/**
   * Called after window creation, descendants should override to initialize Window with
   * class-specific values and perform post-initialization actions.
   */
  void postInit(XCreateWindowParams params) {
    if (log.isLoggable(Level.FINE)) log.fine("WM name is " + getWMName());
    updateWMName();

    // Set WM_CLIENT_LEADER property
    initClientLeader();
  }
  public void dispatchEvent(XEvent xev) {
    if (eventLog.isLoggable(Level.FINEST)) eventLog.finest(xev.toString());
    int type = xev.get_type();

    if (isDisposed()) {
      return;
    }

    switch (type) {
      case VisibilityNotify:
        handleVisibilityEvent(xev);
        break;
      case ClientMessage:
        handleClientMessage(xev);
        break;
      case Expose:
      case GraphicsExpose:
        handleExposeEvent(xev);
        break;
      case ButtonPress:
      case ButtonRelease:
        handleButtonPressRelease(xev);
        break;

      case MotionNotify:
        handleMotionNotify(xev);
        break;
      case KeyPress:
        handleKeyPress(xev);
        break;
      case KeyRelease:
        handleKeyRelease(xev);
        break;
      case EnterNotify:
      case LeaveNotify:
        handleXCrossingEvent(xev);
        break;
      case ConfigureNotify:
        handleConfigureNotifyEvent(xev);
        break;
      case MapNotify:
        handleMapNotifyEvent(xev);
        break;
      case UnmapNotify:
        handleUnmapNotifyEvent(xev);
        break;
      case ReparentNotify:
        handleReparentNotifyEvent(xev);
        break;
      case PropertyNotify:
        handlePropertyNotify(xev);
        break;
      case DestroyNotify:
        handleDestroyNotify(xev);
        break;
      case CreateNotify:
        handleCreateNotify(xev);
        break;
    }
  }
 public void handlePropertyNotify(XEvent xev) {
   XPropertyEvent msg = xev.get_xproperty();
   if (XPropertyCache.isCachingSupported()) {
     XPropertyCache.clearCache(window, XAtom.get(msg.get_atom()));
   }
   if (eventLog.isLoggable(Level.FINER)) {
     eventLog.log(Level.FINER, "{0}", new Object[] {String.valueOf(msg)});
   }
 }
 public void xRequestFocus() {
   XToolkit.awtLock();
   try {
     if (focusLog.isLoggable(Level.FINER))
       focusLog.finer("XSetInputFocus on " + Long.toHexString(getWindow()));
     XlibWrapper.XSetInputFocus(XToolkit.getDisplay(), getWindow());
   } finally {
     XToolkit.awtUnlock();
   }
 }
 public void handleConfigureNotifyEvent(XEvent xev) {
   XConfigureEvent xe = xev.get_xconfigure();
   if (insLog.isLoggable(Level.FINER)) {
     insLog.log(Level.FINER, "Configure, {0}", new Object[] {String.valueOf(xe)});
   }
   x = xe.get_x();
   y = xe.get_y();
   width = xe.get_width();
   height = xe.get_height();
 }
 public void xSetVisible(boolean visible) {
   if (log.isLoggable(Level.FINE)) log.fine("Setting visible on " + this + " to " + visible);
   XToolkit.awtLock();
   try {
     this.visible = visible;
     if (visible) {
       XlibWrapper.XMapWindow(XToolkit.getDisplay(), getWindow());
     } else {
       XlibWrapper.XUnmapWindow(XToolkit.getDisplay(), getWindow());
     }
     XlibWrapper.XFlush(XToolkit.getDisplay());
   } finally {
     XToolkit.awtUnlock();
   }
 }
  /**
   * Creates window using parameters <code>params</code> If params contain flag DELAYED doesn't do
   * anything. Note: Descendants can call this method to create the window at the time different to
   * instance construction.
   */
  protected final void init(XCreateWindowParams params) {
    awtLock();
    initialising = InitialiseState.INITIALISING;
    awtUnlock();

    try {
      if (!Boolean.TRUE.equals(params.get(DELAYED))) {
        preInit(params);
        create(params);
        postInit(params);
      } else {
        instantPreInit(params);
        delayedParams = params;
      }
      awtLock();
      initialising = InitialiseState.INITIALISED;
      awtLockNotifyAll();
      awtUnlock();
    } catch (RuntimeException re) {
      awtLock();
      initialising = InitialiseState.FAILED_INITIALISATION;
      awtLockNotifyAll();
      awtUnlock();
      throw re;
    } catch (Throwable t) {
      log.log(Level.WARNING, "Exception during peer initialization", t);
      awtLock();
      initialising = InitialiseState.FAILED_INITIALISATION;
      awtLockNotifyAll();
      awtUnlock();
    }
  }
 static void ungrabInput() {
   XToolkit.awtLock();
   try {
     XBaseWindow grabWindow = XAwtState.getGrabWindow();
     if (grabLog.isLoggable(Level.FINE)) {
       grabLog.log(Level.FINE, "UnGrab input on {0}", new Object[] {String.valueOf(grabWindow)});
     }
     if (grabWindow != null) {
       grabWindow.ungrabInputImpl();
       XlibWrapper.XUngrabPointer(XToolkit.getDisplay(), CurrentTime);
       XlibWrapper.XUngrabKeyboard(XToolkit.getDisplay(), CurrentTime);
       XAwtState.setGrabWindow(null);
       // we need to call XFlush() here to force ungrab
       // see 6384219 for details
       XlibWrapper.XFlush(XToolkit.getDisplay());
     }
   } finally {
     XToolkit.awtUnlock();
   }
 }
 public void xSetBounds(int x, int y, int width, int height) {
   if (getWindow() == 0) {
     insLog.warning("Attempt to resize uncreated window");
     throw new IllegalStateException("Attempt to resize uncreated window");
   }
   insLog.fine(
       "Setting bounds on " + this + " to (" + x + ", " + y + "), " + width + "x" + height);
   if (width <= 0) {
     width = 1;
   }
   if (height <= 0) {
     height = 1;
   }
   XToolkit.awtLock();
   try {
     XlibWrapper.XMoveResizeWindow(XToolkit.getDisplay(), getWindow(), x, y, width, height);
   } finally {
     XToolkit.awtUnlock();
   }
 }
 public void handleClientMessage(XEvent xev) {
   if (eventLog.isLoggable(Level.FINER)) {
     XClientMessageEvent msg = xev.get_xclient();
     eventLog.finer(msg.toString());
   }
 }
 public void handleReparentNotifyEvent(XEvent xev) {
   if (eventLog.isLoggable(Level.FINER)) {
     XReparentEvent msg = xev.get_xreparent();
     eventLog.finer(msg.toString());
   }
 }
 static void checkSecurity() {
   if (XToolkit.isSecurityWarningEnabled() && XToolkit.isToolkitThread()) {
     StackTraceElement stack[] = (new Throwable()).getStackTrace();
     log.warning(stack[1] + ": Security violation: calling user code on toolkit thread");
   }
 }
  /**
   * We should always grab both keyboard and pointer to control event flow on popups. This also
   * simplifies synthetic grab implementation. The active grab overrides activated automatic grab.
   */
  public boolean grabInput() {
    if (grabLog.isLoggable(Level.FINE)) {
      grabLog.log(Level.FINE, "Grab input on {0}", new Object[] {String.valueOf(this)});
    }

    XToolkit.awtLock();
    try {
      if (XAwtState.getGrabWindow() == this && XAwtState.isManualGrab()) {
        grabLog.fine("    Already Grabbed");
        return true;
      }
      // 6273031: PIT. Choice drop down does not close once it is right clicked to show a popup menu
      // remember previous window having grab and if it's not null ungrab it.
      XBaseWindow prevGrabWindow = XAwtState.getGrabWindow();
      final int eventMask =
          (int)
              (ButtonPressMask
                  | ButtonReleaseMask
                  | EnterWindowMask
                  | LeaveWindowMask
                  | PointerMotionMask
                  | ButtonMotionMask);
      final int ownerEvents = 1;

      int ptrGrab =
          XlibWrapper.XGrabPointer(
              XToolkit.getDisplay(),
              getContentWindow(),
              ownerEvents,
              eventMask,
              GrabModeAsync,
              GrabModeAsync,
              None,
              (XWM.isMotif() ? XToolkit.arrowCursor : None),
              CurrentTime);
      // Check grab results to be consistent with X server grab
      if (ptrGrab != GrabSuccess) {
        XlibWrapper.XUngrabPointer(XToolkit.getDisplay(), CurrentTime);
        XAwtState.setGrabWindow(null);
        grabLog.fine("    Grab Failure - mouse");
        return false;
      }

      int keyGrab =
          XlibWrapper.XGrabKeyboard(
              XToolkit.getDisplay(),
              getContentWindow(),
              ownerEvents,
              GrabModeAsync,
              GrabModeAsync,
              CurrentTime);
      if (keyGrab != GrabSuccess) {
        XlibWrapper.XUngrabPointer(XToolkit.getDisplay(), CurrentTime);
        XlibWrapper.XUngrabKeyboard(XToolkit.getDisplay(), CurrentTime);
        XAwtState.setGrabWindow(null);
        grabLog.fine("    Grab Failure - keyboard");
        return false;
      }
      if (prevGrabWindow != null) {
        prevGrabWindow.ungrabInputImpl();
      }
      XAwtState.setGrabWindow(this);
      grabLog.fine("    Grab - success");
      return true;
    } finally {
      XToolkit.awtUnlock();
    }
  }
 public void setSizeHints(long flags, int x, int y, int width, int height) {
   if (insLog.isLoggable(Level.FINER))
     insLog.finer("Setting hints, flags " + XlibWrapper.hintsToString(flags));
   XToolkit.awtLock();
   try {
     XSizeHints hints = getHints();
     // Note: if PPosition is not set in flags this means that
     // we want to reset PPosition in hints.  This is necessary
     // for locationByPlatform functionality
     if ((flags & XlibWrapper.PPosition) != 0) {
       hints.set_x(x);
       hints.set_y(y);
     }
     if ((flags & XlibWrapper.PSize) != 0) {
       hints.set_width(width);
       hints.set_height(height);
     } else if ((hints.get_flags() & XlibWrapper.PSize) != 0) {
       flags |= XlibWrapper.PSize;
     }
     if ((flags & XlibWrapper.PMinSize) != 0) {
       hints.set_min_width(width);
       hints.set_min_height(height);
     } else if ((hints.get_flags() & XlibWrapper.PMinSize) != 0) {
       flags |= XlibWrapper.PMinSize;
       // Fix for 4320050: Minimum size for java.awt.Frame is not being enforced.
       // We don't need to reset minimum size if it's already set
     }
     if ((flags & XlibWrapper.PMaxSize) != 0) {
       if (maxBounds != null) {
         if (maxBounds.width != Integer.MAX_VALUE) {
           hints.set_max_width(maxBounds.width);
         } else {
           hints.set_max_width(XToolkit.getDefaultScreenWidth());
         }
         if (maxBounds.height != Integer.MAX_VALUE) {
           hints.set_max_height(maxBounds.height);
         } else {
           hints.set_max_height(XToolkit.getDefaultScreenHeight());
         }
       } else {
         hints.set_max_width(width);
         hints.set_max_height(height);
       }
     } else if ((hints.get_flags() & XlibWrapper.PMaxSize) != 0) {
       flags |= XlibWrapper.PMaxSize;
       if (maxBounds != null) {
         if (maxBounds.width != Integer.MAX_VALUE) {
           hints.set_max_width(maxBounds.width);
         } else {
           hints.set_max_width(XToolkit.getDefaultScreenWidth());
         }
         if (maxBounds.height != Integer.MAX_VALUE) {
           hints.set_max_height(maxBounds.height);
         } else {
           hints.set_max_height(XToolkit.getDefaultScreenHeight());
         }
       } else {
         // Leave intact
       }
     }
     flags |= XlibWrapper.PWinGravity;
     hints.set_flags(flags);
     hints.set_win_gravity((int) XlibWrapper.NorthWestGravity);
     if (insLog.isLoggable(Level.FINER))
       insLog.finer(
           "Setting hints, resulted flags "
               + XlibWrapper.hintsToString(flags)
               + ", values "
               + hints);
     XlibWrapper.XSetWMNormalHints(XToolkit.getDisplay(), getWindow(), hints.pData);
   } finally {
     XToolkit.awtUnlock();
   }
 }
public class XBaseWindow implements XConstants, XUtilConstants {
  private static final Logger log = Logger.getLogger("sun.awt.X11.XBaseWindow");
  private static final Logger insLog = Logger.getLogger("sun.awt.X11.insets.XBaseWindow");
  private static final Logger eventLog = Logger.getLogger("sun.awt.X11.event.XBaseWindow");
  private static final Logger focusLog = Logger.getLogger("sun.awt.X11.focus.XBaseWindow");
  private static final Logger grabLog = Logger.getLogger("sun.awt.X11.grab.XBaseWindow");

  public static final String PARENT_WINDOW = "parent window", // parent window, Long
      BOUNDS = "bounds", // bounds of the window, Rectangle
      OVERRIDE_REDIRECT = "overrideRedirect", // override_redirect setting, Boolean
      EVENT_MASK = "event mask", // event mask, Integer
      VALUE_MASK = "value mask", // value mask, Long
      BORDER_PIXEL = "border pixel", // border pixel value, Integer
      COLORMAP = "color map", // color map, Long
      DEPTH = "visual depth", // depth, Integer
      VISUAL_CLASS = "visual class", // visual class, Integer
      VISUAL = "visual", // visual, Long
      EMBEDDED = "embedded", // is embedded?, Boolean
      DELAYED = "delayed", // is creation delayed?, Boolean
      PARENT = "parent", // parent peer
      BACKGROUND_PIXMAP = "pixmap", // background pixmap
      VISIBLE = "visible", // whether it is visible by default
      SAVE_UNDER = "save under", // save content under this window
      BACKING_STORE = "backing store", // enables double buffering
      BIT_GRAVITY = "bit gravity"; // copy old content on geometry change
  private XCreateWindowParams delayedParams;

  Set<Long> children = new HashSet<Long>();
  long window;
  boolean visible;
  boolean mapped;
  boolean embedded;
  Rectangle maxBounds;
  volatile XBaseWindow parentWindow;

  private boolean disposed;

  private long screen;
  private XSizeHints hints;
  private XWMHints wmHints;

  static final int MIN_SIZE = 1;
  static final int DEF_LOCATION = 1;

  private static XAtom wm_client_leader;

  static enum InitialiseState {
    INITIALISING,
    NOT_INITIALISED,
    INITIALISED,
    FAILED_INITIALISATION
  };

  private InitialiseState initialising;

  int x;
  int y;
  int width;
  int height;

  void awtLock() {
    XToolkit.awtLock();
  }

  void awtUnlock() {
    XToolkit.awtUnlock();
  }

  void awtLockNotifyAll() {
    XToolkit.awtLockNotifyAll();
  }

  void awtLockWait() throws InterruptedException {
    XToolkit.awtLockWait();
  }

  // To prevent errors from overriding obsolete methods
  protected final void init(long parentWindow, Rectangle bounds) {}

  protected final void preInit() {}

  protected final void postInit() {}

  // internal lock for synchronizing state changes and paint calls, initialized in preInit.
  // the order with other locks: AWTLock -> stateLock
  static class StateLock extends Object {}

  protected StateLock state_lock;

  /** Called for delayed inits during construction */
  void instantPreInit(XCreateWindowParams params) {
    state_lock = new StateLock();
    initialising = InitialiseState.NOT_INITIALISED;
  }

  /**
   * Called before window creation, descendants should override to initialize the data, initialize
   * params.
   */
  void preInit(XCreateWindowParams params) {
    state_lock = new StateLock();
    initialising = InitialiseState.NOT_INITIALISED;
    embedded = Boolean.TRUE.equals(params.get(EMBEDDED));
    visible = Boolean.TRUE.equals(params.get(VISIBLE));

    Object parent = params.get(PARENT);
    if (parent instanceof XBaseWindow) {
      parentWindow = (XBaseWindow) parent;
    } else {
      Long parentWindowID = (Long) params.get(PARENT_WINDOW);
      if (parentWindowID != null) {
        parentWindow = XToolkit.windowToXWindow(parentWindowID);
      }
    }

    Long eventMask = (Long) params.get(EVENT_MASK);
    if (eventMask != null) {
      long mask = eventMask.longValue();
      mask |= SubstructureNotifyMask;
      params.put(EVENT_MASK, mask);
    }

    screen = -1;
  }

  /**
   * Called after window creation, descendants should override to initialize Window with
   * class-specific values and perform post-initialization actions.
   */
  void postInit(XCreateWindowParams params) {
    if (log.isLoggable(Level.FINE)) log.fine("WM name is " + getWMName());
    updateWMName();

    // Set WM_CLIENT_LEADER property
    initClientLeader();
  }

  /**
   * Creates window using parameters <code>params</code> If params contain flag DELAYED doesn't do
   * anything. Note: Descendants can call this method to create the window at the time different to
   * instance construction.
   */
  protected final void init(XCreateWindowParams params) {
    awtLock();
    initialising = InitialiseState.INITIALISING;
    awtUnlock();

    try {
      if (!Boolean.TRUE.equals(params.get(DELAYED))) {
        preInit(params);
        create(params);
        postInit(params);
      } else {
        instantPreInit(params);
        delayedParams = params;
      }
      awtLock();
      initialising = InitialiseState.INITIALISED;
      awtLockNotifyAll();
      awtUnlock();
    } catch (RuntimeException re) {
      awtLock();
      initialising = InitialiseState.FAILED_INITIALISATION;
      awtLockNotifyAll();
      awtUnlock();
      throw re;
    } catch (Throwable t) {
      log.log(Level.WARNING, "Exception during peer initialization", t);
      awtLock();
      initialising = InitialiseState.FAILED_INITIALISATION;
      awtLockNotifyAll();
      awtUnlock();
    }
  }

  public boolean checkInitialised() {
    awtLock();
    try {
      switch (initialising) {
        case INITIALISED:
          return true;
        case INITIALISING:
          try {
            while (initialising != InitialiseState.INITIALISED) {
              awtLockWait();
            }
          } catch (InterruptedException ie) {
            return false;
          }
          return true;
        case NOT_INITIALISED:
        case FAILED_INITIALISATION:
          return false;
        default:
          return false;
      }
    } finally {
      awtUnlock();
    }
  }

  /*
   * Creates an invisible InputOnly window without an associated Component.
   */
  XBaseWindow() {
    this(new XCreateWindowParams());
  }

  /** Creates normal child window */
  XBaseWindow(long parentWindow, Rectangle bounds) {
    this(
        new XCreateWindowParams(
            new Object[] {BOUNDS, bounds, PARENT_WINDOW, Long.valueOf(parentWindow)}));
  }

  /** Creates top-level window */
  XBaseWindow(Rectangle bounds) {
    this(new XCreateWindowParams(new Object[] {BOUNDS, bounds}));
  }

  public XBaseWindow(XCreateWindowParams params) {
    init(params);
  }

  /* This create is used by the XEmbeddedFramePeer since it has to create the window
  as a child of the netscape window. This netscape window is passed in as wid */
  XBaseWindow(long parentWindow) {
    this(
        new XCreateWindowParams(
            new Object[] {PARENT_WINDOW, Long.valueOf(parentWindow), EMBEDDED, Boolean.TRUE}));
  }

  /**
   * Verifies that all required parameters are set. If not, sets them to default values. Verifies
   * values of critical parameters, adjust their values when needed.
   *
   * @throws IllegalArgumentException if params is null
   */
  protected void checkParams(XCreateWindowParams params) {
    if (params == null) {
      throw new IllegalArgumentException("Window creation parameters are null");
    }
    params.putIfNull(PARENT_WINDOW, Long.valueOf(XToolkit.getDefaultRootWindow()));
    params.putIfNull(BOUNDS, new Rectangle(DEF_LOCATION, DEF_LOCATION, MIN_SIZE, MIN_SIZE));
    params.putIfNull(DEPTH, Integer.valueOf((int) XlibWrapper.CopyFromParent));
    params.putIfNull(VISUAL, Long.valueOf(XlibWrapper.CopyFromParent));
    params.putIfNull(VISUAL_CLASS, Integer.valueOf((int) XlibWrapper.InputOnly));
    params.putIfNull(VALUE_MASK, Long.valueOf(XlibWrapper.CWEventMask));
    Rectangle bounds = (Rectangle) params.get(BOUNDS);
    bounds.width = Math.max(MIN_SIZE, bounds.width);
    bounds.height = Math.max(MIN_SIZE, bounds.height);

    Long eventMaskObj = (Long) params.get(EVENT_MASK);
    long eventMask = eventMaskObj != null ? eventMaskObj.longValue() : 0;
    // We use our own synthetic grab see XAwtState.getGrabWindow()
    // (see X vol. 1, 8.3.3.2)
    eventMask |= PropertyChangeMask | OwnerGrabButtonMask;
    params.put(EVENT_MASK, Long.valueOf(eventMask));
  }

  /**
   * Creates window with parameters specified by <code>params</code>
   *
   * @see #init
   */
  private final void create(XCreateWindowParams params) {
    XToolkit.awtLock();
    try {
      XSetWindowAttributes xattr = new XSetWindowAttributes();
      try {
        checkParams(params);

        long value_mask = ((Long) params.get(VALUE_MASK)).longValue();

        Long eventMask = (Long) params.get(EVENT_MASK);
        xattr.set_event_mask(eventMask.longValue());
        value_mask |= XlibWrapper.CWEventMask;

        Long border_pixel = (Long) params.get(BORDER_PIXEL);
        if (border_pixel != null) {
          xattr.set_border_pixel(border_pixel.longValue());
          value_mask |= XlibWrapper.CWBorderPixel;
        }

        Long colormap = (Long) params.get(COLORMAP);
        if (colormap != null) {
          xattr.set_colormap(colormap.longValue());
          value_mask |= XlibWrapper.CWColormap;
        }
        Long background_pixmap = (Long) params.get(BACKGROUND_PIXMAP);
        if (background_pixmap != null) {
          xattr.set_background_pixmap(background_pixmap.longValue());
          value_mask |= XlibWrapper.CWBackPixmap;
        }

        Long parentWindow = (Long) params.get(PARENT_WINDOW);
        Rectangle bounds = (Rectangle) params.get(BOUNDS);
        Integer depth = (Integer) params.get(DEPTH);
        Integer visual_class = (Integer) params.get(VISUAL_CLASS);
        Long visual = (Long) params.get(VISUAL);
        Boolean overrideRedirect = (Boolean) params.get(OVERRIDE_REDIRECT);
        if (overrideRedirect != null) {
          xattr.set_override_redirect(overrideRedirect.booleanValue());
          value_mask |= XlibWrapper.CWOverrideRedirect;
        }

        Boolean saveUnder = (Boolean) params.get(SAVE_UNDER);
        if (saveUnder != null) {
          xattr.set_save_under(saveUnder.booleanValue());
          value_mask |= XlibWrapper.CWSaveUnder;
        }

        Integer backingStore = (Integer) params.get(BACKING_STORE);
        if (backingStore != null) {
          xattr.set_backing_store(backingStore.intValue());
          value_mask |= XlibWrapper.CWBackingStore;
        }

        Integer bitGravity = (Integer) params.get(BIT_GRAVITY);
        if (bitGravity != null) {
          xattr.set_bit_gravity(bitGravity.intValue());
          value_mask |= XlibWrapper.CWBitGravity;
        }

        if (log.isLoggable(Level.FINE)) {
          log.fine("Creating window for " + this + " with the following attributes: \n" + params);
        }
        window =
            XlibWrapper.XCreateWindow(
                XToolkit.getDisplay(),
                parentWindow.longValue(),
                bounds.x,
                bounds.y, // location
                bounds.width,
                bounds.height, // size
                0, // border
                depth.intValue(), // depth
                visual_class.intValue(), // class
                visual.longValue(), // visual
                value_mask, // value mask
                xattr.pData); // attributes

        if (window == 0) {
          throw new IllegalStateException(
              "Couldn't create window because of wrong parameters. Run with NOISY_AWT to see details");
        }
        XToolkit.addToWinMap(window, this);
      } finally {
        xattr.dispose();
      }
    } finally {
      XToolkit.awtUnlock();
    }
  }

  public XCreateWindowParams getDelayedParams() {
    return delayedParams;
  }

  protected String getWMName() {
    return XToolkit.getCorrectXIDString(getClass().getName());
  }

  protected void initClientLeader() {
    XToolkit.awtLock();
    try {
      if (wm_client_leader == null) {
        wm_client_leader = XAtom.get("WM_CLIENT_LEADER");
      }
      wm_client_leader.setWindowProperty(this, getXAWTRootWindow());
    } finally {
      XToolkit.awtUnlock();
    }
  }

  static XRootWindow getXAWTRootWindow() {
    return XRootWindow.getInstance();
  }

  void destroy() {
    XToolkit.awtLock();
    try {
      if (hints != null) {
        XlibWrapper.XFree(hints.pData);
        hints = null;
      }
      XToolkit.removeFromWinMap(getWindow(), this);
      XlibWrapper.XDestroyWindow(XToolkit.getDisplay(), getWindow());
      if (XPropertyCache.isCachingSupported()) {
        XPropertyCache.clearCache(window);
      }
      window = -1;
      if (!isDisposed()) {
        setDisposed(true);
      }

      XAwtState
          .getGrabWindow(); // Magic - getGrabWindow clear state if grabbing window is disposed of.
    } finally {
      XToolkit.awtUnlock();
    }
  }

  void flush() {
    XToolkit.awtLock();
    try {
      XlibWrapper.XFlush(XToolkit.getDisplay());
    } finally {
      XToolkit.awtUnlock();
    }
  }

  /** Helper function to set W */
  public final void setWMHints(XWMHints hints) {
    XToolkit.awtLock();
    try {
      XlibWrapper.XSetWMHints(XToolkit.getDisplay(), getWindow(), hints.pData);
    } finally {
      XToolkit.awtUnlock();
    }
  }

  public XWMHints getWMHints() {
    if (wmHints == null) {
      wmHints = new XWMHints(XlibWrapper.XAllocWMHints());
      //              XlibWrapper.XGetWMHints(XToolkit.getDisplay(),
      //                                      getWindow(),
      //                                      wmHints.pData);
    }
    return wmHints;
  }

  /*
   * Call this method under AWTLock.
   * The lock should be acquired untill all operations with XSizeHints are completed.
   */
  public XSizeHints getHints() {
    if (hints == null) {
      long p_hints = XlibWrapper.XAllocSizeHints();
      hints = new XSizeHints(p_hints);
      //              XlibWrapper.XGetWMNormalHints(XToolkit.getDisplay(), getWindow(), p_hints,
      // XlibWrapper.larg1);
      // TODO: Shouldn't we listen for WM updates on this property?
    }
    return hints;
  }

  public void setSizeHints(long flags, int x, int y, int width, int height) {
    if (insLog.isLoggable(Level.FINER))
      insLog.finer("Setting hints, flags " + XlibWrapper.hintsToString(flags));
    XToolkit.awtLock();
    try {
      XSizeHints hints = getHints();
      // Note: if PPosition is not set in flags this means that
      // we want to reset PPosition in hints.  This is necessary
      // for locationByPlatform functionality
      if ((flags & XlibWrapper.PPosition) != 0) {
        hints.set_x(x);
        hints.set_y(y);
      }
      if ((flags & XlibWrapper.PSize) != 0) {
        hints.set_width(width);
        hints.set_height(height);
      } else if ((hints.get_flags() & XlibWrapper.PSize) != 0) {
        flags |= XlibWrapper.PSize;
      }
      if ((flags & XlibWrapper.PMinSize) != 0) {
        hints.set_min_width(width);
        hints.set_min_height(height);
      } else if ((hints.get_flags() & XlibWrapper.PMinSize) != 0) {
        flags |= XlibWrapper.PMinSize;
        // Fix for 4320050: Minimum size for java.awt.Frame is not being enforced.
        // We don't need to reset minimum size if it's already set
      }
      if ((flags & XlibWrapper.PMaxSize) != 0) {
        if (maxBounds != null) {
          if (maxBounds.width != Integer.MAX_VALUE) {
            hints.set_max_width(maxBounds.width);
          } else {
            hints.set_max_width(XToolkit.getDefaultScreenWidth());
          }
          if (maxBounds.height != Integer.MAX_VALUE) {
            hints.set_max_height(maxBounds.height);
          } else {
            hints.set_max_height(XToolkit.getDefaultScreenHeight());
          }
        } else {
          hints.set_max_width(width);
          hints.set_max_height(height);
        }
      } else if ((hints.get_flags() & XlibWrapper.PMaxSize) != 0) {
        flags |= XlibWrapper.PMaxSize;
        if (maxBounds != null) {
          if (maxBounds.width != Integer.MAX_VALUE) {
            hints.set_max_width(maxBounds.width);
          } else {
            hints.set_max_width(XToolkit.getDefaultScreenWidth());
          }
          if (maxBounds.height != Integer.MAX_VALUE) {
            hints.set_max_height(maxBounds.height);
          } else {
            hints.set_max_height(XToolkit.getDefaultScreenHeight());
          }
        } else {
          // Leave intact
        }
      }
      flags |= XlibWrapper.PWinGravity;
      hints.set_flags(flags);
      hints.set_win_gravity((int) XlibWrapper.NorthWestGravity);
      if (insLog.isLoggable(Level.FINER))
        insLog.finer(
            "Setting hints, resulted flags "
                + XlibWrapper.hintsToString(flags)
                + ", values "
                + hints);
      XlibWrapper.XSetWMNormalHints(XToolkit.getDisplay(), getWindow(), hints.pData);
    } finally {
      XToolkit.awtUnlock();
    }
  }

  public boolean isMinSizeSet() {
    XSizeHints hints = getHints();
    long flags = hints.get_flags();
    return ((flags & XlibWrapper.PMinSize) == XlibWrapper.PMinSize);
  }

  /**
   * This lock object can be used to protect instance data from concurrent access by two threads. If
   * both state lock and AWT lock are taken, AWT Lock should be taken first.
   */
  Object getStateLock() {
    return state_lock;
  }

  public long getWindow() {
    return window;
  }

  public long getContentWindow() {
    return window;
  }

  public XBaseWindow getContentXWindow() {
    return XToolkit.windowToXWindow(getContentWindow());
  }

  public Rectangle getBounds() {
    return new Rectangle(x, y, width, height);
  }

  public Dimension getSize() {
    return new Dimension(width, height);
  }

  public void toFront() {
    XToolkit.awtLock();
    try {
      XlibWrapper.XRaiseWindow(XToolkit.getDisplay(), getWindow());
    } finally {
      XToolkit.awtUnlock();
    }
  }

  public void xRequestFocus(long time) {
    XToolkit.awtLock();
    try {
      if (focusLog.isLoggable(Level.FINER))
        focusLog.finer("XSetInputFocus on " + Long.toHexString(getWindow()) + " with time " + time);
      XlibWrapper.XSetInputFocus2(XToolkit.getDisplay(), getWindow(), time);
    } finally {
      XToolkit.awtUnlock();
    }
  }

  public void xRequestFocus() {
    XToolkit.awtLock();
    try {
      if (focusLog.isLoggable(Level.FINER))
        focusLog.finer("XSetInputFocus on " + Long.toHexString(getWindow()));
      XlibWrapper.XSetInputFocus(XToolkit.getDisplay(), getWindow());
    } finally {
      XToolkit.awtUnlock();
    }
  }

  public static long xGetInputFocus() {
    XToolkit.awtLock();
    try {
      return XlibWrapper.XGetInputFocus(XToolkit.getDisplay());
    } finally {
      XToolkit.awtUnlock();
    }
  }

  public void xSetVisible(boolean visible) {
    if (log.isLoggable(Level.FINE)) log.fine("Setting visible on " + this + " to " + visible);
    XToolkit.awtLock();
    try {
      this.visible = visible;
      if (visible) {
        XlibWrapper.XMapWindow(XToolkit.getDisplay(), getWindow());
      } else {
        XlibWrapper.XUnmapWindow(XToolkit.getDisplay(), getWindow());
      }
      XlibWrapper.XFlush(XToolkit.getDisplay());
    } finally {
      XToolkit.awtUnlock();
    }
  }

  boolean isMapped() {
    return mapped;
  }

  void updateWMName() {
    String name = getWMName();
    XToolkit.awtLock();
    try {
      if (name == null) {
        name = " ";
      }
      XAtom nameAtom = XAtom.get(XAtom.XA_WM_NAME);
      nameAtom.setProperty(getWindow(), name);
      XAtom netNameAtom = XAtom.get("_NET_WM_NAME");
      netNameAtom.setPropertyUTF8(getWindow(), name);
    } finally {
      XToolkit.awtUnlock();
    }
  }

  void setWMClass(String[] cl) {
    if (cl.length != 2) {
      throw new IllegalArgumentException("WM_CLASS_NAME consists of exactly two strings");
    }
    XToolkit.awtLock();
    try {
      XAtom xa = XAtom.get(XAtom.XA_WM_CLASS);
      xa.setProperty8(getWindow(), cl[0] + '\0' + cl[1]);
    } finally {
      XToolkit.awtUnlock();
    }
  }

  boolean isVisible() {
    return visible;
  }

  static long getScreenOfWindow(long window) {
    XToolkit.awtLock();
    try {
      return XlibWrapper.getScreenOfWindow(XToolkit.getDisplay(), window);
    } finally {
      XToolkit.awtUnlock();
    }
  }

  long getScreenNumber() {
    XToolkit.awtLock();
    try {
      return XlibWrapper.XScreenNumberOfScreen(getScreen());
    } finally {
      XToolkit.awtUnlock();
    }
  }

  long getScreen() {
    if (screen == -1) { // Not initialized
      screen = getScreenOfWindow(window);
    }
    return screen;
  }

  public void xSetBounds(Rectangle bounds) {
    xSetBounds(bounds.x, bounds.y, bounds.width, bounds.height);
  }

  public void xSetBounds(int x, int y, int width, int height) {
    if (getWindow() == 0) {
      insLog.warning("Attempt to resize uncreated window");
      throw new IllegalStateException("Attempt to resize uncreated window");
    }
    insLog.fine(
        "Setting bounds on " + this + " to (" + x + ", " + y + "), " + width + "x" + height);
    if (width <= 0) {
      width = 1;
    }
    if (height <= 0) {
      height = 1;
    }
    XToolkit.awtLock();
    try {
      XlibWrapper.XMoveResizeWindow(XToolkit.getDisplay(), getWindow(), x, y, width, height);
    } finally {
      XToolkit.awtUnlock();
    }
  }

  /**
   * Translate coordinates from one window into another. Optimized for XAWT - uses cached data when
   * possible. Preferable over pure XTranslateCoordinates.
   *
   * @return coordinates relative to dst, or null if error happened
   */
  static Point toOtherWindow(long src, long dst, int x, int y) {
    Point rpt = new Point(0, 0);

    // Check if both windows belong to XAWT - then no X calls are necessary

    XBaseWindow srcPeer = XToolkit.windowToXWindow(src);
    XBaseWindow dstPeer = XToolkit.windowToXWindow(dst);

    if (srcPeer != null && dstPeer != null) {
      // (x, y) is relative to src
      rpt.x = x + srcPeer.getAbsoluteX() - dstPeer.getAbsoluteX();
      rpt.y = y + srcPeer.getAbsoluteY() - dstPeer.getAbsoluteY();
    } else if (dstPeer != null && XlibUtil.isRoot(src, dstPeer.getScreenNumber())) {
      // from root into peer
      rpt.x = x - dstPeer.getAbsoluteX();
      rpt.y = y - dstPeer.getAbsoluteY();
    } else if (srcPeer != null && XlibUtil.isRoot(dst, srcPeer.getScreenNumber())) {
      // from peer into root
      rpt.x = x + srcPeer.getAbsoluteX();
      rpt.y = y + srcPeer.getAbsoluteY();
    } else {
      rpt = XlibUtil.translateCoordinates(src, dst, new Point(x, y));
    }
    return rpt;
  }

  /*
   * Convert to global coordinates.
   */
  Rectangle toGlobal(Rectangle rec) {
    Point p = toGlobal(rec.getLocation());
    Rectangle newRec = new Rectangle(rec);
    if (p != null) {
      newRec.setLocation(p);
    }
    return newRec;
  }

  Point toGlobal(Point pt) {
    Point p = toGlobal(pt.x, pt.y);
    if (p != null) {
      return p;
    } else {
      return new Point(pt);
    }
  }

  Point toGlobal(int x, int y) {
    long root;
    XToolkit.awtLock();
    try {
      root = XlibWrapper.RootWindow(XToolkit.getDisplay(), getScreenNumber());
    } finally {
      XToolkit.awtUnlock();
    }
    Point p = toOtherWindow(getContentWindow(), root, x, y);
    if (p != null) {
      return p;
    } else {
      return new Point(x, y);
    }
  }

  /*
   * Convert to local coordinates.
   */
  Point toLocal(Point pt) {
    Point p = toLocal(pt.x, pt.y);
    if (p != null) {
      return p;
    } else {
      return new Point(pt);
    }
  }

  Point toLocal(int x, int y) {
    long root;
    XToolkit.awtLock();
    try {
      root = XlibWrapper.RootWindow(XToolkit.getDisplay(), getScreenNumber());
    } finally {
      XToolkit.awtUnlock();
    }
    Point p = toOtherWindow(root, getContentWindow(), x, y);
    if (p != null) {
      return p;
    } else {
      return new Point(x, y);
    }
  }

  /**
   * We should always grab both keyboard and pointer to control event flow on popups. This also
   * simplifies synthetic grab implementation. The active grab overrides activated automatic grab.
   */
  public boolean grabInput() {
    if (grabLog.isLoggable(Level.FINE)) {
      grabLog.log(Level.FINE, "Grab input on {0}", new Object[] {String.valueOf(this)});
    }

    XToolkit.awtLock();
    try {
      if (XAwtState.getGrabWindow() == this && XAwtState.isManualGrab()) {
        grabLog.fine("    Already Grabbed");
        return true;
      }
      // 6273031: PIT. Choice drop down does not close once it is right clicked to show a popup menu
      // remember previous window having grab and if it's not null ungrab it.
      XBaseWindow prevGrabWindow = XAwtState.getGrabWindow();
      final int eventMask =
          (int)
              (ButtonPressMask
                  | ButtonReleaseMask
                  | EnterWindowMask
                  | LeaveWindowMask
                  | PointerMotionMask
                  | ButtonMotionMask);
      final int ownerEvents = 1;

      int ptrGrab =
          XlibWrapper.XGrabPointer(
              XToolkit.getDisplay(),
              getContentWindow(),
              ownerEvents,
              eventMask,
              GrabModeAsync,
              GrabModeAsync,
              None,
              (XWM.isMotif() ? XToolkit.arrowCursor : None),
              CurrentTime);
      // Check grab results to be consistent with X server grab
      if (ptrGrab != GrabSuccess) {
        XlibWrapper.XUngrabPointer(XToolkit.getDisplay(), CurrentTime);
        XAwtState.setGrabWindow(null);
        grabLog.fine("    Grab Failure - mouse");
        return false;
      }

      int keyGrab =
          XlibWrapper.XGrabKeyboard(
              XToolkit.getDisplay(),
              getContentWindow(),
              ownerEvents,
              GrabModeAsync,
              GrabModeAsync,
              CurrentTime);
      if (keyGrab != GrabSuccess) {
        XlibWrapper.XUngrabPointer(XToolkit.getDisplay(), CurrentTime);
        XlibWrapper.XUngrabKeyboard(XToolkit.getDisplay(), CurrentTime);
        XAwtState.setGrabWindow(null);
        grabLog.fine("    Grab Failure - keyboard");
        return false;
      }
      if (prevGrabWindow != null) {
        prevGrabWindow.ungrabInputImpl();
      }
      XAwtState.setGrabWindow(this);
      grabLog.fine("    Grab - success");
      return true;
    } finally {
      XToolkit.awtUnlock();
    }
  }

  static void ungrabInput() {
    XToolkit.awtLock();
    try {
      XBaseWindow grabWindow = XAwtState.getGrabWindow();
      if (grabLog.isLoggable(Level.FINE)) {
        grabLog.log(Level.FINE, "UnGrab input on {0}", new Object[] {String.valueOf(grabWindow)});
      }
      if (grabWindow != null) {
        grabWindow.ungrabInputImpl();
        XlibWrapper.XUngrabPointer(XToolkit.getDisplay(), CurrentTime);
        XlibWrapper.XUngrabKeyboard(XToolkit.getDisplay(), CurrentTime);
        XAwtState.setGrabWindow(null);
        // we need to call XFlush() here to force ungrab
        // see 6384219 for details
        XlibWrapper.XFlush(XToolkit.getDisplay());
      }
    } finally {
      XToolkit.awtUnlock();
    }
  }

  // called from ungrabInput, used in popup windows to hide theirselfs in ungrabbing
  void ungrabInputImpl() {}

  static void checkSecurity() {
    if (XToolkit.isSecurityWarningEnabled() && XToolkit.isToolkitThread()) {
      StackTraceElement stack[] = (new Throwable()).getStackTrace();
      log.warning(stack[1] + ": Security violation: calling user code on toolkit thread");
    }
  }

  public Set<Long> getChildren() {
    synchronized (getStateLock()) {
      return new HashSet<Long>(children);
    }
  }

  // -------------- Event handling ----------------
  public void handleMapNotifyEvent(XEvent xev) {
    mapped = true;
  }

  public void handleUnmapNotifyEvent(XEvent xev) {
    mapped = false;
  }

  public void handleReparentNotifyEvent(XEvent xev) {
    if (eventLog.isLoggable(Level.FINER)) {
      XReparentEvent msg = xev.get_xreparent();
      eventLog.finer(msg.toString());
    }
  }

  public void handlePropertyNotify(XEvent xev) {
    XPropertyEvent msg = xev.get_xproperty();
    if (XPropertyCache.isCachingSupported()) {
      XPropertyCache.clearCache(window, XAtom.get(msg.get_atom()));
    }
    if (eventLog.isLoggable(Level.FINER)) {
      eventLog.log(Level.FINER, "{0}", new Object[] {String.valueOf(msg)});
    }
  }

  public void handleDestroyNotify(XEvent xev) {
    XAnyEvent xany = xev.get_xany();
    if (xany.get_window() == getWindow()) {
      XToolkit.removeFromWinMap(getWindow(), this);
      if (XPropertyCache.isCachingSupported()) {
        XPropertyCache.clearCache(getWindow());
      }
    }
    if (xany.get_window() != getWindow()) {
      synchronized (getStateLock()) {
        children.remove(xany.get_window());
      }
    }
  }

  public void handleCreateNotify(XEvent xev) {
    XAnyEvent xany = xev.get_xany();
    if (xany.get_window() != getWindow()) {
      synchronized (getStateLock()) {
        children.add(xany.get_window());
      }
    }
  }

  public void handleClientMessage(XEvent xev) {
    if (eventLog.isLoggable(Level.FINER)) {
      XClientMessageEvent msg = xev.get_xclient();
      eventLog.finer(msg.toString());
    }
  }

  public void handleVisibilityEvent(XEvent xev) {}

  public void handleKeyPress(XEvent xev) {}

  public void handleKeyRelease(XEvent xev) {}

  public void handleExposeEvent(XEvent xev) {}
  /** Activate automatic grab on first ButtonPress, deactivate on full mouse release */
  public void handleButtonPressRelease(XEvent xev) {
    XButtonEvent xbe = xev.get_xbutton();
    final int buttonState =
        xbe.get_state() & (Button1Mask | Button2Mask | Button3Mask | Button4Mask | Button5Mask);
    switch (xev.get_type()) {
      case ButtonPress:
        if (buttonState == 0) {
          XAwtState.setAutoGrabWindow(this);
        }
        break;
      case ButtonRelease:
        if (isFullRelease(buttonState, xbe.get_button())) {
          XAwtState.setAutoGrabWindow(null);
        }
        break;
    }
  }

  public void handleMotionNotify(XEvent xev) {}

  public void handleXCrossingEvent(XEvent xev) {}

  public void handleConfigureNotifyEvent(XEvent xev) {
    XConfigureEvent xe = xev.get_xconfigure();
    if (insLog.isLoggable(Level.FINER)) {
      insLog.log(Level.FINER, "Configure, {0}", new Object[] {String.valueOf(xe)});
    }
    x = xe.get_x();
    y = xe.get_y();
    width = xe.get_width();
    height = xe.get_height();
  }
  /** Checks ButtonRelease released all Mouse buttons */
  static boolean isFullRelease(int buttonState, int button) {
    switch (button) {
      case Button1:
        return buttonState == Button1Mask;
      case Button2:
        return buttonState == Button2Mask;
      case Button3:
        return buttonState == Button3Mask;
      case Button4:
        return buttonState == Button4Mask;
      case Button5:
        return buttonState == Button5Mask;
    }
    return buttonState == 0;
  }

  static boolean isGrabbedEvent(XEvent ev, XBaseWindow target) {
    switch (ev.get_type()) {
      case ButtonPress:
      case ButtonRelease:
      case MotionNotify:
      case KeyPress:
      case KeyRelease:
        return true;
      case LeaveNotify:
      case EnterNotify:
        // We shouldn't dispatch this events to the grabbed components (see 6317481)
        // But this logic is important if the grabbed component is top-level (see realSync)
        return (target instanceof XWindowPeer);
      default:
        return false;
    }
  }
  /**
   * Dispatches event to the grab Window or event source window depending on whether the grab is
   * active and on the event type
   */
  static void dispatchToWindow(XEvent ev) {
    XBaseWindow target = XAwtState.getGrabWindow();
    if (target == null || !isGrabbedEvent(ev, target)) {
      target = XToolkit.windowToXWindow(ev.get_xany().get_window());
    }
    if (target != null && target.checkInitialised()) {
      target.dispatchEvent(ev);
    }
  }

  public void dispatchEvent(XEvent xev) {
    if (eventLog.isLoggable(Level.FINEST)) eventLog.finest(xev.toString());
    int type = xev.get_type();

    if (isDisposed()) {
      return;
    }

    switch (type) {
      case VisibilityNotify:
        handleVisibilityEvent(xev);
        break;
      case ClientMessage:
        handleClientMessage(xev);
        break;
      case Expose:
      case GraphicsExpose:
        handleExposeEvent(xev);
        break;
      case ButtonPress:
      case ButtonRelease:
        handleButtonPressRelease(xev);
        break;

      case MotionNotify:
        handleMotionNotify(xev);
        break;
      case KeyPress:
        handleKeyPress(xev);
        break;
      case KeyRelease:
        handleKeyRelease(xev);
        break;
      case EnterNotify:
      case LeaveNotify:
        handleXCrossingEvent(xev);
        break;
      case ConfigureNotify:
        handleConfigureNotifyEvent(xev);
        break;
      case MapNotify:
        handleMapNotifyEvent(xev);
        break;
      case UnmapNotify:
        handleUnmapNotifyEvent(xev);
        break;
      case ReparentNotify:
        handleReparentNotifyEvent(xev);
        break;
      case PropertyNotify:
        handlePropertyNotify(xev);
        break;
      case DestroyNotify:
        handleDestroyNotify(xev);
        break;
      case CreateNotify:
        handleCreateNotify(xev);
        break;
    }
  }

  protected boolean isEventDisabled(XEvent e) {
    return false;
  }

  int getX() {
    return x;
  }

  int getY() {
    return y;
  }

  int getWidth() {
    return width;
  }

  int getHeight() {
    return height;
  }

  void setDisposed(boolean d) {
    disposed = d;
  }

  boolean isDisposed() {
    return disposed;
  }

  public int getAbsoluteX() {
    XBaseWindow pw = getParentWindow();
    if (pw != null) {
      return pw.getAbsoluteX() + getX();
    } else {
      // Overridden for top-levels as their (x,y) is Java (x, y), not native location
      return getX();
    }
  }

  public int getAbsoluteY() {
    XBaseWindow pw = getParentWindow();
    if (pw != null) {
      return pw.getAbsoluteY() + getY();
    } else {
      return getY();
    }
  }

  public XBaseWindow getParentWindow() {
    return parentWindow;
  }

  public XWindowPeer getToplevelXWindow() {
    XBaseWindow bw = this;
    while (bw != null && !(bw instanceof XWindowPeer)) {
      bw = bw.getParentWindow();
    }
    return (XWindowPeer) bw;
  }

  public String toString() {
    return super.toString() + "(" + Long.toString(getWindow(), 16) + ")";
  }

  /** Returns whether the given point is inside of the window. Coordinates are local. */
  public boolean contains(int x, int y) {
    return x >= 0 && y >= 0 && x < getWidth() && y < getHeight();
  }

  /** Returns whether the given point is inside of the window. Coordinates are global. */
  public boolean containsGlobal(int x, int y) {
    return x >= getAbsoluteX()
        && y >= getAbsoluteY()
        && x < (getAbsoluteX() + getWidth())
        && y < (getAbsoluteY() + getHeight());
  }
}
  /**
   * Creates window with parameters specified by <code>params</code>
   *
   * @see #init
   */
  private final void create(XCreateWindowParams params) {
    XToolkit.awtLock();
    try {
      XSetWindowAttributes xattr = new XSetWindowAttributes();
      try {
        checkParams(params);

        long value_mask = ((Long) params.get(VALUE_MASK)).longValue();

        Long eventMask = (Long) params.get(EVENT_MASK);
        xattr.set_event_mask(eventMask.longValue());
        value_mask |= XlibWrapper.CWEventMask;

        Long border_pixel = (Long) params.get(BORDER_PIXEL);
        if (border_pixel != null) {
          xattr.set_border_pixel(border_pixel.longValue());
          value_mask |= XlibWrapper.CWBorderPixel;
        }

        Long colormap = (Long) params.get(COLORMAP);
        if (colormap != null) {
          xattr.set_colormap(colormap.longValue());
          value_mask |= XlibWrapper.CWColormap;
        }
        Long background_pixmap = (Long) params.get(BACKGROUND_PIXMAP);
        if (background_pixmap != null) {
          xattr.set_background_pixmap(background_pixmap.longValue());
          value_mask |= XlibWrapper.CWBackPixmap;
        }

        Long parentWindow = (Long) params.get(PARENT_WINDOW);
        Rectangle bounds = (Rectangle) params.get(BOUNDS);
        Integer depth = (Integer) params.get(DEPTH);
        Integer visual_class = (Integer) params.get(VISUAL_CLASS);
        Long visual = (Long) params.get(VISUAL);
        Boolean overrideRedirect = (Boolean) params.get(OVERRIDE_REDIRECT);
        if (overrideRedirect != null) {
          xattr.set_override_redirect(overrideRedirect.booleanValue());
          value_mask |= XlibWrapper.CWOverrideRedirect;
        }

        Boolean saveUnder = (Boolean) params.get(SAVE_UNDER);
        if (saveUnder != null) {
          xattr.set_save_under(saveUnder.booleanValue());
          value_mask |= XlibWrapper.CWSaveUnder;
        }

        Integer backingStore = (Integer) params.get(BACKING_STORE);
        if (backingStore != null) {
          xattr.set_backing_store(backingStore.intValue());
          value_mask |= XlibWrapper.CWBackingStore;
        }

        Integer bitGravity = (Integer) params.get(BIT_GRAVITY);
        if (bitGravity != null) {
          xattr.set_bit_gravity(bitGravity.intValue());
          value_mask |= XlibWrapper.CWBitGravity;
        }

        if (log.isLoggable(Level.FINE)) {
          log.fine("Creating window for " + this + " with the following attributes: \n" + params);
        }
        window =
            XlibWrapper.XCreateWindow(
                XToolkit.getDisplay(),
                parentWindow.longValue(),
                bounds.x,
                bounds.y, // location
                bounds.width,
                bounds.height, // size
                0, // border
                depth.intValue(), // depth
                visual_class.intValue(), // class
                visual.longValue(), // visual
                value_mask, // value mask
                xattr.pData); // attributes

        if (window == 0) {
          throw new IllegalStateException(
              "Couldn't create window because of wrong parameters. Run with NOISY_AWT to see details");
        }
        XToolkit.addToWinMap(window, this);
      } finally {
        xattr.dispose();
      }
    } finally {
      XToolkit.awtUnlock();
    }
  }