1 /*
   2  * Copyright (c) 2002, 2009, 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 public class GTKLookAndFeel extends SynthLookAndFeel {
  55     private static final boolean IS_22;
  56 
  57     /**
  58      * Whether or not text is drawn antialiased.  This keys off the
  59      * desktop property 'gnome.Xft/Antialias' and 'gnome.Xft/RGBA'
  60      * We should assume ON - or some variation of ON as no GTK desktop
  61      * ships with it OFF.
  62      */
  63     static Object aaTextInfo;
  64 
  65     /**
  66      * Solaris, or Linux with Sun JDS in a CJK Locale.
  67      * Used to determine if Sun's high quality CJK fonts are present.
  68      */
  69     private static boolean isSunCJK;
  70 
  71     /*
  72      * Used to override if system (desktop) text anti-aliasing settings should
  73      * be used. The reasons for this are are is that currently its "off"
  74      * for CJK locales which is not likely to be a good universal answer, and
  75      * also its off for remote display. So this provides an unsupported
  76      * way to explicitly request that it be "on".
  77      */
  78     private static boolean gtkAAFontSettingsCond;
  79 
  80     /**
  81      * Font to use in places where there is no widget.
  82      */
  83     private Font fallbackFont;
  84 
  85     /**
  86      * If true, GTKLookAndFeel is inside the <code>initialize</code>
  87      * method.
  88      */
  89     private boolean inInitialize;
  90 
  91     /**
  92      * If true, PropertyChangeListeners have been installed for the
  93      * Toolkit.
  94      */
  95     private boolean pclInstalled;
  96 
  97     /**
  98      * StyleFactory needs to be created only the first time.
  99      */
 100     private GTKStyleFactory styleFactory;
 101 
 102     /**
 103      * Cached theme name. Used by GTKGraphicsUtils
 104      */
 105     private static String gtkThemeName = "Default";
 106 
 107     static {
 108         // Backup for specifying the version, this isn't currently documented.
 109         // If you pass in anything but 2.2 you got the 2.0 colors/look.
 110         String version = AccessController.doPrivileged(
 111                new GetPropertyAction("swing.gtk.version"));
 112         if (version != null) {
 113             IS_22 = version.equals("2.2");
 114         }
 115         else {
 116             IS_22 = true;
 117         }
 118 
 119         String language = Locale.getDefault().getLanguage();
 120         boolean cjkLocale =
 121             (Locale.CHINESE.getLanguage().equals(language) ||
 122              Locale.JAPANESE.getLanguage().equals(language) ||
 123              Locale.KOREAN.getLanguage().equals(language));
 124 
 125         if (cjkLocale) {
 126             boolean isSunDesktop = false;
 127             switch (OSInfo.getOSType()) {
 128                 case SOLARIS:
 129                     isSunDesktop = true;
 130                     break;
 131 
 132                 case LINUX:
 133                     Boolean val = AccessController.doPrivileged(
 134                                     new PrivilegedAction<Boolean>() {
 135                                         public Boolean run() {
 136                                             File f = new File("/etc/sun-release");
 137                                             return Boolean.valueOf(f.exists());
 138                                         }
 139                                     });
 140                     isSunDesktop = val.booleanValue();
 141             }
 142             if (isSunDesktop && !sun.java2d.SunGraphicsEnvironment.isOpenSolaris) {
 143                 isSunCJK = true;
 144             }
 145         }
 146     }
 147 
 148     /**
 149      * Returns true if running on system containing at least 2.2.
 150      */
 151     static boolean is2_2() {
 152         // NOTE: We're currently hard coding to use 2.2.
 153         // If we want to support both GTK 2.0 and 2.2, we'll
 154         // need to get the major/minor/micro version from the .so.
 155         // Refer to bug 4912613 for details.
 156         return IS_22;
 157     }
 158 
 159     /**
 160      * Maps a swing constant to a GTK constant.
 161      */
 162     static PositionType SwingOrientationConstantToGTK(int side) {
 163         switch (side) {
 164         case SwingConstants.LEFT:
 165             return PositionType.LEFT;
 166         case SwingConstants.RIGHT:
 167             return PositionType.RIGHT;
 168         case SwingConstants.TOP:
 169             return PositionType.TOP;
 170         case SwingConstants.BOTTOM:
 171             return PositionType.BOTTOM;
 172         }
 173         assert false : "Unknown orientation: " + side;
 174         return PositionType.TOP;
 175     }
 176 
 177     /**
 178      * Maps from Synth state to native GTK state using typesafe enumeration
 179      * StateType.  This is only used by GTKEngine.
 180      */
 181     static StateType synthStateToGTKStateType(int state) {
 182         StateType result;
 183         switch (state) {
 184             case SynthConstants.PRESSED:
 185                 result = StateType.ACTIVE;
 186                 break;
 187             case SynthConstants.MOUSE_OVER:
 188                 result = StateType.PRELIGHT;
 189                 break;
 190             case SynthConstants.SELECTED:
 191                 result = StateType.SELECTED;
 192                 break;
 193             case SynthConstants.DISABLED:
 194                 result = StateType.INSENSITIVE;
 195                 break;
 196             case SynthConstants.ENABLED:
 197             default:
 198                 result = StateType.NORMAL;
 199                 break;
 200         }
 201         return result;
 202     }
 203 
 204     /**
 205      * Maps from a Synth state to the corresponding GTK state.
 206      * The GTK states are named differently than Synth's states, the
 207      * following gives the mapping:
 208      * <table><tr><td>Synth<td>GTK
 209      * <tr><td>SynthConstants.PRESSED<td>ACTIVE
 210      * <tr><td>SynthConstants.SELECTED<td>SELECTED
 211      * <tr><td>SynthConstants.MOUSE_OVER<td>PRELIGHT
 212      * <tr><td>SynthConstants.DISABLED<td>INSENSITIVE
 213      * <tr><td>SynthConstants.ENABLED<td>NORMAL
 214      * </table>
 215      * Additionally some widgets are special cased.
 216      */
 217     static int synthStateToGTKState(Region region, int state) {
 218         if ((state & SynthConstants.PRESSED) != 0) {
 219             if (region == Region.RADIO_BUTTON
 220                     || region == Region.CHECK_BOX
 221                     || region == Region.MENU
 222                     || region == Region.MENU_ITEM
 223                     || region == Region.RADIO_BUTTON_MENU_ITEM
 224                     || region == Region.CHECK_BOX_MENU_ITEM
 225                     || region == Region.SPLIT_PANE) {
 226                 state = SynthConstants.MOUSE_OVER;
 227             } else {
 228                 state = SynthConstants.PRESSED;
 229             }
 230 
 231         } else if (region == Region.TABBED_PANE_TAB) {
 232             if ((state & SynthConstants.DISABLED) != 0) {
 233                 state = SynthConstants.DISABLED;
 234             }
 235             else if ((state & SynthConstants.SELECTED) != 0) {
 236                 state = SynthConstants.ENABLED;
 237             } else {
 238                 state = SynthConstants.PRESSED;
 239             }
 240 
 241         } else if ((state & SynthConstants.SELECTED) != 0) {
 242             if (region == Region.MENU) {
 243                 state = SynthConstants.MOUSE_OVER;
 244             } else if (region == Region.RADIO_BUTTON ||
 245                           region == Region.TOGGLE_BUTTON ||
 246                           region == Region.RADIO_BUTTON_MENU_ITEM ||
 247                           region == Region.CHECK_BOX_MENU_ITEM ||
 248                           region == Region.CHECK_BOX ||
 249                           region == Region.BUTTON) {
 250                 if ((state & SynthConstants.DISABLED) != 0) {
 251                     state = SynthConstants.DISABLED;
 252                 }
 253                 // If the button is SELECTED and is PRELIGHT we need to
 254                 // make the state MOUSE_OVER otherwise we don't paint the
 255                 // PRELIGHT.
 256                 else if ((state & SynthConstants.MOUSE_OVER) != 0) {
 257                     state = SynthConstants.MOUSE_OVER;
 258                 } else {
 259                     state = SynthConstants.PRESSED;
 260                 }
 261             } else {
 262                 state = SynthConstants.SELECTED;
 263             }
 264         }
 265 
 266         else if ((state & SynthConstants.MOUSE_OVER) != 0) {
 267             state = SynthConstants.MOUSE_OVER;
 268         }
 269         else if ((state & SynthConstants.DISABLED) != 0) {
 270             state = SynthConstants.DISABLED;
 271         }
 272         else {
 273             if (region == Region.SLIDER_TRACK) {
 274                 state = SynthConstants.PRESSED;
 275             } else {
 276                 state = SynthConstants.ENABLED;
 277             }
 278         }
 279         return state;
 280     }
 281 
 282     static boolean isText(Region region) {
 283         // These Regions treat FOREGROUND as TEXT.
 284         return (region == Region.TEXT_FIELD ||
 285                 region == Region.FORMATTED_TEXT_FIELD ||
 286                 region == Region.LIST ||
 287                 region == Region.PASSWORD_FIELD ||
 288                 region == Region.SPINNER ||
 289                 region == Region.TABLE ||
 290                 region == Region.TEXT_AREA ||
 291                 region == Region.TEXT_FIELD ||
 292                 region == Region.TEXT_PANE ||
 293                 region == Region.TREE);
 294     }
 295 
 296     public UIDefaults getDefaults() {
 297         // We need to call super for basic's properties file.
 298         UIDefaults table = super.getDefaults();
 299 
 300         // SynthTabbedPaneUI supports rollover on tabs, GTK does not
 301         table.put("TabbedPane.isTabRollover", Boolean.FALSE);
 302 
 303         // Prevents Synth from setting text AA by itself
 304         table.put("Synth.doNotSetTextAA", true);
 305 
 306         initResourceBundle(table);
 307         // For compatibility with apps expecting certain defaults we'll
 308         // populate the table with the values from basic.
 309         initSystemColorDefaults(table);
 310         initComponentDefaults(table);
 311         installPropertyChangeListeners();
 312         return table;
 313     }
 314 
 315     private void installPropertyChangeListeners() {
 316         if(!pclInstalled) {
 317             Toolkit kit = Toolkit.getDefaultToolkit();
 318             WeakPCL pcl = new WeakPCL(this, kit, "gnome.Net/ThemeName");
 319             kit.addPropertyChangeListener(pcl.getKey(), pcl);
 320             pcl = new WeakPCL(this, kit, "gnome.Gtk/FontName");
 321             kit.addPropertyChangeListener(pcl.getKey(), pcl);
 322             pcl = new WeakPCL(this, kit, "gnome.Xft/DPI");
 323             kit.addPropertyChangeListener(pcl.getKey(), pcl);
 324 
 325             flushUnreferenced();
 326             pclInstalled = true;
 327         }
 328     }
 329 
 330     private void initResourceBundle(UIDefaults table) {
 331         table.addResourceBundle("com.sun.java.swing.plaf.gtk.resources.gtk");
 332     }
 333 
 334     protected void initComponentDefaults(UIDefaults table) {
 335         // For compatibility with apps expecting certain defaults we'll
 336         // populate the table with the values from basic.
 337         super.initComponentDefaults(table);
 338 
 339         Integer zero =  Integer.valueOf(0);
 340         Object zeroBorder = new sun.swing.SwingLazyValue(
 341             "javax.swing.plaf.BorderUIResource$EmptyBorderUIResource",
 342             new Object[] {zero, zero, zero, zero});
 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     private static class GnomeLayoutStyle extends DefaultLayoutStyle {
1687         private static GnomeLayoutStyle INSTANCE = new GnomeLayoutStyle();
1688 
1689         @Override
1690         public int getPreferredGap(JComponent component1,
1691                 JComponent component2, ComponentPlacement type, int position,
1692                 Container parent) {
1693             // Checks args
1694             super.getPreferredGap(component1, component2, type, position,
1695                                   parent);
1696 
1697             switch(type) {
1698             case INDENT:
1699                 if (position == SwingConstants.EAST ||
1700                         position == SwingConstants.WEST) {
1701                     // Indent group members 12 pixels to denote hierarchy and
1702                     // association.
1703                     return 12;
1704                 }
1705                 // Fall through to related
1706             // As a basic rule of thumb, leave space between user
1707             // interface components in increments of 6 pixels, going up as
1708             // the relationship between related elements becomes more
1709             // distant. For example, between icon labels and associated
1710             // graphics within an icon, 6 pixels are adequate. Between
1711             // labels and associated components, leave 12 horizontal
1712             // pixels. For vertical spacing between groups of components,
1713             // 18 pixels is adequate.
1714             //
1715             // The first part of this is handled automatically by Icon (which
1716             // won't give you 6 pixels).
1717             case RELATED:
1718                 if (isLabelAndNonlabel(component1, component2, position)) {
1719                     return 12;
1720                 }
1721                 return 6;
1722             case UNRELATED:
1723                 return 12;
1724             }
1725             return 0;
1726         }
1727 
1728         @Override
1729         public int getContainerGap(JComponent component, int position,
1730                                    Container parent) {
1731             // Checks args
1732             super.getContainerGap(component, position, parent);
1733             // A general padding of 12 pixels is
1734             // recommended between the contents of a dialog window and the
1735             // window borders.
1736             return 12;
1737         }
1738     }
1739 }