001: /*
002: * Copyright 2003-2006 Sun Microsystems, Inc. All Rights Reserved.
003: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
004: *
005: * This code is free software; you can redistribute it and/or modify it
006: * under the terms of the GNU General Public License version 2 only, as
007: * published by the Free Software Foundation. Sun designates this
008: * particular file as subject to the "Classpath" exception as provided
009: * by Sun in the LICENSE file that accompanied this code.
010: *
011: * This code is distributed in the hope that it will be useful, but WITHOUT
012: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
013: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
014: * version 2 for more details (a copy is included in the LICENSE file that
015: * accompanied this code).
016: *
017: * You should have received a copy of the GNU General Public License version
018: * 2 along with this work; if not, write to the Free Software Foundation,
019: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
020: *
021: * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
022: * CA 95054 USA or visit www.sun.com if you need additional information or
023: * have any questions.
024: */
025:
026: package sun.awt.X11;
027:
028: import java.awt.*;
029: import java.io.*;
030: import sun.security.action.GetPropertyAction;
031: import java.security.AccessController;
032:
033: /**
034: *
035: * This class contains code that is need to mimic the
036: * Motif Color selection and color defaults code.
037: *
038: * Portions of this code have been ported to java from
039: * Motif sources (Color.c) (ColorP.h) etc.
040: *
041: * Author: Bino George
042: *
043: */
044:
045: class MotifColorUtilities {
046:
047: static final float XmRED_LUMINOSITY = 0.30f;
048: static final float XmGREEN_LUMINOSITY = 0.59f;
049: static final float XmBLUE_LUMINOSITY = 0.11f;
050: static final int XmINTENSITY_FACTOR = 75;
051: static final int XmLIGHT_FACTOR = 0;
052: static final int XmLUMINOSITY_FACTOR = 25;
053:
054: static final int XmMAX_SHORT = 65535;
055:
056: static final int XmCOLOR_PERCENTILE = (XmMAX_SHORT / 100);
057:
058: static final int XmDEFAULT_DARK_THRESHOLD = 20;
059: static final int XmDEFAULT_LIGHT_THRESHOLD = 93;
060: static final int XmDEFAULT_FOREGROUND_THRESHOLD = 70;
061:
062: static final int BLACK = 0xFF000000;
063: static final int WHITE = 0xFFFFFFFF;
064: static final int MOTIF_WINDOW_COLOR = 0xFFDFDFDF;
065:
066: static final int DEFAULT_COLOR = 0xFFC4C4C4;
067:
068: static final int XmCOLOR_LITE_THRESHOLD = XmDEFAULT_LIGHT_THRESHOLD
069: * XmCOLOR_PERCENTILE;
070: static final int XmCOLOR_DARK_THRESHOLD = XmDEFAULT_DARK_THRESHOLD
071: * XmCOLOR_PERCENTILE;
072: static final int XmFOREGROUND_THRESHOLD = XmDEFAULT_FOREGROUND_THRESHOLD
073: * XmCOLOR_PERCENTILE;
074:
075: /* LITE color model
076: percent to interpolate RGB towards black for SEL, BS, TS */
077:
078: static final int XmCOLOR_LITE_SEL_FACTOR = 15;
079: static final int XmCOLOR_LITE_BS_FACTOR = 40;
080: static final int XmCOLOR_LITE_TS_FACTOR = 20;
081:
082: /* DARK color model
083: percent to interpolate RGB towards white for SEL, BS, TS */
084:
085: static final int XmCOLOR_DARK_SEL_FACTOR = 15;
086: static final int XmCOLOR_DARK_BS_FACTOR = 30;
087: static final int XmCOLOR_DARK_TS_FACTOR = 50;
088:
089: /* STD color model
090: percent to interpolate RGB towards black for SEL, BS
091: percent to interpolate RGB towards white for TS
092: HI values used for high brightness (within STD)
093: LO values used for low brightness (within STD)
094: Interpolate factors between HI & LO values based on brightness */
095:
096: static final int XmCOLOR_HI_SEL_FACTOR = 15;
097: static final int XmCOLOR_HI_BS_FACTOR = 40;
098: static final int XmCOLOR_HI_TS_FACTOR = 60;
099:
100: static final int XmCOLOR_LO_SEL_FACTOR = 15;
101: static final int XmCOLOR_LO_BS_FACTOR = 60;
102: static final int XmCOLOR_LO_TS_FACTOR = 50;
103:
104: static int brightness(int red, int green, int blue) {
105: float brightness;
106: float intensity;
107: float light;
108: float luminosity, maxprimary, minprimary;
109:
110: // To mimix Motif logic, we need to convert to 16 bit color values.
111:
112: red = red << 8;
113: green = green << 8;
114: blue = blue << 8;
115:
116: intensity = (red + green + blue) / 3;
117:
118: /*
119: * The casting nonsense below is to try to control the point at
120: * the truncation occurs.
121: */
122:
123: luminosity = (int) ((XmRED_LUMINOSITY * (float) red)
124: + (XmGREEN_LUMINOSITY * (float) green) + (XmBLUE_LUMINOSITY * (float) blue));
125:
126: maxprimary = ((red > green) ? ((red > blue) ? red : blue)
127: : ((green > blue) ? green : blue));
128:
129: minprimary = ((red < green) ? ((red < blue) ? red : blue)
130: : ((green < blue) ? green : blue));
131:
132: light = (minprimary + maxprimary) / 2;
133:
134: brightness = ((intensity * XmINTENSITY_FACTOR)
135: + (light * XmLIGHT_FACTOR) + (luminosity * XmLUMINOSITY_FACTOR)) / 100;
136: return Math.round(brightness);
137: }
138:
139: static int calculateForegroundFromBackground(int r, int g, int b) {
140:
141: int foreground = WHITE;
142: int brightness = brightness(r, g, b);
143:
144: if (brightness > XmFOREGROUND_THRESHOLD) {
145: foreground = BLACK;
146: } else
147: foreground = WHITE;
148:
149: return foreground;
150: }
151:
152: static int calculateTopShadowFromBackground(int r, int g, int b) {
153:
154: float color_value, f;
155:
156: int br = r << 8;
157: int bg = g << 8;
158: int bb = b << 8;
159:
160: int brightness = brightness(r, g, b);
161:
162: float red;
163: float green;
164: float blue;
165:
166: if (brightness < XmCOLOR_DARK_THRESHOLD) {
167: // dark background
168:
169: color_value = br;
170: color_value += XmCOLOR_DARK_TS_FACTOR
171: * (XmMAX_SHORT - color_value) / 100;
172: red = color_value;
173:
174: color_value = bg;
175: color_value += XmCOLOR_DARK_TS_FACTOR
176: * (XmMAX_SHORT - color_value) / 100;
177: green = color_value;
178:
179: color_value = bb;
180: color_value += XmCOLOR_DARK_TS_FACTOR
181: * (XmMAX_SHORT - color_value) / 100;
182: blue = color_value;
183: } else if (brightness > XmCOLOR_LITE_THRESHOLD) {
184: // lite background
185:
186: color_value = br;
187: color_value -= (color_value * XmCOLOR_LITE_TS_FACTOR) / 100;
188: red = color_value;
189:
190: color_value = bg;
191: color_value -= (color_value * XmCOLOR_LITE_TS_FACTOR) / 100;
192: green = color_value;
193:
194: color_value = bb;
195: color_value -= (color_value * XmCOLOR_LITE_TS_FACTOR) / 100;
196: blue = color_value;
197:
198: } else {
199: // medium
200: f = XmCOLOR_LO_TS_FACTOR
201: + (brightness
202: * (XmCOLOR_HI_TS_FACTOR - XmCOLOR_LO_TS_FACTOR) / XmMAX_SHORT);
203:
204: color_value = br;
205: color_value += f * (XmMAX_SHORT - color_value) / 100;
206: red = color_value;
207:
208: color_value = bg;
209: color_value += f * (XmMAX_SHORT - color_value) / 100;
210: green = color_value;
211:
212: color_value = bb;
213: color_value += f * (XmMAX_SHORT - color_value) / 100;
214: blue = color_value;
215:
216: }
217:
218: int ired = ((int) red) >> 8;
219: int igreen = ((int) green) >> 8;
220: int iblue = ((int) blue) >> 8;
221:
222: int ret = 0xff000000 | ired << 16 | igreen << 8 | iblue;
223:
224: return ret;
225: }
226:
227: static int calculateBottomShadowFromBackground(int r, int g, int b) {
228:
229: float color_value, f;
230:
231: int br = r << 8;
232: int bg = g << 8;
233: int bb = b << 8;
234:
235: int brightness = brightness(r, g, b);
236:
237: float red;
238: float green;
239: float blue;
240:
241: if (brightness < XmCOLOR_DARK_THRESHOLD) {
242: // dark background
243: color_value = br;
244: color_value += XmCOLOR_DARK_BS_FACTOR
245: * (XmMAX_SHORT - color_value) / 100;
246: red = color_value;
247:
248: color_value = bg;
249: color_value += XmCOLOR_DARK_BS_FACTOR
250: * (XmMAX_SHORT - color_value) / 100;
251: green = color_value;
252:
253: color_value = bb;
254: color_value += XmCOLOR_DARK_BS_FACTOR
255: * (XmMAX_SHORT - color_value) / 100;
256: blue = color_value;
257:
258: } else if (brightness > XmCOLOR_LITE_THRESHOLD) {
259: // lite background
260: color_value = br;
261: color_value -= (color_value * XmCOLOR_LITE_BS_FACTOR) / 100;
262: red = color_value;
263:
264: color_value = bg;
265: color_value -= (color_value * XmCOLOR_LITE_BS_FACTOR) / 100;
266: green = color_value;
267:
268: color_value = bb;
269: color_value -= (color_value * XmCOLOR_LITE_BS_FACTOR) / 100;
270: blue = color_value;
271:
272: } else {
273: // medium
274: f = XmCOLOR_LO_BS_FACTOR
275: + (brightness
276: * (XmCOLOR_HI_BS_FACTOR - XmCOLOR_LO_BS_FACTOR) / XmMAX_SHORT);
277:
278: color_value = br;
279: color_value -= (color_value * f) / 100;
280: red = color_value;
281:
282: color_value = bg;
283: color_value -= (color_value * f) / 100;
284: green = color_value;
285:
286: color_value = bb;
287: color_value -= (color_value * f) / 100;
288: blue = color_value;
289: }
290:
291: int ired = ((int) red) >> 8;
292: int igreen = ((int) green) >> 8;
293: int iblue = ((int) blue) >> 8;
294:
295: int ret = 0xff000000 | ired << 16 | igreen << 8 | iblue;
296:
297: return ret;
298: }
299:
300: static int calculateSelectFromBackground(int r, int g, int b) {
301:
302: float color_value, f;
303:
304: int br = r << 8;
305: int bg = g << 8;
306: int bb = b << 8;
307:
308: int brightness = brightness(r, g, b);
309:
310: float red;
311: float green;
312: float blue;
313:
314: if (brightness < XmCOLOR_DARK_THRESHOLD) {
315: // dark background
316: color_value = br;
317: color_value += XmCOLOR_DARK_SEL_FACTOR
318: * (XmMAX_SHORT - color_value) / 100;
319: red = color_value;
320:
321: color_value = bg;
322: color_value += XmCOLOR_DARK_SEL_FACTOR
323: * (XmMAX_SHORT - color_value) / 100;
324: green = color_value;
325:
326: color_value = bb;
327: color_value += XmCOLOR_DARK_SEL_FACTOR
328: * (XmMAX_SHORT - color_value) / 100;
329: blue = color_value;
330:
331: } else if (brightness > XmCOLOR_LITE_THRESHOLD) {
332: // lite background
333: color_value = br;
334: color_value -= (color_value * XmCOLOR_LITE_SEL_FACTOR) / 100;
335: red = color_value;
336:
337: color_value = bg;
338: color_value -= (color_value * XmCOLOR_LITE_SEL_FACTOR) / 100;
339: green = color_value;
340:
341: color_value = bb;
342: color_value -= (color_value * XmCOLOR_LITE_SEL_FACTOR) / 100;
343: blue = color_value;
344:
345: } else {
346: // medium
347: f = XmCOLOR_LO_SEL_FACTOR
348: + (brightness
349: * (XmCOLOR_HI_SEL_FACTOR - XmCOLOR_LO_SEL_FACTOR) / XmMAX_SHORT);
350:
351: color_value = br;
352: color_value -= (color_value * f) / 100;
353: red = color_value;
354:
355: color_value = bg;
356: color_value -= (color_value * f) / 100;
357: green = color_value;
358:
359: color_value = bb;
360: color_value -= (color_value * f) / 100;
361: blue = color_value;
362: }
363:
364: int ired = ((int) red) >> 8;
365: int igreen = ((int) green) >> 8;
366: int iblue = ((int) blue) >> 8;
367:
368: int ret = 0xff000000 | ired << 16 | igreen << 8 | iblue;
369:
370: return ret;
371: }
372:
373: static void loadSystemColorsForCDE(int[] systemColors)
374: throws Exception {
375: // System.out.println("loadSystemColorsForCDE");
376: XAtom resourceManager = XAtom.get("RESOURCE_MANAGER");
377:
378: String resourceString = resourceManager.getProperty(XToolkit
379: .getDefaultRootWindow());
380:
381: int index = resourceString.indexOf("ColorPalette:");
382: int len = resourceString.length();
383: while ((index < len) && (resourceString.charAt(index) != ':'))
384: index++;
385: index++; // skip :
386: if (resourceString.charAt(index) == '\t')
387: index++; // skip \t
388:
389: String paletteFile = resourceString.substring(index,
390: resourceString.indexOf("\n", index));
391:
392: //System.out.println("Palette File = " + paletteFile);
393:
394: // Check if palette is a user palette.
395:
396: String paletteFilePath = System.getProperty("user.home")
397: + "/.dt/palettes/" + paletteFile;
398:
399: File pFile = new File(paletteFilePath);
400: if (!pFile.exists()) {
401: // Must be a system palette
402: paletteFilePath = "/usr/dt/palettes/" + paletteFile;
403: pFile = new File(paletteFilePath);
404: if (!pFile.exists()) {
405: throw new FileNotFoundException("Could not open : "
406: + paletteFilePath);
407: }
408: }
409: BufferedReader bfr = new BufferedReader(new FileReader(pFile));
410:
411: int colors[] = new int[8];
412: int r, g, b;
413: String temp, color;
414:
415: for (int i = 0; i < 8; i++) {
416: temp = bfr.readLine();
417: color = temp.substring(1, temp.length());
418: r = Integer.valueOf(color.substring(0, 4), 16).intValue() >> 8;
419: g = Integer.valueOf(color.substring(4, 8), 16).intValue() >> 8;
420: b = Integer.valueOf(color.substring(8, 12), 16).intValue() >> 8;
421: colors[i] = 0xff000000 | r << 16 | g << 8 | b;
422: // System.out.println("color["+i+"]="+Integer.toHexString(colors[i]) + "r = " +r + "g="+g+"b="+b);
423: }
424:
425: systemColors[SystemColor.ACTIVE_CAPTION] = colors[0];
426: systemColors[SystemColor.ACTIVE_CAPTION_BORDER] = colors[0];
427:
428: systemColors[SystemColor.INACTIVE_CAPTION] = colors[1];
429: systemColors[SystemColor.INACTIVE_CAPTION_BORDER] = colors[1];
430:
431: systemColors[SystemColor.WINDOW] = colors[1];
432:
433: systemColors[SystemColor.WINDOW_BORDER] = colors[1];
434: systemColors[SystemColor.MENU] = colors[1];
435:
436: systemColors[SystemColor.TEXT] = colors[3];
437:
438: systemColors[SystemColor.SCROLLBAR] = colors[1];
439: systemColors[SystemColor.CONTROL] = colors[1];
440:
441: int activeFore;
442: int inactiveFore;
443: int textFore;
444:
445: r = (colors[0] & 0x00FF0000) >> 16;
446: g = (colors[0] & 0x0000FF00) >> 8;
447: b = (colors[0] & 0x000000FF);
448:
449: activeFore = MotifColorUtilities
450: .calculateForegroundFromBackground(r, g, b);
451:
452: r = (colors[1] & 0x00FF0000) >> 16;
453: g = (colors[1] & 0x0000FF00) >> 8;
454: b = (colors[1] & 0x000000FF);
455:
456: inactiveFore = MotifColorUtilities
457: .calculateForegroundFromBackground(r, g, b);
458:
459: int top_shadow = MotifColorUtilities
460: .calculateTopShadowFromBackground(r, g, b);
461: int bottom_shadow = MotifColorUtilities
462: .calculateBottomShadowFromBackground(r, g, b);
463:
464: r = (colors[3] & 0x00FF0000) >> 16;
465: g = (colors[3] & 0x0000FF00) >> 8;
466: b = (colors[3] & 0x000000FF);
467:
468: textFore = MotifColorUtilities
469: .calculateForegroundFromBackground(r, g, b);
470:
471: systemColors[SystemColor.ACTIVE_CAPTION_TEXT] = activeFore;
472: systemColors[SystemColor.INACTIVE_CAPTION_TEXT] = inactiveFore;
473: systemColors[SystemColor.WINDOW_TEXT] = inactiveFore;
474: systemColors[SystemColor.MENU_TEXT] = inactiveFore;
475: systemColors[SystemColor.TEXT_TEXT] = textFore;
476: systemColors[SystemColor.TEXT_HIGHLIGHT] = MotifColorUtilities.BLACK;
477: systemColors[SystemColor.TEXT_HIGHLIGHT_TEXT] = MotifColorUtilities.DEFAULT_COLOR;
478: systemColors[SystemColor.CONTROL_TEXT] = inactiveFore;
479: Color tmp = new Color(top_shadow);
480: systemColors[SystemColor.CONTROL_HIGHLIGHT] = top_shadow;
481: systemColors[SystemColor.CONTROL_LT_HIGHLIGHT] = tmp.brighter()
482: .getRGB();
483:
484: tmp = new Color(bottom_shadow);
485: systemColors[SystemColor.CONTROL_SHADOW] = bottom_shadow;
486: systemColors[SystemColor.CONTROL_DK_SHADOW] = tmp.darker()
487: .getRGB();
488:
489: }
490:
491: static void loadMotifDefaultColors(int[] systemColors) {
492: //fix for 5092883. WINDOW should be light gray and TEXT should be WHITE to look similar to Motif
493: systemColors[SystemColor.WINDOW] = MotifColorUtilities.MOTIF_WINDOW_COLOR;
494: systemColors[SystemColor.TEXT] = MotifColorUtilities.WHITE;
495: systemColors[SystemColor.WINDOW_TEXT] = MotifColorUtilities.BLACK;
496: systemColors[SystemColor.MENU_TEXT] = MotifColorUtilities.BLACK;
497: systemColors[SystemColor.ACTIVE_CAPTION_TEXT] = MotifColorUtilities.BLACK;
498: systemColors[SystemColor.INACTIVE_CAPTION_TEXT] = MotifColorUtilities.BLACK;
499: systemColors[SystemColor.TEXT_TEXT] = MotifColorUtilities.BLACK;
500: systemColors[SystemColor.TEXT_HIGHLIGHT] = MotifColorUtilities.BLACK;
501: systemColors[SystemColor.TEXT_HIGHLIGHT_TEXT] = MotifColorUtilities.DEFAULT_COLOR;
502: systemColors[SystemColor.CONTROL_TEXT] = MotifColorUtilities.BLACK;
503: systemColors[SystemColor.WINDOW_BORDER] = MotifColorUtilities.DEFAULT_COLOR;
504: systemColors[SystemColor.MENU] = MotifColorUtilities.DEFAULT_COLOR;
505: systemColors[SystemColor.SCROLLBAR] = MotifColorUtilities.DEFAULT_COLOR;
506: systemColors[SystemColor.CONTROL] = MotifColorUtilities.MOTIF_WINDOW_COLOR;
507:
508: int r = (MotifColorUtilities.DEFAULT_COLOR & 0x00FF0000) >> 16;
509: int g = (MotifColorUtilities.DEFAULT_COLOR & 0x0000FF00) >> 8;
510: int b = (MotifColorUtilities.DEFAULT_COLOR & 0x000000FF);
511:
512: int top_shadow = MotifColorUtilities
513: .calculateTopShadowFromBackground(r, g, b);
514: int bottom_shadow = MotifColorUtilities
515: .calculateBottomShadowFromBackground(r, g, b);
516:
517: Color tmp = new Color(top_shadow);
518: systemColors[SystemColor.CONTROL_HIGHLIGHT] = top_shadow;
519: systemColors[SystemColor.CONTROL_LT_HIGHLIGHT] = tmp.brighter()
520: .getRGB();
521:
522: tmp = new Color(bottom_shadow);
523: systemColors[SystemColor.CONTROL_SHADOW] = bottom_shadow;
524: systemColors[SystemColor.CONTROL_DK_SHADOW] = tmp.darker()
525: .getRGB();
526:
527: }
528:
529: static void loadSystemColors(int[] systemColors) {
530: if ("Linux".equals(AccessController
531: .doPrivileged(new GetPropertyAction("os.name")))) { // Load motif default colors on Linux.
532: loadMotifDefaultColors(systemColors);
533: } else {
534: try {
535: loadSystemColorsForCDE(systemColors);
536: } catch (Exception e) // Failure to load CDE colors.
537: {
538: loadMotifDefaultColors(systemColors);
539: }
540: }
541: }
542: }
|