| /* |
| * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved. |
| * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
| * |
| * This code is free software; you can redistribute it and/or modify it |
| * under the terms of the GNU General Public License version 2 only, as |
| * published by the Free Software Foundation. Oracle designates this |
| * particular file as subject to the "Classpath" exception as provided |
| * by Oracle in the LICENSE file that accompanied this code. |
| * |
| * This code is distributed in the hope that it will be useful, but WITHOUT |
| * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
| * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
| * version 2 for more details (a copy is included in the LICENSE file that |
| * accompanied this code). |
| * |
| * You should have received a copy of the GNU General Public License version |
| * 2 along with this work; if not, write to the Free Software Foundation, |
| * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. |
| * |
| * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
| * or visit www.oracle.com if you need additional information or have any |
| * questions. |
| */ |
| package sun.awt.X11; |
| |
| import java.awt.*; |
| import java.awt.geom.Point2D; |
| import java.lang.ref.WeakReference; |
| |
| import sun.awt.IconInfo; |
| import sun.awt.AWTAccessor; |
| import sun.awt.SunToolkit; |
| |
| class XWarningWindow extends XWindow { |
| private final static int SHOWING_DELAY = 330; |
| private final static int HIDING_DELAY = 2000; |
| |
| private final Window ownerWindow; |
| private WeakReference<XWindowPeer> ownerPeer; |
| private long parentWindow; |
| |
| private final static String OWNER = "OWNER"; |
| private InfoWindow.Tooltip tooltip; |
| |
| /** |
| * Animation stage. |
| */ |
| private volatile int currentIcon = 0; |
| |
| /* -1 - uninitialized. |
| * 0 - 16x16 |
| * 1 - 24x24 |
| * 2 - 32x32 |
| * 3 - 48x48 |
| */ |
| private int currentSize = -1; |
| private static IconInfo[][] icons; |
| private static IconInfo getSecurityIconInfo(int size, int num) { |
| synchronized (XWarningWindow.class) { |
| if (icons == null) { |
| icons = new IconInfo[4][3]; |
| if (XlibWrapper.dataModel == 32) { |
| icons[0][0] = new IconInfo(sun.awt.AWTIcon32_security_icon_bw16_png.security_icon_bw16_png); |
| icons[0][1] = new IconInfo(sun.awt.AWTIcon32_security_icon_interim16_png.security_icon_interim16_png); |
| icons[0][2] = new IconInfo(sun.awt.AWTIcon32_security_icon_yellow16_png.security_icon_yellow16_png); |
| icons[1][0] = new IconInfo(sun.awt.AWTIcon32_security_icon_bw24_png.security_icon_bw24_png); |
| icons[1][1] = new IconInfo(sun.awt.AWTIcon32_security_icon_interim24_png.security_icon_interim24_png); |
| icons[1][2] = new IconInfo(sun.awt.AWTIcon32_security_icon_yellow24_png.security_icon_yellow24_png); |
| icons[2][0] = new IconInfo(sun.awt.AWTIcon32_security_icon_bw32_png.security_icon_bw32_png); |
| icons[2][1] = new IconInfo(sun.awt.AWTIcon32_security_icon_interim32_png.security_icon_interim32_png); |
| icons[2][2] = new IconInfo(sun.awt.AWTIcon32_security_icon_yellow32_png.security_icon_yellow32_png); |
| icons[3][0] = new IconInfo(sun.awt.AWTIcon32_security_icon_bw48_png.security_icon_bw48_png); |
| icons[3][1] = new IconInfo(sun.awt.AWTIcon32_security_icon_interim48_png.security_icon_interim48_png); |
| icons[3][2] = new IconInfo(sun.awt.AWTIcon32_security_icon_yellow48_png.security_icon_yellow48_png); |
| } else { |
| icons[0][0] = new IconInfo(sun.awt.AWTIcon64_security_icon_bw16_png.security_icon_bw16_png); |
| icons[0][1] = new IconInfo(sun.awt.AWTIcon64_security_icon_interim16_png.security_icon_interim16_png); |
| icons[0][2] = new IconInfo(sun.awt.AWTIcon64_security_icon_yellow16_png.security_icon_yellow16_png); |
| icons[1][0] = new IconInfo(sun.awt.AWTIcon64_security_icon_bw24_png.security_icon_bw24_png); |
| icons[1][1] = new IconInfo(sun.awt.AWTIcon64_security_icon_interim24_png.security_icon_interim24_png); |
| icons[1][2] = new IconInfo(sun.awt.AWTIcon64_security_icon_yellow24_png.security_icon_yellow24_png); |
| icons[2][0] = new IconInfo(sun.awt.AWTIcon64_security_icon_bw32_png.security_icon_bw32_png); |
| icons[2][1] = new IconInfo(sun.awt.AWTIcon64_security_icon_interim32_png.security_icon_interim32_png); |
| icons[2][2] = new IconInfo(sun.awt.AWTIcon64_security_icon_yellow32_png.security_icon_yellow32_png); |
| icons[3][0] = new IconInfo(sun.awt.AWTIcon64_security_icon_bw48_png.security_icon_bw48_png); |
| icons[3][1] = new IconInfo(sun.awt.AWTIcon64_security_icon_interim48_png.security_icon_interim48_png); |
| icons[3][2] = new IconInfo(sun.awt.AWTIcon64_security_icon_yellow48_png.security_icon_yellow48_png); |
| } |
| } |
| } |
| final int sizeIndex = size % icons.length; |
| return icons[sizeIndex][num % icons[sizeIndex].length]; |
| } |
| |
| private void updateIconSize() { |
| int newSize = -1; |
| |
| if (ownerWindow != null) { |
| Insets insets = ownerWindow.getInsets(); |
| int max = Math.max(insets.top, Math.max(insets.bottom, |
| Math.max(insets.left, insets.right))); |
| if (max < 24) { |
| newSize = 0; |
| } else if (max < 32) { |
| newSize = 1; |
| } else if (max < 48) { |
| newSize = 2; |
| } else { |
| newSize = 3; |
| } |
| } |
| // Make sure we have a valid size |
| if (newSize == -1) { |
| newSize = 0; |
| } |
| |
| // Note: this is not the most wise solution to use awtLock here, |
| // this should have been sync'ed with the stateLock. However, |
| // the awtLock must be taken first (see XBaseWindow.getStateLock()), |
| // and we need the awtLock anyway to update the shape of the icon. |
| // So it's easier to use just one lock instead. |
| XToolkit.awtLock(); |
| try { |
| if (newSize != currentSize) { |
| currentSize = newSize; |
| IconInfo ico = getSecurityIconInfo(currentSize, 0); |
| XlibWrapper.SetBitmapShape(XToolkit.getDisplay(), getWindow(), |
| ico.getWidth(), ico.getHeight(), ico.getIntData()); |
| AWTAccessor.getWindowAccessor().setSecurityWarningSize( |
| ownerWindow, ico.getWidth(), ico.getHeight()); |
| } |
| } finally { |
| XToolkit.awtUnlock(); |
| } |
| } |
| |
| private IconInfo getSecurityIconInfo() { |
| updateIconSize(); |
| return getSecurityIconInfo(currentSize, currentIcon); |
| } |
| |
| XWarningWindow(final Window ownerWindow, long parentWindow, XWindowPeer ownerPeer) { |
| super(new XCreateWindowParams(new Object[] { |
| TARGET, ownerWindow, |
| OWNER, Long.valueOf(parentWindow) |
| })); |
| this.ownerWindow = ownerWindow; |
| this.parentWindow = parentWindow; |
| this.tooltip = new InfoWindow.Tooltip(null, getTarget(), |
| new InfoWindow.Tooltip.LiveArguments() { |
| public boolean isDisposed() { |
| return XWarningWindow.this.isDisposed(); |
| } |
| public Rectangle getBounds() { |
| return XWarningWindow.this.getBounds(); |
| } |
| public String getTooltipString() { |
| return XWarningWindow.this.ownerWindow.getWarningString(); |
| } |
| }); |
| this.ownerPeer = new WeakReference<XWindowPeer>(ownerPeer); |
| } |
| |
| private void requestNoTaskbar() { |
| XNETProtocol netProtocol = XWM.getWM().getNETProtocol(); |
| if (netProtocol != null) { |
| netProtocol.requestState(this, netProtocol.XA_NET_WM_STATE_SKIP_TASKBAR, true); |
| } |
| } |
| |
| @Override |
| void postInit(XCreateWindowParams params) { |
| super.postInit(params); |
| XToolkit.awtLock(); |
| try { |
| XWM.setMotifDecor(this, false, 0, 0); |
| XWM.setOLDecor(this, false, 0); |
| |
| long parentWindow = ((Long)params.get(OWNER)).longValue(); |
| XlibWrapper.XSetTransientFor(XToolkit.getDisplay(), |
| getWindow(), parentWindow); |
| |
| XWMHints hints = getWMHints(); |
| hints.set_flags(hints.get_flags() | (int)XUtilConstants.InputHint | (int)XUtilConstants.StateHint); |
| hints.set_input(false); |
| hints.set_initial_state(XUtilConstants.NormalState); |
| XlibWrapper.XSetWMHints(XToolkit.getDisplay(), getWindow(), hints.pData); |
| |
| initWMProtocols(); |
| requestNoTaskbar(); |
| } finally { |
| XToolkit.awtUnlock(); |
| } |
| } |
| |
| /** |
| * @param x,y,w,h coordinates of the untrusted window |
| */ |
| public void reposition(int x, int y, int w, int h) { |
| Point2D point = AWTAccessor.getWindowAccessor(). |
| calculateSecurityWarningPosition(ownerWindow, |
| x, y, w, h); |
| reshape((int)point.getX(), (int)point.getY(), getWidth(), getHeight()); |
| } |
| |
| protected String getWMName() { |
| return "Warning window"; |
| } |
| |
| public Graphics getGraphics() { |
| if ((surfaceData == null) || (ownerWindow == null)) return null; |
| return getGraphics(surfaceData, |
| getColor(), |
| getBackground(), |
| getFont()); |
| } |
| void paint(Graphics g, int x, int y, int width, int height) { |
| g.drawImage(getSecurityIconInfo().getImage(), 0, 0, null); |
| } |
| |
| String getWarningString() { |
| return ownerWindow.getWarningString(); |
| } |
| |
| int getWidth() { |
| return getSecurityIconInfo().getWidth(); |
| } |
| |
| int getHeight() { |
| return getSecurityIconInfo().getHeight(); |
| } |
| |
| Color getBackground() { |
| return SystemColor.window; |
| } |
| Color getColor() { |
| return Color.black; |
| } |
| Font getFont () { |
| return ownerWindow.getFont(); |
| } |
| public void repaint() { |
| Rectangle bounds = getBounds(); |
| Graphics g = getGraphics(); |
| try { |
| paint(g, 0, 0, bounds.width, bounds.height); |
| } finally { |
| g.dispose(); |
| } |
| } |
| |
| @Override |
| public void handleExposeEvent(XEvent xev) { |
| super.handleExposeEvent(xev); |
| |
| XExposeEvent xe = xev.get_xexpose(); |
| final int x = xe.get_x(); |
| final int y = xe.get_y(); |
| final int width = xe.get_width(); |
| final int height = xe.get_height(); |
| SunToolkit.executeOnEventHandlerThread(target, |
| new Runnable() { |
| public void run() { |
| Graphics g = getGraphics(); |
| try { |
| paint(g, x, y, width, height); |
| } finally { |
| g.dispose(); |
| } |
| } |
| }); |
| } |
| |
| @Override |
| protected boolean isEventDisabled(XEvent e) { |
| return true; |
| } |
| |
| /** Send a synthetic UnmapNotify in order to withdraw the window. |
| */ |
| private void withdraw() { |
| XEvent req = new XEvent(); |
| try { |
| long root; |
| XToolkit.awtLock(); |
| try { |
| root = XlibWrapper.RootWindow(XToolkit.getDisplay(), getScreenNumber()); |
| } |
| finally { |
| XToolkit.awtUnlock(); |
| } |
| |
| req.set_type(XConstants.UnmapNotify); |
| |
| XUnmapEvent umev = req.get_xunmap(); |
| |
| umev.set_event(root); |
| umev.set_window(getWindow()); |
| umev.set_from_configure(false); |
| |
| XToolkit.awtLock(); |
| try { |
| XlibWrapper.XSendEvent(XToolkit.getDisplay(), |
| root, |
| false, |
| XConstants.SubstructureRedirectMask | XConstants.SubstructureNotifyMask, |
| req.pData); |
| } |
| finally { |
| XToolkit.awtUnlock(); |
| } |
| } finally { |
| req.dispose(); |
| } |
| } |
| |
| @Override |
| protected void stateChanged(long time, int oldState, int newState) { |
| if (newState == XUtilConstants.IconicState) { |
| super.xSetVisible(false); |
| withdraw(); |
| } |
| } |
| |
| @Override |
| protected void setMouseAbove(boolean above) { |
| super.setMouseAbove(above); |
| XWindowPeer p = ownerPeer.get(); |
| if (p != null) { |
| p.updateSecurityWarningVisibility(); |
| } |
| } |
| |
| @Override |
| protected void enterNotify(long window) { |
| super.enterNotify(window); |
| if (window == getWindow()) { |
| tooltip.enter(); |
| } |
| } |
| |
| @Override |
| protected void leaveNotify(long window) { |
| super.leaveNotify(window); |
| if (window == getWindow()) { |
| tooltip.exit(); |
| } |
| } |
| |
| @Override |
| public void xSetVisible(boolean visible) { |
| super.xSetVisible(visible); |
| |
| // The _NET_WM_STATE_SKIP_TASKBAR got reset upon hiding/showing, |
| // so we request it every time whenever we change the visibility. |
| requestNoTaskbar(); |
| } |
| |
| private final Runnable hidingTask = new Runnable() { |
| public void run() { |
| xSetVisible(false); |
| } |
| }; |
| |
| private final Runnable showingTask = new Runnable() { |
| public void run() { |
| if (!isVisible()) { |
| xSetVisible(true); |
| updateIconSize(); |
| XWindowPeer peer = ownerPeer.get(); |
| if (peer != null) { |
| peer.repositionSecurityWarning(); |
| } |
| } |
| repaint(); |
| if (currentIcon > 0) { |
| currentIcon--; |
| XToolkit.schedule(showingTask, SHOWING_DELAY); |
| } |
| } |
| }; |
| |
| public void setSecurityWarningVisible(boolean visible, boolean doSchedule) { |
| if (visible) { |
| XToolkit.remove(hidingTask); |
| XToolkit.remove(showingTask); |
| if (isVisible()) { |
| currentIcon = 0; |
| } else { |
| currentIcon = 3; |
| } |
| if (doSchedule) { |
| XToolkit.schedule(showingTask, 1); |
| } else { |
| showingTask.run(); |
| } |
| } else { |
| XToolkit.remove(showingTask); |
| XToolkit.remove(hidingTask); |
| if (!isVisible()) { |
| return; |
| } |
| if (doSchedule) { |
| XToolkit.schedule(hidingTask, HIDING_DELAY); |
| } else { |
| hidingTask.run(); |
| } |
| } |
| } |
| } |