1 /*
2 * Copyright (c) 2002, 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
35 import java.util.Locale;
36 import javax.swing.*;
37 import javax.swing.colorchooser.*;
38 import javax.swing.plaf.*;
39 import javax.swing.plaf.synth.*;
40 import javax.swing.text.DefaultEditorKit;
41
42 import com.sun.java.swing.plaf.gtk.GTKConstants.PositionType;
43 import com.sun.java.swing.plaf.gtk.GTKConstants.StateType;
44 import sun.awt.SunToolkit;
45 import sun.awt.UNIXToolkit;
46 import sun.awt.OSInfo;
47 import sun.security.action.GetPropertyAction;
48 import sun.swing.DefaultLayoutStyle;
49 import sun.swing.SwingUtilities2;
50
51 /**
52 * @author Scott Violet
53 */
54 public class GTKLookAndFeel extends SynthLookAndFeel {
55 private static final boolean IS_22;
56
57 /**
58 * Whether or not text is drawn antialiased. This keys off the
59 * desktop property 'gnome.Xft/Antialias' and 'gnome.Xft/RGBA'
60 * We should assume ON - or some variation of ON as no GTK desktop
61 * ships with it OFF.
62 */
63 static Object aaTextInfo;
64
65 /**
66 * Solaris, or Linux with Sun JDS in a CJK Locale.
67 * Used to determine if Sun's high quality CJK fonts are present.
68 */
69 private static boolean isSunCJK;
70
71 /*
72 * Used to override if system (desktop) text anti-aliasing settings should
73 * be used. The reasons for this are are is that currently its "off"
74 * for CJK locales which is not likely to be a good universal answer, and
75 * also its off for remote display. So this provides an unsupported
88 */
89 private boolean inInitialize;
90
91 /**
92 * If true, PropertyChangeListeners have been installed for the
93 * Toolkit.
94 */
95 private boolean pclInstalled;
96
97 /**
98 * StyleFactory needs to be created only the first time.
99 */
100 private GTKStyleFactory styleFactory;
101
102 /**
103 * Cached theme name. Used by GTKGraphicsUtils
104 */
105 private static String gtkThemeName = "Default";
106
107 static {
108 // Backup for specifying the version, this isn't currently documented.
109 // If you pass in anything but 2.2 you got the 2.0 colors/look.
110 String version = AccessController.doPrivileged(
111 new GetPropertyAction("swing.gtk.version"));
112 if (version != null) {
113 IS_22 = version.equals("2.2");
114 }
115 else {
116 IS_22 = true;
117 }
118
119 String language = Locale.getDefault().getLanguage();
120 boolean cjkLocale =
121 (Locale.CHINESE.getLanguage().equals(language) ||
122 Locale.JAPANESE.getLanguage().equals(language) ||
123 Locale.KOREAN.getLanguage().equals(language));
124
125 if (cjkLocale) {
126 boolean isSunDesktop = false;
127 switch (OSInfo.getOSType()) {
128 case SOLARIS:
129 isSunDesktop = true;
130 break;
131
132 case LINUX:
133 Boolean val = AccessController.doPrivileged(
134 new PrivilegedAction<Boolean>() {
135 public Boolean run() {
136 File f = new File("/etc/sun-release");
137 return Boolean.valueOf(f.exists());
139 });
140 isSunDesktop = val.booleanValue();
141 }
142 if (isSunDesktop && !sun.java2d.SunGraphicsEnvironment.isOpenSolaris) {
143 isSunCJK = true;
144 }
145 }
146 }
147
148 /**
149 * Returns true if running on system containing at least 2.2.
150 */
151 static boolean is2_2() {
152 // NOTE: We're currently hard coding to use 2.2.
153 // If we want to support both GTK 2.0 and 2.2, we'll
154 // need to get the major/minor/micro version from the .so.
155 // Refer to bug 4912613 for details.
156 return IS_22;
157 }
158
159 /**
160 * Maps a swing constant to a GTK constant.
161 */
162 static PositionType SwingOrientationConstantToGTK(int side) {
163 switch (side) {
164 case SwingConstants.LEFT:
165 return PositionType.LEFT;
166 case SwingConstants.RIGHT:
167 return PositionType.RIGHT;
168 case SwingConstants.TOP:
169 return PositionType.TOP;
170 case SwingConstants.BOTTOM:
171 return PositionType.BOTTOM;
172 }
173 assert false : "Unknown orientation: " + side;
174 return PositionType.TOP;
175 }
176
177 /**
178 * Maps from Synth state to native GTK state using typesafe enumeration
528 "TAB", DefaultEditorKit.insertTabAction,
529 "ctrl BACK_SLASH", "unselect"/*DefaultEditorKit.unselectAction*/,
530 "ctrl HOME", DefaultEditorKit.beginAction,
531 "ctrl END", DefaultEditorKit.endAction,
532 "ctrl shift HOME", DefaultEditorKit.selectionBeginAction,
533 "ctrl shift END", DefaultEditorKit.selectionEndAction,
534 "ctrl T", "next-link-action",
535 "ctrl shift T", "previous-link-action",
536 "ctrl SPACE", "activate-link-action",
537 "control shift O", "toggle-componentOrientation"/*DefaultEditorKit.toggleComponentOrientation*/
538 });
539
540 class FontLazyValue implements UIDefaults.LazyValue {
541 private Region region;
542 FontLazyValue(Region region) {
543 this.region = region;
544 }
545 public Object createValue(UIDefaults table) {
546 GTKStyleFactory factory = (GTKStyleFactory)getStyleFactory();
547 GTKStyle style = (GTKStyle)factory.getStyle(null, region);
548 return style.getFontForState(null);
549 }
550 }
551
552 Object[] defaults = new Object[] {
553 "ArrowButton.size", Integer.valueOf(13),
554
555
556 "Button.defaultButtonFollowsFocus", Boolean.FALSE,
557 "Button.focusInputMap", new UIDefaults.LazyInputMap(new Object[] {
558 "SPACE", "pressed",
559 "released SPACE", "released",
560 "ENTER", "pressed",
561 "released ENTER", "released"
562 }),
563 "Button.font", new FontLazyValue(Region.BUTTON),
564 "Button.margin", zeroInsets,
565
566
567 "CheckBox.focusInputMap", new UIDefaults.LazyInputMap(new Object[]{
568 "SPACE", "pressed",
1438 return gtkThemeName;
1439 }
1440
1441 static boolean isLeftToRight(Component c) {
1442 return c.getComponentOrientation().isLeftToRight();
1443 }
1444
1445 public void initialize() {
1446 /*
1447 * We need to call loadGTK() to ensure that the native GTK
1448 * libraries are loaded. It is very unlikely that this call will
1449 * fail (since we've already verified native GTK support in
1450 * isSupportedLookAndFeel()), but we can throw an error in the
1451 * failure situation just in case.
1452 */
1453 Toolkit toolkit = Toolkit.getDefaultToolkit();
1454 if (toolkit instanceof UNIXToolkit &&
1455 !((UNIXToolkit)toolkit).loadGTK())
1456 {
1457 throw new InternalError("Unable to load native GTK libraries");
1458 }
1459
1460 super.initialize();
1461 inInitialize = true;
1462 loadStyles();
1463 inInitialize = false;
1464
1465 /*
1466 * Check if system AA font settings should be used.
1467 * Sun's JDS (for Linux and Solaris) ships with high quality CJK
1468 * fonts and specifies via fontconfig that these be rendered in
1469 * B&W to take advantage of the embedded bitmaps.
1470 * If is a Sun CJK locale or remote display, indicate by the condition
1471 * variable that in this case the L&F recommends ignoring desktop
1472 * settings. On other Unixes (eg Linux) this doesn't apply.
1473 * REMIND 1: The isSunCJK test is really just a place holder
1474 * until we can properly query fontconfig and use the properties
1475 * set for specific fonts.
1476 * REMIND 2: See comment on isLocalDisplay() definition regarding
1477 * XRender.
|
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
35 import java.util.Locale;
36 import javax.swing.*;
37 import javax.swing.colorchooser.*;
38 import javax.swing.plaf.*;
39 import javax.swing.plaf.synth.*;
40 import javax.swing.text.DefaultEditorKit;
41
42 import com.sun.java.swing.plaf.gtk.GTKConstants.PositionType;
43 import com.sun.java.swing.plaf.gtk.GTKConstants.StateType;
44 import sun.awt.SunToolkit;
45 import sun.awt.UNIXToolkit;
46 import sun.awt.OSInfo;
47 import sun.security.action.GetPropertyAction;
48 import sun.swing.DefaultLayoutStyle;
49 import sun.swing.SwingUtilities2;
50
51 /**
52 * @author Scott Violet
53 */
54 public class GTKLookAndFeel extends SynthLookAndFeel {
55 private static boolean IS_22;
56 private static boolean IS_3;
57
58 /**
59 * Whether or not text is drawn antialiased. This keys off the
60 * desktop property 'gnome.Xft/Antialias' and 'gnome.Xft/RGBA'
61 * We should assume ON - or some variation of ON as no GTK desktop
62 * ships with it OFF.
63 */
64 static Object aaTextInfo;
65
66 /**
67 * Solaris, or Linux with Sun JDS in a CJK Locale.
68 * Used to determine if Sun's high quality CJK fonts are present.
69 */
70 private static boolean isSunCJK;
71
72 /*
73 * Used to override if system (desktop) text anti-aliasing settings should
74 * be used. The reasons for this are are is that currently its "off"
75 * for CJK locales which is not likely to be a good universal answer, and
76 * also its off for remote display. So this provides an unsupported
89 */
90 private boolean inInitialize;
91
92 /**
93 * If true, PropertyChangeListeners have been installed for the
94 * Toolkit.
95 */
96 private boolean pclInstalled;
97
98 /**
99 * StyleFactory needs to be created only the first time.
100 */
101 private GTKStyleFactory styleFactory;
102
103 /**
104 * Cached theme name. Used by GTKGraphicsUtils
105 */
106 private static String gtkThemeName = "Default";
107
108 static {
109
110 String language = Locale.getDefault().getLanguage();
111 boolean cjkLocale =
112 (Locale.CHINESE.getLanguage().equals(language) ||
113 Locale.JAPANESE.getLanguage().equals(language) ||
114 Locale.KOREAN.getLanguage().equals(language));
115
116 if (cjkLocale) {
117 boolean isSunDesktop = false;
118 switch (OSInfo.getOSType()) {
119 case SOLARIS:
120 isSunDesktop = true;
121 break;
122
123 case LINUX:
124 Boolean val = AccessController.doPrivileged(
125 new PrivilegedAction<Boolean>() {
126 public Boolean run() {
127 File f = new File("/etc/sun-release");
128 return Boolean.valueOf(f.exists());
130 });
131 isSunDesktop = val.booleanValue();
132 }
133 if (isSunDesktop && !sun.java2d.SunGraphicsEnvironment.isOpenSolaris) {
134 isSunCJK = true;
135 }
136 }
137 }
138
139 /**
140 * Returns true if running on system containing at least 2.2.
141 */
142 static boolean is2_2() {
143 // NOTE: We're currently hard coding to use 2.2.
144 // If we want to support both GTK 2.0 and 2.2, we'll
145 // need to get the major/minor/micro version from the .so.
146 // Refer to bug 4912613 for details.
147 return IS_22;
148 }
149
150 static boolean is3() {
151 return IS_3;
152 }
153
154 /**
155 * Maps a swing constant to a GTK constant.
156 */
157 static PositionType SwingOrientationConstantToGTK(int side) {
158 switch (side) {
159 case SwingConstants.LEFT:
160 return PositionType.LEFT;
161 case SwingConstants.RIGHT:
162 return PositionType.RIGHT;
163 case SwingConstants.TOP:
164 return PositionType.TOP;
165 case SwingConstants.BOTTOM:
166 return PositionType.BOTTOM;
167 }
168 assert false : "Unknown orientation: " + side;
169 return PositionType.TOP;
170 }
171
172 /**
173 * Maps from Synth state to native GTK state using typesafe enumeration
523 "TAB", DefaultEditorKit.insertTabAction,
524 "ctrl BACK_SLASH", "unselect"/*DefaultEditorKit.unselectAction*/,
525 "ctrl HOME", DefaultEditorKit.beginAction,
526 "ctrl END", DefaultEditorKit.endAction,
527 "ctrl shift HOME", DefaultEditorKit.selectionBeginAction,
528 "ctrl shift END", DefaultEditorKit.selectionEndAction,
529 "ctrl T", "next-link-action",
530 "ctrl shift T", "previous-link-action",
531 "ctrl SPACE", "activate-link-action",
532 "control shift O", "toggle-componentOrientation"/*DefaultEditorKit.toggleComponentOrientation*/
533 });
534
535 class FontLazyValue implements UIDefaults.LazyValue {
536 private Region region;
537 FontLazyValue(Region region) {
538 this.region = region;
539 }
540 public Object createValue(UIDefaults table) {
541 GTKStyleFactory factory = (GTKStyleFactory)getStyleFactory();
542 GTKStyle style = (GTKStyle)factory.getStyle(null, region);
543 return style.getDefaultFont();
544 }
545 }
546
547 Object[] defaults = new Object[] {
548 "ArrowButton.size", Integer.valueOf(13),
549
550
551 "Button.defaultButtonFollowsFocus", Boolean.FALSE,
552 "Button.focusInputMap", new UIDefaults.LazyInputMap(new Object[] {
553 "SPACE", "pressed",
554 "released SPACE", "released",
555 "ENTER", "pressed",
556 "released ENTER", "released"
557 }),
558 "Button.font", new FontLazyValue(Region.BUTTON),
559 "Button.margin", zeroInsets,
560
561
562 "CheckBox.focusInputMap", new UIDefaults.LazyInputMap(new Object[]{
563 "SPACE", "pressed",
1433 return gtkThemeName;
1434 }
1435
1436 static boolean isLeftToRight(Component c) {
1437 return c.getComponentOrientation().isLeftToRight();
1438 }
1439
1440 public void initialize() {
1441 /*
1442 * We need to call loadGTK() to ensure that the native GTK
1443 * libraries are loaded. It is very unlikely that this call will
1444 * fail (since we've already verified native GTK support in
1445 * isSupportedLookAndFeel()), but we can throw an error in the
1446 * failure situation just in case.
1447 */
1448 Toolkit toolkit = Toolkit.getDefaultToolkit();
1449 if (toolkit instanceof UNIXToolkit &&
1450 !((UNIXToolkit)toolkit).loadGTK())
1451 {
1452 throw new InternalError("Unable to load native GTK libraries");
1453 }
1454
1455 if (UNIXToolkit.getGtkVersion() == UNIXToolkit.GtkVersions.GTK2) {
1456 String version = AccessController.doPrivileged(
1457 new GetPropertyAction("jdk.gtk.version"));
1458 if (version != null) {
1459 IS_22 = version.equals("2.2");
1460 } else {
1461 IS_22 = true;
1462 }
1463 } else if (UNIXToolkit.getGtkVersion() ==
1464 UNIXToolkit.GtkVersions.GTK3) {
1465 IS_3 = true;
1466 }
1467
1468 super.initialize();
1469 inInitialize = true;
1470 loadStyles();
1471 inInitialize = false;
1472
1473 /*
1474 * Check if system AA font settings should be used.
1475 * Sun's JDS (for Linux and Solaris) ships with high quality CJK
1476 * fonts and specifies via fontconfig that these be rendered in
1477 * B&W to take advantage of the embedded bitmaps.
1478 * If is a Sun CJK locale or remote display, indicate by the condition
1479 * variable that in this case the L&F recommends ignoring desktop
1480 * settings. On other Unixes (eg Linux) this doesn't apply.
1481 * REMIND 1: The isSunCJK test is really just a place holder
1482 * until we can properly query fontconfig and use the properties
1483 * set for specific fonts.
1484 * REMIND 2: See comment on isLocalDisplay() definition regarding
1485 * XRender.
|