Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/solaris/classes/sun/awt/X11/XBaseWindow.java
32288 views
/*1* Copyright (c) 2003, 2013, 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;7374final static int MIN_SIZE = 1;75final static 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 extends Object { }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</code>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((int)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* Creates window with parameters specified by <code>params</code>299* @see #init300*/301private final void create(XCreateWindowParams params) {302XToolkit.awtLock();303try {304XSetWindowAttributes xattr = new XSetWindowAttributes();305try {306checkParams(params);307308long value_mask = ((Long)params.get(VALUE_MASK)).longValue();309310Long eventMask = (Long)params.get(EVENT_MASK);311xattr.set_event_mask(eventMask.longValue());312value_mask |= XConstants.CWEventMask;313314Long border_pixel = (Long)params.get(BORDER_PIXEL);315if (border_pixel != null) {316xattr.set_border_pixel(border_pixel.longValue());317value_mask |= XConstants.CWBorderPixel;318}319320Long colormap = (Long)params.get(COLORMAP);321if (colormap != null) {322xattr.set_colormap(colormap.longValue());323value_mask |= XConstants.CWColormap;324}325Long background_pixmap = (Long)params.get(BACKGROUND_PIXMAP);326if (background_pixmap != null) {327xattr.set_background_pixmap(background_pixmap.longValue());328value_mask |= XConstants.CWBackPixmap;329}330331Long parentWindow = (Long)params.get(PARENT_WINDOW);332Rectangle bounds = (Rectangle)params.get(BOUNDS);333Integer depth = (Integer)params.get(DEPTH);334Integer visual_class = (Integer)params.get(VISUAL_CLASS);335Long visual = (Long)params.get(VISUAL);336Boolean overrideRedirect = (Boolean)params.get(OVERRIDE_REDIRECT);337if (overrideRedirect != null) {338xattr.set_override_redirect(overrideRedirect.booleanValue());339value_mask |= XConstants.CWOverrideRedirect;340}341342Boolean saveUnder = (Boolean)params.get(SAVE_UNDER);343if (saveUnder != null) {344xattr.set_save_under(saveUnder.booleanValue());345value_mask |= XConstants.CWSaveUnder;346}347348Integer backingStore = (Integer)params.get(BACKING_STORE);349if (backingStore != null) {350xattr.set_backing_store(backingStore.intValue());351value_mask |= XConstants.CWBackingStore;352}353354Integer bitGravity = (Integer)params.get(BIT_GRAVITY);355if (bitGravity != null) {356xattr.set_bit_gravity(bitGravity.intValue());357value_mask |= XConstants.CWBitGravity;358}359360if (log.isLoggable(PlatformLogger.Level.FINE)) {361log.fine("Creating window for " + this + " with the following attributes: \n" + params);362}363window = XlibWrapper.XCreateWindow(XToolkit.getDisplay(),364parentWindow.longValue(),365bounds.x, bounds.y, // location366bounds.width, bounds.height, // size3670, // border368depth.intValue(), // depth369visual_class.intValue(), // class370visual.longValue(), // visual371value_mask, // value mask372xattr.pData); // attributes373374if (window == 0) {375throw new IllegalStateException("Couldn't create window because of wrong parameters. Run with NOISY_AWT to see details");376}377XToolkit.addToWinMap(window, this);378} finally {379xattr.dispose();380}381} finally {382XToolkit.awtUnlock();383}384}385386public XCreateWindowParams getDelayedParams() {387return delayedParams;388}389390protected String getWMName() {391return XToolkit.getCorrectXIDString(getClass().getName());392}393394protected void initClientLeader() {395XToolkit.awtLock();396try {397if (wm_client_leader == null) {398wm_client_leader = XAtom.get("WM_CLIENT_LEADER");399}400wm_client_leader.setWindowProperty(this, getXAWTRootWindow());401} finally {402XToolkit.awtUnlock();403}404}405406static XRootWindow getXAWTRootWindow() {407return XRootWindow.getInstance();408}409410void destroy() {411XToolkit.awtLock();412try {413if (hints != null) {414XlibWrapper.XFree(hints.pData);415hints = null;416}417XToolkit.removeFromWinMap(getWindow(), this);418XlibWrapper.XDestroyWindow(XToolkit.getDisplay(), getWindow());419if (XPropertyCache.isCachingSupported()) {420XPropertyCache.clearCache(window);421}422window = -1;423if( !isDisposed() ) {424setDisposed( true );425}426427XAwtState.getGrabWindow(); // Magic - getGrabWindow clear state if grabbing window is disposed of.428} finally {429XToolkit.awtUnlock();430}431}432433void flush() {434XToolkit.awtLock();435try {436XlibWrapper.XFlush(XToolkit.getDisplay());437} finally {438XToolkit.awtUnlock();439}440}441442/**443* Helper function to set W444*/445public final void setWMHints(XWMHints hints) {446XToolkit.awtLock();447try {448XlibWrapper.XSetWMHints(XToolkit.getDisplay(), getWindow(), hints.pData);449} finally {450XToolkit.awtUnlock();451}452}453454public XWMHints getWMHints() {455if (wmHints == null) {456wmHints = new XWMHints(XlibWrapper.XAllocWMHints());457// XlibWrapper.XGetWMHints(XToolkit.getDisplay(),458// getWindow(),459// wmHints.pData);460}461return wmHints;462}463464465/*466* Call this method under AWTLock.467* The lock should be acquired untill all operations with XSizeHints are completed.468*/469public XSizeHints getHints() {470if (hints == null) {471long p_hints = XlibWrapper.XAllocSizeHints();472hints = new XSizeHints(p_hints);473// XlibWrapper.XGetWMNormalHints(XToolkit.getDisplay(), getWindow(), p_hints, XlibWrapper.larg1);474// TODO: Shouldn't we listen for WM updates on this property?475}476return hints;477}478479public void setSizeHints(long flags, int x, int y, int width, int height) {480if (insLog.isLoggable(PlatformLogger.Level.FINER)) {481insLog.finer("Setting hints, flags " + XlibWrapper.hintsToString(flags));482}483XToolkit.awtLock();484try {485XSizeHints hints = getHints();486// Note: if PPosition is not set in flags this means that487// we want to reset PPosition in hints. This is necessary488// for locationByPlatform functionality489if ((flags & XUtilConstants.PPosition) != 0) {490hints.set_x(x);491hints.set_y(y);492}493if ((flags & XUtilConstants.PSize) != 0) {494hints.set_width(width);495hints.set_height(height);496} else if ((hints.get_flags() & XUtilConstants.PSize) != 0) {497flags |= XUtilConstants.PSize;498}499if ((flags & XUtilConstants.PMinSize) != 0) {500hints.set_min_width(width);501hints.set_min_height(height);502} else if ((hints.get_flags() & XUtilConstants.PMinSize) != 0) {503flags |= XUtilConstants.PMinSize;504//Fix for 4320050: Minimum size for java.awt.Frame is not being enforced.505//We don't need to reset minimum size if it's already set506}507if ((flags & XUtilConstants.PMaxSize) != 0) {508if (maxBounds != null) {509if (maxBounds.width != Integer.MAX_VALUE) {510hints.set_max_width(maxBounds.width);511} else {512hints.set_max_width(XToolkit.getDefaultScreenWidth());513}514if (maxBounds.height != Integer.MAX_VALUE) {515hints.set_max_height(maxBounds.height);516} else {517hints.set_max_height(XToolkit.getDefaultScreenHeight());518}519} else {520hints.set_max_width(width);521hints.set_max_height(height);522}523} else if ((hints.get_flags() & XUtilConstants.PMaxSize) != 0) {524flags |= XUtilConstants.PMaxSize;525if (maxBounds != null) {526if (maxBounds.width != Integer.MAX_VALUE) {527hints.set_max_width(maxBounds.width);528} else {529hints.set_max_width(XToolkit.getDefaultScreenWidth());530}531if (maxBounds.height != Integer.MAX_VALUE) {532hints.set_max_height(maxBounds.height);533} else {534hints.set_max_height(XToolkit.getDefaultScreenHeight());535}536} else {537// Leave intact538}539}540flags |= XUtilConstants.PWinGravity;541hints.set_flags(flags);542hints.set_win_gravity((int)XConstants.NorthWestGravity);543if (insLog.isLoggable(PlatformLogger.Level.FINER)) {544insLog.finer("Setting hints, resulted flags " + XlibWrapper.hintsToString(flags) +545", values " + hints);546}547XlibWrapper.XSetWMNormalHints(XToolkit.getDisplay(), getWindow(), hints.pData);548} finally {549XToolkit.awtUnlock();550}551}552553public boolean isMinSizeSet() {554XSizeHints hints = getHints();555long flags = hints.get_flags();556return ((flags & XUtilConstants.PMinSize) == XUtilConstants.PMinSize);557}558559/**560* This lock object can be used to protect instance data from concurrent access561* by two threads. If both state lock and AWT lock are taken, AWT Lock should be taken first.562*/563Object getStateLock() {564return state_lock;565}566567public long getWindow() {568return window;569}570public long getContentWindow() {571return window;572}573574public XBaseWindow getContentXWindow() {575return XToolkit.windowToXWindow(getContentWindow());576}577578public Rectangle getBounds() {579return new Rectangle(x, y, width, height);580}581public Dimension getSize() {582return new Dimension(width, height);583}584585586public void toFront() {587XToolkit.awtLock();588try {589XlibWrapper.XRaiseWindow(XToolkit.getDisplay(), getWindow());590} finally {591XToolkit.awtUnlock();592}593}594public void xRequestFocus(long time) {595XToolkit.awtLock();596try {597if (focusLog.isLoggable(PlatformLogger.Level.FINER)) {598focusLog.finer("XSetInputFocus on " + Long.toHexString(getWindow()) + " with time " + time);599}600XlibWrapper.XSetInputFocus2(XToolkit.getDisplay(), getWindow(), time);601} finally {602XToolkit.awtUnlock();603}604}605public void xRequestFocus() {606XToolkit.awtLock();607try {608if (focusLog.isLoggable(PlatformLogger.Level.FINER)) {609focusLog.finer("XSetInputFocus on " + Long.toHexString(getWindow()));610}611XlibWrapper.XSetInputFocus(XToolkit.getDisplay(), getWindow());612} finally {613XToolkit.awtUnlock();614}615}616617public static long xGetInputFocus() {618XToolkit.awtLock();619try {620return XlibWrapper.XGetInputFocus(XToolkit.getDisplay());621} finally {622XToolkit.awtUnlock();623}624}625626public void xSetVisible(boolean visible) {627if (log.isLoggable(PlatformLogger.Level.FINE)) {628log.fine("Setting visible on " + this + " to " + visible);629}630XToolkit.awtLock();631try {632this.visible = visible;633if (visible) {634XlibWrapper.XMapWindow(XToolkit.getDisplay(), getWindow());635}636else {637XlibWrapper.XUnmapWindow(XToolkit.getDisplay(), getWindow());638}639XlibWrapper.XFlush(XToolkit.getDisplay());640} finally {641XToolkit.awtUnlock();642}643}644645boolean isMapped() {646return mapped;647}648649void updateWMName() {650String name = getWMName();651XToolkit.awtLock();652try {653if (name == null) {654name = " ";655}656XAtom nameAtom = XAtom.get(XAtom.XA_WM_NAME);657nameAtom.setProperty(getWindow(), name);658XAtom netNameAtom = XAtom.get("_NET_WM_NAME");659netNameAtom.setPropertyUTF8(getWindow(), name);660} finally {661XToolkit.awtUnlock();662}663}664void setWMClass(String[] cl) {665if (cl.length != 2) {666throw new IllegalArgumentException("WM_CLASS_NAME consists of exactly two strings");667}668XToolkit.awtLock();669try {670XAtom xa = XAtom.get(XAtom.XA_WM_CLASS);671xa.setProperty8(getWindow(), cl[0] + '\0' + cl[1] + '\0');672} finally {673XToolkit.awtUnlock();674}675}676677boolean isVisible() {678return visible;679}680681static long getScreenOfWindow(long window) {682XToolkit.awtLock();683try {684return XlibWrapper.getScreenOfWindow(XToolkit.getDisplay(), window);685} finally {686XToolkit.awtUnlock();687}688}689long getScreenNumber() {690XToolkit.awtLock();691try {692return XlibWrapper.XScreenNumberOfScreen(getScreen());693} finally {694XToolkit.awtUnlock();695}696}697698long getScreen() {699if (screen == -1) { // Not initialized700screen = getScreenOfWindow(window);701}702return screen;703}704705public void xSetBounds(Rectangle bounds) {706xSetBounds(bounds.x, bounds.y, bounds.width, bounds.height);707}708709public void xSetBounds(int x, int y, int width, int height) {710if (getWindow() == 0) {711insLog.warning("Attempt to resize uncreated window");712throw new IllegalStateException("Attempt to resize uncreated window");713}714if (insLog.isLoggable(PlatformLogger.Level.FINE)) {715insLog.fine("Setting bounds on " + this + " to (" + x + ", " + y + "), " + width + "x" + height);716}717width = Math.max(MIN_SIZE, width);718height = Math.max(MIN_SIZE, height);719XToolkit.awtLock();720try {721XlibWrapper.XMoveResizeWindow(XToolkit.getDisplay(), getWindow(), x,y,width,height);722} finally {723XToolkit.awtUnlock();724}725}726727/**728* Translate coordinates from one window into another. Optimized729* for XAWT - uses cached data when possible. Preferable over730* pure XTranslateCoordinates.731* @return coordinates relative to dst, or null if error happened732*/733static Point toOtherWindow(long src, long dst, int x, int y) {734Point rpt = new Point(0, 0);735736// Check if both windows belong to XAWT - then no X calls are necessary737738XBaseWindow srcPeer = XToolkit.windowToXWindow(src);739XBaseWindow dstPeer = XToolkit.windowToXWindow(dst);740741if (srcPeer != null && dstPeer != null) {742// (x, y) is relative to src743rpt.x = x + srcPeer.getAbsoluteX() - dstPeer.getAbsoluteX();744rpt.y = y + srcPeer.getAbsoluteY() - dstPeer.getAbsoluteY();745} else if (dstPeer != null && XlibUtil.isRoot(src, dstPeer.getScreenNumber())) {746// from root into peer747rpt.x = x - dstPeer.getAbsoluteX();748rpt.y = y - dstPeer.getAbsoluteY();749} else if (srcPeer != null && XlibUtil.isRoot(dst, srcPeer.getScreenNumber())) {750// from peer into root751rpt.x = x + srcPeer.getAbsoluteX();752rpt.y = y + srcPeer.getAbsoluteY();753} else {754rpt = XlibUtil.translateCoordinates(src, dst, new Point(x, y));755}756return rpt;757}758759/*760* Convert to global coordinates.761*/762Rectangle toGlobal(Rectangle rec) {763Point p = toGlobal(rec.getLocation());764Rectangle newRec = new Rectangle(rec);765if (p != null) {766newRec.setLocation(p);767}768return newRec;769}770771Point toGlobal(Point pt) {772Point p = toGlobal(pt.x, pt.y);773if (p != null) {774return p;775} else {776return new Point(pt);777}778}779780Point toGlobal(int x, int y) {781long root;782XToolkit.awtLock();783try {784root = XlibWrapper.RootWindow(XToolkit.getDisplay(),785getScreenNumber());786} finally {787XToolkit.awtUnlock();788}789Point p = toOtherWindow(getContentWindow(), root, x, y);790if (p != null) {791return p;792} else {793return new Point(x, y);794}795}796797/*798* Convert to local coordinates.799*/800Point toLocal(Point pt) {801Point p = toLocal(pt.x, pt.y);802if (p != null) {803return p;804} else {805return new Point(pt);806}807}808809Point toLocal(int x, int y) {810long root;811XToolkit.awtLock();812try {813root = XlibWrapper.RootWindow(XToolkit.getDisplay(),814getScreenNumber());815} finally {816XToolkit.awtUnlock();817}818Point p = toOtherWindow(root, getContentWindow(), x, y);819if (p != null) {820return p;821} else {822return new Point(x, y);823}824}825826/**827* We should always grab both keyboard and pointer to control event flow828* on popups. This also simplifies synthetic grab implementation.829* The active grab overrides activated automatic grab.830*/831public boolean grabInput() {832if (grabLog.isLoggable(PlatformLogger.Level.FINE)) {833grabLog.fine("Grab input on {0}", this);834}835836XToolkit.awtLock();837try {838if (XAwtState.getGrabWindow() == this &&839XAwtState.isManualGrab())840{841grabLog.fine(" Already Grabbed");842return true;843}844//6273031: PIT. Choice drop down does not close once it is right clicked to show a popup menu845//remember previous window having grab and if it's not null ungrab it.846XBaseWindow prevGrabWindow = XAwtState.getGrabWindow();847final int eventMask = (int) (XConstants.ButtonPressMask | XConstants.ButtonReleaseMask848| XConstants.EnterWindowMask | XConstants.LeaveWindowMask | XConstants.PointerMotionMask849| XConstants.ButtonMotionMask);850final int ownerEvents = 1;851852853//6714678: IDE (Netbeans, Eclipse, JDeveloper) Debugger hangs854//process on Linux855//The user must pass the sun.awt.disablegrab property to disable856//taking grabs. This prevents hanging of the GUI when a breakpoint857//is hit while a popup window taking the grab is open.858if (!XToolkit.getSunAwtDisableGrab()) {859int ptrGrab = XlibWrapper.XGrabPointer(XToolkit.getDisplay(),860getContentWindow(), ownerEvents, eventMask, XConstants.GrabModeAsync,861XConstants.GrabModeAsync, XConstants.None, (XWM.isMotif() ? XToolkit.arrowCursor : XConstants.None),862XConstants.CurrentTime);863// Check grab results to be consistent with X server grab864if (ptrGrab != XConstants.GrabSuccess) {865XlibWrapper.XUngrabPointer(XToolkit.getDisplay(), XConstants.CurrentTime);866XAwtState.setGrabWindow(null);867grabLog.fine(" Grab Failure - mouse");868return false;869}870871int keyGrab = XlibWrapper.XGrabKeyboard(XToolkit.getDisplay(),872getContentWindow(), ownerEvents, XConstants.GrabModeAsync, XConstants.GrabModeAsync,873XConstants.CurrentTime);874if (keyGrab != XConstants.GrabSuccess) {875XlibWrapper.XUngrabPointer(XToolkit.getDisplay(), XConstants.CurrentTime);876XlibWrapper.XUngrabKeyboard(XToolkit.getDisplay(), XConstants.CurrentTime);877XAwtState.setGrabWindow(null);878grabLog.fine(" Grab Failure - keyboard");879return false;880}881}882if (prevGrabWindow != null) {883prevGrabWindow.ungrabInputImpl();884}885XAwtState.setGrabWindow(this);886grabLog.fine(" Grab - success");887return true;888} finally {889XToolkit.awtUnlock();890}891}892893static void ungrabInput() {894XToolkit.awtLock();895try {896XBaseWindow grabWindow = XAwtState.getGrabWindow();897if (grabLog.isLoggable(PlatformLogger.Level.FINE)) {898grabLog.fine("UnGrab input on {0}", grabWindow);899}900if (grabWindow != null) {901grabWindow.ungrabInputImpl();902if (!XToolkit.getSunAwtDisableGrab()) {903XlibWrapper.XUngrabPointer(XToolkit.getDisplay(), XConstants.CurrentTime);904XlibWrapper.XUngrabKeyboard(XToolkit.getDisplay(), XConstants.CurrentTime);905}906XAwtState.setGrabWindow(null);907// we need to call XFlush() here to force ungrab908// see 6384219 for details909XlibWrapper.XFlush(XToolkit.getDisplay());910}911} finally {912XToolkit.awtUnlock();913}914}915916// called from ungrabInput, used in popup windows to hide theirselfs in ungrabbing917void ungrabInputImpl() {918}919920static void checkSecurity() {921if (XToolkit.isSecurityWarningEnabled() && XToolkit.isToolkitThread()) {922StackTraceElement stack[] = (new Throwable()).getStackTrace();923log.warning(stack[1] + ": Security violation: calling user code on toolkit thread");924}925}926927public Set<Long> getChildren() {928synchronized (getStateLock()) {929return new HashSet<Long>(children);930}931}932933// -------------- Event handling ----------------934public void handleMapNotifyEvent(XEvent xev) {935mapped = true;936}937public void handleUnmapNotifyEvent(XEvent xev) {938mapped = false;939}940public void handleReparentNotifyEvent(XEvent xev) {941if (eventLog.isLoggable(PlatformLogger.Level.FINER)) {942XReparentEvent msg = xev.get_xreparent();943eventLog.finer(msg.toString());944}945}946public void handlePropertyNotify(XEvent xev) {947XPropertyEvent msg = xev.get_xproperty();948if (XPropertyCache.isCachingSupported()) {949XPropertyCache.clearCache(window, XAtom.get(msg.get_atom()));950}951if (eventLog.isLoggable(PlatformLogger.Level.FINER)) {952eventLog.finer("{0}", msg);953}954}955956public void handleDestroyNotify(XEvent xev) {957XAnyEvent xany = xev.get_xany();958if (xany.get_window() == getWindow()) {959XToolkit.removeFromWinMap(getWindow(), this);960if (XPropertyCache.isCachingSupported()) {961XPropertyCache.clearCache(getWindow());962}963}964if (xany.get_window() != getWindow()) {965synchronized (getStateLock()) {966children.remove(xany.get_window());967}968}969}970971public void handleCreateNotify(XEvent xev) {972XAnyEvent xany = xev.get_xany();973if (xany.get_window() != getWindow()) {974synchronized (getStateLock()) {975children.add(xany.get_window());976}977}978}979980public void handleClientMessage(XEvent xev) {981if (eventLog.isLoggable(PlatformLogger.Level.FINER)) {982XClientMessageEvent msg = xev.get_xclient();983eventLog.finer(msg.toString());984}985}986987public void handleVisibilityEvent(XEvent xev) {988}989public void handleKeyPress(XEvent xev) {990}991public void handleKeyRelease(XEvent xev) {992}993public void handleExposeEvent(XEvent xev) {994}995/**996* Activate automatic grab on first ButtonPress,997* deactivate on full mouse release998*/999public void handleButtonPressRelease(XEvent xev) {1000XButtonEvent xbe = xev.get_xbutton();1001/*1002* Ignore the buttons above 20 due to the bit limit for1003* InputEvent.BUTTON_DOWN_MASK.1004* One more bit is reserved for FIRST_HIGH_BIT.1005*/1006int theButton = xbe.get_button();1007if (theButton > SunToolkit.MAX_BUTTONS_SUPPORTED) {1008return;1009}1010int buttonState = 0;1011buttonState = xbe.get_state() & XConstants.ALL_BUTTONS_MASK;10121013boolean isWheel = (theButton == XConstants.MouseWheelUp ||1014theButton == XConstants.MouseWheelDown);10151016// don't give focus if it's just the mouse wheel turning1017if (!isWheel) {1018switch (xev.get_type()) {1019case XConstants.ButtonPress:1020if (buttonState == 0) {1021XWindowPeer parent = getToplevelXWindow();1022// See 6385277, 6981400.1023if (parent != null && parent.isFocusableWindow()) {1024// A click in a client area drops the actual focused window retaining.1025parent.setActualFocusedWindow(null);1026parent.requestWindowFocus(xbe.get_time(), true);1027}1028XAwtState.setAutoGrabWindow(this);1029}1030break;1031case XConstants.ButtonRelease:1032if (isFullRelease(buttonState, xbe.get_button())) {1033XAwtState.setAutoGrabWindow(null);1034}1035break;1036}1037}1038}1039public void handleMotionNotify(XEvent xev) {1040}1041public void handleXCrossingEvent(XEvent xev) {1042}1043public void handleConfigureNotifyEvent(XEvent xev) {1044XConfigureEvent xe = xev.get_xconfigure();1045if (insLog.isLoggable(PlatformLogger.Level.FINER)) {1046insLog.finer("Configure, {0}", xe);1047}1048x = xe.get_x();1049y = xe.get_y();1050width = xe.get_width();1051height = xe.get_height();1052}1053/**1054* Checks ButtonRelease released all Mouse buttons1055*/1056static boolean isFullRelease(int buttonState, int button) {1057final int buttonsNumber = XToolkit.getNumberOfButtonsForMask();10581059if (button < 0 || button > buttonsNumber) {1060return buttonState == 0;1061} else {1062return buttonState == XlibUtil.getButtonMask(button);1063}1064}10651066static boolean isGrabbedEvent(XEvent ev, XBaseWindow target) {1067switch (ev.get_type()) {1068case XConstants.ButtonPress:1069case XConstants.ButtonRelease:1070case XConstants.MotionNotify:1071case XConstants.KeyPress:1072case XConstants.KeyRelease:1073return true;1074case XConstants.LeaveNotify:1075case XConstants.EnterNotify:1076// We shouldn't dispatch this events to the grabbed components (see 6317481)1077// But this logic is important if the grabbed component is top-level (see realSync)1078return (target instanceof XWindowPeer);1079default:1080return false;1081}1082}1083/**1084* Dispatches event to the grab Window or event source window depending1085* on whether the grab is active and on the event type1086*/1087static void dispatchToWindow(XEvent ev) {1088XBaseWindow target = XAwtState.getGrabWindow();1089if (target == null || !isGrabbedEvent(ev, target)) {1090target = XToolkit.windowToXWindow(ev.get_xany().get_window());1091}1092if (target != null && target.checkInitialised()) {1093target.dispatchEvent(ev);1094}1095}10961097public void dispatchEvent(XEvent xev) {1098if (eventLog.isLoggable(PlatformLogger.Level.FINEST)) {1099eventLog.finest(xev.toString());1100}1101int type = xev.get_type();11021103if (isDisposed()) {1104return;1105}11061107switch (type)1108{1109case XConstants.VisibilityNotify:1110handleVisibilityEvent(xev);1111break;1112case XConstants.ClientMessage:1113handleClientMessage(xev);1114break;1115case XConstants.Expose :1116case XConstants.GraphicsExpose :1117handleExposeEvent(xev);1118break;1119case XConstants.ButtonPress:1120case XConstants.ButtonRelease:1121handleButtonPressRelease(xev);1122break;11231124case XConstants.MotionNotify:1125handleMotionNotify(xev);1126break;1127case XConstants.KeyPress:1128handleKeyPress(xev);1129break;1130case XConstants.KeyRelease:1131handleKeyRelease(xev);1132break;1133case XConstants.EnterNotify:1134case XConstants.LeaveNotify:1135handleXCrossingEvent(xev);1136break;1137case XConstants.ConfigureNotify:1138handleConfigureNotifyEvent(xev);1139break;1140case XConstants.MapNotify:1141handleMapNotifyEvent(xev);1142break;1143case XConstants.UnmapNotify:1144handleUnmapNotifyEvent(xev);1145break;1146case XConstants.ReparentNotify:1147handleReparentNotifyEvent(xev);1148break;1149case XConstants.PropertyNotify:1150handlePropertyNotify(xev);1151break;1152case XConstants.DestroyNotify:1153handleDestroyNotify(xev);1154break;1155case XConstants.CreateNotify:1156handleCreateNotify(xev);1157break;1158}1159}1160protected boolean isEventDisabled(XEvent e) {1161return false;1162}11631164int getX() {1165return x;1166}11671168int getY() {1169return y;1170}11711172int getWidth() {1173return width;1174}11751176int getHeight() {1177return height;1178}11791180void setDisposed(boolean d) {1181disposed = d;1182}11831184boolean isDisposed() {1185return disposed;1186}11871188public int getAbsoluteX() {1189XBaseWindow pw = getParentWindow();1190if (pw != null) {1191return pw.getAbsoluteX() + getX();1192} else {1193// Overridden for top-levels as their (x,y) is Java (x, y), not native location1194return getX();1195}1196}11971198public int getAbsoluteY() {1199XBaseWindow pw = getParentWindow();1200if (pw != null) {1201return pw.getAbsoluteY() + getY();1202} else {1203return getY();1204}1205}12061207public XBaseWindow getParentWindow() {1208return parentWindow;1209}12101211public XWindowPeer getToplevelXWindow() {1212XBaseWindow bw = this;1213while (bw != null && !(bw instanceof XWindowPeer)) {1214bw = bw.getParentWindow();1215}1216return (XWindowPeer)bw;1217}1218public String toString() {1219return super.toString() + "(" + Long.toString(getWindow(), 16) + ")";1220}12211222/**1223* Returns whether the given point is inside of the window. Coordinates are local.1224*/1225public boolean contains(int x, int y) {1226return x >= 0 && y >= 0 && x < getWidth() && y < getHeight();1227}12281229/**1230* Returns whether the given point is inside of the window. Coordinates are global.1231*/1232public boolean containsGlobal(int x, int y) {1233return x >= getAbsoluteX() && y >= getAbsoluteY() && x < (getAbsoluteX()+getWidth()) && y < (getAbsoluteY()+getHeight());1234}12351236}123712381239