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
  23  * questions.
  24  */
  25 
  26 package com.sun.java.swing.plaf.gtk;
  27 
  28 import java.awt.*;
  29 import java.beans.*;
  30 import java.io.File;
  31 import java.lang.ref.*;
  32 import java.security.AccessController;
  33 import java.security.PrivilegedAction;
  34 import java.util.Locale;
  35 import javax.swing.*;
  36 import javax.swing.colorchooser.*;
  37 import javax.swing.plaf.*;
  38 import javax.swing.plaf.synth.*;
  39 import javax.swing.text.DefaultEditorKit;
  40 
  41 import com.sun.java.swing.plaf.gtk.GTKConstants.PositionType;
  42 import com.sun.java.swing.plaf.gtk.GTKConstants.StateType;
  43 import java.util.HashMap;
  44 import java.util.Map;
  45 import sun.awt.SunToolkit;
  46 import sun.awt.UNIXToolkit;
  47 import sun.awt.OSInfo;
  48 import sun.security.action.GetPropertyAction;
  49 import sun.swing.DefaultLayoutStyle;
  50 import sun.swing.SwingAccessor;
  51 import sun.swing.SwingUtilities2;
  52 
  53 /**
  54  * @author Scott Violet
  55  */
  56 @SuppressWarnings("serial") // Superclass not serializable
  57 public class GTKLookAndFeel extends SynthLookAndFeel {
  58     private static boolean IS_22;
  59     private static boolean IS_3;
  60 
  61     /**
  62      * Whether or not text is drawn antialiased.  This keys off the
  63      * desktop property 'gnome.Xft/Antialias' and 'gnome.Xft/RGBA'
  64      * We should assume ON - or some variation of ON as no GTK desktop
  65      * ships with it OFF.
  66      */
  67     static Map<Object, Object> aaTextInfo;
  68 
  69     /*
  70      * Used to override if system (desktop) text anti-aliasing settings should
  71      * be used. The reasons for this are are is that currently its "off"
  72      * for CJK locales which is not likely to be a good universal answer, and
  73      * also its off for remote display. So this provides an unsupported
  74      * way to explicitly request that it be "on".
  75      */
  76     private static boolean gtkAAFontSettingsCond;
  77 
  78     /**
  79      * Font to use in places where there is no widget.
  80      */
  81     private Font fallbackFont;
  82 
  83     /**
  84      * If true, GTKLookAndFeel is inside the <code>initialize</code>
  85      * method.
  86      */
  87     private boolean inInitialize;
  88 
  89     /**
  90      * If true, PropertyChangeListeners have been installed for the
  91      * Toolkit.
  92      */
  93     private boolean pclInstalled;
  94 
  95     /**
  96      * StyleFactory needs to be created only the first time.
  97      */
  98     private GTKStyleFactory styleFactory;
  99 
 100     /**
 101      * Cached theme name. Used by GTKGraphicsUtils
 102      */
 103     private static String gtkThemeName = "Default";
 104 
 105     /**
 106      * Returns true if running on system containing at least 2.2.
 107      */
 108     static boolean is2_2() {
 109         // NOTE: We're currently hard coding to use 2.2.
 110         // If we want to support both GTK 2.0 and 2.2, we'll
 111         // need to get the major/minor/micro version from the .so.
 112         // Refer to bug 4912613 for details.
 113         return IS_22;
 114     }
 115 
 116     static boolean is3() {
 117         return IS_3;
 118     }
 119 
 120     /**
 121      * Maps a swing constant to a GTK constant.
 122      */
 123     static PositionType SwingOrientationConstantToGTK(int side) {
 124         switch (side) {
 125         case SwingConstants.LEFT:
 126             return PositionType.LEFT;
 127         case SwingConstants.RIGHT:
 128             return PositionType.RIGHT;
 129         case SwingConstants.TOP:
 130             return PositionType.TOP;
 131         case SwingConstants.BOTTOM:
 132             return PositionType.BOTTOM;
 133         }
 134         assert false : "Unknown orientation: " + side;
 135         return PositionType.TOP;
 136     }
 137 
 138     /**
 139      * Maps from Synth state to native GTK state using typesafe enumeration
 140      * StateType.  This is only used by GTKEngine.
 141      */
 142     static StateType synthStateToGTKStateType(int state) {
 143         StateType result;
 144         switch (state) {
 145             case SynthConstants.PRESSED:
 146                 result = StateType.ACTIVE;
 147                 break;
 148             case SynthConstants.MOUSE_OVER:
 149                 result = StateType.PRELIGHT;
 150                 break;
 151             case SynthConstants.SELECTED:
 152                 result = StateType.SELECTED;
 153                 break;
 154             case SynthConstants.DISABLED:
 155                 result = StateType.INSENSITIVE;
 156                 break;
 157             case SynthConstants.ENABLED:
 158             default:
 159                 result = StateType.NORMAL;
 160                 break;
 161         }
 162         return result;
 163     }
 164 
 165     /**
 166      * Maps from a Synth state to the corresponding GTK state.
 167      * The GTK states are named differently than Synth's states, the
 168      * following gives the mapping:
 169      * <table><tr><td>Synth<td>GTK
 170      * <tr><td>SynthConstants.PRESSED<td>ACTIVE
 171      * <tr><td>SynthConstants.SELECTED<td>SELECTED
 172      * <tr><td>SynthConstants.MOUSE_OVER<td>PRELIGHT
 173      * <tr><td>SynthConstants.DISABLED<td>INSENSITIVE
 174      * <tr><td>SynthConstants.ENABLED<td>NORMAL
 175      * </table>
 176      * Additionally some widgets are special cased.
 177      */
 178     static int synthStateToGTKState(Region region, int state) {
 179         if ((state & SynthConstants.PRESSED) != 0) {
 180             if (region == Region.RADIO_BUTTON
 181                     || region == Region.CHECK_BOX
 182                     || region == Region.MENU
 183                     || region == Region.MENU_ITEM
 184                     || region == Region.RADIO_BUTTON_MENU_ITEM
 185                     || region == Region.CHECK_BOX_MENU_ITEM
 186                     || region == Region.SPLIT_PANE) {
 187                 state = SynthConstants.MOUSE_OVER;
 188             } else {
 189                 state = SynthConstants.PRESSED;
 190             }
 191 
 192         } else if (region == Region.TABBED_PANE_TAB) {
 193             if ((state & SynthConstants.DISABLED) != 0) {
 194                 state = SynthConstants.DISABLED;
 195             }
 196             else if ((state & SynthConstants.SELECTED) != 0) {
 197                 state = SynthConstants.ENABLED;
 198             } else {
 199                 state = SynthConstants.PRESSED;
 200             }
 201 
 202         } else if ((state & SynthConstants.SELECTED) != 0) {
 203             if (region == Region.MENU) {
 204                 state = SynthConstants.MOUSE_OVER;
 205             } else if (region == Region.RADIO_BUTTON ||
 206                           region == Region.TOGGLE_BUTTON ||
 207                           region == Region.RADIO_BUTTON_MENU_ITEM ||
 208                           region == Region.CHECK_BOX_MENU_ITEM ||
 209                           region == Region.CHECK_BOX ||
 210                           region == Region.BUTTON) {
 211                 if ((state & SynthConstants.DISABLED) != 0) {
 212                     state = SynthConstants.DISABLED;
 213                 }
 214                 // If the button is SELECTED and is PRELIGHT we need to
 215                 // make the state MOUSE_OVER otherwise we don't paint the
 216                 // PRELIGHT.
 217                 else if ((state & SynthConstants.MOUSE_OVER) != 0) {
 218                     state = SynthConstants.MOUSE_OVER;
 219                 } else {
 220                     state = SynthConstants.PRESSED;
 221                 }
 222             } else {
 223                 state = SynthConstants.SELECTED;
 224             }
 225         }
 226 
 227         else if ((state & SynthConstants.MOUSE_OVER) != 0) {
 228             state = SynthConstants.MOUSE_OVER;
 229         }
 230         else if ((state & SynthConstants.DISABLED) != 0) {
 231             state = SynthConstants.DISABLED;
 232         }
 233         else {
 234             if (region == Region.SLIDER_TRACK) {
 235                 state = SynthConstants.PRESSED;
 236             } else {
 237                 state = SynthConstants.ENABLED;
 238             }
 239         }
 240         return state;
 241     }
 242 
 243     static boolean isText(Region region) {
 244         // These Regions treat FOREGROUND as TEXT.
 245         return (region == Region.TEXT_FIELD ||
 246                 region == Region.FORMATTED_TEXT_FIELD ||
 247                 region == Region.LIST ||
 248                 region == Region.PASSWORD_FIELD ||
 249                 region == Region.SPINNER ||
 250                 region == Region.TABLE ||
 251                 region == Region.TEXT_AREA ||
 252                 region == Region.TEXT_FIELD ||
 253                 region == Region.TEXT_PANE ||
 254                 region == Region.TREE);
 255     }
 256 
 257     public UIDefaults getDefaults() {
 258         // We need to call super for basic's properties file.
 259         UIDefaults table = super.getDefaults();
 260 
 261         // SynthTabbedPaneUI supports rollover on tabs, GTK does not
 262         table.put("TabbedPane.isTabRollover", Boolean.FALSE);
 263 
 264         // Prevents Synth from setting text AA by itself
 265         table.put("Synth.doNotSetTextAA", true);
 266 
 267         initResourceBundle(table);
 268         // For compatibility with apps expecting certain defaults we'll
 269         // populate the table with the values from basic.
 270         initSystemColorDefaults(table);
 271         initComponentDefaults(table);
 272         installPropertyChangeListeners();
 273         return table;
 274     }
 275 
 276     private void installPropertyChangeListeners() {
 277         if(!pclInstalled) {
 278             Toolkit kit = Toolkit.getDefaultToolkit();
 279             WeakPCL pcl = new WeakPCL(this, kit, "gnome.Net/ThemeName");
 280             kit.addPropertyChangeListener(pcl.getKey(), pcl);
 281             pcl = new WeakPCL(this, kit, "gnome.Gtk/FontName");
 282             kit.addPropertyChangeListener(pcl.getKey(), pcl);
 283             pcl = new WeakPCL(this, kit, "gnome.Xft/DPI");
 284             kit.addPropertyChangeListener(pcl.getKey(), pcl);
 285 
 286             flushUnreferenced();
 287             pclInstalled = true;
 288         }
 289     }
 290 
 291     private void initResourceBundle(UIDefaults table) {
 292         SwingAccessor.getUIDefaultsAccessor()
 293                      .addInternalBundle(table,
 294                              "com.sun.java.swing.plaf.gtk.resources.gtk");
 295     }
 296 
 297     protected void initComponentDefaults(UIDefaults table) {
 298         // For compatibility with apps expecting certain defaults we'll
 299         // populate the table with the values from basic.
 300         super.initComponentDefaults(table);
 301 
 302         UIDefaults.LazyValue zeroBorder =
 303             t -> new BorderUIResource.EmptyBorderUIResource(0, 0, 0, 0);
 304 
 305         Object focusBorder = new GTKStyle.GTKLazyValue(
 306             "com.sun.java.swing.plaf.gtk.GTKPainter$ListTableFocusBorder",
 307             "getUnselectedCellBorder");
 308         Object focusSelectedBorder = new GTKStyle.GTKLazyValue(
 309             "com.sun.java.swing.plaf.gtk.GTKPainter$ListTableFocusBorder",
 310             "getSelectedCellBorder");
 311         Object noFocusBorder = new GTKStyle.GTKLazyValue(
 312             "com.sun.java.swing.plaf.gtk.GTKPainter$ListTableFocusBorder",
 313             "getNoFocusCellBorder");
 314 
 315         GTKStyleFactory factory = (GTKStyleFactory)getStyleFactory();
 316         GTKStyle tableStyle = (GTKStyle)factory.getStyle(null, Region.TREE);
 317         Color tableBg = tableStyle.getGTKColor(SynthConstants.ENABLED,
 318                 GTKColorType.TEXT_BACKGROUND);
 319         Color tableFocusCellBg = tableStyle.getGTKColor(SynthConstants.ENABLED,
 320                 GTKColorType.BACKGROUND);
 321         Color tableFocusCellFg = tableStyle.getGTKColor(SynthConstants.ENABLED,
 322                 GTKColorType.FOREGROUND);
 323 
 324         // The following progress bar size calculations come from
 325         // gtkprogressbar.c (version 2.8.20), see MIN_* constants and
 326         // the gtk_progress_bar_size_request() method.
 327         GTKStyle progStyle = (GTKStyle)
 328             factory.getStyle(null, Region.PROGRESS_BAR);
 329         int progXThickness = progStyle.getXThickness();
 330         int progYThickness = progStyle.getYThickness();
 331         int hProgWidth  = 150 - (progXThickness * 2);
 332         int hProgHeight =  20 - (progYThickness * 2);
 333         int vProgWidth  =  22 - (progXThickness * 2);
 334         int vProgHeight =  80 - (progYThickness * 2);
 335 
 336         Integer caretBlinkRate;
 337         if (Boolean.FALSE.equals(GTKEngine.INSTANCE.getSetting(
 338                 GTKEngine.Settings.GTK_CURSOR_BLINK))) {
 339             caretBlinkRate = Integer.valueOf(0);
 340         } else {
 341             caretBlinkRate = (Integer) GTKEngine.INSTANCE.getSetting(
 342                     GTKEngine.Settings.GTK_CURSOR_BLINK_TIME);
 343             if (caretBlinkRate == null) {
 344                 caretBlinkRate = Integer.valueOf(500);
 345             }
 346         }
 347         Insets zeroInsets = new InsetsUIResource(0, 0, 0, 0);
 348 
 349         Double defaultCaretAspectRatio = Double.valueOf(0.025);
 350         Color caretColor = table.getColor("caretColor");
 351         Color controlText = table.getColor("controlText");
 352 
 353         Object fieldInputMap = new UIDefaults.LazyInputMap(new Object[] {
 354                        "ctrl C", DefaultEditorKit.copyAction,
 355                        "ctrl V", DefaultEditorKit.pasteAction,
 356                        "ctrl X", DefaultEditorKit.cutAction,
 357                          "COPY", DefaultEditorKit.copyAction,
 358                         "PASTE", DefaultEditorKit.pasteAction,
 359                           "CUT", DefaultEditorKit.cutAction,
 360                "control INSERT", DefaultEditorKit.copyAction,
 361                  "shift INSERT", DefaultEditorKit.pasteAction,
 362                  "shift DELETE", DefaultEditorKit.cutAction,
 363                    "shift LEFT", DefaultEditorKit.selectionBackwardAction,
 364                 "shift KP_LEFT", DefaultEditorKit.selectionBackwardAction,
 365                   "shift RIGHT", DefaultEditorKit.selectionForwardAction,
 366                "shift KP_RIGHT", DefaultEditorKit.selectionForwardAction,
 367                     "ctrl LEFT", DefaultEditorKit.previousWordAction,
 368                  "ctrl KP_LEFT", DefaultEditorKit.previousWordAction,
 369                    "ctrl RIGHT", DefaultEditorKit.nextWordAction,
 370                 "ctrl KP_RIGHT", DefaultEditorKit.nextWordAction,
 371               "ctrl shift LEFT", DefaultEditorKit.selectionPreviousWordAction,
 372            "ctrl shift KP_LEFT", DefaultEditorKit.selectionPreviousWordAction,
 373              "ctrl shift RIGHT", DefaultEditorKit.selectionNextWordAction,
 374           "ctrl shift KP_RIGHT", DefaultEditorKit.selectionNextWordAction,
 375                        "ctrl A", DefaultEditorKit.selectAllAction,
 376                          "HOME", DefaultEditorKit.beginLineAction,
 377                           "END", DefaultEditorKit.endLineAction,
 378                    "shift HOME", DefaultEditorKit.selectionBeginLineAction,
 379                     "shift END", DefaultEditorKit.selectionEndLineAction,
 380                    "BACK_SPACE", DefaultEditorKit.deletePrevCharAction,
 381              "shift BACK_SPACE", DefaultEditorKit.deletePrevCharAction,
 382                        "ctrl H", DefaultEditorKit.deletePrevCharAction,
 383                        "DELETE", DefaultEditorKit.deleteNextCharAction,
 384                   "ctrl DELETE", DefaultEditorKit.deleteNextWordAction,
 385               "ctrl BACK_SPACE", DefaultEditorKit.deletePrevWordAction,
 386                         "RIGHT", DefaultEditorKit.forwardAction,
 387                          "LEFT", DefaultEditorKit.backwardAction,
 388                      "KP_RIGHT", DefaultEditorKit.forwardAction,
 389                       "KP_LEFT", DefaultEditorKit.backwardAction,
 390                         "ENTER", JTextField.notifyAction,
 391               "ctrl BACK_SLASH", "unselect"/*DefaultEditorKit.unselectAction*/,
 392                "control shift O", "toggle-componentOrientation"/*DefaultEditorKit.toggleComponentOrientation*/
 393             });
 394 
 395         Object passwordInputMap = new UIDefaults.LazyInputMap(new Object[] {
 396                        "ctrl C", DefaultEditorKit.copyAction,
 397                        "ctrl V", DefaultEditorKit.pasteAction,
 398                        "ctrl X", DefaultEditorKit.cutAction,
 399                          "COPY", DefaultEditorKit.copyAction,
 400                         "PASTE", DefaultEditorKit.pasteAction,
 401                           "CUT", DefaultEditorKit.cutAction,
 402                "control INSERT", DefaultEditorKit.copyAction,
 403                  "shift INSERT", DefaultEditorKit.pasteAction,
 404                  "shift DELETE", DefaultEditorKit.cutAction,
 405                    "shift LEFT", DefaultEditorKit.selectionBackwardAction,
 406                 "shift KP_LEFT", DefaultEditorKit.selectionBackwardAction,
 407                   "shift RIGHT", DefaultEditorKit.selectionForwardAction,
 408                "shift KP_RIGHT", DefaultEditorKit.selectionForwardAction,
 409                     "ctrl LEFT", DefaultEditorKit.beginLineAction,
 410                  "ctrl KP_LEFT", DefaultEditorKit.beginLineAction,
 411                    "ctrl RIGHT", DefaultEditorKit.endLineAction,
 412                 "ctrl KP_RIGHT", DefaultEditorKit.endLineAction,
 413               "ctrl shift LEFT", DefaultEditorKit.selectionBeginLineAction,
 414            "ctrl shift KP_LEFT", DefaultEditorKit.selectionBeginLineAction,
 415              "ctrl shift RIGHT", DefaultEditorKit.selectionEndLineAction,
 416           "ctrl shift KP_RIGHT", DefaultEditorKit.selectionEndLineAction,
 417                        "ctrl A", DefaultEditorKit.selectAllAction,
 418                          "HOME", DefaultEditorKit.beginLineAction,
 419                           "END", DefaultEditorKit.endLineAction,
 420                    "shift HOME", DefaultEditorKit.selectionBeginLineAction,
 421                     "shift END", DefaultEditorKit.selectionEndLineAction,
 422                    "BACK_SPACE", DefaultEditorKit.deletePrevCharAction,
 423              "shift BACK_SPACE", DefaultEditorKit.deletePrevCharAction,
 424                        "ctrl H", DefaultEditorKit.deletePrevCharAction,
 425                        "DELETE", DefaultEditorKit.deleteNextCharAction,
 426                         "RIGHT", DefaultEditorKit.forwardAction,
 427                          "LEFT", DefaultEditorKit.backwardAction,
 428                      "KP_RIGHT", DefaultEditorKit.forwardAction,
 429                       "KP_LEFT", DefaultEditorKit.backwardAction,
 430                         "ENTER", JTextField.notifyAction,
 431               "ctrl BACK_SLASH", "unselect"/*DefaultEditorKit.unselectAction*/,
 432                "control shift O", "toggle-componentOrientation"/*DefaultEditorKit.toggleComponentOrientation*/
 433             });
 434 
 435         Object editorMargin = new InsetsUIResource(3,3,3,3);
 436 
 437         Object multilineInputMap = new UIDefaults.LazyInputMap(new Object[] {
 438                            "ctrl C", DefaultEditorKit.copyAction,
 439                            "ctrl V", DefaultEditorKit.pasteAction,
 440                            "ctrl X", DefaultEditorKit.cutAction,
 441                              "COPY", DefaultEditorKit.copyAction,
 442                             "PASTE", DefaultEditorKit.pasteAction,
 443                               "CUT", DefaultEditorKit.cutAction,
 444                    "control INSERT", DefaultEditorKit.copyAction,
 445                      "shift INSERT", DefaultEditorKit.pasteAction,
 446                      "shift DELETE", DefaultEditorKit.cutAction,
 447                        "shift LEFT", DefaultEditorKit.selectionBackwardAction,
 448                     "shift KP_LEFT", DefaultEditorKit.selectionBackwardAction,
 449                       "shift RIGHT", DefaultEditorKit.selectionForwardAction,
 450                    "shift KP_RIGHT", DefaultEditorKit.selectionForwardAction,
 451                         "ctrl LEFT", DefaultEditorKit.previousWordAction,
 452                      "ctrl KP_LEFT", DefaultEditorKit.previousWordAction,
 453                        "ctrl RIGHT", DefaultEditorKit.nextWordAction,
 454                     "ctrl KP_RIGHT", DefaultEditorKit.nextWordAction,
 455                   "ctrl shift LEFT", DefaultEditorKit.selectionPreviousWordAction,
 456                "ctrl shift KP_LEFT", DefaultEditorKit.selectionPreviousWordAction,
 457                  "ctrl shift RIGHT", DefaultEditorKit.selectionNextWordAction,
 458               "ctrl shift KP_RIGHT", DefaultEditorKit.selectionNextWordAction,
 459                            "ctrl A", DefaultEditorKit.selectAllAction,
 460                              "HOME", DefaultEditorKit.beginLineAction,
 461                               "END", DefaultEditorKit.endLineAction,
 462                        "shift HOME", DefaultEditorKit.selectionBeginLineAction,
 463                         "shift END", DefaultEditorKit.selectionEndLineAction,
 464 
 465                                "UP", DefaultEditorKit.upAction,
 466                             "KP_UP", DefaultEditorKit.upAction,
 467                              "DOWN", DefaultEditorKit.downAction,
 468                           "KP_DOWN", DefaultEditorKit.downAction,
 469                           "PAGE_UP", DefaultEditorKit.pageUpAction,
 470                         "PAGE_DOWN", DefaultEditorKit.pageDownAction,
 471                     "shift PAGE_UP", "selection-page-up",
 472                   "shift PAGE_DOWN", "selection-page-down",
 473                "ctrl shift PAGE_UP", "selection-page-left",
 474              "ctrl shift PAGE_DOWN", "selection-page-right",
 475                          "shift UP", DefaultEditorKit.selectionUpAction,
 476                       "shift KP_UP", DefaultEditorKit.selectionUpAction,
 477                        "shift DOWN", DefaultEditorKit.selectionDownAction,
 478                     "shift KP_DOWN", DefaultEditorKit.selectionDownAction,
 479                             "ENTER", DefaultEditorKit.insertBreakAction,
 480                        "BACK_SPACE", DefaultEditorKit.deletePrevCharAction,
 481                  "shift BACK_SPACE", DefaultEditorKit.deletePrevCharAction,
 482                            "ctrl H", DefaultEditorKit.deletePrevCharAction,
 483                            "DELETE", DefaultEditorKit.deleteNextCharAction,
 484                       "ctrl DELETE", DefaultEditorKit.deleteNextWordAction,
 485                   "ctrl BACK_SPACE", DefaultEditorKit.deletePrevWordAction,
 486                             "RIGHT", DefaultEditorKit.forwardAction,
 487                              "LEFT", DefaultEditorKit.backwardAction,
 488                          "KP_RIGHT", DefaultEditorKit.forwardAction,
 489                           "KP_LEFT", DefaultEditorKit.backwardAction,
 490                               "TAB", DefaultEditorKit.insertTabAction,
 491                   "ctrl BACK_SLASH", "unselect"/*DefaultEditorKit.unselectAction*/,
 492                         "ctrl HOME", DefaultEditorKit.beginAction,
 493                          "ctrl END", DefaultEditorKit.endAction,
 494                   "ctrl shift HOME", DefaultEditorKit.selectionBeginAction,
 495                    "ctrl shift END", DefaultEditorKit.selectionEndAction,
 496                            "ctrl T", "next-link-action",
 497                      "ctrl shift T", "previous-link-action",
 498                        "ctrl SPACE", "activate-link-action",
 499                    "control shift O", "toggle-componentOrientation"/*DefaultEditorKit.toggleComponentOrientation*/
 500             });
 501 
 502         class FontLazyValue implements UIDefaults.LazyValue {
 503             private Region region;
 504             FontLazyValue(Region region) {
 505                 this.region = region;
 506             }
 507             public Object createValue(UIDefaults table) {
 508                 GTKStyleFactory factory = (GTKStyleFactory)getStyleFactory();
 509                 GTKStyle style = (GTKStyle)factory.getStyle(null, region);
 510                 return style.getDefaultFont();
 511             }
 512         }
 513 
 514         Object[] defaults = new Object[] {
 515             "ArrowButton.size", Integer.valueOf(13),
 516 
 517 
 518             "Button.defaultButtonFollowsFocus", Boolean.FALSE,
 519             "Button.focusInputMap", new UIDefaults.LazyInputMap(new Object[] {
 520                          "SPACE", "pressed",
 521                 "released SPACE", "released",
 522                          "ENTER", "pressed",
 523                 "released ENTER", "released"
 524               }),
 525             "Button.font", new FontLazyValue(Region.BUTTON),
 526             "Button.margin", zeroInsets,
 527 
 528 
 529             "CheckBox.focusInputMap", new UIDefaults.LazyInputMap(new Object[]{
 530                          "SPACE", "pressed",
 531                 "released SPACE", "released"
 532               }),
 533             "CheckBox.icon", new GTKStyle.GTKLazyValue(
 534                               "com.sun.java.swing.plaf.gtk.GTKIconFactory",
 535                               "getCheckBoxIcon"),
 536             "CheckBox.font", new FontLazyValue(Region.CHECK_BOX),
 537             "CheckBox.margin", zeroInsets,
 538 
 539 
 540             "CheckBoxMenuItem.arrowIcon", null,
 541             "CheckBoxMenuItem.checkIcon", new GTKStyle.GTKLazyValue(
 542                               "com.sun.java.swing.plaf.gtk.GTKIconFactory",
 543                               "getCheckBoxMenuItemCheckIcon"),
 544             "CheckBoxMenuItem.font",
 545                 new FontLazyValue(Region.CHECK_BOX_MENU_ITEM),
 546             "CheckBoxMenuItem.margin", zeroInsets,
 547             "CheckBoxMenuItem.alignAcceleratorText", Boolean.FALSE,
 548 
 549 
 550             "ColorChooser.showPreviewPanelText", Boolean.FALSE,
 551             "ColorChooser.panels", new UIDefaults.ActiveValue() {
 552                 public Object createValue(UIDefaults table) {
 553                     return new AbstractColorChooserPanel[] {
 554                                        new GTKColorChooserPanel() };
 555                 }
 556             },
 557             "ColorChooser.font", new FontLazyValue(Region.COLOR_CHOOSER),
 558 
 559 
 560             "ComboBox.ancestorInputMap",
 561                new UIDefaults.LazyInputMap(new Object[] {
 562                      "ESCAPE", "hidePopup",
 563                     "PAGE_UP", "pageUpPassThrough",
 564                   "PAGE_DOWN", "pageDownPassThrough",
 565                        "HOME", "homePassThrough",
 566                         "END", "endPassThrough",
 567                        "DOWN", "selectNext",
 568                     "KP_DOWN", "selectNext",
 569                    "alt DOWN", "togglePopup",
 570                 "alt KP_DOWN", "togglePopup",
 571                      "alt UP", "togglePopup",
 572                   "alt KP_UP", "togglePopup",
 573                       "SPACE", "spacePopup",
 574                       "ENTER", "enterPressed",
 575                          "UP", "selectPrevious",
 576                       "KP_UP", "selectPrevious"
 577 
 578                  }),
 579             "ComboBox.font", new FontLazyValue(Region.COMBO_BOX),
 580             "ComboBox.isEnterSelectablePopup", Boolean.TRUE,
 581 
 582 
 583             "EditorPane.caretForeground", caretColor,
 584             "EditorPane.caretAspectRatio", defaultCaretAspectRatio,
 585             "EditorPane.caretBlinkRate", caretBlinkRate,
 586             "EditorPane.margin", editorMargin,
 587             "EditorPane.focusInputMap", multilineInputMap,
 588             "EditorPane.font", new FontLazyValue(Region.EDITOR_PANE),
 589 
 590 
 591             "FileChooser.ancestorInputMap",
 592                new UIDefaults.LazyInputMap(new Object[] {
 593                      "ESCAPE", "cancelSelection",
 594                  "ctrl ENTER", "approveSelection"
 595                  }),
 596             "FileChooserUI", "com.sun.java.swing.plaf.gtk.GTKLookAndFeel",
 597 
 598 
 599             "FormattedTextField.caretForeground", caretColor,
 600             "FormattedTextField.caretAspectRatio", defaultCaretAspectRatio,
 601             "FormattedTextField.caretBlinkRate", caretBlinkRate,
 602             "FormattedTextField.focusInputMap",
 603               new UIDefaults.LazyInputMap(new Object[] {
 604                            "ctrl C", DefaultEditorKit.copyAction,
 605                            "ctrl V", DefaultEditorKit.pasteAction,
 606                            "ctrl X", DefaultEditorKit.cutAction,
 607                              "COPY", DefaultEditorKit.copyAction,
 608                             "PASTE", DefaultEditorKit.pasteAction,
 609                               "CUT", DefaultEditorKit.cutAction,
 610                    "control INSERT", DefaultEditorKit.copyAction,
 611                      "shift INSERT", DefaultEditorKit.pasteAction,
 612                      "shift DELETE", DefaultEditorKit.cutAction,
 613                        "shift LEFT", DefaultEditorKit.selectionBackwardAction,
 614                     "shift KP_LEFT", DefaultEditorKit.selectionBackwardAction,
 615                       "shift RIGHT", DefaultEditorKit.selectionForwardAction,
 616                    "shift KP_RIGHT", DefaultEditorKit.selectionForwardAction,
 617                         "ctrl LEFT", DefaultEditorKit.previousWordAction,
 618                      "ctrl KP_LEFT", DefaultEditorKit.previousWordAction,
 619                        "ctrl RIGHT", DefaultEditorKit.nextWordAction,
 620                     "ctrl KP_RIGHT", DefaultEditorKit.nextWordAction,
 621                   "ctrl shift LEFT", DefaultEditorKit.selectionPreviousWordAction,
 622                "ctrl shift KP_LEFT", DefaultEditorKit.selectionPreviousWordAction,
 623                  "ctrl shift RIGHT", DefaultEditorKit.selectionNextWordAction,
 624               "ctrl shift KP_RIGHT", DefaultEditorKit.selectionNextWordAction,
 625                            "ctrl A", DefaultEditorKit.selectAllAction,
 626                              "HOME", DefaultEditorKit.beginLineAction,
 627                               "END", DefaultEditorKit.endLineAction,
 628                        "shift HOME", DefaultEditorKit.selectionBeginLineAction,
 629                         "shift END", DefaultEditorKit.selectionEndLineAction,
 630                        "BACK_SPACE", DefaultEditorKit.deletePrevCharAction,
 631                  "shift BACK_SPACE", DefaultEditorKit.deletePrevCharAction,
 632                            "ctrl H", DefaultEditorKit.deletePrevCharAction,
 633                            "DELETE", DefaultEditorKit.deleteNextCharAction,
 634                       "ctrl DELETE", DefaultEditorKit.deleteNextWordAction,
 635                   "ctrl BACK_SPACE", DefaultEditorKit.deletePrevWordAction,
 636                             "RIGHT", DefaultEditorKit.forwardAction,
 637                              "LEFT", DefaultEditorKit.backwardAction,
 638                          "KP_RIGHT", DefaultEditorKit.forwardAction,
 639                           "KP_LEFT", DefaultEditorKit.backwardAction,
 640                             "ENTER", JTextField.notifyAction,
 641                   "ctrl BACK_SLASH", "unselect",
 642                   "control shift O", "toggle-componentOrientation",
 643                            "ESCAPE", "reset-field-edit",
 644                                "UP", "increment",
 645                             "KP_UP", "increment",
 646                              "DOWN", "decrement",
 647                           "KP_DOWN", "decrement",
 648               }),
 649             "FormattedTextField.font",
 650                 new FontLazyValue(Region.FORMATTED_TEXT_FIELD),
 651 
 652 
 653             "InternalFrameTitlePane.titlePaneLayout",
 654                                 new GTKStyle.GTKLazyValue("com.sun.java.swing.plaf.gtk.Metacity",
 655                                                  "getTitlePaneLayout"),
 656             "InternalFrame.windowBindings", new Object[] {
 657                   "shift ESCAPE", "showSystemMenu",
 658                     "ctrl SPACE", "showSystemMenu",
 659                         "ESCAPE", "hideSystemMenu" },
 660             "InternalFrame.layoutTitlePaneAtOrigin", Boolean.TRUE,
 661             "InternalFrame.useTaskBar", Boolean.TRUE,
 662 
 663             "InternalFrameTitlePane.iconifyButtonOpacity", null,
 664             "InternalFrameTitlePane.maximizeButtonOpacity", null,
 665             "InternalFrameTitlePane.closeButtonOpacity", null,
 666 
 667             "Label.font", new FontLazyValue(Region.LABEL),
 668 
 669             "List.background", tableBg,
 670             "List.focusCellHighlightBorder", focusBorder,
 671             "List.focusSelectedCellHighlightBorder", focusSelectedBorder,
 672             "List.noFocusBorder", noFocusBorder,
 673             "List.focusInputMap",
 674                new UIDefaults.LazyInputMap(new Object[] {
 675                            "ctrl C", "copy",
 676                            "ctrl V", "paste",
 677                            "ctrl X", "cut",
 678                              "COPY", "copy",
 679                             "PASTE", "paste",
 680                               "CUT", "cut",
 681                    "control INSERT", "copy",
 682                      "shift INSERT", "paste",
 683                      "shift DELETE", "cut",
 684                                "UP", "selectPreviousRow",
 685                             "KP_UP", "selectPreviousRow",
 686                          "shift UP", "selectPreviousRowExtendSelection",
 687                       "shift KP_UP", "selectPreviousRowExtendSelection",
 688                     "ctrl shift UP", "selectPreviousRowExtendSelection",
 689                  "ctrl shift KP_UP", "selectPreviousRowExtendSelection",
 690                           "ctrl UP", "selectPreviousRowChangeLead",
 691                        "ctrl KP_UP", "selectPreviousRowChangeLead",
 692                              "DOWN", "selectNextRow",
 693                           "KP_DOWN", "selectNextRow",
 694                        "shift DOWN", "selectNextRowExtendSelection",
 695                     "shift KP_DOWN", "selectNextRowExtendSelection",
 696                   "ctrl shift DOWN", "selectNextRowExtendSelection",
 697                "ctrl shift KP_DOWN", "selectNextRowExtendSelection",
 698                         "ctrl DOWN", "selectNextRowChangeLead",
 699                      "ctrl KP_DOWN", "selectNextRowChangeLead",
 700                              "LEFT", "selectPreviousColumn",
 701                           "KP_LEFT", "selectPreviousColumn",
 702                        "shift LEFT", "selectPreviousColumnExtendSelection",
 703                     "shift KP_LEFT", "selectPreviousColumnExtendSelection",
 704                   "ctrl shift LEFT", "selectPreviousColumnExtendSelection",
 705                "ctrl shift KP_LEFT", "selectPreviousColumnExtendSelection",
 706                         "ctrl LEFT", "selectPreviousColumnChangeLead",
 707                      "ctrl KP_LEFT", "selectPreviousColumnChangeLead",
 708                             "RIGHT", "selectNextColumn",
 709                          "KP_RIGHT", "selectNextColumn",
 710                       "shift RIGHT", "selectNextColumnExtendSelection",
 711                    "shift KP_RIGHT", "selectNextColumnExtendSelection",
 712                  "ctrl shift RIGHT", "selectNextColumnExtendSelection",
 713               "ctrl shift KP_RIGHT", "selectNextColumnExtendSelection",
 714                        "ctrl RIGHT", "selectNextColumnChangeLead",
 715                     "ctrl KP_RIGHT", "selectNextColumnChangeLead",
 716                              "HOME", "selectFirstRow",
 717                        "shift HOME", "selectFirstRowExtendSelection",
 718                   "ctrl shift HOME", "selectFirstRowExtendSelection",
 719                         "ctrl HOME", "selectFirstRowChangeLead",
 720                               "END", "selectLastRow",
 721                         "shift END", "selectLastRowExtendSelection",
 722                    "ctrl shift END", "selectLastRowExtendSelection",
 723                          "ctrl END", "selectLastRowChangeLead",
 724                           "PAGE_UP", "scrollUp",
 725                     "shift PAGE_UP", "scrollUpExtendSelection",
 726                "ctrl shift PAGE_UP", "scrollUpExtendSelection",
 727                      "ctrl PAGE_UP", "scrollUpChangeLead",
 728                         "PAGE_DOWN", "scrollDown",
 729                   "shift PAGE_DOWN", "scrollDownExtendSelection",
 730              "ctrl shift PAGE_DOWN", "scrollDownExtendSelection",
 731                    "ctrl PAGE_DOWN", "scrollDownChangeLead",
 732                            "ctrl A", "selectAll",
 733                        "ctrl SLASH", "selectAll",
 734                   "ctrl BACK_SLASH", "clearSelection",
 735                             "SPACE", "addToSelection",
 736                        "ctrl SPACE", "toggleAndAnchor",
 737                       "shift SPACE", "extendTo",
 738                  "ctrl shift SPACE", "moveSelectionTo"
 739                  }),
 740             "List.focusInputMap.RightToLeft",
 741                new UIDefaults.LazyInputMap(new Object[] {
 742                              "LEFT", "selectNextColumn",
 743                           "KP_LEFT", "selectNextColumn",
 744                        "shift LEFT", "selectNextColumnExtendSelection",
 745                     "shift KP_LEFT", "selectNextColumnExtendSelection",
 746                   "ctrl shift LEFT", "selectNextColumnExtendSelection",
 747                "ctrl shift KP_LEFT", "selectNextColumnExtendSelection",
 748                         "ctrl LEFT", "selectNextColumnChangeLead",
 749                      "ctrl KP_LEFT", "selectNextColumnChangeLead",
 750                             "RIGHT", "selectPreviousColumn",
 751                          "KP_RIGHT", "selectPreviousColumn",
 752                       "shift RIGHT", "selectPreviousColumnExtendSelection",
 753                    "shift KP_RIGHT", "selectPreviousColumnExtendSelection",
 754                  "ctrl shift RIGHT", "selectPreviousColumnExtendSelection",
 755               "ctrl shift KP_RIGHT", "selectPreviousColumnExtendSelection",
 756                        "ctrl RIGHT", "selectPreviousColumnChangeLead",
 757                     "ctrl KP_RIGHT", "selectPreviousColumnChangeLead",
 758                  }),
 759             "List.font", new FontLazyValue(Region.LIST),
 760             "List.rendererUseUIBorder", Boolean.FALSE,
 761 
 762             "Menu.arrowIcon", new GTKStyle.GTKLazyValue(
 763                               "com.sun.java.swing.plaf.gtk.GTKIconFactory",
 764                               "getMenuArrowIcon"),
 765             "Menu.checkIcon", null,
 766             "Menu.font", new FontLazyValue(Region.MENU),
 767             "Menu.margin", zeroInsets,
 768             "Menu.cancelMode", "hideMenuTree",
 769             "Menu.alignAcceleratorText", Boolean.FALSE,
 770             "Menu.useMenuBarForTopLevelMenus", Boolean.TRUE,
 771 
 772 
 773                 "MenuBar.windowBindings", new Object[] {
 774                 "F10", "takeFocus" },
 775             "MenuBar.font", new FontLazyValue(Region.MENU_BAR),
 776 
 777 
 778             "MenuItem.arrowIcon", null,
 779             "MenuItem.checkIcon", null,
 780             "MenuItem.font", new FontLazyValue(Region.MENU_ITEM),
 781             "MenuItem.margin", zeroInsets,
 782             "MenuItem.alignAcceleratorText", Boolean.FALSE,
 783 
 784 
 785             "OptionPane.setButtonMargin", Boolean.FALSE,
 786             "OptionPane.sameSizeButtons", Boolean.TRUE,
 787             "OptionPane.buttonOrientation", SwingConstants.RIGHT,
 788             "OptionPane.minimumSize", new DimensionUIResource(262, 90),
 789             "OptionPane.buttonPadding", 10,
 790             "OptionPane.windowBindings", new Object[] {
 791                 "ESCAPE", "close" },
 792             "OptionPane.buttonClickThreshhold", 500,
 793             "OptionPane.isYesLast", Boolean.TRUE,
 794             "OptionPane.font", new FontLazyValue(Region.OPTION_PANE),
 795 
 796             "Panel.font", new FontLazyValue(Region.PANEL),
 797 
 798             "PasswordField.caretForeground", caretColor,
 799             "PasswordField.caretAspectRatio", defaultCaretAspectRatio,
 800             "PasswordField.caretBlinkRate", caretBlinkRate,
 801             "PasswordField.margin", zeroInsets,
 802             "PasswordField.focusInputMap", passwordInputMap,
 803             "PasswordField.font", new FontLazyValue(Region.PASSWORD_FIELD),
 804 
 805 
 806             "PopupMenu.consumeEventOnClose", Boolean.TRUE,
 807             "PopupMenu.selectedWindowInputMapBindings", new Object[] {
 808                   "ESCAPE", "cancel",
 809                     "DOWN", "selectNext",
 810                  "KP_DOWN", "selectNext",
 811                       "UP", "selectPrevious",
 812                    "KP_UP", "selectPrevious",
 813                     "LEFT", "selectParent",
 814                  "KP_LEFT", "selectParent",
 815                    "RIGHT", "selectChild",
 816                 "KP_RIGHT", "selectChild",
 817                    "ENTER", "return",
 818                    "SPACE", "return"
 819             },
 820             "PopupMenu.selectedWindowInputMapBindings.RightToLeft",
 821                   new Object[] {
 822                     "LEFT", "selectChild",
 823                  "KP_LEFT", "selectChild",
 824                    "RIGHT", "selectParent",
 825                 "KP_RIGHT", "selectParent",
 826             },
 827             "PopupMenu.font", new FontLazyValue(Region.POPUP_MENU),
 828 
 829             "ProgressBar.horizontalSize",
 830                 new DimensionUIResource(hProgWidth, hProgHeight),
 831             "ProgressBar.verticalSize",
 832                 new DimensionUIResource(vProgWidth, vProgHeight),
 833             "ProgressBar.font", new FontLazyValue(Region.PROGRESS_BAR),
 834 
 835             "RadioButton.focusInputMap",
 836                    new UIDefaults.LazyInputMap(new Object[] {
 837                             "SPACE", "pressed",
 838                    "released SPACE", "released",
 839                            "RETURN", "pressed"
 840                    }),
 841             "RadioButton.icon", new GTKStyle.GTKLazyValue(
 842                               "com.sun.java.swing.plaf.gtk.GTKIconFactory",
 843                               "getRadioButtonIcon"),
 844             "RadioButton.font", new FontLazyValue(Region.RADIO_BUTTON),
 845             "RadioButton.margin", zeroInsets,
 846 
 847 
 848             "RadioButtonMenuItem.arrowIcon", null,
 849             "RadioButtonMenuItem.checkIcon", new GTKStyle.GTKLazyValue(
 850                               "com.sun.java.swing.plaf.gtk.GTKIconFactory",
 851                               "getRadioButtonMenuItemCheckIcon"),
 852             "RadioButtonMenuItem.font", new FontLazyValue(Region.RADIO_BUTTON_MENU_ITEM),
 853             "RadioButtonMenuItem.margin", zeroInsets,
 854             "RadioButtonMenuItem.alignAcceleratorText", Boolean.FALSE,
 855 
 856 
 857             // These bindings are only enabled when there is a default
 858             // button set on the rootpane.
 859             "RootPane.defaultButtonWindowKeyBindings", new Object[] {
 860                                "ENTER", "press",
 861                       "released ENTER", "release",
 862                           "ctrl ENTER", "press",
 863                  "ctrl released ENTER", "release"
 864             },
 865 
 866 
 867             "ScrollBar.squareButtons", Boolean.FALSE,
 868             "ScrollBar.thumbHeight", Integer.valueOf(14),
 869             "ScrollBar.width", Integer.valueOf(16),
 870             "ScrollBar.minimumThumbSize", new Dimension(8, 8),
 871             "ScrollBar.maximumThumbSize", new Dimension(4096, 4096),
 872             "ScrollBar.allowsAbsolutePositioning", Boolean.TRUE,
 873             "ScrollBar.alwaysShowThumb", Boolean.TRUE,
 874             "ScrollBar.ancestorInputMap",
 875                    new UIDefaults.LazyInputMap(new Object[] {
 876                        "RIGHT", "positiveUnitIncrement",
 877                     "KP_RIGHT", "positiveUnitIncrement",
 878                         "DOWN", "positiveUnitIncrement",
 879                      "KP_DOWN", "positiveUnitIncrement",
 880                    "PAGE_DOWN", "positiveBlockIncrement",
 881                         "LEFT", "negativeUnitIncrement",
 882                      "KP_LEFT", "negativeUnitIncrement",
 883                           "UP", "negativeUnitIncrement",
 884                        "KP_UP", "negativeUnitIncrement",
 885                      "PAGE_UP", "negativeBlockIncrement",
 886                         "HOME", "minScroll",
 887                          "END", "maxScroll"
 888                    }),
 889             "ScrollBar.ancestorInputMap.RightToLeft",
 890                     new UIDefaults.LazyInputMap(new Object[] {
 891                        "RIGHT", "negativeUnitIncrement",
 892                     "KP_RIGHT", "negativeUnitIncrement",
 893                         "LEFT", "positiveUnitIncrement",
 894                      "KP_LEFT", "positiveUnitIncrement",
 895                     }),
 896 
 897 
 898             "Spinner.disableOnBoundaryValues", Boolean.TRUE,
 899 
 900 
 901             "ScrollPane.fillUpperCorner", Boolean.TRUE,
 902             "ScrollPane.fillLowerCorner", Boolean.TRUE,
 903             "ScrollPane.ancestorInputMap",
 904                     new UIDefaults.LazyInputMap(new Object[] {
 905                            "RIGHT", "unitScrollRight",
 906                         "KP_RIGHT", "unitScrollRight",
 907                             "DOWN", "unitScrollDown",
 908                          "KP_DOWN", "unitScrollDown",
 909                             "LEFT", "unitScrollLeft",
 910                          "KP_LEFT", "unitScrollLeft",
 911                               "UP", "unitScrollUp",
 912                            "KP_UP", "unitScrollUp",
 913                          "PAGE_UP", "scrollUp",
 914                        "PAGE_DOWN", "scrollDown",
 915                     "ctrl PAGE_UP", "scrollLeft",
 916                   "ctrl PAGE_DOWN", "scrollRight",
 917                        "ctrl HOME", "scrollHome",
 918                         "ctrl END", "scrollEnd"
 919                     }),
 920             "ScrollPane.ancestorInputMap.RightToLeft",
 921                     new UIDefaults.LazyInputMap(new Object[] {
 922                     "ctrl PAGE_UP", "scrollRight",
 923                   "ctrl PAGE_DOWN", "scrollLeft",
 924                     }),
 925             "ScrollPane.font", new FontLazyValue(Region.SCROLL_PANE),
 926 
 927 
 928             "Separator.insets", zeroInsets,
 929             "Separator.thickness", Integer.valueOf(2),
 930 
 931 
 932             "Slider.paintValue", Boolean.TRUE,
 933             "Slider.thumbWidth", Integer.valueOf(30),
 934             "Slider.thumbHeight", Integer.valueOf(14),
 935             "Slider.focusInputMap",
 936                     new UIDefaults.LazyInputMap(new Object[] {
 937                             "RIGHT", "positiveUnitIncrement",
 938                          "KP_RIGHT", "positiveUnitIncrement",
 939                              "DOWN", "negativeUnitIncrement",
 940                           "KP_DOWN", "negativeUnitIncrement",
 941                         "PAGE_DOWN", "negativeBlockIncrement",
 942                              "LEFT", "negativeUnitIncrement",
 943                           "KP_LEFT", "negativeUnitIncrement",
 944                                "UP", "positiveUnitIncrement",
 945                             "KP_UP", "positiveUnitIncrement",
 946                           "PAGE_UP", "positiveBlockIncrement",
 947                              "HOME", "minScroll",
 948                               "END", "maxScroll"
 949                         }),
 950             "Slider.focusInputMap.RightToLeft",
 951                     new UIDefaults.LazyInputMap(new Object[] {
 952                             "RIGHT", "negativeUnitIncrement",
 953                          "KP_RIGHT", "negativeUnitIncrement",
 954                              "LEFT", "positiveUnitIncrement",
 955                           "KP_LEFT", "positiveUnitIncrement",
 956                          }),
 957             "Slider.onlyLeftMouseButtonDrag", Boolean.FALSE,
 958 
 959             "Spinner.ancestorInputMap",
 960                new UIDefaults.LazyInputMap(new Object[] {
 961                                "UP", "increment",
 962                             "KP_UP", "increment",
 963                              "DOWN", "decrement",
 964                           "KP_DOWN", "decrement",
 965                }),
 966             "Spinner.font", new FontLazyValue(Region.SPINNER),
 967             "Spinner.editorAlignment", JTextField.LEADING,
 968 
 969             "SplitPane.ancestorInputMap",
 970                     new UIDefaults.LazyInputMap(new Object[] {
 971                         "UP", "negativeIncrement",
 972                       "DOWN", "positiveIncrement",
 973                       "LEFT", "negativeIncrement",
 974                      "RIGHT", "positiveIncrement",
 975                      "KP_UP", "negativeIncrement",
 976                    "KP_DOWN", "positiveIncrement",
 977                    "KP_LEFT", "negativeIncrement",
 978                   "KP_RIGHT", "positiveIncrement",
 979                       "HOME", "selectMin",
 980                        "END", "selectMax",
 981                         "F8", "startResize",
 982                         "F6", "toggleFocus",
 983                   "ctrl TAB", "focusOutForward",
 984             "ctrl shift TAB", "focusOutBackward"
 985                     }),
 986 
 987 
 988             "SplitPane.size", Integer.valueOf(7),
 989             "SplitPane.oneTouchOffset", Integer.valueOf(2),
 990             "SplitPane.oneTouchButtonSize", Integer.valueOf(5),
 991             "SplitPane.supportsOneTouchButtons", Boolean.FALSE,
 992 
 993 
 994             "TabbedPane.focusInputMap",
 995               new UIDefaults.LazyInputMap(new Object[] {
 996                          "RIGHT", "navigateRight",
 997                       "KP_RIGHT", "navigateRight",
 998                           "LEFT", "navigateLeft",
 999                        "KP_LEFT", "navigateLeft",
1000                             "UP", "navigateUp",
1001                          "KP_UP", "navigateUp",
1002                           "DOWN", "navigateDown",
1003                        "KP_DOWN", "navigateDown",
1004                      "ctrl DOWN", "requestFocusForVisibleComponent",
1005                   "ctrl KP_DOWN", "requestFocusForVisibleComponent",
1006                          "SPACE", "selectTabWithFocus"
1007                 }),
1008             "TabbedPane.ancestorInputMap",
1009                new UIDefaults.LazyInputMap(new Object[] {
1010                          "ctrl TAB", "navigateNext",
1011                    "ctrl shift TAB", "navigatePrevious",
1012                    "ctrl PAGE_DOWN", "navigatePageDown",
1013                      "ctrl PAGE_UP", "navigatePageUp",
1014                           "ctrl UP", "requestFocus",
1015                        "ctrl KP_UP", "requestFocus",
1016                  }),
1017 
1018             "TabbedPane.labelShift", 3,
1019             "TabbedPane.selectedLabelShift", 3,
1020             "TabbedPane.font", new FontLazyValue(Region.TABBED_PANE),
1021             "TabbedPane.selectedTabPadInsets", new InsetsUIResource(2, 2, 0, 1),
1022 
1023             "Table.scrollPaneBorder", zeroBorder,
1024             "Table.background", tableBg,
1025             "Table.focusCellBackground", tableFocusCellBg,
1026             "Table.focusCellForeground", tableFocusCellFg,
1027             "Table.focusCellHighlightBorder", focusBorder,
1028             "Table.focusSelectedCellHighlightBorder", focusSelectedBorder,
1029             "Table.ancestorInputMap",
1030                     new UIDefaults.LazyInputMap(new Object[] {
1031                                "ctrl C", "copy",
1032                                "ctrl V", "paste",
1033                                "ctrl X", "cut",
1034                                  "COPY", "copy",
1035                                 "PASTE", "paste",
1036                                   "CUT", "cut",
1037                        "control INSERT", "copy",
1038                          "shift INSERT", "paste",
1039                          "shift DELETE", "cut",
1040                                 "RIGHT", "selectNextColumn",
1041                              "KP_RIGHT", "selectNextColumn",
1042                           "shift RIGHT", "selectNextColumnExtendSelection",
1043                        "shift KP_RIGHT", "selectNextColumnExtendSelection",
1044                      "ctrl shift RIGHT", "selectNextColumnExtendSelection",
1045                   "ctrl shift KP_RIGHT", "selectNextColumnExtendSelection",
1046                            "ctrl RIGHT", "selectNextColumnChangeLead",
1047                         "ctrl KP_RIGHT", "selectNextColumnChangeLead",
1048                                  "LEFT", "selectPreviousColumn",
1049                               "KP_LEFT", "selectPreviousColumn",
1050                            "shift LEFT", "selectPreviousColumnExtendSelection",
1051                         "shift KP_LEFT", "selectPreviousColumnExtendSelection",
1052                       "ctrl shift LEFT", "selectPreviousColumnExtendSelection",
1053                    "ctrl shift KP_LEFT", "selectPreviousColumnExtendSelection",
1054                             "ctrl LEFT", "selectPreviousColumnChangeLead",
1055                          "ctrl KP_LEFT", "selectPreviousColumnChangeLead",
1056                                  "DOWN", "selectNextRow",
1057                               "KP_DOWN", "selectNextRow",
1058                            "shift DOWN", "selectNextRowExtendSelection",
1059                         "shift KP_DOWN", "selectNextRowExtendSelection",
1060                       "ctrl shift DOWN", "selectNextRowExtendSelection",
1061                    "ctrl shift KP_DOWN", "selectNextRowExtendSelection",
1062                             "ctrl DOWN", "selectNextRowChangeLead",
1063                          "ctrl KP_DOWN", "selectNextRowChangeLead",
1064                                    "UP", "selectPreviousRow",
1065                                 "KP_UP", "selectPreviousRow",
1066                              "shift UP", "selectPreviousRowExtendSelection",
1067                           "shift KP_UP", "selectPreviousRowExtendSelection",
1068                         "ctrl shift UP", "selectPreviousRowExtendSelection",
1069                      "ctrl shift KP_UP", "selectPreviousRowExtendSelection",
1070                               "ctrl UP", "selectPreviousRowChangeLead",
1071                            "ctrl KP_UP", "selectPreviousRowChangeLead",
1072                                  "HOME", "selectFirstColumn",
1073                            "shift HOME", "selectFirstColumnExtendSelection",
1074                       "ctrl shift HOME", "selectFirstRowExtendSelection",
1075                             "ctrl HOME", "selectFirstRow",
1076                                   "END", "selectLastColumn",
1077                             "shift END", "selectLastColumnExtendSelection",
1078                        "ctrl shift END", "selectLastRowExtendSelection",
1079                              "ctrl END", "selectLastRow",
1080                               "PAGE_UP", "scrollUpChangeSelection",
1081                         "shift PAGE_UP", "scrollUpExtendSelection",
1082                    "ctrl shift PAGE_UP", "scrollLeftExtendSelection",
1083                          "ctrl PAGE_UP", "scrollLeftChangeSelection",
1084                             "PAGE_DOWN", "scrollDownChangeSelection",
1085                       "shift PAGE_DOWN", "scrollDownExtendSelection",
1086                  "ctrl shift PAGE_DOWN", "scrollRightExtendSelection",
1087                        "ctrl PAGE_DOWN", "scrollRightChangeSelection",
1088                                   "TAB", "selectNextColumnCell",
1089                             "shift TAB", "selectPreviousColumnCell",
1090                                 "ENTER", "selectNextRowCell",
1091                           "shift ENTER", "selectPreviousRowCell",
1092                                "ctrl A", "selectAll",
1093                            "ctrl SLASH", "selectAll",
1094                       "ctrl BACK_SLASH", "clearSelection",
1095                                "ESCAPE", "cancel",
1096                                    "F2", "startEditing",
1097                                 "SPACE", "addToSelection",
1098                            "ctrl SPACE", "toggleAndAnchor",
1099                           "shift SPACE", "extendTo",
1100                      "ctrl shift SPACE", "moveSelectionTo",
1101                                    "F8", "focusHeader"
1102                     }),
1103             "Table.ancestorInputMap.RightToLeft",
1104                     new UIDefaults.LazyInputMap(new Object[] {
1105                                 "RIGHT", "selectPreviousColumn",
1106                              "KP_RIGHT", "selectPreviousColumn",
1107                           "shift RIGHT", "selectPreviousColumnExtendSelection",
1108                        "shift KP_RIGHT", "selectPreviousColumnExtendSelection",
1109                      "ctrl shift RIGHT", "selectPreviousColumnExtendSelection",
1110                   "ctrl shift KP_RIGHT", "selectPreviousColumnExtendSelection",
1111                           "shift RIGHT", "selectPreviousColumnChangeLead",
1112                        "shift KP_RIGHT", "selectPreviousColumnChangeLead",
1113                                  "LEFT", "selectNextColumn",
1114                               "KP_LEFT", "selectNextColumn",
1115                            "shift LEFT", "selectNextColumnExtendSelection",
1116                         "shift KP_LEFT", "selectNextColumnExtendSelection",
1117                       "ctrl shift LEFT", "selectNextColumnExtendSelection",
1118                    "ctrl shift KP_LEFT", "selectNextColumnExtendSelection",
1119                             "ctrl LEFT", "selectNextColumnChangeLead",
1120                          "ctrl KP_LEFT", "selectNextColumnChangeLead",
1121                          "ctrl PAGE_UP", "scrollRightChangeSelection",
1122                        "ctrl PAGE_DOWN", "scrollLeftChangeSelection",
1123                    "ctrl shift PAGE_UP", "scrollRightExtendSelection",
1124                  "ctrl shift PAGE_DOWN", "scrollLeftExtendSelection",
1125                     }),
1126             "Table.font", new FontLazyValue(Region.TABLE),
1127             "Table.ascendingSortIcon",  new GTKStyle.GTKLazyValue(
1128                               "com.sun.java.swing.plaf.gtk.GTKIconFactory",
1129                               "getAscendingSortIcon"),
1130             "Table.descendingSortIcon",  new GTKStyle.GTKLazyValue(
1131                               "com.sun.java.swing.plaf.gtk.GTKIconFactory",
1132                               "getDescendingSortIcon"),
1133 
1134             "TableHeader.font", new FontLazyValue(Region.TABLE_HEADER),
1135             "TableHeader.alignSorterArrow", Boolean.TRUE,
1136 
1137             "TextArea.caretForeground", caretColor,
1138             "TextArea.caretAspectRatio", defaultCaretAspectRatio,
1139             "TextArea.caretBlinkRate", caretBlinkRate,
1140             "TextArea.margin", zeroInsets,
1141             "TextArea.focusInputMap", multilineInputMap,
1142             "TextArea.font", new FontLazyValue(Region.TEXT_AREA),
1143 
1144 
1145             "TextField.caretForeground", caretColor,
1146             "TextField.caretAspectRatio", defaultCaretAspectRatio,
1147             "TextField.caretBlinkRate", caretBlinkRate,
1148             "TextField.margin", zeroInsets,
1149             "TextField.focusInputMap", fieldInputMap,
1150             "TextField.font", new FontLazyValue(Region.TEXT_FIELD),
1151 
1152 
1153             "TextPane.caretForeground", caretColor,
1154             "TextPane.caretAspectRatio", defaultCaretAspectRatio,
1155             "TextPane.caretBlinkRate", caretBlinkRate,
1156             "TextPane.margin", editorMargin,
1157             "TextPane.focusInputMap", multilineInputMap,
1158             "TextPane.font", new FontLazyValue(Region.TEXT_PANE),
1159 
1160 
1161             "TitledBorder.titleColor", controlText,
1162             "TitledBorder.border", new UIDefaults.LazyValue() {
1163                 public Object createValue(UIDefaults table) {
1164                     return new GTKPainter.TitledBorder();
1165                 }
1166             },
1167 
1168             "ToggleButton.focusInputMap",
1169                    new UIDefaults.LazyInputMap(new Object[] {
1170                             "SPACE", "pressed",
1171                    "released SPACE", "released"
1172                    }),
1173             "ToggleButton.font", new FontLazyValue(Region.TOGGLE_BUTTON),
1174             "ToggleButton.margin", zeroInsets,
1175 
1176 
1177             "ToolBar.separatorSize", new DimensionUIResource(10, 10),
1178             "ToolBar.handleIcon", new UIDefaults.ActiveValue() {
1179                 public Object createValue(UIDefaults table) {
1180                     return GTKIconFactory.getToolBarHandleIcon();
1181                 }
1182             },
1183             "ToolBar.ancestorInputMap",
1184                new UIDefaults.LazyInputMap(new Object[] {
1185                         "UP", "navigateUp",
1186                      "KP_UP", "navigateUp",
1187                       "DOWN", "navigateDown",
1188                    "KP_DOWN", "navigateDown",
1189                       "LEFT", "navigateLeft",
1190                    "KP_LEFT", "navigateLeft",
1191                      "RIGHT", "navigateRight",
1192                   "KP_RIGHT", "navigateRight"
1193                  }),
1194             "ToolBar.font", new FontLazyValue(Region.TOOL_BAR),
1195 
1196             "ToolTip.font", new FontLazyValue(Region.TOOL_TIP),
1197 
1198             "Tree.padding", Integer.valueOf(4),
1199             "Tree.background", tableBg,
1200             "Tree.drawHorizontalLines", Boolean.FALSE,
1201             "Tree.drawVerticalLines", Boolean.FALSE,
1202             "Tree.rowHeight", Integer.valueOf(-1),
1203             "Tree.scrollsOnExpand", Boolean.FALSE,
1204             "Tree.expanderSize", Integer.valueOf(10),
1205             "Tree.repaintWholeRow", Boolean.TRUE,
1206             "Tree.closedIcon", null,
1207             "Tree.leafIcon", null,
1208             "Tree.openIcon", null,
1209             "Tree.expandedIcon", new GTKStyle.GTKLazyValue(
1210                               "com.sun.java.swing.plaf.gtk.GTKIconFactory",
1211                               "getTreeExpandedIcon"),
1212             "Tree.collapsedIcon", new GTKStyle.GTKLazyValue(
1213                               "com.sun.java.swing.plaf.gtk.GTKIconFactory",
1214                               "getTreeCollapsedIcon"),
1215             "Tree.leftChildIndent", Integer.valueOf(2),
1216             "Tree.rightChildIndent", Integer.valueOf(12),
1217             "Tree.scrollsHorizontallyAndVertically", Boolean.FALSE,
1218             "Tree.drawsFocusBorder", Boolean.TRUE,
1219             "Tree.focusInputMap",
1220                     new UIDefaults.LazyInputMap(new Object[] {
1221                                  "ctrl C", "copy",
1222                                  "ctrl V", "paste",
1223                                  "ctrl X", "cut",
1224                                    "COPY", "copy",
1225                                   "PASTE", "paste",
1226                                     "CUT", "cut",
1227                          "control INSERT", "copy",
1228                            "shift INSERT", "paste",
1229                            "shift DELETE", "cut",
1230                                      "UP", "selectPrevious",
1231                                   "KP_UP", "selectPrevious",
1232                                "shift UP", "selectPreviousExtendSelection",
1233                             "shift KP_UP", "selectPreviousExtendSelection",
1234                           "ctrl shift UP", "selectPreviousExtendSelection",
1235                        "ctrl shift KP_UP", "selectPreviousExtendSelection",
1236                                 "ctrl UP", "selectPreviousChangeLead",
1237                              "ctrl KP_UP", "selectPreviousChangeLead",
1238                                    "DOWN", "selectNext",
1239                                 "KP_DOWN", "selectNext",
1240                              "shift DOWN", "selectNextExtendSelection",
1241                           "shift KP_DOWN", "selectNextExtendSelection",
1242                         "ctrl shift DOWN", "selectNextExtendSelection",
1243                      "ctrl shift KP_DOWN", "selectNextExtendSelection",
1244                               "ctrl DOWN", "selectNextChangeLead",
1245                            "ctrl KP_DOWN", "selectNextChangeLead",
1246                                   "RIGHT", "selectChild",
1247                                "KP_RIGHT", "selectChild",
1248                                    "LEFT", "selectParent",
1249                                 "KP_LEFT", "selectParent",
1250                                 "typed +", "expand",
1251                                 "typed -", "collapse",
1252                              "BACK_SPACE", "moveSelectionToParent",
1253                                 "PAGE_UP", "scrollUpChangeSelection",
1254                           "shift PAGE_UP", "scrollUpExtendSelection",
1255                      "ctrl shift PAGE_UP", "scrollUpExtendSelection",
1256                            "ctrl PAGE_UP", "scrollUpChangeLead",
1257                               "PAGE_DOWN", "scrollDownChangeSelection",
1258                         "shift PAGE_DOWN", "scrollDownExtendSelection",
1259                    "ctrl shift PAGE_DOWN", "scrollDownExtendSelection",
1260                          "ctrl PAGE_DOWN", "scrollDownChangeLead",
1261                                    "HOME", "selectFirst",
1262                              "shift HOME", "selectFirstExtendSelection",
1263                         "ctrl shift HOME", "selectFirstExtendSelection",
1264                               "ctrl HOME", "selectFirstChangeLead",
1265                                     "END", "selectLast",
1266                               "shift END", "selectLastExtendSelection",
1267                          "ctrl shift END", "selectLastExtendSelection",
1268                                "ctrl END", "selectLastChangeLead",
1269                                      "F2", "startEditing",
1270                                  "ctrl A", "selectAll",
1271                              "ctrl SLASH", "selectAll",
1272                         "ctrl BACK_SLASH", "clearSelection",
1273                               "ctrl LEFT", "scrollLeft",
1274                            "ctrl KP_LEFT", "scrollLeft",
1275                              "ctrl RIGHT", "scrollRight",
1276                           "ctrl KP_RIGHT", "scrollRight",
1277                                   "SPACE", "addToSelection",
1278                              "ctrl SPACE", "toggleAndAnchor",
1279                             "shift SPACE", "extendTo",
1280                        "ctrl shift SPACE", "moveSelectionTo"
1281                     }),
1282             "Tree.focusInputMap.RightToLeft",
1283                     new UIDefaults.LazyInputMap(new Object[] {
1284                                   "RIGHT", "selectParent",
1285                                "KP_RIGHT", "selectParent",
1286                                    "LEFT", "selectChild",
1287                                 "KP_LEFT", "selectChild",
1288                  }),
1289             "Tree.ancestorInputMap",
1290                       new UIDefaults.LazyInputMap(new Object[] {
1291                          "ESCAPE", "cancel"
1292                       }),
1293             "Tree.font", new FontLazyValue(Region.TREE),
1294 
1295             "Viewport.font", new FontLazyValue(Region.VIEWPORT)
1296         };
1297         table.putDefaults(defaults);
1298 
1299         if (fallbackFont != null) {
1300             table.put("TitledBorder.font", fallbackFont);
1301         }
1302         if (aaTextInfo != null) {
1303             table.putAll(aaTextInfo);
1304         }
1305     }
1306 
1307     protected void initSystemColorDefaults(UIDefaults table) {
1308         GTKStyleFactory factory = (GTKStyleFactory)getStyleFactory();
1309         GTKStyle windowStyle =
1310                 (GTKStyle)factory.getStyle(null, Region.INTERNAL_FRAME);
1311         table.put("window", windowStyle.getGTKColor(SynthConstants.ENABLED,
1312                 GTKColorType.BACKGROUND));
1313         table.put("windowText", windowStyle.getGTKColor(SynthConstants.ENABLED,
1314                 GTKColorType.TEXT_FOREGROUND));
1315 
1316         GTKStyle entryStyle = (GTKStyle)factory.getStyle(null, Region.TEXT_FIELD);
1317         table.put("text", entryStyle.getGTKColor(SynthConstants.ENABLED,
1318                                            GTKColorType.TEXT_BACKGROUND));
1319         table.put("textText", entryStyle.getGTKColor(SynthConstants.ENABLED,
1320                                            GTKColorType.TEXT_FOREGROUND));
1321         table.put("textHighlight",
1322                 entryStyle.getGTKColor(SynthConstants.SELECTED,
1323                                          GTKColorType.TEXT_BACKGROUND));
1324         table.put("textHighlightText",
1325                   entryStyle.getGTKColor(SynthConstants.SELECTED,
1326                                          GTKColorType.TEXT_FOREGROUND));
1327         table.put("textInactiveText",
1328                   entryStyle.getGTKColor(SynthConstants.DISABLED,
1329                                          GTKColorType.TEXT_FOREGROUND));
1330         Object caretColor =
1331             entryStyle.getClassSpecificValue("cursor-color");
1332         if (caretColor == null) {
1333             caretColor = GTKStyle.BLACK_COLOR;
1334         }
1335         table.put("caretColor", caretColor);
1336 
1337         GTKStyle menuStyle = (GTKStyle)factory.getStyle(null, Region.MENU_ITEM);
1338         table.put("menu", menuStyle.getGTKColor(SynthConstants.ENABLED,
1339                                            GTKColorType.BACKGROUND));
1340         table.put("menuText", menuStyle.getGTKColor(SynthConstants.ENABLED,
1341                                            GTKColorType.TEXT_FOREGROUND));
1342 
1343         GTKStyle scrollbarStyle = (GTKStyle)factory.getStyle(null, Region.SCROLL_BAR);
1344         table.put("scrollbar", scrollbarStyle.getGTKColor(SynthConstants.ENABLED,
1345                                            GTKColorType.BACKGROUND));
1346 
1347         GTKStyle infoStyle = (GTKStyle)factory.getStyle(null, Region.OPTION_PANE);
1348         table.put("info", infoStyle.getGTKColor(SynthConstants.ENABLED,
1349                                            GTKColorType.BACKGROUND));
1350         table.put("infoText", infoStyle.getGTKColor(SynthConstants.ENABLED,
1351                                            GTKColorType.TEXT_FOREGROUND));
1352 
1353         GTKStyle desktopStyle = (GTKStyle)factory.getStyle(null, Region.DESKTOP_PANE);
1354         table.put("desktop", desktopStyle.getGTKColor(SynthConstants.ENABLED,
1355                                            GTKColorType.BACKGROUND));
1356 
1357         // colors specific only for GTK
1358         // It is impossible to create a simple GtkWidget without specifying the
1359         // type. So for GtkWidget we can use any appropriate concrete type of
1360         // wigdet. LABEL in this case.
1361         GTKStyle widgetStyle = (GTKStyle)factory.getStyle(null, Region.LABEL);
1362         Color bg = widgetStyle.getGTKColor(SynthConstants.ENABLED,
1363                                            GTKColorType.BACKGROUND);
1364         table.put("control", bg);
1365         table.put("controlHighlight", bg);
1366         table.put("controlText", widgetStyle.getGTKColor(SynthConstants.ENABLED,
1367                                                GTKColorType.TEXT_FOREGROUND));
1368         table.put("controlLtHighlight", widgetStyle.getGTKColor(
1369                 SynthConstants.ENABLED, GTKColorType.LIGHT));
1370         table.put("controlShadow", widgetStyle.getGTKColor(
1371                 SynthConstants.ENABLED, GTKColorType.DARK));
1372         table.put("controlDkShadow", widgetStyle.getGTKColor(
1373                 SynthConstants.ENABLED, GTKColorType.BLACK));
1374         table.put("light", widgetStyle.getGTKColor(
1375                 SynthConstants.ENABLED, GTKColorType.LIGHT));
1376         table.put("mid", widgetStyle.getGTKColor(
1377                 SynthConstants.ENABLED, GTKColorType.MID));
1378         table.put("dark", widgetStyle.getGTKColor(
1379                 SynthConstants.ENABLED, GTKColorType.DARK));
1380         table.put("black", widgetStyle.getGTKColor(
1381                 SynthConstants.ENABLED, GTKColorType.BLACK));
1382         table.put("white", widgetStyle.getGTKColor(
1383                 SynthConstants.ENABLED, GTKColorType.WHITE));
1384     }
1385 
1386     /**
1387      * Creates the GTK look and feel class for the passed in Component.
1388      */
1389     public static ComponentUI createUI(JComponent c) {
1390         String key = c.getUIClassID().intern();
1391 
1392         if (key == "FileChooserUI") {
1393             return GTKFileChooserUI.createUI(c);
1394         }
1395         return SynthLookAndFeel.createUI(c);
1396     }
1397 
1398     /**
1399      * Returns the cached gtkThemeName
1400      */
1401     static String getGtkThemeName() {
1402         return gtkThemeName;
1403     }
1404 
1405     static boolean isLeftToRight(Component c) {
1406         return c.getComponentOrientation().isLeftToRight();
1407     }
1408 
1409     public void initialize() {
1410         /*
1411          * We need to call loadGTK() to ensure that the native GTK
1412          * libraries are loaded.  It is very unlikely that this call will
1413          * fail (since we've already verified native GTK support in
1414          * isSupportedLookAndFeel()), but we can throw an error in the
1415          * failure situation just in case.
1416          */
1417         Toolkit toolkit = Toolkit.getDefaultToolkit();
1418         if (toolkit instanceof UNIXToolkit &&
1419             !((UNIXToolkit)toolkit).loadGTK())
1420         {
1421             throw new InternalError("Unable to load native GTK libraries");
1422         }
1423 
1424         if (UNIXToolkit.getGtkVersion() == UNIXToolkit.GtkVersions.GTK2) {
1425             String version = AccessController.doPrivileged(
1426                     new GetPropertyAction("jdk.gtk.version"));
1427             if (version != null) {
1428                 IS_22 = version.equals("2.2");
1429             } else {
1430                 IS_22 = true;
1431             }
1432         } else if (UNIXToolkit.getGtkVersion() ==
1433                                 UNIXToolkit.GtkVersions.GTK3) {
1434             IS_3 = true;
1435         }
1436 
1437         super.initialize();
1438         inInitialize = true;
1439         loadStyles();
1440         inInitialize = false;
1441 
1442         /*
1443          * Check if system AA font settings should be used.
1444          * REMIND: See comment on isLocalDisplay() definition regarding
1445          * XRender.
1446          */
1447         gtkAAFontSettingsCond = SwingUtilities2.isLocalDisplay();
1448         aaTextInfo = new HashMap<>(2);
1449         SwingUtilities2.putAATextInfo(gtkAAFontSettingsCond, aaTextInfo);
1450     }
1451 
1452     static ReferenceQueue<GTKLookAndFeel> queue = new ReferenceQueue<GTKLookAndFeel>();
1453 
1454     private static void flushUnreferenced() {
1455         WeakPCL pcl;
1456 
1457         while ((pcl = (WeakPCL)queue.poll()) != null) {
1458             pcl.dispose();
1459         }
1460     }
1461 
1462     static class WeakPCL extends WeakReference<GTKLookAndFeel> implements
1463             PropertyChangeListener {
1464         private Toolkit kit;
1465         private String key;
1466 
1467         WeakPCL(GTKLookAndFeel target, Toolkit kit, String key) {
1468             super(target, queue);
1469             this.kit = kit;
1470             this.key = key;
1471         }
1472 
1473         public String getKey() { return key; }
1474 
1475         public void propertyChange(final PropertyChangeEvent pce) {
1476             final GTKLookAndFeel lnf = get();
1477 
1478             if (lnf == null || UIManager.getLookAndFeel() != lnf) {
1479                 // The property was GC'ed, we're no longer interested in
1480                 // PropertyChanges, remove the listener.
1481                 dispose();
1482             }
1483             else {
1484                 // We are using invokeLater here because we are getting called
1485                 // on the AWT-Motif thread which can cause a deadlock.
1486                 SwingUtilities.invokeLater(new Runnable() {
1487                     public void run() {
1488                         String name = pce.getPropertyName();
1489                         /* We are listening for GTK desktop text AA settings:
1490                          * "gnome.Xft/Antialias" and "gnome.Xft/RGBA".
1491                          * However we don't need to read these here as
1492                          * the UIDefaults reads them and this event causes
1493                          * those to be reinitialised.
1494                          */
1495                         if ("gnome.Net/ThemeName".equals(name)) {
1496                             GTKEngine.INSTANCE.themeChanged();
1497                             GTKIconFactory.resetIcons();
1498                         }
1499                         lnf.loadStyles();
1500                         Window appWindows[] = Window.getWindows();
1501                         for (int i = 0; i < appWindows.length; i++) {
1502                             SynthLookAndFeel.updateStyles(appWindows[i]);
1503                         }
1504                     }
1505                 });
1506             }
1507         }
1508 
1509         void dispose() {
1510             kit.removePropertyChangeListener(key, this);
1511         }
1512     }
1513 
1514     public boolean isSupportedLookAndFeel() {
1515         Toolkit toolkit = Toolkit.getDefaultToolkit();
1516         return (toolkit instanceof SunToolkit &&
1517                 ((SunToolkit)toolkit).isNativeGTKAvailable());
1518     }
1519 
1520     public boolean isNativeLookAndFeel() {
1521         return true;
1522     }
1523 
1524     public String getDescription() {
1525         return "GTK look and feel";
1526     }
1527 
1528     public String getName() {
1529         return "GTK look and feel";
1530     }
1531 
1532     public String getID() {
1533         return "GTK";
1534     }
1535 
1536     // Subclassed to pass in false to the superclass, we don't want to try
1537     // and load the system colors.
1538     protected void loadSystemColors(UIDefaults table, String[] systemColors, boolean useNative) {
1539         super.loadSystemColors(table, systemColors, false);
1540     }
1541 
1542     private void loadStyles() {
1543         gtkThemeName = (String)Toolkit.getDefaultToolkit().
1544                 getDesktopProperty("gnome.Net/ThemeName");
1545 
1546         setStyleFactory(getGTKStyleFactory());
1547 
1548         // If we are in initialize initializations will be
1549         // called later, don't do it now.
1550         if (!inInitialize) {
1551             UIDefaults table = UIManager.getLookAndFeelDefaults();
1552             initSystemColorDefaults(table);
1553             initComponentDefaults(table);
1554         }
1555     }
1556 
1557     private GTKStyleFactory getGTKStyleFactory() {
1558 
1559         GTKEngine engine = GTKEngine.INSTANCE;
1560         Object iconSizes = engine.getSetting(GTKEngine.Settings.GTK_ICON_SIZES);
1561         if (iconSizes instanceof String) {
1562             if (!configIconSizes((String)iconSizes)) {
1563                 System.err.println("Error parsing gtk-icon-sizes string: '" + iconSizes + "'");
1564             }
1565         }
1566 
1567         // Desktop property appears to have preference over rc font.
1568         Object fontName = Toolkit.getDefaultToolkit().getDesktopProperty(
1569                                   "gnome.Gtk/FontName");
1570 
1571        if (!(fontName instanceof String)) {
1572             fontName = engine.getSetting(GTKEngine.Settings.GTK_FONT_NAME);
1573             if (!(fontName instanceof String)) {
1574                fontName = "sans 10";
1575             }
1576         }
1577 
1578         if (styleFactory == null) {
1579             styleFactory = new GTKStyleFactory();
1580         }
1581 
1582         Font defaultFont = PangoFonts.lookupFont((String)fontName);
1583         fallbackFont = defaultFont;
1584         styleFactory.initStyles(defaultFont);
1585 
1586         return styleFactory;
1587     }
1588 
1589     private boolean configIconSizes(String sizeString) {
1590         String[] sizes = sizeString.split(":");
1591         for (int i = 0; i < sizes.length; i++) {
1592             String[] splits = sizes[i].split("=");
1593 
1594             if (splits.length != 2) {
1595                 return false;
1596             }
1597 
1598             String size = splits[0].trim().intern();
1599             if (size.length() < 1) {
1600                 return false;
1601             }
1602 
1603             splits = splits[1].split(",");
1604 
1605             if (splits.length != 2) {
1606                 return false;
1607             }
1608 
1609             String width = splits[0].trim();
1610             String height = splits[1].trim();
1611 
1612             if (width.length() < 1 || height.length() < 1) {
1613                 return false;
1614             }
1615 
1616             int w;
1617             int h;
1618 
1619             try {
1620                 w = Integer.parseInt(width);
1621                 h = Integer.parseInt(height);
1622             } catch (NumberFormatException nfe) {
1623                 return false;
1624             }
1625 
1626             if (w > 0 && h > 0) {
1627                 int type = GTKStyle.GTKStockIconInfo.getIconType(size);
1628                 GTKStyle.GTKStockIconInfo.setIconSize(type, w, h);
1629             } else {
1630                 System.err.println("Invalid size in gtk-icon-sizes: " + w + "," + h);
1631             }
1632         }
1633 
1634         return true;
1635     }
1636 
1637     /**
1638      * Returns whether or not the UIs should update their
1639      * <code>SynthStyles</code> from the <code>SynthStyleFactory</code>
1640      * when the ancestor of the Component changes.
1641      *
1642      * @return whether or not the UIs should update their
1643      * <code>SynthStyles</code> from the <code>SynthStyleFactory</code>
1644      * when the ancestor changed.
1645      */
1646     public boolean shouldUpdateStyleOnAncestorChanged() {
1647         return true;
1648     }
1649 
1650     /**
1651      * {@inheritDoc}
1652      */
1653     public LayoutStyle getLayoutStyle() {
1654         return GnomeLayoutStyle.INSTANCE;
1655     }
1656 
1657 
1658     /**
1659      * Gnome layout style.  From:
1660      * http://developer.gnome.org/projects/gup/hig/2.0/design-window.html#window-layout-spacing
1661      * You'll notice this doesn't do the radiobutton/checkbox border
1662      * adjustments that windows/metal do.  This is because gtk doesn't
1663      * provide margins/insets for checkbox/radiobuttons.
1664      */
1665     @SuppressWarnings("fallthrough")
1666     private static class GnomeLayoutStyle extends DefaultLayoutStyle {
1667         private static GnomeLayoutStyle INSTANCE = new GnomeLayoutStyle();
1668 
1669         @Override
1670         public int getPreferredGap(JComponent component1,
1671                 JComponent component2, ComponentPlacement type, int position,
1672                 Container parent) {
1673             // Checks args
1674             super.getPreferredGap(component1, component2, type, position,
1675                                   parent);
1676 
1677             switch(type) {
1678             case INDENT:
1679                 if (position == SwingConstants.EAST ||
1680                         position == SwingConstants.WEST) {
1681                     // Indent group members 12 pixels to denote hierarchy and
1682                     // association.
1683                     return 12;
1684                 }
1685                 // Fall through to related
1686             // As a basic rule of thumb, leave space between user
1687             // interface components in increments of 6 pixels, going up as
1688             // the relationship between related elements becomes more
1689             // distant. For example, between icon labels and associated
1690             // graphics within an icon, 6 pixels are adequate. Between
1691             // labels and associated components, leave 12 horizontal
1692             // pixels. For vertical spacing between groups of components,
1693             // 18 pixels is adequate.
1694             //
1695             // The first part of this is handled automatically by Icon (which
1696             // won't give you 6 pixels).
1697             case RELATED:
1698                 if (isLabelAndNonlabel(component1, component2, position)) {
1699                     return 12;
1700                 }
1701                 return 6;
1702             case UNRELATED:
1703                 return 12;
1704             }
1705             return 0;
1706         }
1707 
1708         @Override
1709         public int getContainerGap(JComponent component, int position,
1710                                    Container parent) {
1711             // Checks args
1712             super.getContainerGap(component, position, parent);
1713             // A general padding of 12 pixels is
1714             // recommended between the contents of a dialog window and the
1715             // window borders.
1716             return 12;
1717         }
1718     }
1719 }