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