1 7 8 package com.sun.java.swing.plaf.gtk; 9 10 import java.util.*; 11 import java.io.*; 12 import java.awt.*; 13 import java.util.regex.PatternSyntaxException ; 14 import javax.swing.plaf.ColorUIResource ; 15 import java.security.AccessController ; 16 import sun.security.action.GetPropertyAction; 17 import javax.swing.plaf.synth.SynthConstants ; 18 19 23 class GTKParser { 24 25 private ArrayList freeScanners = new ArrayList(); 26 27 private HashMap namedStyles = new HashMap(); 28 29 private ArrayList assignments = new ArrayList(); 30 31 private HashMap settings = new HashMap(); 32 33 private File[] pixmapPaths = null; 34 35 private ArrayList dirStack = new ArrayList(); 36 37 private HashMap engineParsers = new HashMap(); 38 39 { 42 engineParsers.put("pixmap", "com.sun.java.swing.plaf.gtk.PixmapEngineParser"); 43 engineParsers.put("bluecurve", "com.sun.java.swing.plaf.gtk.BluecurveEngineParser"); 44 engineParsers.put("wonderland", "com.sun.java.swing.plaf.gtk.BluecurveEngineParser"); 45 engineParsers.put("blueprint", "com.sun.java.swing.plaf.gtk.BlueprintEngineParser"); 46 } 47 48 private GTKScanner scanner; 49 50 private final String CWD = (String )AccessController.doPrivileged( 51 new GetPropertyAction("user.dir")); 52 53 static class Symbol { 54 55 public String name; 56 public int val; 57 58 public Symbol(String name, int val) { 59 this.name = name; 60 this.val = val; 61 } 62 } 63 64 private static final Symbol SYMBOL_INVALID = new Symbol("invalid", GTKScanner.TOKEN_LAST); 65 private static final Symbol SYMBOL_INCLUDE = new Symbol("include", SYMBOL_INVALID.val + 1); 66 private static final Symbol SYMBOL_NORMAL = new Symbol("NORMAL", SYMBOL_INCLUDE.val + 1); 67 private static final Symbol SYMBOL_ACTIVE = new Symbol("ACTIVE", SYMBOL_NORMAL.val + 1); 68 private static final Symbol SYMBOL_PRELIGHT = new Symbol("PRELIGHT", SYMBOL_ACTIVE.val + 1); 69 private static final Symbol SYMBOL_SELECTED = new Symbol("SELECTED", SYMBOL_PRELIGHT.val + 1); 70 private static final Symbol SYMBOL_INSENSITIVE = new Symbol("INSENSITIVE", SYMBOL_SELECTED.val + 1); 71 private static final Symbol SYMBOL_FG = new Symbol("fg", SYMBOL_INSENSITIVE.val + 1); 72 private static final Symbol SYMBOL_BG = new Symbol("bg", SYMBOL_FG.val + 1); 73 private static final Symbol SYMBOL_TEXT = new Symbol("text", SYMBOL_BG.val + 1); 74 private static final Symbol SYMBOL_BASE = new Symbol("base", SYMBOL_TEXT.val + 1); 75 private static final Symbol SYMBOL_XTHICKNESS = new Symbol("xthickness", SYMBOL_BASE.val + 1); 76 private static final Symbol SYMBOL_YTHICKNESS = new Symbol("ythickness", SYMBOL_XTHICKNESS.val + 1); 77 private static final Symbol SYMBOL_FONT = new Symbol("font", SYMBOL_YTHICKNESS.val + 1); 78 private static final Symbol SYMBOL_FONTSET = new Symbol("fontset", SYMBOL_FONT.val + 1); 79 private static final Symbol SYMBOL_FONT_NAME = new Symbol("font_name", SYMBOL_FONTSET.val + 1); 80 private static final Symbol SYMBOL_BG_PIXMAP = new Symbol("bg_pixmap", SYMBOL_FONT_NAME.val + 1); 81 private static final Symbol SYMBOL_PIXMAP_PATH = new Symbol("pixmap_path", SYMBOL_BG_PIXMAP.val + 1); 82 private static final Symbol SYMBOL_STYLE = new Symbol("style", SYMBOL_PIXMAP_PATH.val + 1); 83 private static final Symbol SYMBOL_BINDING = new Symbol("binding", SYMBOL_STYLE.val + 1); 84 private static final Symbol SYMBOL_BIND = new Symbol("bind", SYMBOL_BINDING.val + 1); 85 private static final Symbol SYMBOL_WIDGET = new Symbol("widget", SYMBOL_BIND.val + 1); 86 private static final Symbol SYMBOL_WIDGET_CLASS = new Symbol("widget_class", SYMBOL_WIDGET.val + 1); 87 private static final Symbol SYMBOL_CLASS = new Symbol("class", SYMBOL_WIDGET_CLASS.val + 1); 88 private static final Symbol SYMBOL_LOWEST = new Symbol("lowest", SYMBOL_CLASS.val + 1); 89 private static final Symbol SYMBOL_GTK = new Symbol("gtk", SYMBOL_LOWEST.val + 1); 90 private static final Symbol SYMBOL_APPLICATION = new Symbol("application", SYMBOL_GTK.val + 1); 91 private static final Symbol SYMBOL_THEME = new Symbol("theme", SYMBOL_APPLICATION.val + 1); 92 private static final Symbol SYMBOL_RC = new Symbol("rc", SYMBOL_THEME.val + 1); 93 private static final Symbol SYMBOL_HIGHEST = new Symbol("highest", SYMBOL_RC.val + 1); 94 private static final Symbol SYMBOL_ENGINE = new Symbol("engine", SYMBOL_HIGHEST.val + 1); 95 private static final Symbol SYMBOL_MODULE_PATH = new Symbol("module_path", SYMBOL_ENGINE.val + 1); 96 private static final Symbol SYMBOL_IM_MODULE_PATH = new Symbol("im_module_path", SYMBOL_MODULE_PATH.val + 1); 97 private static final Symbol SYMBOL_IM_MODULE_FILE = new Symbol("im_module_file", SYMBOL_IM_MODULE_PATH.val + 1); 98 private static final Symbol SYMBOL_STOCK = new Symbol("stock", SYMBOL_IM_MODULE_FILE.val + 1); 99 private static final Symbol SYMBOL_LTR = new Symbol("LTR", SYMBOL_STOCK.val + 1); 100 private static final Symbol SYMBOL_RTL = new Symbol("RTL", SYMBOL_LTR.val + 1); 101 private static final Symbol SYMBOL_LAST = new Symbol("last", SYMBOL_RTL.val + 1); 102 103 private static final Symbol[] symbols = { 104 SYMBOL_INCLUDE, SYMBOL_NORMAL, SYMBOL_ACTIVE, SYMBOL_PRELIGHT, 105 SYMBOL_SELECTED, SYMBOL_INSENSITIVE, SYMBOL_FG, SYMBOL_BG, 106 SYMBOL_TEXT, SYMBOL_BASE, SYMBOL_XTHICKNESS, SYMBOL_YTHICKNESS, 107 SYMBOL_FONT, SYMBOL_FONTSET, SYMBOL_FONT_NAME, SYMBOL_BG_PIXMAP, 108 SYMBOL_PIXMAP_PATH, SYMBOL_STYLE, SYMBOL_BINDING, SYMBOL_BIND, 109 SYMBOL_WIDGET, SYMBOL_WIDGET_CLASS, SYMBOL_CLASS, SYMBOL_LOWEST, 110 SYMBOL_GTK, SYMBOL_APPLICATION, SYMBOL_THEME, SYMBOL_RC, 111 SYMBOL_HIGHEST, SYMBOL_ENGINE, SYMBOL_MODULE_PATH, 112 SYMBOL_IM_MODULE_FILE, SYMBOL_STOCK, SYMBOL_LTR, SYMBOL_RTL 113 }; 114 115 private static class StyleInfo { 116 String name; 117 118 static final int NUM_STATES = 5; 119 120 static final int NORMAL = 0; 121 static final int PRELIGHT = 1; 122 static final int ACTIVE = 2; 123 static final int INSENSITIVE = 3; 124 static final int SELECTED = 4; 125 126 Color[] fg = new Color[NUM_STATES]; 127 Color[] bg = new Color[NUM_STATES]; 128 Color[] text = new Color[NUM_STATES]; 129 Color[] base = new Color[NUM_STATES]; 130 String [] bgPixmapName = new String [NUM_STATES]; 131 132 Font font = null; 133 134 int xThickness = GTKStyle.UNDEFINED_THICKNESS; 135 int yThickness = GTKStyle.UNDEFINED_THICKNESS; 136 137 ArrayList stocks = null; 141 142 CircularIdentityList props = null; 143 144 EngineInfo engineInfo = null; 145 146 private GTKStyle cachedStyle = null; 147 private static GTKStyle EMPTY_STYLE = new GTKStyle(); 148 149 StyleInfo(String name) { 150 this.name = name; 151 } 152 153 private void initStocksIfNecessary() { 154 if (stocks == null) { 155 stocks = new ArrayList(); 156 stocks.add(new HashMap()); 158 } 159 } 160 161 void addStockItem(String id, GTKStyle.GTKIconSource[] sources) { 162 initStocksIfNecessary(); 163 164 GTKStyle.GTKStockIconInfo iconInfo = new GTKStyle.GTKStockIconInfo(id, sources); 165 166 HashMap map = (HashMap)stocks.get(0); 167 map.put(id, iconInfo); 168 } 169 170 void addProperty(String klass, String prop, Object value) { 171 if (props == null) { 172 props = new CircularIdentityList(); 173 } 174 175 CircularIdentityList subList = (CircularIdentityList)props.get(klass); 176 177 if (subList == null) { 178 subList = new CircularIdentityList(); 179 props.set(klass, subList); 180 } 181 182 subList.set(prop, value); 183 } 184 185 void copyDataFrom(StyleInfo other) { 186 for (int i = 0; i < NUM_STATES; i++) { 187 fg[i] = other.fg[i]; 188 bg[i] = other.bg[i]; 189 text[i] = other.text[i]; 190 base[i] = other.base[i]; 191 bgPixmapName[i] = other.bgPixmapName[i]; 192 } 193 194 xThickness = other.xThickness; 195 yThickness = other.yThickness; 196 font = other.font; 197 198 if (other.stocks != null) { 199 initStocksIfNecessary(); 200 stocks.addAll(other.stocks); 201 } 202 203 if (props == null) { 204 props = GTKStyle.cloneClassSpecificValues(other.props); 205 } else { 206 GTKStyle.addClassSpecificValues(other.props, props); 207 } 208 } 209 210 GTKStyle toGTKStyle() { 211 if (cachedStyle != null) { 212 return cachedStyle; 213 } 214 215 ArrayList stateInfos = new ArrayList(); 216 217 for (int i = 0; i < NUM_STATES; i++) { 218 Color[] colors = null; 219 220 if (fg[i] != null 221 || bg[i] != null 222 || text[i] != null 223 || base[i] != null) { 224 colors = new Color[GTKColorType.MAX_COUNT]; 225 colors[GTKColorType.FOREGROUND.getID()] = fg[i]; 226 colors[GTKColorType.BACKGROUND.getID()] = bg[i]; 227 colors[GTKColorType.TEXT_FOREGROUND.getID()] = text[i]; 228 colors[GTKColorType.TEXT_BACKGROUND.getID()] = base[i]; 229 } 230 231 if (colors != null || bgPixmapName[i] != null) { 232 GTKStyle.GTKStateInfo stateInfo = 233 new GTKStyle.GTKStateInfo(toSynthState(i), 234 null, colors, bgPixmapName[i]); 235 stateInfos.add(stateInfo); 236 } 237 } 238 239 GTKStyle.GTKStateInfo[] infoArray = null; 240 if (stateInfos.size() != 0) { 241 infoArray = new GTKStyle.GTKStateInfo[stateInfos.size()]; 242 infoArray = (GTKStyle.GTKStateInfo[])stateInfos.toArray(infoArray); 243 } 244 245 GTKStyle.GTKStockIconInfo[] stockArray = stocksToArray(); 246 247 if (engineInfo != null) { 249 cachedStyle = engineInfo.constructGTKStyle(infoArray, 250 props, 251 font, 252 xThickness, 253 yThickness, 254 stockArray); 255 } else if (infoArray != null 257 || stockArray != null 258 || props != null 259 || font != null 260 || xThickness != GTKStyle.UNDEFINED_THICKNESS 261 || yThickness != GTKStyle.UNDEFINED_THICKNESS) { 262 cachedStyle = new GTKStyle(infoArray, 263 props, 264 font, 265 xThickness, 266 yThickness, 267 stockArray); 268 } else { 269 cachedStyle = EMPTY_STYLE; 270 } 271 272 return cachedStyle; 273 } 274 275 private GTKStyle.GTKStockIconInfo[] stocksToArray() { 276 if (stocks == null) { 277 return null; 278 } 279 280 ArrayList tmpList = new ArrayList(); 281 282 HashMap[] maps = new HashMap[stocks.size()]; 283 maps = (HashMap[])stocks.toArray(maps); 284 285 for (int i = 0; i < maps.length; i++) { 286 tmpList.addAll(maps[i].values()); 287 } 288 289 GTKStyle.GTKStockIconInfo[] retVal = new GTKStyle.GTKStockIconInfo[tmpList.size()]; 290 retVal = (GTKStyle.GTKStockIconInfo[])tmpList.toArray(retVal); 291 292 return retVal; 293 } 294 295 private static int toSynthState(int ourState) { 296 switch(ourState) { 297 case NORMAL: return SynthConstants.ENABLED; 298 case PRELIGHT: return SynthConstants.MOUSE_OVER; 299 case ACTIVE: return SynthConstants.PRESSED; 300 case INSENSITIVE: return SynthConstants.DISABLED; 301 case SELECTED: return SynthConstants.SELECTED; 302 } 303 304 return SynthConstants.ENABLED; 306 } 307 } 308 309 static abstract class EngineInfo { 310 private String engineName; 311 312 abstract GTKStyle constructGTKStyle(GTKStyle.GTKStateInfo[] infoArray, 313 CircularIdentityList props, 314 Font font, 315 int xThickness, 316 int yThickness, 317 GTKStyle.GTKStockIconInfo[] stockArray); 318 } 319 320 private static class Assignment { 321 int type; 322 String pattern; 323 StyleInfo info; 324 325 Assignment(int type, String pattern, StyleInfo info) { 326 this.type = type; 327 this.pattern = pattern; 328 this.info = info; 329 } 330 331 public String toString() { 332 String sVal = ""; 333 334 switch(type) { 335 case GTKStyleFactory.WIDGET: sVal = "widget, "; break; 336 case GTKStyleFactory.WIDGET_CLASS: sVal = "widget_class, "; break; 337 case GTKStyleFactory.CLASS: sVal = "class, "; break; 338 } 339 340 sVal += pattern + ", "; 341 sVal += info.name; 342 343 return sVal; 344 } 345 } 346 347 private static Symbol getSymbol(int symbol) { 348 if (symbol > SYMBOL_INVALID.val && symbol < SYMBOL_LAST.val) { 349 for (int i = 0; i < symbols.length; i++) { 350 if (symbols[i].val == symbol) { 351 return symbols[i]; 352 } 353 } 354 } 355 356 return null; 357 } 358 359 public GTKParser() { 360 freeScanners.add(createScanner()); 361 } 362 363 public void parseString(String str) throws IOException { 364 StringReader reader = new StringReader(str); 365 parseReader(reader, "-"); 366 } 367 368 public void parseFile(File file, String name) throws IOException { 369 if (!file.canRead() || !file.isFile()) { 370 return; 371 } 372 373 File parent = file.getParentFile(); 374 if (parent == null) { 375 parent = new File(CWD); 376 } 377 378 dirStack.add(parent); 379 380 try { 381 BufferedReader reader = new BufferedReader(new FileReader(file)); 382 parseReader(reader, name); 383 } finally { 384 dirStack.remove(dirStack.size() - 1); 385 } 386 387 } 390 391 private void parseReader(Reader reader, String name) throws IOException { 392 int len = freeScanners.size(); 393 394 if (len == 0) { 395 scanner = createScanner(); 396 } else { 397 scanner = (GTKScanner)freeScanners.remove(len - 1); 398 } 399 400 scanner.scanReader(reader, name); 401 402 try { 403 parseCurrent(); 404 } finally { 405 scanner.clearScanner(); 406 freeScanners.add(scanner); 407 } 408 } 409 410 private static GTKScanner createScanner() { 411 GTKScanner scanner = new GTKScanner(); 412 413 scanner.caseSensitive = true; 415 scanner.scanBinary = true; 416 scanner.scanHexDollar = true; 417 scanner.symbol2Token = true; 418 419 for (int i = 0; i < symbols.length; i++) { 420 scanner.addSymbol(symbols[i].name, symbols[i].val); 421 } 422 423 return scanner; 424 } 425 426 public void loadStylesInto(GTKStyleFactory factory) { 427 Assignment[] assigns = new Assignment[assignments.size()]; 428 assigns = (Assignment[])assignments.toArray(assigns); 429 430 for (int i = 0; i < assigns.length; i++) { 431 Assignment assign = assigns[i]; 432 GTKStyle style = assign.info.toGTKStyle(); 433 434 if (style != StyleInfo.EMPTY_STYLE) { 435 try { 436 factory.addStyle(style, assign.pattern, assign.type); 437 } catch (PatternSyntaxException pse) { 438 } 440 } 441 } 442 } 443 444 public HashMap getGTKSettings() { 445 return settings; 446 } 447 448 public void clearParser() { 449 namedStyles.clear(); 450 settings.clear(); 451 assignments.clear(); 452 dirStack.clear(); 453 pixmapPaths = null; 454 } 455 456 457 458 460 private void parseCurrent() throws IOException { 461 while (true) { 462 if (scanner.peekNextToken() == GTKScanner.TOKEN_EOF) { 463 break; 464 } 465 466 int expected = parseStatement(); 467 468 if (expected != GTKScanner.TOKEN_NONE) { 469 String symbolName = null; 470 String msg = null; 471 472 if (scanner.currScope == 0) { 473 Symbol lookup; 474 475 lookup = getSymbol(expected); 476 if (lookup != null) { 477 msg = "e.g. `" + lookup.name + "'"; 478 } 479 480 lookup = getSymbol(scanner.currToken); 481 if (lookup != null) { 482 symbolName = lookup.name; 483 } 484 } 485 486 scanner.unexpectedToken(expected, symbolName, msg, true); 487 break; 488 } 489 } 490 } 491 492 private int parseStatement() throws IOException { 493 int token; 494 495 token = scanner.peekNextToken(); 496 if (token == SYMBOL_INCLUDE.val) { 497 return parseInclude(); 498 } else if (token == SYMBOL_STYLE.val) { 499 return parseStyle(); 500 } else if (token == SYMBOL_BINDING.val) { 501 return parseBinding(); 502 } else if (token == SYMBOL_PIXMAP_PATH.val) { 503 return parsePixmapPath(); 504 } else if (token == SYMBOL_WIDGET.val 505 || token == SYMBOL_WIDGET_CLASS.val 506 || token == SYMBOL_CLASS.val) { 507 return parseAssignment(token); 508 } else if (token == SYMBOL_MODULE_PATH.val) { 509 return parseModulePath(); 510 } else if (token == SYMBOL_IM_MODULE_FILE.val) { 511 return parseIMModuleFile(); 512 } else if (token == GTKScanner.TOKEN_IDENTIFIER) { 513 return parseIdentifier(); 514 } 515 516 scanner.getToken(); 517 return SYMBOL_STYLE.val; 518 } 519 520 private int parseInclude() throws IOException { 521 int token; 522 523 token = scanner.getToken(); 524 if (token != SYMBOL_INCLUDE.val) { 525 return SYMBOL_INCLUDE.val; 526 } 527 528 token = scanner.getToken(); 529 if (token != GTKScanner.TOKEN_STRING) { 530 return GTKScanner.TOKEN_STRING; 531 } 532 533 File parseFile = null; 534 535 String name = scanner.currValue.stringVal; 536 File file = new File(name); 537 538 if (file.isAbsolute()) { 539 parseFile = file; 540 } else { 541 File[] dirs = new File[dirStack.size()]; 542 dirs = (File[])dirStack.toArray(dirs); 543 544 for (int i = dirs.length - 1; i >= 0; i--) { 545 file = new File(dirs[i], name); 546 if (file.exists()) { 547 parseFile = file; 548 break; 549 } 550 } 551 } 552 553 if (parseFile == null) { 554 scanner.printMessage("Unable to find include file: \"" + name + "\"", false); 555 } else { 556 GTKScanner savedScanner = scanner; 558 559 try { 560 parseFile(file, name); 561 } catch (IOException ioe) { 562 savedScanner.printMessage("(" + ioe.toString() 563 + ") while parsing include file: \"" 564 + name 565 + "\"", false); 566 } 567 568 scanner = savedScanner; 570 } 571 572 return GTKScanner.TOKEN_NONE; 573 } 574 575 private int parseStyle() throws IOException { 576 int token; 577 578 token = scanner.getToken(); 579 if (token != SYMBOL_STYLE.val) { 580 return SYMBOL_STYLE.val; 581 } 582 583 token = scanner.getToken(); 584 if (token != GTKScanner.TOKEN_STRING) { 585 return GTKScanner.TOKEN_STRING; 586 } 587 588 StyleInfo info = (StyleInfo)namedStyles.get(scanner.currValue.stringVal); 589 590 if (info == null) { 591 info = new StyleInfo(scanner.currValue.stringVal); 592 } 593 594 token = scanner.peekNextToken(); 595 if (token == GTKScanner.TOKEN_EQUAL_SIGN) { 596 token = scanner.getToken(); 597 token = scanner.getToken(); 598 599 if (token != GTKScanner.TOKEN_STRING) { 600 return GTKScanner.TOKEN_STRING; 601 } 602 603 StyleInfo parent = (StyleInfo)namedStyles.get(scanner.currValue.stringVal); 604 if (parent != null) { 605 info.copyDataFrom(parent); 606 } 607 } 608 609 token = scanner.getToken(); 610 if (token != GTKScanner.TOKEN_LEFT_CURLY) { 611 return GTKScanner.TOKEN_LEFT_CURLY; 612 } 613 614 token = scanner.peekNextToken(); 615 while (token != GTKScanner.TOKEN_RIGHT_CURLY) { 616 if (token == SYMBOL_FG.val 617 || token == SYMBOL_BG.val 618 || token == SYMBOL_TEXT.val 619 || token == SYMBOL_BASE.val) { 620 token = parseColorSetting(token, info); 621 } else if (token == SYMBOL_XTHICKNESS.val 622 || token == SYMBOL_YTHICKNESS.val) { 623 token = parseThickness(token, info); 624 } else if (token == SYMBOL_BG_PIXMAP.val) { 625 token = parseBGPixmap(info); 626 } else if (token == SYMBOL_FONT.val 627 || token == SYMBOL_FONTSET.val 628 || token == SYMBOL_FONT_NAME.val) { 629 token = parseFont(token, info); 630 } else if (token == SYMBOL_ENGINE.val) { 631 token = parseEngine(info); 632 } else if (token == SYMBOL_STOCK.val) { 633 token = parseStock(info); 634 } else if (token == GTKScanner.TOKEN_IDENTIFIER) { 635 token = parseIdentifierInStyle(info); 636 } else { 637 scanner.getToken(); 638 token = GTKScanner.TOKEN_RIGHT_CURLY; 639 } 640 641 if (token != GTKScanner.TOKEN_NONE) { 642 return token; 643 } 644 645 token = scanner.peekNextToken(); 646 } 647 648 token = scanner.getToken(); 649 if (token != GTKScanner.TOKEN_RIGHT_CURLY) { 650 return GTKScanner.TOKEN_RIGHT_CURLY; 651 } 652 653 namedStyles.put(info.name, info); 654 655 return GTKScanner.TOKEN_NONE; 656 } 657 658 private int parseBinding() throws IOException { 659 int token; 660 661 token = scanner.getToken(); 662 if (token != SYMBOL_BINDING.val) { 663 return SYMBOL_BINDING.val; 664 } 665 666 token = scanner.getToken(); 667 if (token != GTKScanner.TOKEN_STRING) { 668 return GTKScanner.TOKEN_STRING; 669 } 670 671 token = ignoreBlock(); 672 if (token != GTKScanner.TOKEN_NONE) { 673 return token; 674 } 675 676 scanner.printMessage("Binding specification is unsupported, ignoring", false); 677 678 return GTKScanner.TOKEN_NONE; 679 } 680 681 private int parsePixmapPath() throws IOException { 682 int token; 683 684 token = scanner.getToken(); 685 if (token != SYMBOL_PIXMAP_PATH.val) { 686 return SYMBOL_PIXMAP_PATH.val; 687 } 688 689 token = scanner.getToken(); 690 if (token != GTKScanner.TOKEN_STRING) { 691 return GTKScanner.TOKEN_STRING; 692 } 693 694 pixmapPaths = null; 695 696 ArrayList tempPaths = new ArrayList(); 697 698 StringTokenizer tok = new StringTokenizer(scanner.currValue.stringVal, File.pathSeparator); 699 while (tok.hasMoreTokens()) { 700 String path = tok.nextToken(); 701 File file = new File(path); 702 if (file.isAbsolute()) { 703 tempPaths.add(file); 704 } else { 705 scanner.printMessage("Pixmap path element: \"" + path + "\" must be absolute", false); 706 } 707 } 708 709 if (tempPaths.size() > 0) { 710 pixmapPaths = new File[tempPaths.size()]; 711 pixmapPaths = (File[])tempPaths.toArray(pixmapPaths); 712 } 713 714 return GTKScanner.TOKEN_NONE; 715 } 716 717 private int parseAssignment(int expVal) throws IOException { 718 int token; 719 720 token = scanner.getToken(); 721 if (token != expVal) { 722 return expVal; 723 } 724 725 int type; 726 String pattern; 727 StyleInfo info; 728 729 boolean isBinding; 730 731 if (token == SYMBOL_WIDGET.val) { 732 type = GTKStyleFactory.WIDGET; 733 } else if (token == SYMBOL_WIDGET_CLASS.val) { 734 type = GTKStyleFactory.WIDGET_CLASS; 735 } else if (token == SYMBOL_CLASS.val) { 736 type = GTKStyleFactory.CLASS; 737 } else { 738 return SYMBOL_WIDGET_CLASS.val; 739 } 740 741 token = scanner.getToken(); 742 if (token != GTKScanner.TOKEN_STRING) { 743 return GTKScanner.TOKEN_STRING; 744 } 745 746 pattern = scanner.currValue.stringVal; 747 748 token = scanner.getToken(); 749 if (token == SYMBOL_STYLE.val) { 750 isBinding = false; 751 } else if (token == SYMBOL_BINDING.val) { 752 isBinding = true; 753 } else { 754 return SYMBOL_STYLE.val; 755 } 756 757 token = scanner.peekNextToken(); 758 if (token == ':') { 759 token = scanner.getToken(); 760 761 token = scanner.getToken(); 762 if (token != SYMBOL_LOWEST.val 763 && token != SYMBOL_GTK.val 764 && token != SYMBOL_APPLICATION.val 765 && token != SYMBOL_THEME.val 766 && token != SYMBOL_RC.val 767 && token != SYMBOL_HIGHEST.val) { 768 return SYMBOL_APPLICATION.val; 769 } 770 771 scanner.printMessage("Priority specification is unsupported, ignoring", false); 772 } 773 774 token = scanner.getToken(); 775 if (token != GTKScanner.TOKEN_STRING) { 776 return GTKScanner.TOKEN_STRING; 777 } 778 779 if (isBinding) { 782 scanner.printMessage("Binding assignment is unsupported, ignoring", false); 784 } else { 785 info = (StyleInfo)namedStyles.get(scanner.currValue.stringVal); 786 if (info == null) { 787 return GTKScanner.TOKEN_STRING; 788 } 789 790 Assignment assignment = new Assignment(type, pattern, info); 791 assignments.add(assignment); 792 } 793 794 return GTKScanner.TOKEN_NONE; 795 } 796 797 private int parseModulePath() throws IOException { 798 int token; 799 800 token = scanner.getToken(); 801 if (token != SYMBOL_MODULE_PATH.val) { 802 return SYMBOL_MODULE_PATH.val; 803 } 804 805 token = scanner.getToken(); 806 if (token != GTKScanner.TOKEN_STRING) { 807 return GTKScanner.TOKEN_STRING; 808 } 809 810 scanner.printMessage("module_path directive is now ignored", false); 811 812 return GTKScanner.TOKEN_NONE; 813 } 814 815 private int parseIMModuleFile() throws IOException { 816 int token; 817 818 token = scanner.getToken(); 819 if (token != SYMBOL_IM_MODULE_FILE.val) { 820 return SYMBOL_IM_MODULE_FILE.val; 821 } 822 823 token = scanner.getToken(); 824 if (token != GTKScanner.TOKEN_STRING) { 825 return GTKScanner.TOKEN_STRING; 826 } 827 828 scanner.printMessage("im_module_file directive is unsupported, ignoring", false); 829 830 return GTKScanner.TOKEN_NONE; 831 } 832 833 private int parseIdentifier() throws IOException { 834 int token; 835 836 token = scanner.getToken(); 837 if (token != GTKScanner.TOKEN_IDENTIFIER) { 838 return GTKScanner.TOKEN_IDENTIFIER; 839 } 840 841 String prop; 842 Object [] value = new Object [1]; 843 844 StringBuffer buf = new StringBuffer (scanner.currValue.stringVal); 845 846 String validChars = GTKScanner.CHARS_A_2_Z 847 + GTKScanner.CHARS_a_2_z 848 + GTKScanner.CHARS_DIGITS 849 + "-"; 850 851 int len = buf.length(); 853 for (int i = 0; i < len; i++) { 854 if (validChars.indexOf(buf.charAt(i)) == -1) { 855 buf.setCharAt(i, '-'); 856 } 857 } 858 859 prop = buf.toString().intern(); 860 861 token = parsePropertyAssignment(value); 862 if (token != GTKScanner.TOKEN_NONE) { 863 return token; 864 } 865 866 settings.put(prop, value[0]); 867 868 return GTKScanner.TOKEN_NONE; 869 } 870 871 private int parseColorSetting(int expVal, StyleInfo info) throws IOException { 872 int token; 873 874 token = scanner.getToken(); 875 if (token != expVal) { 876 return expVal; 877 } 878 879 Color[] cols = null; 880 881 if (token == SYMBOL_FG.val) { 882 cols = info.fg; 883 } else if (token == SYMBOL_BG.val) { 884 cols = info.bg; 885 } else if (token == SYMBOL_TEXT.val) { 886 cols = info.text; 887 } else if (token == SYMBOL_BASE.val) { 888 cols = info.base; 889 } else { 890 return SYMBOL_FG.val; 891 } 892 893 int[] state = new int[1]; 894 token = parseState(state); 895 896 if (token != GTKScanner.TOKEN_NONE) { 897 return token; 898 } 899 900 token = scanner.getToken(); 901 if (token != GTKScanner.TOKEN_EQUAL_SIGN) { 902 return GTKScanner.TOKEN_EQUAL_SIGN; 903 } 904 905 return parseColor(scanner, cols, state[0]); 906 } 907 908 private int parseState(int[] retVal) throws IOException { 909 int token; 910 911 token = scanner.getToken(); 912 if (token != GTKScanner.TOKEN_LEFT_BRACE) { 913 return GTKScanner.TOKEN_LEFT_BRACE; 914 } 915 916 token = scanner.getToken(); 917 if (token == SYMBOL_NORMAL.val) { 918 retVal[0] = StyleInfo.NORMAL; 919 } else if (token == SYMBOL_ACTIVE.val) { 920 retVal[0] = StyleInfo.ACTIVE; 921 } else if (token == SYMBOL_PRELIGHT.val) { 922 retVal[0] = StyleInfo.PRELIGHT; 923 } else if (token == SYMBOL_SELECTED.val) { 924 retVal[0] = StyleInfo.SELECTED; 925 } else if (token == SYMBOL_INSENSITIVE.val) { 926 retVal[0] = StyleInfo.INSENSITIVE; 927 } else { 928 return SYMBOL_NORMAL.val; 929 } 930 931 token = scanner.getToken(); 932 if (token != GTKScanner.TOKEN_RIGHT_BRACE) { 933 return GTKScanner.TOKEN_RIGHT_BRACE; 934 } 935 936 return GTKScanner.TOKEN_NONE; 937 } 938 939 static int parseColor(GTKScanner scanner, Color[] colors, int index) 942 throws IOException { 943 int token; 944 945 long lVal; 946 double dVal; 947 948 float red; 949 float green; 950 float blue; 951 952 token = scanner.getToken(); 953 954 switch(token) { 955 case GTKScanner.TOKEN_LEFT_CURLY: 956 token = scanner.getToken(); 957 if (token == GTKScanner.TOKEN_INT) { 958 red = javaColorVal(scanner.currValue.longVal); 959 } else if (token == GTKScanner.TOKEN_FLOAT) { 960 red = javaColorVal(scanner.currValue.doubleVal); 961 } else { 962 return GTKScanner.TOKEN_FLOAT; 963 } 964 965 token = scanner.getToken(); 966 if (token != GTKScanner.TOKEN_COMMA) { 967 return GTKScanner.TOKEN_COMMA; 968 } 969 970 token = scanner.getToken(); 971 if (token == GTKScanner.TOKEN_INT) { 972 green = javaColorVal(scanner.currValue.longVal); 973 } else if (token == GTKScanner.TOKEN_FLOAT) { 974 green = javaColorVal(scanner.currValue.doubleVal); 975 } else { 976 return GTKScanner.TOKEN_FLOAT; 977 } 978 979 token = scanner.getToken(); 980 if (token != GTKScanner.TOKEN_COMMA) { 981 return GTKScanner.TOKEN_COMMA; 982 } 983 984 token = scanner.getToken(); 985 if (token == GTKScanner.TOKEN_INT) { 986 blue = javaColorVal(scanner.currValue.longVal); 987 } else if (token == GTKScanner.TOKEN_FLOAT) { 988 blue = javaColorVal(scanner.currValue.doubleVal); 989 } else { 990 return GTKScanner.TOKEN_FLOAT; 991 } 992 993 token = scanner.getToken(); 994 if (token != GTKScanner.TOKEN_RIGHT_CURLY) { 995 return GTKScanner.TOKEN_RIGHT_CURLY; 996 } 997 998 colors[index] = new ColorUIResource (red, green, blue); 999 1000 break; 1001 case GTKScanner.TOKEN_STRING: 1002 Color color = parseColorString(scanner.currValue.stringVal); 1003 1004 if (color == null) { 1005 scanner.printMessage("Invalid color constant '" + 1006 scanner.currValue.stringVal 1007 + "'", false); 1008 return GTKScanner.TOKEN_STRING; 1009 } 1010 1011 colors[index] = color; 1012 1013 break; 1014 default: 1015 return GTKScanner.TOKEN_STRING; 1016 } 1017 1018 return GTKScanner.TOKEN_NONE; 1019 } 1020 1021 static Color parseColorString(String str) { 1022 if (str.charAt(0) == '#') { 1023 str = str.substring(1); 1024 1025 int i = str.length(); 1026 1027 if (i < 3 || i > 12 || (i % 3) != 0) { 1028 return null; 1029 } 1030 1031 i /= 3; 1032 1033 int r; 1034 int g; 1035 int b; 1036 1037 try { 1038 r = Integer.parseInt(str.substring(0, i), 16); 1039 g = Integer.parseInt(str.substring(i, i * 2), 16); 1040 b = Integer.parseInt(str.substring(i * 2, i * 3), 16); 1041 } catch (NumberFormatException nfe) { 1042 return null; 1043 } 1044 1045 if (i == 4) { 1046 return new ColorUIResource (r / 65535.0f, g / 65535.0f, b / 65535.0f); 1047 } else if (i == 1) { 1048 return new ColorUIResource (r / 15.0f, g / 15.0f, b / 15.0f); 1049 } else if (i == 2) { 1050 return new ColorUIResource (r, g, b); 1051 } else { 1052 return new ColorUIResource (r / 4095.0f, g / 4095.0f, b / 4095.0f); 1053 } 1054 } else { 1055 return XColors.lookupColor(str); 1056 } 1057 } 1058 1059 private static float javaColorVal(long col) { 1060 int color = (int)Math.max(Math.min(col, 65535), 0); 1061 return color / 65535.0f; 1062 } 1063 1064 private static float javaColorVal(double col) { 1065 float color = (float)Math.max(Math.min(col, 1.0f), 0.0f); 1066 return color; 1067 } 1068 1069 private int parseThickness(int expVal, StyleInfo info) throws IOException { 1070 int token; 1071 boolean isXThickness; 1072 1073 token = scanner.getToken(); 1074 if (token != expVal) { 1075 return expVal; 1076 } 1077 1078 if (token == SYMBOL_XTHICKNESS.val) { 1079 isXThickness = true; 1080 } else if (token == SYMBOL_YTHICKNESS.val) { 1081 isXThickness = false; 1082 } else { 1083 return SYMBOL_XTHICKNESS.val; 1084 } 1085 1086 token = scanner.getToken(); 1087 if (token != GTKScanner.TOKEN_EQUAL_SIGN) { 1088 return GTKScanner.TOKEN_EQUAL_SIGN; 1089 } 1090 1091 token = scanner.getToken(); 1092 if (token != GTKScanner.TOKEN_INT) { 1093 return GTKScanner.TOKEN_INT; 1094 } 1095 1096 int thickness = (int)scanner.currValue.longVal; 1097 1098 if (isXThickness) { 1099 info.xThickness = thickness; 1100 } else { 1101 info.yThickness = thickness; 1102 } 1103 1104 return GTKScanner.TOKEN_NONE; 1105 } 1106 1107 private int parseBGPixmap(StyleInfo info) throws IOException { 1108 int token; 1109 1110 token = scanner.getToken(); 1111 if (token != SYMBOL_BG_PIXMAP.val) { 1112 return SYMBOL_BG_PIXMAP.val; 1113 } 1114 1115 int[] state = new int[1]; 1116 token = parseState(state); 1117 1118 if (token != GTKScanner.TOKEN_NONE) { 1119 return token; 1120 } 1121 1122 token = scanner.getToken(); 1123 if (token != GTKScanner.TOKEN_EQUAL_SIGN) { 1124 return GTKScanner.TOKEN_EQUAL_SIGN; 1125 } 1126 1127 token = scanner.getToken(); 1128 if (token != GTKScanner.TOKEN_STRING) { 1129 return GTKScanner.TOKEN_STRING; 1130 } 1131 1132 String pixmapStr = null; 1133 1134 String str = scanner.currValue.stringVal; 1135 1136 if (str.equals("<none>") || str.equals("<parent>")) { 1137 pixmapStr = str.intern(); 1138 } else { 1139 pixmapStr = resolvePixmapPath(str); 1140 } 1141 1142 if (pixmapStr == null) { 1143 scanner.printMessage("Unable to locate image file in pixmap_path: \"" + str + "\"", false); 1144 } else { 1145 info.bgPixmapName[state[0]] = pixmapStr; 1146 } 1147 1148 return GTKScanner.TOKEN_NONE; 1149 } 1150 1151 String resolvePixmapPath(String str) { 1152 if (pixmapPaths != null) { 1154 for (int i = 0; i < pixmapPaths.length; i++) { 1155 File file = new File(pixmapPaths[i], str); 1156 if (file.canRead()) { 1157 return file.getAbsolutePath(); 1158 } 1159 } 1160 } 1161 1162 File[] dirs = new File[dirStack.size()]; 1164 dirs = (File[])dirStack.toArray(dirs); 1165 1166 for (int i = dirs.length - 1; i >= 0; i--) { 1167 File file = new File(dirs[i], str); 1168 if (file.canRead()) { 1169 return file.getAbsolutePath(); 1170 } 1171 } 1172 1173 return null; 1174 } 1175 1176 private int parseFont(int expVal, StyleInfo info) throws IOException { 1177 int token; 1178 boolean isPango; 1179 1180 token = scanner.getToken(); 1181 if (token != expVal) { 1182 return expVal; 1183 } 1184 1185 if (token == SYMBOL_FONT_NAME.val) { 1186 isPango = true; 1187 } else if (token == SYMBOL_FONT.val 1188 || token == SYMBOL_FONTSET.val) { 1189 isPango = false; 1190 } else { 1191 return SYMBOL_FONT_NAME.val; 1192 } 1193 1194 token = scanner.getToken(); 1195 if (token != GTKScanner.TOKEN_EQUAL_SIGN) { 1196 return GTKScanner.TOKEN_EQUAL_SIGN; 1197 } 1198 1199 token = scanner.getToken(); 1200 if (token != GTKScanner.TOKEN_STRING) { 1201 return GTKScanner.TOKEN_STRING; 1202 } 1203 1204 if (isPango) { 1206 String pangoName = scanner.currValue.stringVal; 1207 1208 info.font = PangoFonts.lookupFont(pangoName); 1209 } 1210 1211 return GTKScanner.TOKEN_NONE; 1212 } 1213 1214 private GTKEngineParser getParser(String engineName) { 1215 Object o = engineParsers.get(engineName); 1216 1217 if (o == null) { 1218 return null; 1219 } 1220 1221 if (o instanceof GTKEngineParser) { 1222 return (GTKEngineParser)o; 1223 } 1224 1225 GTKEngineParser parser = null; 1226 1227 try { 1228 parser = (GTKEngineParser)Class.forName((String )o).newInstance(); 1229 } catch (ClassNotFoundException e) { 1230 } catch (InstantiationException e) { 1231 } catch (IllegalAccessException e) { 1232 } 1233 1234 if (parser == null) { 1235 engineParsers.remove(engineName); 1237 } else { 1238 engineParsers.put(engineName, parser); 1240 } 1241 1242 return parser; 1243 } 1244 1245 private int parseEngine(StyleInfo info) throws IOException { 1246 int token; 1247 1248 token = scanner.getToken(); 1249 if (token != SYMBOL_ENGINE.val) { 1250 return SYMBOL_ENGINE.val; 1251 } 1252 1253 token = scanner.getToken(); 1254 if (token != GTKScanner.TOKEN_STRING) { 1255 return GTKScanner.TOKEN_STRING; 1256 } 1257 1258 String engineName = scanner.currValue.stringVal; 1259 1260 if (engineName.length() == 0) { 1262 token = scanner.getToken(); 1263 if (token != GTKScanner.TOKEN_LEFT_CURLY) { 1264 return GTKScanner.TOKEN_LEFT_CURLY; 1265 } 1266 1267 token = scanner.getToken(); 1268 if (token != GTKScanner.TOKEN_RIGHT_CURLY) { 1269 return GTKScanner.TOKEN_RIGHT_CURLY; 1270 } 1271 1272 info.engineInfo = null; 1273 1274 return GTKScanner.TOKEN_NONE; 1275 } 1276 1277 GTKEngineParser parser = getParser(engineName); 1278 1279 if (parser == null) { 1280 token = ignoreBlock(); 1281 if (token != GTKScanner.TOKEN_NONE) { 1282 return token; 1283 } 1284 1285 scanner.printMessage("Engine \"" + engineName + "\" is unsupported, ignoring", false); 1286 } else { 1287 token = scanner.getToken(); 1288 if (token != GTKScanner.TOKEN_LEFT_CURLY) { 1289 return GTKScanner.TOKEN_LEFT_CURLY; 1290 } 1291 1292 EngineInfo[] engineInfo = new EngineInfo[1]; 1293 1294 if (info.engineInfo != null && engineName.equals(info.engineInfo.engineName)) { 1296 engineInfo[0] = info.engineInfo; 1297 } 1298 1299 token = parser.parse(scanner, this, engineInfo); 1300 if (token != GTKScanner.TOKEN_NONE) { 1301 return token; 1302 } 1303 1304 if (engineInfo[0] != null) { 1306 engineInfo[0].engineName = engineName; 1307 } 1308 1309 info.engineInfo = engineInfo[0]; 1310 } 1311 1312 return GTKScanner.TOKEN_NONE; 1313 } 1314 1315 private int parseStock(StyleInfo info) throws IOException { 1316 String id; 1317 1318 int token; 1319 1320 token = scanner.getToken(); 1321 if (token != SYMBOL_STOCK.val) { 1322 return SYMBOL_STOCK.val; 1323 } 1324 1325 token = scanner.getToken(); 1326 if (token != GTKScanner.TOKEN_LEFT_BRACE) { 1327 return GTKScanner.TOKEN_LEFT_BRACE; 1328 } 1329 1330 token = scanner.getToken(); 1331 if (token != GTKScanner.TOKEN_STRING) { 1332 return GTKScanner.TOKEN_STRING; 1333 } 1334 1335 id = scanner.currValue.stringVal; 1336 1337 token = scanner.getToken(); 1338 if (token != GTKScanner.TOKEN_RIGHT_BRACE) { 1339 return GTKScanner.TOKEN_RIGHT_BRACE; 1340 } 1341 1342 token = scanner.getToken(); 1343 if (token != GTKScanner.TOKEN_EQUAL_SIGN) { 1344 return GTKScanner.TOKEN_EQUAL_SIGN; 1345 } 1346 1347 token = scanner.getToken(); 1348 if (token != GTKScanner.TOKEN_LEFT_CURLY) { 1349 return GTKScanner.TOKEN_LEFT_CURLY; 1350 } 1351 1352 ArrayList iconSources = new ArrayList(); 1353 1354 GTKStyle.GTKIconSource[] sources = new GTKStyle.GTKIconSource[1]; 1358 1359 token = scanner.peekNextToken(); 1360 while (token != GTKScanner.TOKEN_RIGHT_CURLY) { 1361 token = parseIconSource(sources); 1362 1363 if (token != GTKScanner.TOKEN_NONE) { 1364 return token; 1365 } 1366 1367 token = scanner.getToken(); 1368 if (token != GTKScanner.TOKEN_COMMA 1369 && token != GTKScanner.TOKEN_RIGHT_CURLY) { 1370 return GTKScanner.TOKEN_RIGHT_CURLY; 1371 } 1372 1373 if (sources[0] != null) { 1374 iconSources.add(sources[0]); 1375 } 1376 } 1377 1378 if (iconSources.size() != 0) { 1379 sources = new GTKStyle.GTKIconSource[iconSources.size()]; 1380 sources = (GTKStyle.GTKIconSource[])iconSources.toArray(sources); 1381 info.addStockItem(id, sources); 1382 } 1383 1384 return GTKScanner.TOKEN_NONE; 1385 } 1386 1387 private GTKStyle.GTKIconSource createIconSource(String path, 1388 int direction, 1389 int state, 1390 String size) { 1391 String resolvedPath = resolvePixmapPath(path); 1392 1393 if (resolvedPath != null) { 1394 return new GTKStyle.GTKIconSource(resolvedPath, direction, state, size); 1395 } 1396 1397 return null; 1398 } 1399 1400 private int parseIconSource(GTKStyle.GTKIconSource[] retVal) throws IOException { 1401 int token; 1402 1403 String pixmapStr = null; 1404 int direction = GTKConstants.UNDEFINED; 1405 int state = GTKConstants.UNDEFINED; 1406 String size = null; 1407 1408 token = scanner.getToken(); 1409 if (token != GTKScanner.TOKEN_LEFT_CURLY) { 1410 return GTKScanner.TOKEN_LEFT_CURLY; 1411 } 1412 1413 token = scanner.getToken(); 1414 if (token != GTKScanner.TOKEN_STRING) { 1415 return GTKScanner.TOKEN_STRING; 1416 } 1417 1418 pixmapStr = scanner.currValue.stringVal; 1419 1420 token = scanner.getToken(); 1421 if (token == GTKScanner.TOKEN_RIGHT_CURLY) { 1422 retVal[0] = createIconSource(pixmapStr, direction, state, size); 1423 return GTKScanner.TOKEN_NONE; 1424 } else if (token != GTKScanner.TOKEN_COMMA) { 1425 return GTKScanner.TOKEN_COMMA; 1426 } 1427 1428 token = scanner.getToken(); 1429 if (token == SYMBOL_RTL.val) { 1430 direction = GTKConstants.RTL; 1431 } else if (token == SYMBOL_LTR.val) { 1432 direction = GTKConstants.LTR; 1433 } else if (token == '*') { 1434 } else { 1436 return SYMBOL_RTL.val; 1437 } 1438 1439 token = scanner.getToken(); 1440 if (token == GTKScanner.TOKEN_RIGHT_CURLY) { 1441 retVal[0] = createIconSource(pixmapStr, direction, state, size); 1442 return GTKScanner.TOKEN_NONE; 1443 } else if (token != GTKScanner.TOKEN_COMMA) { 1444 return GTKScanner.TOKEN_COMMA; 1445 } 1446 1447 token = scanner.getToken(); 1448 if (token == SYMBOL_NORMAL.val) { 1449 state = SynthConstants.ENABLED; 1450 } else if (token == SYMBOL_ACTIVE.val) { 1451 state = SynthConstants.PRESSED; 1452 } else if (token == SYMBOL_PRELIGHT.val) { 1453 state = SynthConstants.MOUSE_OVER; 1454 } else if (token == SYMBOL_SELECTED.val) { 1455 state = SynthConstants.SELECTED; 1456 } else if (token == SYMBOL_INSENSITIVE.val) { 1457 state = SynthConstants.DISABLED; 1458 } else if (token == '*') { 1459 } else { 1461 return SYMBOL_PRELIGHT.val; 1462 } 1463 1464 token = scanner.getToken(); 1465 if (token == GTKScanner.TOKEN_RIGHT_CURLY) { 1466 retVal[0] = createIconSource(pixmapStr, direction, state, size); 1467 return GTKScanner.TOKEN_NONE; 1468 } else if (token != GTKScanner.TOKEN_COMMA) { 1469 return GTKScanner.TOKEN_COMMA; 1470 } 1471 1472 token = scanner.getToken(); 1473 if (token != '*') { 1474 if (token != GTKScanner.TOKEN_STRING) { 1475 return GTKScanner.TOKEN_STRING; 1476 } 1477 size = scanner.currValue.stringVal; 1478 } 1479 1480 token = scanner.getToken(); 1481 if (token != GTKScanner.TOKEN_RIGHT_CURLY) { 1482 return GTKScanner.TOKEN_RIGHT_CURLY; 1483 } 1484 1485 retVal[0] = createIconSource(pixmapStr, direction, state, size); 1486 1487 return GTKScanner.TOKEN_NONE; 1488 } 1489 1490 private int parseIdentifierInStyle(StyleInfo info) throws IOException { 1491 int token; 1492 1493 token = scanner.getToken(); 1494 if (token != GTKScanner.TOKEN_IDENTIFIER 1495 || scanner.currValue.stringVal.charAt(0) < 'A' 1496 || scanner.currValue.stringVal.charAt(0) > 'Z') { 1497 return GTKScanner.TOKEN_IDENTIFIER; 1498 } 1499 1500 String klass; 1501 String prop; 1502 Object [] value = new Object [1]; 1503 1504 klass = scanner.currValue.stringVal.intern(); 1505 1506 if (scanner.getToken() != ':' || scanner.getToken() != ':') { 1508 return ':'; 1509 } 1510 1511 token = scanner.getToken(); 1512 if (token != GTKScanner.TOKEN_IDENTIFIER) { 1513 return GTKScanner.TOKEN_IDENTIFIER; 1514 } 1515 1516 StringBuffer buf = new StringBuffer (scanner.currValue.stringVal); 1517 1518 String validChars = GTKScanner.CHARS_A_2_Z 1519 + GTKScanner.CHARS_a_2_z 1520 + GTKScanner.CHARS_DIGITS 1521 + "-"; 1522 1523 int len = buf.length(); 1525 for (int i = 0; i < len; i++) { 1526 if (validChars.indexOf(buf.charAt(i)) == -1) { 1527 buf.setCharAt(i, '-'); 1528 } 1529 } 1530 1531 prop = buf.toString().intern(); 1532 1533 token = parsePropertyAssignment(value); 1534 if (token != GTKScanner.TOKEN_NONE) { 1535 return token; 1536 } 1537 1538 if (value[0] instanceof String || value[0] instanceof StringBuffer ) { 1541 Object val = value[0]; 1542 1543 PropertyParser pp = PropertyParser.getParserFor(prop); 1544 1545 if (pp == null) { 1546 info.addProperty(klass, prop, 1548 val instanceof String ? val : val.toString()); 1549 } else { 1550 String toParse; 1551 if (val instanceof String ) { 1552 if (pp.needSimpleStringsEscaped()) { 1553 toParse = '"' + escapeString((String ) val) + '"'; 1554 } else { 1555 toParse = (String )val; 1556 } 1557 } else { 1558 toParse = val.toString(); 1559 } 1560 1561 Object parsedVal = pp.parse(toParse); 1562 if (parsedVal == null) { 1563 scanner.printMessage("Failed to parse property value \"" + toParse + "\" for `" 1564 + klass + "::" + prop + "'", false); 1565 } else { 1566 info.addProperty(klass, prop, parsedVal); 1567 } 1568 } 1569 } else { 1570 info.addProperty(klass, prop, value[0]); 1571 } 1572 1573 return GTKScanner.TOKEN_NONE; 1574 } 1575 1576 private int parsePropertyAssignment(Object [] retVal) throws IOException { 1577 int token; 1578 1579 token = scanner.getToken(); 1580 if (token != '=') { 1581 return '='; 1582 } 1583 1584 boolean scanIdentifier = scanner.scanIdentifier; 1586 boolean scanSymbols = scanner.scanSymbols; 1587 boolean identifier2String = scanner.identifier2String; 1588 boolean char2Token = scanner.char2Token; 1589 boolean scanIdentifierNULL = scanner.scanIdentifierNULL; 1590 boolean numbers2Int = scanner.numbers2Int; 1591 1592 scanner.scanIdentifier = true; 1594 scanner.scanSymbols = false; 1595 scanner.identifier2String = false; 1596 scanner.char2Token = true; 1597 scanner.scanIdentifierNULL = false; 1598 scanner.numbers2Int = true; 1599 1600 boolean negate = false; 1601 1602 if (scanner.peekNextToken() == '-') { 1603 scanner.getToken(); 1604 negate = true; 1605 } 1606 1607 token = scanner.peekNextToken(); 1608 switch(token) { 1609 case GTKScanner.TOKEN_INT: 1610 scanner.getToken(); 1611 retVal[0] = new Long (negate ? -scanner.currValue.longVal : scanner.currValue.longVal); 1612 token = GTKScanner.TOKEN_NONE; 1613 break; 1614 case GTKScanner.TOKEN_FLOAT: 1615 scanner.getToken(); 1616 retVal[0] = new Double (negate ? -scanner.currValue.doubleVal : scanner.currValue.doubleVal); 1617 token = GTKScanner.TOKEN_NONE; 1618 break; 1619 case GTKScanner.TOKEN_STRING: 1620 scanner.getToken(); 1621 if (negate) { 1622 token = GTKScanner.TOKEN_INT; 1623 } else { 1624 retVal[0] = scanner.currValue.stringVal; 1625 token = GTKScanner.TOKEN_NONE; 1626 } 1627 break; 1628 case GTKScanner.TOKEN_IDENTIFIER: 1629 case GTKScanner.TOKEN_LEFT_PAREN: 1630 case GTKScanner.TOKEN_LEFT_CURLY: 1631 case GTKScanner.TOKEN_LEFT_BRACE: 1632 if (negate) { 1633 token = GTKScanner.TOKEN_INT; 1634 } else { 1635 StringBuffer result = new StringBuffer (); 1636 1637 token = parseComplexPropVal(result, GTKScanner.TOKEN_EOF); 1638 if (token == GTKScanner.TOKEN_NONE) { 1639 result.append(' '); 1640 retVal[0] = result; 1642 } 1643 } 1644 break; 1645 default: 1646 scanner.getToken(); 1647 token = GTKScanner.TOKEN_INT; 1648 break; 1649 } 1650 1651 scanner.scanIdentifier = scanIdentifier; 1653 scanner.scanSymbols = scanSymbols; 1654 scanner.identifier2String = identifier2String; 1655 scanner.char2Token = char2Token; 1656 scanner.scanIdentifierNULL = scanIdentifierNULL; 1657 scanner.numbers2Int = numbers2Int; 1658 1659 return token; 1660 } 1661 1662 private int parseComplexPropVal(StringBuffer into, int delim) throws IOException { 1663 int token; 1664 1665 token = scanner.getToken(); 1666 switch(token) { 1667 case GTKScanner.TOKEN_INT: 1668 into.append(" 0x"); 1669 into.append(Long.toHexString(scanner.currValue.longVal)); 1670 break; 1671 case GTKScanner.TOKEN_FLOAT: 1672 into.append(' '); 1673 into.append(scanner.currValue.doubleVal); 1674 break; 1675 case GTKScanner.TOKEN_STRING: 1676 into.append(" \""); 1677 into.append(escapeString(scanner.currValue.stringVal)); 1678 into.append('"'); 1679 break; 1680 case GTKScanner.TOKEN_IDENTIFIER: 1681 into.append(' '); 1682 into.append(scanner.currValue.stringVal); 1683 break; 1684 case GTKScanner.TOKEN_LEFT_PAREN: 1685 into.append(' '); 1686 into.append((char)token); 1687 token = parseComplexPropVal(into, GTKScanner.TOKEN_RIGHT_PAREN); 1688 if (token != GTKScanner.TOKEN_NONE) { 1689 return token; 1690 } 1691 break; 1692 case GTKScanner.TOKEN_LEFT_CURLY: 1693 into.append(' '); 1694 into.append((char)token); 1695 token = parseComplexPropVal(into, GTKScanner.TOKEN_RIGHT_CURLY); 1696 if (token != GTKScanner.TOKEN_NONE) { 1697 return token; 1698 } 1699 break; 1700 case GTKScanner.TOKEN_LEFT_BRACE: 1701 into.append(' '); 1702 into.append((char)token); 1703 token = parseComplexPropVal(into, GTKScanner.TOKEN_RIGHT_BRACE); 1704 if (token != GTKScanner.TOKEN_NONE) { 1705 return token; 1706 } 1707 break; 1708 default: 1709 if (token >= GTKScanner.TOKEN_NONE || token <= GTKScanner.TOKEN_EOF) { 1710 return delim != GTKScanner.TOKEN_EOF ? delim : GTKScanner.TOKEN_STRING; 1711 } 1712 into.append(' '); 1713 into.append((char)token); 1714 if (token == delim) { 1715 return GTKScanner.TOKEN_NONE; 1716 } 1717 } 1718 1719 if (delim == GTKScanner.TOKEN_EOF) { 1720 return GTKScanner.TOKEN_NONE; 1721 } else { 1722 return parseComplexPropVal(into, delim); 1723 } 1724 } 1725 1726 private String escapeString(String source) { 1727 int len = source.length(); 1728 1729 StringBuffer result = new StringBuffer (len * 4); 1730 1731 for (int i = 0; i < len; i++) { 1732 char ch = source.charAt(i); 1733 1734 switch(ch) { 1735 case '\b': 1736 result.append("\\b"); 1737 break; 1738 case '\f': 1739 result.append("\\f"); 1740 break; 1741 case '\n': 1742 result.append("\\n"); 1743 break; 1744 case '\r': 1745 result.append("\\r"); 1746 break; 1747 case '\t': 1748 result.append("\\t"); 1749 break; 1750 case '\\': 1751 result.append("\\\\"); 1752 break; 1753 case '"': 1754 result.append("\\\""); 1755 break; 1756 default: 1757 if (ch < ' ' || ch > '~') { 1758 result.append('\\'); 1759 result.append(Integer.toOctalString(ch)); 1760 } else { 1761 result.append((char)ch); 1762 } 1763 break; 1764 } 1765 } 1766 1767 return result.toString(); 1768 } 1769 1770 private int ignoreBlock() throws IOException { 1771 int token; 1772 1773 token = scanner.getToken(); 1774 if (token != GTKScanner.TOKEN_LEFT_CURLY) { 1775 return GTKScanner.TOKEN_LEFT_CURLY; 1776 } 1777 1778 int curlys = 1; 1779 1780 while (curlys > 0) { 1781 token = scanner.getToken(); 1782 switch(token) { 1783 case GTKScanner.TOKEN_EOF: 1784 return GTKScanner.TOKEN_RIGHT_CURLY; 1785 case GTKScanner.TOKEN_LEFT_CURLY: 1786 curlys++; 1787 break; 1788 case GTKScanner.TOKEN_RIGHT_CURLY: 1789 curlys--; 1790 break; 1791 default: 1792 } 1794 } 1795 1796 return GTKScanner.TOKEN_NONE; 1797 } 1798 1799 public static void main(String [] args) { 1801 if (args.length == 0) { 1802 System.err.println("Usage: java GTKParser <gtkrc file> <gtkrc file>...."); 1803 System.exit(1); 1804 } 1805 1806 GTKParser parser = new GTKParser(); 1807 1808 try { 1809 for (int i = 0; i < args.length; i++) { 1810 parser.parseFile(new File(args[i]), args[i]); 1811 } 1812 } catch (IOException ioe) { 1813 ioe.printStackTrace(); 1814 } 1815 1816 parser.printNamedStyles(); 1817 System.out.println(); 1818 parser.printSettings(); 1819 System.out.println(); 1820 parser.printAssignments(); 1821 } 1822 1823 private void printNamedStyles() { 1825 System.out.println("===== Named Styles ====="); 1826 1827 StyleInfo[] infos = new StyleInfo[namedStyles.size()]; 1828 infos = (StyleInfo[])namedStyles.values().toArray(infos); 1829 1830 for (int i = 0; i < infos.length; i++) { 1831 StyleInfo info = infos[i]; 1832 1833 System.out.println("NAME: " + info.name); 1834 GTKStyle style = info.toGTKStyle(); 1835 System.out.println(style == StyleInfo.EMPTY_STYLE ? "EMPTY_STYLE" : style.toString()); 1836 System.out.println("---------------------------"); 1837 } 1838 } 1839 1840 private void printSettings() { 1842 System.out.println("===== GTK Settings ====="); 1843 1844 Iterator iter = settings.entrySet().iterator(); 1845 while (iter.hasNext()) { 1846 Map.Entry entry = (Map.Entry)iter.next(); 1847 System.out.println(entry.getKey() + "=" + entry.getValue()); 1848 } 1849 } 1850 1851 private void printAssignments() { 1853 System.out.println("===== Assignments ====="); 1854 1855 Assignment[] assigns = new Assignment[assignments.size()]; 1856 assigns = (Assignment[])assignments.toArray(assigns); 1857 1858 for (int i = 0; i < assigns.length; i++) { 1859 System.out.println(assigns[i]); 1860 } 1861 } 1862 1863} 1864 | Popular Tags |