1 /*
2 * Copyright (c) 2002, 2017, 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
198 static TreeMap<Long, XBaseWindow> winMap = new TreeMap<>();
199 static HashMap<Object, Object> specialPeerMap = new HashMap<>();
200 static HashMap<Long, Collection<XEventDispatcher>> winToDispatcher = new HashMap<>();
201 static UIDefaults uidefaults;
202 static final X11GraphicsEnvironment localEnv;
203 private static final X11GraphicsDevice device;
204 private static final long display;
205 static int awt_multiclick_time;
206 static boolean securityWarningEnabled;
207
208 /**
209 * Dimensions of default virtual screen in pixels. These values are used to
210 * limit the maximum size of the window.
211 */
212 private static volatile int maxWindowWidthInPixels = -1;
213 private static volatile int maxWindowHeightInPixels = -1;
214
215 static long awt_defaultFg; // Pixel
216 private static XMouseInfoPeer xPeer;
217
218 static {
219 initSecurityWarning();
220 if (GraphicsEnvironment.isHeadless()) {
221 localEnv = null;
222 device = null;
223 display = 0;
224 } else {
225 localEnv = (X11GraphicsEnvironment) GraphicsEnvironment
226 .getLocalGraphicsEnvironment();
227 device = (X11GraphicsDevice) localEnv.getDefaultScreenDevice();
228 display = device.getDisplay();
229 setupModifierMap();
230 initIDs();
231 setBackingStoreType();
232 }
233 }
234
235 /*
236 * Return (potentially) platform specific display timeout for the
237 * tray icon
809 int rootX = (int)Native.getLong(native_ptr, 0);
810 int rootY = (int)Native.getLong(native_ptr, 1);
811 int rootWidth = (int)Native.getLong(native_ptr, 2);
812 int rootHeight = (int)Native.getLong(native_ptr, 3);
813
814 return new Rectangle(scaleDown(rootX, scale),
815 scaleDown(rootY, scale),
816 scaleDown(rootWidth, scale),
817 scaleDown(rootHeight, scale));
818 }
819 }
820 finally
821 {
822 XlibWrapper.unsafe.freeMemory(native_ptr);
823 }
824
825 return null;
826 }
827
828 /*
829 * If we're running in non-Xinerama environment and the current
830 * window manager supports _NET protocol then the screen insets
831 * are calculated using _NET_WM_WORKAREA property of the root
832 * window.
833 * Otherwise, i. e. if Xinerama is on or _NET_WM_WORKAREA is
834 * not set, we try to calculate the insets ourselves using
835 * getScreenInsetsManually method.
836 */
837 @Override
838 public Insets getScreenInsets(GraphicsConfiguration gc)
839 {
840 XNETProtocol netProto = XWM.getWM().getNETProtocol();
841 if ((netProto == null) || !netProto.active())
842 {
843 return super.getScreenInsets(gc);
844 }
845
846 XToolkit.awtLock();
847 try
848 {
849 X11GraphicsConfig x11gc = (X11GraphicsConfig)gc;
850 X11GraphicsDevice x11gd = x11gc.getDevice();
851 long root = XlibUtil.getRootWindow(x11gd.getScreen());
852 int scale = x11gc.getScale();
853 Rectangle rootBounds = XlibUtil.getWindowGeometry(root, scale);
854
855 X11GraphicsEnvironment x11ge = (X11GraphicsEnvironment)
856 GraphicsEnvironment.getLocalGraphicsEnvironment();
857 if (!x11ge.runningXinerama())
858 {
859 Insets screenInsets = getInsets(root, rootBounds, scale);
860 if (screenInsets != null) return screenInsets;
861 }
862
863 Insets insets = getScreenInsetsManually(root, rootBounds,
864 gc.getBounds(), scale);
865 if ((insets.left | insets.top | insets.bottom | insets.right) == 0
866 && rootBounds != null ) {
867 root = XlibWrapper.RootWindow(XToolkit.getDisplay(),
868 x11gd.getScreen());
869 Insets screenInsets = getInsets(root, rootBounds, scale);
870 if (screenInsets != null) return screenInsets;
871 }
872 return insets;
873 }
874 finally
875 {
876 XToolkit.awtUnlock();
877 }
878 }
879
880 private Insets getInsets(long root, Rectangle rootBounds, int scale) {
881 Rectangle workArea = XToolkit.getWorkArea(root, scale);
882 if (workArea == null) {
883 return null;
884 }
885 return new Insets(workArea.y, workArea.x,
886 rootBounds.height - workArea.height - workArea.y,
887 rootBounds.width - workArea.width - workArea.x);
888 }
889
890 /*
891 * Manual calculation of screen insets: get all the windows with
892 * _NET_WM_STRUT/_NET_WM_STRUT_PARTIAL hints and add these
893 * hints' values to screen insets.
894 *
895 * This method should be called under XToolkit.awtLock()
896 */
897 private Insets getScreenInsetsManually(long root, Rectangle rootBounds,
898 Rectangle screenBounds, int scale)
899 {
900 /*
901 * During the manual calculation of screen insets we iterate
902 * all the X windows hierarchy starting from root window. This
903 * constant is the max level inspected in this hierarchy.
904 * 3 is a heuristic value: I suppose any the toolbar-like
905 * window is a child of either root or desktop window.
906 */
907 final int MAX_NESTED_LEVEL = 3;
908
909 XAtom XA_NET_WM_STRUT = XAtom.get("_NET_WM_STRUT");
910 XAtom XA_NET_WM_STRUT_PARTIAL = XAtom.get("_NET_WM_STRUT_PARTIAL");
911
912 Insets insets = new Insets(0, 0, 0, 0);
913
914 java.util.List<Object> search = new LinkedList<>();
915 search.add(root);
|
1 /*
2 * Copyright (c) 2002, 2018, 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
198 static TreeMap<Long, XBaseWindow> winMap = new TreeMap<>();
199 static HashMap<Object, Object> specialPeerMap = new HashMap<>();
200 static HashMap<Long, Collection<XEventDispatcher>> winToDispatcher = new HashMap<>();
201 static UIDefaults uidefaults;
202 static final X11GraphicsEnvironment localEnv;
203 private static final X11GraphicsDevice device;
204 private static final long display;
205 static int awt_multiclick_time;
206 static boolean securityWarningEnabled;
207
208 /**
209 * Dimensions of default virtual screen in pixels. These values are used to
210 * limit the maximum size of the window.
211 */
212 private static volatile int maxWindowWidthInPixels = -1;
213 private static volatile int maxWindowHeightInPixels = -1;
214
215 static long awt_defaultFg; // Pixel
216 private static XMouseInfoPeer xPeer;
217
218 /**
219 * Should we check "_NET_WM_STRUT/_NET_WM_STRUT_PARTIAL" during insets
220 * calculation.
221 */
222 private static Boolean checkSTRUT;
223
224 static {
225 initSecurityWarning();
226 if (GraphicsEnvironment.isHeadless()) {
227 localEnv = null;
228 device = null;
229 display = 0;
230 } else {
231 localEnv = (X11GraphicsEnvironment) GraphicsEnvironment
232 .getLocalGraphicsEnvironment();
233 device = (X11GraphicsDevice) localEnv.getDefaultScreenDevice();
234 display = device.getDisplay();
235 setupModifierMap();
236 initIDs();
237 setBackingStoreType();
238 }
239 }
240
241 /*
242 * Return (potentially) platform specific display timeout for the
243 * tray icon
815 int rootX = (int)Native.getLong(native_ptr, 0);
816 int rootY = (int)Native.getLong(native_ptr, 1);
817 int rootWidth = (int)Native.getLong(native_ptr, 2);
818 int rootHeight = (int)Native.getLong(native_ptr, 3);
819
820 return new Rectangle(scaleDown(rootX, scale),
821 scaleDown(rootY, scale),
822 scaleDown(rootWidth, scale),
823 scaleDown(rootHeight, scale));
824 }
825 }
826 finally
827 {
828 XlibWrapper.unsafe.freeMemory(native_ptr);
829 }
830
831 return null;
832 }
833
834 /*
835 * If the current window manager supports _NET protocol then the screen
836 * insets are calculated using _NET_WORKAREA property of the root window.
837 * <p>
838 * Note that _NET_WORKAREA is a rectangular area and it does not work
839 * well in the Xinerama mode.
840 * <p>
841 * We will trust the part of this rectangular area only if it starts at the
842 * requested graphics configuration. Below is an example when the
843 * _NET_WORKAREA intersects with the requested graphics configuration but
844 * produce wrong result.
845 *
846 * //<-x1,y1///////
847 * // // ////////////////
848 * // SCREEN1 // // SCREEN2 //
849 * // ********** // // x2,y2->//
850 * //////////////// // //
851 * ////////////////
852 *
853 * When two screens are overlap and the first contain a dock(*****), then
854 * _NET_WORKAREA may start at point x1,y1 and ends at point x2,y2.
855 */
856 @Override
857 public Insets getScreenInsets(GraphicsConfiguration gc)
858 {
859 XNETProtocol netProto = XWM.getWM().getNETProtocol();
860 if ((netProto == null) || !netProto.active())
861 {
862 return super.getScreenInsets(gc);
863 }
864
865 XToolkit.awtLock();
866 try
867 {
868 X11GraphicsEnvironment x11ge = (X11GraphicsEnvironment)
869 GraphicsEnvironment.getLocalGraphicsEnvironment();
870 X11GraphicsConfig x11gc = (X11GraphicsConfig) gc;
871 long root = XlibUtil.getRootWindow(x11gc.getDevice().getScreen());
872 int scale = x11gc.getScale();
873 if (x11ge.runningXinerama() && checkSTRUT()) {
874 // implementation based on _NET_WM_STRUT/_NET_WM_STRUT_PARTIAL
875 Rectangle rootBounds = XlibUtil.getWindowGeometry(root, scale);
876 Insets insets = getScreenInsetsManually(root, rootBounds,
877 gc.getBounds(), scale);
878 if ((insets.left | insets.top | insets.bottom | insets.right) != 0
879 || rootBounds == null) {
880 return insets;
881 }
882 }
883 Rectangle workArea = XToolkit.getWorkArea(root, scale);
884 Rectangle screen = gc.getBounds();
885 if (workArea != null && screen.contains(workArea.getLocation())) {
886 workArea = workArea.intersection(screen);
887 int top = workArea.y - screen.y;
888 int left = workArea.x - screen.x;
889 int bottom = screen.height - workArea.height - top;
890 int right = screen.width - workArea.width - left;
891 return new Insets(top, left, bottom, right);
892 }
893 // Note that it is better to return zeros than inadequate values
894 return new Insets(0, 0, 0, 0);
895 }
896 finally
897 {
898 XToolkit.awtUnlock();
899 }
900 }
901
902 /**
903 * Returns the value of "sun.awt.X11.checkSTRUT" property. Default value is
904 * {@code false}.
905 */
906 private static boolean checkSTRUT() {
907 if (checkSTRUT == null) {
908 checkSTRUT = AccessController.doPrivileged(
909 new GetBooleanAction("sun.awt.X11.checkSTRUT"));
910 }
911 return checkSTRUT;
912 }
913
914 /*
915 * Manual calculation of screen insets: get all the windows with
916 * _NET_WM_STRUT/_NET_WM_STRUT_PARTIAL hints and add these
917 * hints' values to screen insets.
918 *
919 * This method should be called under XToolkit.awtLock()
920 *
921 * This method is unused because of two reasons:
922 * - Iteration over windows may be extremely slow, and execution of
923 * getScreenInsets() can be x100 slower than in one monitor config.
924 * - _NET_WM_STRUT/_NET_WM_STRUT_PARTIAL are hints for the applications.
925 * WM should take into account these hints when "_NET_WORKAREA" is
926 * calculated, but the system panels are not necessary contain these
927 * hints(Gnome 3 for example).
928 */
929 private Insets getScreenInsetsManually(long root, Rectangle rootBounds,
930 Rectangle screenBounds, int scale)
931 {
932 /*
933 * During the manual calculation of screen insets we iterate
934 * all the X windows hierarchy starting from root window. This
935 * constant is the max level inspected in this hierarchy.
936 * 3 is a heuristic value: I suppose any the toolbar-like
937 * window is a child of either root or desktop window.
938 */
939 final int MAX_NESTED_LEVEL = 3;
940
941 XAtom XA_NET_WM_STRUT = XAtom.get("_NET_WM_STRUT");
942 XAtom XA_NET_WM_STRUT_PARTIAL = XAtom.get("_NET_WM_STRUT_PARTIAL");
943
944 Insets insets = new Insets(0, 0, 0, 0);
945
946 java.util.List<Object> search = new LinkedList<>();
947 search.add(root);
|