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