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