Path: blob/master/src/java.desktop/unix/classes/sun/awt/X11/XBaseWindow.java
41159 views
/*1* Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation. Oracle designates this7* particular file as subject to the "Classpath" exception as provided8* by Oracle in the LICENSE file that accompanied this code.9*10* This code is distributed in the hope that it will be useful, but WITHOUT11* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or12* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License13* version 2 for more details (a copy is included in the LICENSE file that14* accompanied this code).15*16* You should have received a copy of the GNU General Public License version17* 2 along with this work; if not, write to the Free Software Foundation,18* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.19*20* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA21* or visit www.oracle.com if you need additional information or have any22* questions.23*/2425package sun.awt.X11;2627import java.awt.*;28import sun.awt.*;29import java.util.*;30import sun.util.logging.PlatformLogger;3132public class XBaseWindow {33private static final PlatformLogger log = PlatformLogger.getLogger("sun.awt.X11.XBaseWindow");34private static final PlatformLogger insLog = PlatformLogger.getLogger("sun.awt.X11.insets.XBaseWindow");35private static final PlatformLogger eventLog = PlatformLogger.getLogger("sun.awt.X11.event.XBaseWindow");36private static final PlatformLogger focusLog = PlatformLogger.getLogger("sun.awt.X11.focus.XBaseWindow");37private static final PlatformLogger grabLog = PlatformLogger.getLogger("sun.awt.X11.grab.XBaseWindow");3839public static final String40PARENT_WINDOW = "parent window", // parent window, Long41BOUNDS = "bounds", // bounds of the window, Rectangle42OVERRIDE_REDIRECT = "overrideRedirect", // override_redirect setting, Boolean43EVENT_MASK = "event mask", // event mask, Integer44VALUE_MASK = "value mask", // value mask, Long45BORDER_PIXEL = "border pixel", // border pixel value, Integer46COLORMAP = "color map", // color map, Long47DEPTH = "visual depth", // depth, Integer48VISUAL_CLASS = "visual class", // visual class, Integer49VISUAL = "visual", // visual, Long50EMBEDDED = "embedded", // is embedded?, Boolean51DELAYED = "delayed", // is creation delayed?, Boolean52PARENT = "parent", // parent peer53BACKGROUND_PIXMAP = "pixmap", // background pixmap54VISIBLE = "visible", // whether it is visible by default55SAVE_UNDER = "save under", // save content under this window56BACKING_STORE = "backing store", // enables double buffering57BIT_GRAVITY = "bit gravity"; // copy old content on geometry change58private XCreateWindowParams delayedParams;5960Set<Long> children = new HashSet<Long>();61long window;62boolean visible;63boolean mapped;64boolean embedded;65Rectangle maxBounds;66volatile XBaseWindow parentWindow;6768private boolean disposed;6970private long screen;71private XSizeHints hints;72private XWMHints wmHints;7374static final int MIN_SIZE = 1;75static final int DEF_LOCATION = 1;7677private static XAtom wm_client_leader;7879static enum InitialiseState {80INITIALISING,81INITIALISED,82FAILED_INITIALISATION83};8485private InitialiseState initialising;8687int x;88int y;89int width;90int height;9192void awtLock() {93XToolkit.awtLock();94}9596void awtUnlock() {97XToolkit.awtUnlock();98}99100void awtLockNotifyAll() {101XToolkit.awtLockNotifyAll();102}103104void awtLockWait() throws InterruptedException {105XToolkit.awtLockWait();106}107108// To prevent errors from overriding obsolete methods109protected final void init(long parentWindow, Rectangle bounds) {}110protected final void preInit() {}111protected final void postInit() {}112113// internal lock for synchronizing state changes and paint calls, initialized in preInit.114// the order with other locks: AWTLock -> stateLock115static class StateLock { }116protected StateLock state_lock;117118/**119* Called for delayed inits during construction120*/121void instantPreInit(XCreateWindowParams params) {122state_lock = new StateLock();123}124125/**126* Called before window creation, descendants should override to initialize the data,127* initialize params.128*/129void preInit(XCreateWindowParams params) {130state_lock = new StateLock();131embedded = Boolean.TRUE.equals(params.get(EMBEDDED));132visible = Boolean.TRUE.equals(params.get(VISIBLE));133134Object parent = params.get(PARENT);135if (parent instanceof XBaseWindow) {136parentWindow = (XBaseWindow)parent;137} else {138Long parentWindowID = (Long)params.get(PARENT_WINDOW);139if (parentWindowID != null) {140parentWindow = XToolkit.windowToXWindow(parentWindowID);141}142}143144Long eventMask = (Long)params.get(EVENT_MASK);145if (eventMask != null) {146long mask = eventMask.longValue();147mask |= XConstants.SubstructureNotifyMask;148params.put(EVENT_MASK, mask);149}150151screen = -1;152}153154/**155* Called after window creation, descendants should override to initialize Window156* with class-specific values and perform post-initialization actions.157*/158void postInit(XCreateWindowParams params) {159if (log.isLoggable(PlatformLogger.Level.FINE)) {160log.fine("WM name is " + getWMName());161}162updateWMName();163164// Set WM_CLIENT_LEADER property165initClientLeader();166}167168/**169* Creates window using parameters {@code params}170* If params contain flag DELAYED doesn't do anything.171* Note: Descendants can call this method to create the window172* at the time different to instance construction.173*/174protected final void init(XCreateWindowParams params) {175awtLock();176initialising = InitialiseState.INITIALISING;177awtUnlock();178179try {180if (!Boolean.TRUE.equals(params.get(DELAYED))) {181preInit(params);182create(params);183postInit(params);184} else {185instantPreInit(params);186delayedParams = params;187}188awtLock();189initialising = InitialiseState.INITIALISED;190awtLockNotifyAll();191awtUnlock();192} catch (RuntimeException re) {193awtLock();194initialising = InitialiseState.FAILED_INITIALISATION;195awtLockNotifyAll();196awtUnlock();197throw re;198} catch (Throwable t) {199log.warning("Exception during peer initialization", t);200awtLock();201initialising = InitialiseState.FAILED_INITIALISATION;202awtLockNotifyAll();203awtUnlock();204}205}206207public boolean checkInitialised() {208awtLock();209try {210switch (initialising) {211case INITIALISED:212return true;213case INITIALISING:214try {215while (initialising != InitialiseState.INITIALISED) {216awtLockWait();217}218} catch (InterruptedException ie) {219return false;220}221return true;222case FAILED_INITIALISATION:223return false;224default:225return false;226}227} finally {228awtUnlock();229}230}231232/*233* Creates an invisible InputOnly window without an associated Component.234*/235XBaseWindow() {236this(new XCreateWindowParams());237}238239/**240* Creates normal child window241*/242XBaseWindow(long parentWindow, Rectangle bounds) {243this(new XCreateWindowParams(new Object[] {244BOUNDS, bounds,245PARENT_WINDOW, Long.valueOf(parentWindow)}));246}247248/**249* Creates top-level window250*/251XBaseWindow(Rectangle bounds) {252this(new XCreateWindowParams(new Object[] {253BOUNDS, bounds254}));255}256257public XBaseWindow (XCreateWindowParams params) {258init(params);259}260261/* This create is used by the XEmbeddedFramePeer since it has to create the window262as a child of the netscape window. This netscape window is passed in as wid */263XBaseWindow(long parentWindow) {264this(new XCreateWindowParams(new Object[] {265PARENT_WINDOW, Long.valueOf(parentWindow),266EMBEDDED, Boolean.TRUE267}));268}269270/**271* Verifies that all required parameters are set. If not, sets them to default values.272* Verifies values of critical parameters, adjust their values when needed.273* @throws IllegalArgumentException if params is null274*/275protected void checkParams(XCreateWindowParams params) {276if (params == null) {277throw new IllegalArgumentException("Window creation parameters are null");278}279params.putIfNull(PARENT_WINDOW, Long.valueOf(XToolkit.getDefaultRootWindow()));280params.putIfNull(BOUNDS, new Rectangle(DEF_LOCATION, DEF_LOCATION, MIN_SIZE, MIN_SIZE));281params.putIfNull(DEPTH, Integer.valueOf((int)XConstants.CopyFromParent));282params.putIfNull(VISUAL, Long.valueOf(XConstants.CopyFromParent));283params.putIfNull(VISUAL_CLASS, Integer.valueOf(XConstants.InputOnly));284params.putIfNull(VALUE_MASK, Long.valueOf(XConstants.CWEventMask));285Rectangle bounds = (Rectangle)params.get(BOUNDS);286bounds.width = Math.max(MIN_SIZE, bounds.width);287bounds.height = Math.max(MIN_SIZE, bounds.height);288289Long eventMaskObj = (Long)params.get(EVENT_MASK);290long eventMask = eventMaskObj != null ? eventMaskObj.longValue() : 0;291// We use our own synthetic grab see XAwtState.getGrabWindow()292// (see X vol. 1, 8.3.3.2)293eventMask |= XConstants.PropertyChangeMask | XConstants.OwnerGrabButtonMask;294params.put(EVENT_MASK, Long.valueOf(eventMask));295}296297/**298* Returns scale factor of the window. It is used to convert native299* coordinates to local and vice verse.300*/301protected int getScale() {302return 1;303}304305protected int scaleUp(int x) {306return x;307}308309protected int scaleDown(int x) {310return x;311}312313/**314* Creates window with parameters specified by {@code params}315* @see #init316*/317private void create(XCreateWindowParams params) {318XToolkit.awtLock();319try {320XSetWindowAttributes xattr = new XSetWindowAttributes();321try {322checkParams(params);323324long value_mask = ((Long)params.get(VALUE_MASK)).longValue();325326Long eventMask = (Long)params.get(EVENT_MASK);327xattr.set_event_mask(eventMask.longValue());328value_mask |= XConstants.CWEventMask;329330Long border_pixel = (Long)params.get(BORDER_PIXEL);331if (border_pixel != null) {332xattr.set_border_pixel(border_pixel.longValue());333value_mask |= XConstants.CWBorderPixel;334}335336Long colormap = (Long)params.get(COLORMAP);337if (colormap != null) {338xattr.set_colormap(colormap.longValue());339value_mask |= XConstants.CWColormap;340}341Long background_pixmap = (Long)params.get(BACKGROUND_PIXMAP);342if (background_pixmap != null) {343xattr.set_background_pixmap(background_pixmap.longValue());344value_mask |= XConstants.CWBackPixmap;345}346347Long parentWindow = (Long)params.get(PARENT_WINDOW);348Rectangle bounds = (Rectangle)params.get(BOUNDS);349Integer depth = (Integer)params.get(DEPTH);350Integer visual_class = (Integer)params.get(VISUAL_CLASS);351Long visual = (Long)params.get(VISUAL);352Boolean overrideRedirect = (Boolean)params.get(OVERRIDE_REDIRECT);353if (overrideRedirect != null) {354xattr.set_override_redirect(overrideRedirect.booleanValue());355value_mask |= XConstants.CWOverrideRedirect;356}357358Boolean saveUnder = (Boolean)params.get(SAVE_UNDER);359if (saveUnder != null) {360xattr.set_save_under(saveUnder.booleanValue());361value_mask |= XConstants.CWSaveUnder;362}363364Integer backingStore = (Integer)params.get(BACKING_STORE);365if (backingStore != null) {366xattr.set_backing_store(backingStore.intValue());367value_mask |= XConstants.CWBackingStore;368}369370Integer bitGravity = (Integer)params.get(BIT_GRAVITY);371if (bitGravity != null) {372xattr.set_bit_gravity(bitGravity.intValue());373value_mask |= XConstants.CWBitGravity;374}375376if (log.isLoggable(PlatformLogger.Level.FINE)) {377log.fine("Creating window for " + this + " with the following attributes: \n" + params);378}379window = XlibWrapper.XCreateWindow(XToolkit.getDisplay(),380parentWindow.longValue(),381scaleUp(bounds.x),382scaleUp(bounds.y),383scaleUp(bounds.width),384scaleUp(bounds.height),3850, // border386depth.intValue(), // depth387visual_class.intValue(), // class388visual.longValue(), // visual389value_mask, // value mask390xattr.pData); // attributes391392if (window == 0) {393throw new IllegalStateException("Couldn't create window because of wrong parameters. Run with NOISY_AWT to see details");394}395XToolkit.addToWinMap(window, this);396} finally {397xattr.dispose();398}399} finally {400XToolkit.awtUnlock();401}402}403404public XCreateWindowParams getDelayedParams() {405return delayedParams;406}407408protected String getWMName() {409return XToolkit.getCorrectXIDString(getClass().getName());410}411412protected void initClientLeader() {413XToolkit.awtLock();414try {415if (wm_client_leader == null) {416wm_client_leader = XAtom.get("WM_CLIENT_LEADER");417}418wm_client_leader.setWindowProperty(this, getXAWTRootWindow());419} finally {420XToolkit.awtUnlock();421}422}423424static XRootWindow getXAWTRootWindow() {425return XRootWindow.getInstance();426}427428void destroy() {429XToolkit.awtLock();430try {431if (hints != null) {432XlibWrapper.XFree(hints.pData);433hints = null;434}435XToolkit.removeFromWinMap(getWindow(), this);436XlibWrapper.XDestroyWindow(XToolkit.getDisplay(), getWindow());437if (XPropertyCache.isCachingSupported()) {438XPropertyCache.clearCache(window);439}440window = -1;441if( !isDisposed() ) {442setDisposed( true );443}444445XAwtState.getGrabWindow(); // Magic - getGrabWindow clear state if grabbing window is disposed of.446} finally {447XToolkit.awtUnlock();448}449}450451void flush() {452XToolkit.awtLock();453try {454XlibWrapper.XFlush(XToolkit.getDisplay());455} finally {456XToolkit.awtUnlock();457}458}459460/**461* Helper function to set W462*/463public final void setWMHints(XWMHints hints) {464XToolkit.awtLock();465try {466XlibWrapper.XSetWMHints(XToolkit.getDisplay(), getWindow(), hints.pData);467} finally {468XToolkit.awtUnlock();469}470}471472public XWMHints getWMHints() {473if (wmHints == null) {474wmHints = new XWMHints(XlibWrapper.XAllocWMHints());475// XlibWrapper.XGetWMHints(XToolkit.getDisplay(),476// getWindow(),477// wmHints.pData);478}479return wmHints;480}481482483/*484* Call this method under AWTLock.485* The lock should be acquired untill all operations with XSizeHints are completed.486*/487public XSizeHints getHints() {488if (hints == null) {489long p_hints = XlibWrapper.XAllocSizeHints();490hints = new XSizeHints(p_hints);491// XlibWrapper.XGetWMNormalHints(XToolkit.getDisplay(), getWindow(), p_hints, XlibWrapper.larg1);492// TODO: Shouldn't we listen for WM updates on this property?493}494return hints;495}496497public void setSizeHints(long flags, int x, int y, int width, int height) {498if (insLog.isLoggable(PlatformLogger.Level.FINER)) {499insLog.finer("Setting hints, flags " + XlibWrapper.hintsToString(flags));500}501XToolkit.awtLock();502try {503XSizeHints hints = getHints();504// Note: if PPosition is not set in flags this means that505// we want to reset PPosition in hints. This is necessary506// for locationByPlatform functionality507if ((flags & XUtilConstants.PPosition) != 0) {508hints.set_x(scaleUp(x));509hints.set_y(scaleUp(y));510}511if ((flags & XUtilConstants.PSize) != 0) {512hints.set_width(scaleUp(width));513hints.set_height(scaleUp(height));514} else if ((hints.get_flags() & XUtilConstants.PSize) != 0) {515flags |= XUtilConstants.PSize;516}517if ((flags & XUtilConstants.PMinSize) != 0) {518hints.set_min_width(scaleUp(width));519hints.set_min_height(scaleUp(height));520} else if ((hints.get_flags() & XUtilConstants.PMinSize) != 0) {521flags |= XUtilConstants.PMinSize;522//Fix for 4320050: Minimum size for java.awt.Frame is not being enforced.523//We don't need to reset minimum size if it's already set524}525if ((flags & XUtilConstants.PMaxSize) != 0) {526if (maxBounds != null) {527if (maxBounds.width != Integer.MAX_VALUE) {528hints.set_max_width(scaleUp(maxBounds.width));529} else {530hints.set_max_width(XToolkit.getMaxWindowWidthInPixels());531}532if (maxBounds.height != Integer.MAX_VALUE) {533hints.set_max_height(scaleUp(maxBounds.height));534} else {535hints.set_max_height(XToolkit.getMaxWindowHeightInPixels());536}537} else {538hints.set_max_width(scaleUp(width));539hints.set_max_height(scaleUp(height));540}541} else if ((hints.get_flags() & XUtilConstants.PMaxSize) != 0) {542flags |= XUtilConstants.PMaxSize;543if (maxBounds != null) {544if (maxBounds.width != Integer.MAX_VALUE) {545hints.set_max_width(scaleUp(maxBounds.width));546} else {547hints.set_max_width(XToolkit.getMaxWindowWidthInPixels());548}549if (maxBounds.height != Integer.MAX_VALUE) {550hints.set_max_height(scaleUp(maxBounds.height));551} else {552hints.set_max_height(XToolkit.getMaxWindowHeightInPixels());553}554} else {555// Leave intact556}557}558flags |= XUtilConstants.PWinGravity;559hints.set_flags(flags);560hints.set_win_gravity(XConstants.NorthWestGravity);561if (insLog.isLoggable(PlatformLogger.Level.FINER)) {562insLog.finer("Setting hints, resulted flags " + XlibWrapper.hintsToString(flags) +563", values " + hints);564}565XlibWrapper.XSetWMNormalHints(XToolkit.getDisplay(), getWindow(), hints.pData);566} finally {567XToolkit.awtUnlock();568}569}570571public boolean isMinSizeSet() {572XSizeHints hints = getHints();573long flags = hints.get_flags();574return ((flags & XUtilConstants.PMinSize) == XUtilConstants.PMinSize);575}576577/**578* This lock object can be used to protect instance data from concurrent access579* by two threads. If both state lock and AWT lock are taken, AWT Lock should be taken first.580*/581Object getStateLock() {582return state_lock;583}584585public long getWindow() {586return window;587}588public long getContentWindow() {589return window;590}591592public XBaseWindow getContentXWindow() {593return XToolkit.windowToXWindow(getContentWindow());594}595596public Rectangle getBounds() {597return new Rectangle(x, y, width, height);598}599public Dimension getSize() {600return new Dimension(width, height);601}602603604public void toFront() {605XToolkit.awtLock();606try {607XlibWrapper.XRaiseWindow(XToolkit.getDisplay(), getWindow());608} finally {609XToolkit.awtUnlock();610}611}612public void xRequestFocus(long time) {613XToolkit.awtLock();614try {615if (focusLog.isLoggable(PlatformLogger.Level.FINER)) {616focusLog.finer("XSetInputFocus on " + Long.toHexString(getWindow()) + " with time " + time);617}618XlibWrapper.XSetInputFocus2(XToolkit.getDisplay(), getWindow(), time);619} finally {620XToolkit.awtUnlock();621}622}623public void xRequestFocus() {624XToolkit.awtLock();625try {626if (focusLog.isLoggable(PlatformLogger.Level.FINER)) {627focusLog.finer("XSetInputFocus on " + Long.toHexString(getWindow()));628}629XlibWrapper.XSetInputFocus(XToolkit.getDisplay(), getWindow());630} finally {631XToolkit.awtUnlock();632}633}634635public static long xGetInputFocus() {636XToolkit.awtLock();637try {638return XlibWrapper.XGetInputFocus(XToolkit.getDisplay());639} finally {640XToolkit.awtUnlock();641}642}643644public void xSetVisible(boolean visible) {645if (log.isLoggable(PlatformLogger.Level.FINE)) {646log.fine("Setting visible on " + this + " to " + visible);647}648XToolkit.awtLock();649try {650this.visible = visible;651if (visible) {652XlibWrapper.XMapWindow(XToolkit.getDisplay(), getWindow());653}654else {655XlibWrapper.XUnmapWindow(XToolkit.getDisplay(), getWindow());656}657XlibWrapper.XFlush(XToolkit.getDisplay());658} finally {659XToolkit.awtUnlock();660}661}662663boolean isMapped() {664return mapped;665}666667void updateWMName() {668String name = getWMName();669XToolkit.awtLock();670try {671if (name == null) {672name = " ";673}674XAtom nameAtom = XAtom.get(XAtom.XA_WM_NAME);675nameAtom.setProperty(getWindow(), name);676XAtom netNameAtom = XAtom.get("_NET_WM_NAME");677netNameAtom.setPropertyUTF8(getWindow(), name);678} finally {679XToolkit.awtUnlock();680}681}682void setWMClass(String[] cl) {683if (cl.length != 2) {684throw new IllegalArgumentException("WM_CLASS_NAME consists of exactly two strings");685}686XToolkit.awtLock();687try {688XAtom xa = XAtom.get(XAtom.XA_WM_CLASS);689xa.setProperty8(getWindow(), cl[0] + '\0' + cl[1] + '\0');690} finally {691XToolkit.awtUnlock();692}693}694695boolean isVisible() {696return visible;697}698699static long getScreenOfWindow(long window) {700XToolkit.awtLock();701try {702return XlibWrapper.getScreenOfWindow(XToolkit.getDisplay(), window);703} finally {704XToolkit.awtUnlock();705}706}707long getScreenNumber() {708XToolkit.awtLock();709try {710return XlibWrapper.XScreenNumberOfScreen(getScreen());711} finally {712XToolkit.awtUnlock();713}714}715716long getScreen() {717if (screen == -1) { // Not initialized718screen = getScreenOfWindow(window);719}720return screen;721}722723public void xSetBounds(Rectangle bounds) {724xSetBounds(bounds.x, bounds.y, bounds.width, bounds.height);725}726727public void xSetBounds(int x, int y, int width, int height) {728if (getWindow() == 0) {729insLog.warning("Attempt to resize uncreated window");730throw new IllegalStateException("Attempt to resize uncreated window");731}732if (insLog.isLoggable(PlatformLogger.Level.FINE)) {733insLog.fine("Setting bounds on " + this + " to (" + x + ", " + y + "), " + width + "x" + height);734}735width = Math.max(MIN_SIZE, width);736height = Math.max(MIN_SIZE, height);737XToolkit.awtLock();738try {739XlibWrapper.XMoveResizeWindow(XToolkit.getDisplay(), getWindow(),740scaleUp(x), scaleUp(y),741scaleUp(width), scaleUp(height));742} finally {743XToolkit.awtUnlock();744}745}746747/**748* Translate coordinates from one window into another. Optimized749* for XAWT - uses cached data when possible. Preferable over750* pure XTranslateCoordinates.751* @return coordinates relative to dst, or null if error happened752*/753static Point toOtherWindow(long src, long dst, int x, int y) {754Point rpt = new Point(0, 0);755756// Check if both windows belong to XAWT - then no X calls are necessary757758XBaseWindow srcPeer = XToolkit.windowToXWindow(src);759XBaseWindow dstPeer = XToolkit.windowToXWindow(dst);760761if (srcPeer != null && dstPeer != null) {762// (x, y) is relative to src763rpt.x = x + srcPeer.getAbsoluteX() - dstPeer.getAbsoluteX();764rpt.y = y + srcPeer.getAbsoluteY() - dstPeer.getAbsoluteY();765} else if (dstPeer != null && XlibUtil.isRoot(src, dstPeer.getScreenNumber())) {766// from root into peer767rpt.x = x - dstPeer.getAbsoluteX();768rpt.y = y - dstPeer.getAbsoluteY();769} else if (srcPeer != null && XlibUtil.isRoot(dst, srcPeer.getScreenNumber())) {770// from peer into root771rpt.x = x + srcPeer.getAbsoluteX();772rpt.y = y + srcPeer.getAbsoluteY();773} else {774int scale = srcPeer == null ? 1 : srcPeer.getScale();775rpt = XlibUtil.translateCoordinates(src, dst, new Point(x, y), scale);776}777return rpt;778}779780/*781* Convert to global coordinates.782*/783Rectangle toGlobal(Rectangle rec) {784Point p = toGlobal(rec.getLocation());785Rectangle newRec = new Rectangle(rec);786if (p != null) {787newRec.setLocation(p);788}789return newRec;790}791792Point toGlobal(Point pt) {793Point p = toGlobal(pt.x, pt.y);794if (p != null) {795return p;796} else {797return new Point(pt);798}799}800801Point toGlobal(int x, int y) {802long root;803XToolkit.awtLock();804try {805root = XlibWrapper.RootWindow(XToolkit.getDisplay(),806getScreenNumber());807} finally {808XToolkit.awtUnlock();809}810Point p = toOtherWindow(getContentWindow(), root, x, y);811if (p != null) {812return p;813} else {814return new Point(x, y);815}816}817818/*819* Convert to local coordinates.820*/821Point toLocal(Point pt) {822Point p = toLocal(pt.x, pt.y);823if (p != null) {824return p;825} else {826return new Point(pt);827}828}829830Point toLocal(int x, int y) {831long root;832XToolkit.awtLock();833try {834root = XlibWrapper.RootWindow(XToolkit.getDisplay(),835getScreenNumber());836} finally {837XToolkit.awtUnlock();838}839Point p = toOtherWindow(root, getContentWindow(), x, y);840if (p != null) {841return p;842} else {843return new Point(x, y);844}845}846847/**848* We should always grab both keyboard and pointer to control event flow849* on popups. This also simplifies synthetic grab implementation.850* The active grab overrides activated automatic grab.851*/852public boolean grabInput() {853if (grabLog.isLoggable(PlatformLogger.Level.FINE)) {854grabLog.fine("Grab input on {0}", this);855}856857XToolkit.awtLock();858try {859if (XAwtState.getGrabWindow() == this &&860XAwtState.isManualGrab())861{862grabLog.fine(" Already Grabbed");863return true;864}865//6273031: PIT. Choice drop down does not close once it is right clicked to show a popup menu866//remember previous window having grab and if it's not null ungrab it.867XBaseWindow prevGrabWindow = XAwtState.getGrabWindow();868final int eventMask = (int) (XConstants.ButtonPressMask | XConstants.ButtonReleaseMask869| XConstants.EnterWindowMask | XConstants.LeaveWindowMask | XConstants.PointerMotionMask870| XConstants.ButtonMotionMask);871final int ownerEvents = 1;872873874//6714678: IDE (Netbeans, Eclipse, JDeveloper) Debugger hangs875//process on Linux876//The user must pass the sun.awt.disablegrab property to disable877//taking grabs. This prevents hanging of the GUI when a breakpoint878//is hit while a popup window taking the grab is open.879if (!XToolkit.getSunAwtDisableGrab()) {880int ptrGrab = XlibWrapper.XGrabPointer(XToolkit.getDisplay(),881getContentWindow(), ownerEvents, eventMask, XConstants.GrabModeAsync,882XConstants.GrabModeAsync, XConstants.None, (XWM.isMotif() ? XToolkit.arrowCursor : XConstants.None),883XConstants.CurrentTime);884// Check grab results to be consistent with X server grab885if (ptrGrab != XConstants.GrabSuccess) {886XlibWrapper.XUngrabPointer(XToolkit.getDisplay(), XConstants.CurrentTime);887XAwtState.setGrabWindow(null);888grabLog.fine(" Grab Failure - mouse");889return false;890}891892int keyGrab = XlibWrapper.XGrabKeyboard(XToolkit.getDisplay(),893getContentWindow(), ownerEvents, XConstants.GrabModeAsync, XConstants.GrabModeAsync,894XConstants.CurrentTime);895if (keyGrab != XConstants.GrabSuccess) {896XlibWrapper.XUngrabPointer(XToolkit.getDisplay(), XConstants.CurrentTime);897XlibWrapper.XUngrabKeyboard(XToolkit.getDisplay(), XConstants.CurrentTime);898XAwtState.setGrabWindow(null);899grabLog.fine(" Grab Failure - keyboard");900return false;901}902}903if (prevGrabWindow != null) {904prevGrabWindow.ungrabInputImpl();905}906XAwtState.setGrabWindow(this);907grabLog.fine(" Grab - success");908return true;909} finally {910XToolkit.awtUnlock();911}912}913914static void ungrabInput() {915XToolkit.awtLock();916try {917XBaseWindow grabWindow = XAwtState.getGrabWindow();918if (grabLog.isLoggable(PlatformLogger.Level.FINE)) {919grabLog.fine("UnGrab input on {0}", grabWindow);920}921if (grabWindow != null) {922grabWindow.ungrabInputImpl();923if (!XToolkit.getSunAwtDisableGrab()) {924XlibWrapper.XUngrabPointer(XToolkit.getDisplay(), XConstants.CurrentTime);925XlibWrapper.XUngrabKeyboard(XToolkit.getDisplay(), XConstants.CurrentTime);926}927XAwtState.setGrabWindow(null);928// we need to call XFlush() here to force ungrab929// see 6384219 for details930XlibWrapper.XFlush(XToolkit.getDisplay());931}932} finally {933XToolkit.awtUnlock();934}935}936937// called from ungrabInput, used in popup windows to hide theirselfs in ungrabbing938void ungrabInputImpl() {939}940941static void checkSecurity() {942if (XToolkit.isSecurityWarningEnabled() && XToolkit.isToolkitThread()) {943StackTraceElement[] stack = (new Throwable()).getStackTrace();944log.warning(stack[1] + ": Security violation: calling user code on toolkit thread");945}946}947948public Set<Long> getChildren() {949synchronized (getStateLock()) {950return new HashSet<Long>(children);951}952}953954// -------------- Event handling ----------------955public void handleMapNotifyEvent(XEvent xev) {956mapped = true;957}958public void handleUnmapNotifyEvent(XEvent xev) {959mapped = false;960}961public void handleReparentNotifyEvent(XEvent xev) {962if (eventLog.isLoggable(PlatformLogger.Level.FINER)) {963XReparentEvent msg = xev.get_xreparent();964eventLog.finer(msg.toString());965}966}967public void handlePropertyNotify(XEvent xev) {968XPropertyEvent msg = xev.get_xproperty();969if (XPropertyCache.isCachingSupported()) {970XPropertyCache.clearCache(window, XAtom.get(msg.get_atom()));971}972if (eventLog.isLoggable(PlatformLogger.Level.FINER)) {973eventLog.finer("{0}", msg);974}975}976977public void handleDestroyNotify(XEvent xev) {978XAnyEvent xany = xev.get_xany();979if (xany.get_window() == getWindow()) {980XToolkit.removeFromWinMap(getWindow(), this);981if (XPropertyCache.isCachingSupported()) {982XPropertyCache.clearCache(getWindow());983}984}985if (xany.get_window() != getWindow()) {986synchronized (getStateLock()) {987children.remove(xany.get_window());988}989}990}991992public void handleCreateNotify(XEvent xev) {993XAnyEvent xany = xev.get_xany();994if (xany.get_window() != getWindow()) {995synchronized (getStateLock()) {996children.add(xany.get_window());997}998}999}10001001public void handleClientMessage(XEvent xev) {1002if (eventLog.isLoggable(PlatformLogger.Level.FINER)) {1003XClientMessageEvent msg = xev.get_xclient();1004eventLog.finer(msg.toString());1005}1006}10071008public void handleVisibilityEvent(XEvent xev) {1009}1010public void handleKeyPress(XEvent xev) {1011}1012public void handleKeyRelease(XEvent xev) {1013}1014public void handleExposeEvent(XEvent xev) {1015}1016/**1017* Activate automatic grab on first ButtonPress,1018* deactivate on full mouse release1019*/1020public void handleButtonPressRelease(XEvent xev) {1021XButtonEvent xbe = xev.get_xbutton();1022/*1023* Ignore the buttons above 20 due to the bit limit for1024* InputEvent.BUTTON_DOWN_MASK.1025* One more bit is reserved for FIRST_HIGH_BIT.1026*/1027int theButton = xbe.get_button();1028if (theButton > SunToolkit.MAX_BUTTONS_SUPPORTED) {1029return;1030}1031int buttonState = 0;1032buttonState = xbe.get_state() & XConstants.ALL_BUTTONS_MASK;10331034boolean isWheel = (theButton == XConstants.MouseWheelUp ||1035theButton == XConstants.MouseWheelDown);10361037// don't give focus if it's just the mouse wheel turning1038if (!isWheel) {1039switch (xev.get_type()) {1040case XConstants.ButtonPress:1041if (buttonState == 0) {1042XWindowPeer parent = getToplevelXWindow();1043// See 6385277, 6981400.1044if (parent != null && parent.isFocusableWindow()) {1045// A click in a client area drops the actual focused window retaining.1046parent.setActualFocusedWindow(null);1047parent.requestWindowFocus(xbe.get_time(), true);1048}1049XAwtState.setAutoGrabWindow(this);1050}1051break;1052case XConstants.ButtonRelease:1053if (isFullRelease(buttonState, xbe.get_button())) {1054XAwtState.setAutoGrabWindow(null);1055}1056break;1057}1058}1059}1060public void handleMotionNotify(XEvent xev) {1061}1062public void handleXCrossingEvent(XEvent xev) {1063}1064public void handleConfigureNotifyEvent(XEvent xev) {1065XConfigureEvent xe = xev.get_xconfigure();1066if (insLog.isLoggable(PlatformLogger.Level.FINER)) {1067insLog.finer("Configure, {0}", xe);1068}10691070x = scaleDown(xe.get_x());1071y = scaleDown(xe.get_y());1072width = scaleDown(xe.get_width());1073height = scaleDown(xe.get_height());1074}1075/**1076* Checks ButtonRelease released all Mouse buttons1077*/1078static boolean isFullRelease(int buttonState, int button) {1079final int buttonsNumber = XToolkit.getNumberOfButtonsForMask();10801081if (button < 0 || button > buttonsNumber) {1082return buttonState == 0;1083} else {1084return buttonState == XlibUtil.getButtonMask(button);1085}1086}10871088static boolean isGrabbedEvent(XEvent ev, XBaseWindow target) {1089switch (ev.get_type()) {1090case XConstants.ButtonPress:1091case XConstants.ButtonRelease:1092case XConstants.MotionNotify:1093case XConstants.KeyPress:1094case XConstants.KeyRelease:1095return true;1096case XConstants.LeaveNotify:1097case XConstants.EnterNotify:1098// We shouldn't dispatch this events to the grabbed components (see 6317481)1099// But this logic is important if the grabbed component is top-level (see realSync)1100return (target instanceof XWindowPeer);1101default:1102return false;1103}1104}1105/**1106* Dispatches event to the grab Window or event source window depending1107* on whether the grab is active and on the event type1108*/1109static void dispatchToWindow(XEvent ev) {1110XBaseWindow target = XAwtState.getGrabWindow();1111if (target == null || !isGrabbedEvent(ev, target)) {1112target = XToolkit.windowToXWindow(ev.get_xany().get_window());1113}1114if (target != null && target.checkInitialised()) {1115target.dispatchEvent(ev);1116}1117}11181119public void dispatchEvent(XEvent xev) {1120if (eventLog.isLoggable(PlatformLogger.Level.FINEST)) {1121eventLog.finest(xev.toString());1122}1123int type = xev.get_type();11241125if (isDisposed()) {1126return;1127}11281129switch (type)1130{1131case XConstants.VisibilityNotify:1132handleVisibilityEvent(xev);1133break;1134case XConstants.ClientMessage:1135handleClientMessage(xev);1136break;1137case XConstants.Expose :1138case XConstants.GraphicsExpose :1139handleExposeEvent(xev);1140break;1141case XConstants.ButtonPress:1142case XConstants.ButtonRelease:1143handleButtonPressRelease(xev);1144break;11451146case XConstants.MotionNotify:1147handleMotionNotify(xev);1148break;1149case XConstants.KeyPress:1150handleKeyPress(xev);1151break;1152case XConstants.KeyRelease:1153handleKeyRelease(xev);1154break;1155case XConstants.EnterNotify:1156case XConstants.LeaveNotify:1157handleXCrossingEvent(xev);1158break;1159case XConstants.ConfigureNotify:1160handleConfigureNotifyEvent(xev);1161break;1162case XConstants.MapNotify:1163handleMapNotifyEvent(xev);1164break;1165case XConstants.UnmapNotify:1166handleUnmapNotifyEvent(xev);1167break;1168case XConstants.ReparentNotify:1169handleReparentNotifyEvent(xev);1170break;1171case XConstants.PropertyNotify:1172handlePropertyNotify(xev);1173break;1174case XConstants.DestroyNotify:1175handleDestroyNotify(xev);1176break;1177case XConstants.CreateNotify:1178handleCreateNotify(xev);1179break;1180}1181}1182protected boolean isEventDisabled(XEvent e) {1183return false;1184}11851186int getX() {1187return x;1188}11891190int getY() {1191return y;1192}11931194int getWidth() {1195return width;1196}11971198int getHeight() {1199return height;1200}12011202void setDisposed(boolean d) {1203disposed = d;1204}12051206boolean isDisposed() {1207return disposed;1208}12091210public int getAbsoluteX() {1211XBaseWindow pw = getParentWindow();1212if (pw != null) {1213return pw.getAbsoluteX() + getX();1214} else {1215// Overridden for top-levels as their (x,y) is Java (x, y), not native location1216return getX();1217}1218}12191220public int getAbsoluteY() {1221XBaseWindow pw = getParentWindow();1222if (pw != null) {1223return pw.getAbsoluteY() + getY();1224} else {1225return getY();1226}1227}12281229public XBaseWindow getParentWindow() {1230return parentWindow;1231}12321233public XWindowPeer getToplevelXWindow() {1234XBaseWindow bw = this;1235while (bw != null && !(bw instanceof XWindowPeer)) {1236bw = bw.getParentWindow();1237}1238return (XWindowPeer)bw;1239}1240public String toString() {1241return super.toString() + "(" + Long.toString(getWindow(), 16) + ")";1242}12431244/**1245* Returns whether the given point is inside of the window. Coordinates are local.1246*/1247public boolean contains(int x, int y) {1248return x >= 0 && y >= 0 && x < getWidth() && y < getHeight();1249}12501251/**1252* Returns whether the given point is inside of the window. Coordinates are global.1253*/1254public boolean containsGlobal(int x, int y) {1255return x >= getAbsoluteX() && y >= getAbsoluteY() && x < (getAbsoluteX()+getWidth()) && y < (getAbsoluteY()+getHeight());1256}12571258}125912601261