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