1/*
2 * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.  Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26package java.awt;
27
28import sun.awt.AWTPermissions;
29import sun.awt.ComponentFactory;
30
31/**
32 * {@code MouseInfo}  provides methods for getting information about the mouse,
33 * such as mouse pointer location and the number of mouse buttons.
34 *
35 * @author     Roman Poborchiy
36 * @since 1.5
37 */
38
39public class MouseInfo {
40
41    /**
42     * Private constructor to prevent instantiation.
43     */
44    private MouseInfo() {
45    }
46
47    /**
48     * Returns a {@code PointerInfo} instance that represents the current
49     * location of the mouse pointer.
50     * The {@code GraphicsDevice} stored in this {@code PointerInfo}
51     * contains the mouse pointer. The coordinate system used for the mouse position
52     * depends on whether or not the {@code GraphicsDevice} is part of a virtual
53     * screen device.
54     * For virtual screen devices, the coordinates are given in the virtual
55     * coordinate system, otherwise they are returned in the coordinate system
56     * of the {@code GraphicsDevice}. See {@link GraphicsConfiguration}
57     * for more information about the virtual screen devices.
58     * On systems without a mouse, returns {@code null}.
59     * <p>
60     * If there is a security manager, its {@code checkPermission} method
61     * is called with an {@code AWTPermission("watchMousePointer")}
62     * permission before creating and returning a {@code PointerInfo}
63     * object. This may result in a {@code SecurityException}.
64     *
65     * @exception HeadlessException if GraphicsEnvironment.isHeadless() returns true
66     * @exception SecurityException if a security manager exists and its
67     *            {@code checkPermission} method doesn't allow the operation
68     * @see       GraphicsConfiguration
69     * @see       SecurityManager#checkPermission
70     * @see       java.awt.AWTPermission
71     * @return    location of the mouse pointer
72     * @since     1.5
73     */
74    public static PointerInfo getPointerInfo() throws HeadlessException {
75        if (GraphicsEnvironment.isHeadless()) {
76            throw new HeadlessException();
77        }
78
79        SecurityManager security = System.getSecurityManager();
80        if (security != null) {
81            security.checkPermission(AWTPermissions.WATCH_MOUSE_PERMISSION);
82        }
83
84        Toolkit toolkit = Toolkit.getDefaultToolkit();
85        Point point = new Point(0, 0);
86        int deviceNum = 0;
87        if (toolkit instanceof ComponentFactory) {
88            deviceNum = ((ComponentFactory) toolkit).getMouseInfoPeer().fillPointWithCoords(point);
89        }
90
91        GraphicsDevice[] gds = GraphicsEnvironment.getLocalGraphicsEnvironment().
92                                   getScreenDevices();
93        PointerInfo retval = null;
94        if (areScreenDevicesIndependent(gds)) {
95            retval = new PointerInfo(gds[deviceNum], point);
96        } else {
97            for (int i = 0; i < gds.length; i++) {
98                GraphicsConfiguration gc = gds[i].getDefaultConfiguration();
99                Rectangle bounds = gc.getBounds();
100                if (bounds.contains(point)) {
101                    retval = new PointerInfo(gds[i], point);
102                }
103            }
104        }
105
106        return retval;
107    }
108
109    private static boolean areScreenDevicesIndependent(GraphicsDevice[] gds) {
110        for (int i = 0; i < gds.length; i++) {
111            Rectangle bounds = gds[i].getDefaultConfiguration().getBounds();
112            if (bounds.x != 0 || bounds.y != 0) {
113                return false;
114            }
115        }
116        return true;
117    }
118
119    /**
120     * Returns the number of buttons on the mouse.
121     * On systems without a mouse, returns {@code -1}.
122     * The number of buttons is obtained from the AWT Toolkit
123     * by requesting the {@code "awt.mouse.numButtons"} desktop property
124     * which is set by the underlying native platform.
125     *
126     * @exception HeadlessException if GraphicsEnvironment.isHeadless() returns true
127     * @return number of buttons on the mouse
128     * @see Toolkit#getDesktopProperty
129     * @since 1.5
130     */
131    public static int getNumberOfButtons() throws HeadlessException {
132        if (GraphicsEnvironment.isHeadless()) {
133            throw new HeadlessException();
134        }
135        Object prop = Toolkit.getDefaultToolkit().
136                              getDesktopProperty("awt.mouse.numButtons");
137        if (prop instanceof Integer) {
138            return ((Integer)prop).intValue();
139        }
140
141        // This should never happen.
142        assert false : "awt.mouse.numButtons is not an integer property";
143        return 0;
144    }
145
146}
147