1 /* 2 * Copyright (c) 2003, 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 sun.awt.X11; 27 28 import java.awt.*; 29 import java.io.*; 30 import sun.security.action.GetPropertyAction; 31 import java.security.AccessController; 32 33 /** 34 * 35 * This class contains code that is need to mimic the 36 * Motif Color selection and color defaults code. 37 * 38 * Portions of this code have been ported to java from 39 * Motif sources (Color.c) (ColorP.h) etc. 40 * 41 * Author: Bino George 42 * 43 */ 44 45 class MotifColorUtilities { 46 47 48 static final float XmRED_LUMINOSITY=0.30f; 49 static final float XmGREEN_LUMINOSITY=0.59f; 50 static final float XmBLUE_LUMINOSITY=0.11f; 51 static final int XmINTENSITY_FACTOR=75; 52 static final int XmLIGHT_FACTOR=0; 53 static final int XmLUMINOSITY_FACTOR=25; 54 55 static final int XmMAX_SHORT=65535; 56 57 58 static final int XmCOLOR_PERCENTILE=(XmMAX_SHORT / 100); 59 60 static final int XmDEFAULT_DARK_THRESHOLD=20; 61 static final int XmDEFAULT_LIGHT_THRESHOLD=93; 62 static final int XmDEFAULT_FOREGROUND_THRESHOLD=70; 63 64 static final int BLACK = 0xFF000000; 65 static final int WHITE = 0xFFFFFFFF; 66 static final int MOTIF_WINDOW_COLOR= 0xFFDFDFDF; 67 68 static final int DEFAULT_COLOR = 0xFFC4C4C4; 69 70 static final int XmCOLOR_LITE_THRESHOLD = XmDEFAULT_LIGHT_THRESHOLD * XmCOLOR_PERCENTILE; 71 static final int XmCOLOR_DARK_THRESHOLD = XmDEFAULT_DARK_THRESHOLD * XmCOLOR_PERCENTILE; 72 static final int XmFOREGROUND_THRESHOLD = XmDEFAULT_FOREGROUND_THRESHOLD * XmCOLOR_PERCENTILE; 73 74 /* LITE color model 75 percent to interpolate RGB towards black for SEL, BS, TS */ 76 77 static final int XmCOLOR_LITE_SEL_FACTOR = 15; 78 static final int XmCOLOR_LITE_BS_FACTOR = 40; 79 static final int XmCOLOR_LITE_TS_FACTOR = 20; 80 81 /* DARK color model 82 percent to interpolate RGB towards white for SEL, BS, TS */ 83 84 static final int XmCOLOR_DARK_SEL_FACTOR= 15; 85 static final int XmCOLOR_DARK_BS_FACTOR = 30; 86 static final int XmCOLOR_DARK_TS_FACTOR = 50; 87 88 /* STD color model 89 percent to interpolate RGB towards black for SEL, BS 90 percent to interpolate RGB towards white for TS 91 HI values used for high brightness (within STD) 92 LO values used for low brightness (within STD) 93 Interpolate factors between HI & LO values based on brightness */ 94 95 static final int XmCOLOR_HI_SEL_FACTOR = 15; 96 static final int XmCOLOR_HI_BS_FACTOR = 40; 97 static final int XmCOLOR_HI_TS_FACTOR = 60; 98 99 static final int XmCOLOR_LO_SEL_FACTOR= 15; 100 static final int XmCOLOR_LO_BS_FACTOR = 60; 101 static final int XmCOLOR_LO_TS_FACTOR = 50; 102 103 static int brightness( int red, int green, int blue ) 104 { 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 117 intensity = (red + green + blue) / 3; 118 119 120 /* 121 * The casting nonsense below is to try to control the point at 122 * the truncation occurs. 123 */ 124 125 luminosity = (int) ((XmRED_LUMINOSITY * (float) red) 126 + (XmGREEN_LUMINOSITY * (float) green) 127 + (XmBLUE_LUMINOSITY * (float) blue)); 128 129 maxprimary = ( (red > green) ? 130 ( (red > blue) ? red : blue ) : 131 ( (green > blue) ? green : blue ) ); 132 133 minprimary = ( (red < green) ? 134 ( (red < blue) ? red : blue ) : 135 ( (green < blue) ? green : blue ) ); 136 137 light = (minprimary + maxprimary) / 2; 138 139 brightness = ( (intensity * XmINTENSITY_FACTOR) + 140 (light * XmLIGHT_FACTOR) + 141 (luminosity * XmLUMINOSITY_FACTOR) ) / 100; 142 return Math.round(brightness); 143 } 144 145 static int calculateForegroundFromBackground(int r, int g, int b) { 146 147 int foreground = WHITE; 148 int brightness = brightness(r,g,b); 149 150 if (brightness > XmFOREGROUND_THRESHOLD) { 151 foreground = BLACK; 152 } 153 else foreground = WHITE; 154 155 return foreground; 156 } 157 158 static int calculateTopShadowFromBackground(int r, int g, int b) { 159 160 float color_value,f; 161 162 int br = r << 8; 163 int bg = g << 8; 164 int bb = b << 8; 165 166 int brightness = brightness(r,g,b); 167 168 float red; 169 float green; 170 float blue; 171 172 if (brightness < XmCOLOR_DARK_THRESHOLD) { 173 // dark background 174 175 color_value = br; 176 color_value += XmCOLOR_DARK_TS_FACTOR * 177 (XmMAX_SHORT - color_value) / 100; 178 red = color_value; 179 180 color_value = bg; 181 color_value += XmCOLOR_DARK_TS_FACTOR * 182 (XmMAX_SHORT - color_value) / 100; 183 green = color_value; 184 185 color_value = bb; 186 color_value += XmCOLOR_DARK_TS_FACTOR * 187 (XmMAX_SHORT - color_value) / 100; 188 blue = color_value; 189 } 190 else if (brightness > XmCOLOR_LITE_THRESHOLD) { 191 // lite background 192 193 color_value = br; 194 color_value -= (color_value * XmCOLOR_LITE_TS_FACTOR) / 100; 195 red = color_value; 196 197 color_value = bg; 198 color_value -= (color_value * XmCOLOR_LITE_TS_FACTOR) / 100; 199 green = color_value; 200 201 color_value = bb; 202 color_value -= (color_value * XmCOLOR_LITE_TS_FACTOR) / 100; 203 blue = color_value; 204 205 } 206 else { 207 // medium 208 f = XmCOLOR_LO_TS_FACTOR + (brightness 209 * ( XmCOLOR_HI_TS_FACTOR - XmCOLOR_LO_TS_FACTOR ) 210 / XmMAX_SHORT); 211 212 color_value = br; 213 color_value += f * ( XmMAX_SHORT - color_value ) / 100; 214 red = color_value; 215 216 color_value = bg; 217 color_value += f * ( XmMAX_SHORT - color_value ) / 100; 218 green = color_value; 219 220 color_value = bb; 221 color_value += f * ( XmMAX_SHORT - color_value ) / 100; 222 blue = color_value; 223 224 225 } 226 227 228 int ired = ((int)red) >> 8; 229 int igreen = ((int)green) >> 8; 230 int iblue = ((int)blue) >> 8; 231 232 int ret = 0xff000000 | ired <<16 | igreen<<8 | iblue; 233 234 return ret; 235 } 236 237 238 static int calculateBottomShadowFromBackground(int r, int g, int b) { 239 240 float color_value,f; 241 242 int br = r << 8; 243 int bg = g << 8; 244 int bb = b << 8; 245 246 int brightness = brightness(r,g,b); 247 248 float red; 249 float green; 250 float blue; 251 252 if (brightness < XmCOLOR_DARK_THRESHOLD) { 253 // dark background 254 color_value = br; 255 color_value += XmCOLOR_DARK_BS_FACTOR * 256 (XmMAX_SHORT - color_value) / 100; 257 red = color_value; 258 259 color_value = bg; 260 color_value += XmCOLOR_DARK_BS_FACTOR * 261 (XmMAX_SHORT - color_value) / 100; 262 green = color_value; 263 264 color_value = bb; 265 color_value += XmCOLOR_DARK_BS_FACTOR * 266 (XmMAX_SHORT - color_value) / 100; 267 blue = color_value; 268 269 } 270 else if (brightness > XmCOLOR_LITE_THRESHOLD) { 271 // lite background 272 color_value = br; 273 color_value -= (color_value * XmCOLOR_LITE_BS_FACTOR) / 100; 274 red = color_value; 275 276 color_value = bg; 277 color_value -= (color_value * XmCOLOR_LITE_BS_FACTOR) / 100; 278 green = color_value; 279 280 color_value = bb; 281 color_value -= (color_value * XmCOLOR_LITE_BS_FACTOR) / 100; 282 blue = color_value; 283 284 } 285 else { 286 // medium 287 f = XmCOLOR_LO_BS_FACTOR + (brightness 288 * ( XmCOLOR_HI_BS_FACTOR - XmCOLOR_LO_BS_FACTOR ) 289 / XmMAX_SHORT); 290 291 color_value = br; 292 color_value -= (color_value * f) / 100; 293 red = color_value; 294 295 color_value = bg; 296 color_value -= (color_value * f) / 100; 297 green = color_value; 298 299 color_value = bb; 300 color_value -= (color_value * f) / 100; 301 blue = color_value; 302 } 303 304 305 int ired = ((int)red) >> 8; 306 int igreen = ((int)green) >> 8; 307 int iblue = ((int)blue) >> 8; 308 309 int ret = 0xff000000 | ired <<16 | igreen<<8 | iblue; 310 311 return ret; 312 } 313 314 static int calculateSelectFromBackground(int r, int g, int b) { 315 316 float color_value,f; 317 318 int br = r << 8; 319 int bg = g << 8; 320 int bb = b << 8; 321 322 int brightness = brightness(r,g,b); 323 324 float red; 325 float green; 326 float blue; 327 328 if (brightness < XmCOLOR_DARK_THRESHOLD) { 329 // dark background 330 color_value = br; 331 color_value += XmCOLOR_DARK_SEL_FACTOR * 332 (XmMAX_SHORT - color_value) / 100; 333 red = color_value; 334 335 color_value = bg; 336 color_value += XmCOLOR_DARK_SEL_FACTOR * 337 (XmMAX_SHORT - color_value) / 100; 338 green = color_value; 339 340 color_value = bb; 341 color_value += XmCOLOR_DARK_SEL_FACTOR * 342 (XmMAX_SHORT - color_value) / 100; 343 blue = color_value; 344 345 } 346 else if (brightness > XmCOLOR_LITE_THRESHOLD) { 347 // lite background 348 color_value = br; 349 color_value -= (color_value * XmCOLOR_LITE_SEL_FACTOR) / 100; 350 red = color_value; 351 352 color_value = bg; 353 color_value -= (color_value * XmCOLOR_LITE_SEL_FACTOR) / 100; 354 green = color_value; 355 356 color_value = bb; 357 color_value -= (color_value * XmCOLOR_LITE_SEL_FACTOR) / 100; 358 blue = color_value; 359 360 } 361 else { 362 // medium 363 f = XmCOLOR_LO_SEL_FACTOR + (brightness 364 * ( XmCOLOR_HI_SEL_FACTOR - XmCOLOR_LO_SEL_FACTOR ) 365 / XmMAX_SHORT); 366 367 color_value = br; 368 color_value -= (color_value * f) / 100; 369 red = color_value; 370 371 color_value = bg; 372 color_value -= (color_value * f) / 100; 373 green = color_value; 374 375 color_value = bb; 376 color_value -= (color_value * f) / 100; 377 blue = color_value; 378 } 379 380 381 int ired = ((int)red) >> 8; 382 int igreen = ((int)green) >> 8; 383 int iblue = ((int)blue) >> 8; 384 385 int ret = 0xff000000 | ired <<16 | igreen<<8 | iblue; 386 387 return ret; 388 } 389 390 static void loadSystemColorsForCDE(int[] systemColors) throws Exception { 391 // System.out.println("loadSystemColorsForCDE"); 392 XAtom resourceManager = XAtom.get("RESOURCE_MANAGER"); 393 394 String resourceString = resourceManager.getProperty(XToolkit.getDefaultRootWindow()); 395 396 int index = resourceString.indexOf("ColorPalette:"); 397 int len = resourceString.length(); 398 while ( (index < len) && (resourceString.charAt(index) != ':')) index++; 399 index++; // skip : 400 if (resourceString.charAt(index) == '\t') index++; // skip \t 401 402 String paletteFile = resourceString.substring(index,resourceString.indexOf("\n",index)); 403 404 //System.out.println("Palette File = " + paletteFile); 405 406 // Check if palette is a user palette. 407 408 String paletteFilePath = System.getProperty("user.home") + "/.dt/palettes/" + paletteFile; 409 410 File pFile = new File(paletteFilePath); 411 if (!pFile.exists()) 412 { 413 // Must be a system palette 414 paletteFilePath = "/usr/dt/palettes/" + paletteFile; 415 pFile = new File(paletteFilePath); 416 if (!pFile.exists()) 417 { 418 throw new FileNotFoundException("Could not open : "+ paletteFilePath); 419 } 420 } 421 BufferedReader bfr = new BufferedReader(new FileReader(pFile)); 422 423 int[] colors = new int[8]; 424 int r,g,b; 425 String temp,color; 426 427 for (int i=0;i<8;i++) { 428 temp = bfr.readLine(); 429 color = temp.substring(1,temp.length()); 430 r = Integer.valueOf(color.substring(0,4),16).intValue() >> 8; 431 g = Integer.valueOf(color.substring(4,8),16).intValue() >> 8; 432 b = Integer.valueOf(color.substring(8,12),16).intValue() >> 8; 433 colors[i] = 0xff000000 | r<<16 | g<<8 | b; 434 // System.out.println("color["+i+"]="+Integer.toHexString(colors[i]) + "r = " +r + "g="+g+"b="+b); 435 } 436 437 systemColors[SystemColor.ACTIVE_CAPTION] = colors[0]; 438 systemColors[SystemColor.ACTIVE_CAPTION_BORDER] = colors[0]; 439 440 systemColors[SystemColor.INACTIVE_CAPTION] = colors[1]; 441 systemColors[SystemColor.INACTIVE_CAPTION_BORDER] = colors[1]; 442 443 systemColors[SystemColor.WINDOW] = colors[1]; 444 445 systemColors[SystemColor.WINDOW_BORDER] = colors[1]; 446 systemColors[SystemColor.MENU] = colors[1]; 447 448 systemColors[SystemColor.TEXT] = colors[3]; 449 450 systemColors[SystemColor.SCROLLBAR] = colors[1]; 451 systemColors[SystemColor.CONTROL] = colors[1]; 452 453 int activeFore; 454 int inactiveFore; 455 int textFore; 456 457 458 r = (colors[0] & 0x00FF0000) >> 16; 459 g = (colors[0] & 0x0000FF00) >> 8; 460 b = (colors[0] & 0x000000FF); 461 462 activeFore = MotifColorUtilities.calculateForegroundFromBackground(r,g,b); 463 464 r = (colors[1] & 0x00FF0000) >> 16; 465 g = (colors[1] & 0x0000FF00) >> 8; 466 b = (colors[1] & 0x000000FF); 467 468 inactiveFore = MotifColorUtilities.calculateForegroundFromBackground(r,g,b); 469 470 int top_shadow = MotifColorUtilities.calculateTopShadowFromBackground(r,g,b); 471 int bottom_shadow = MotifColorUtilities.calculateBottomShadowFromBackground(r,g,b); 472 473 474 r = (colors[3] & 0x00FF0000) >> 16; 475 g = (colors[3] & 0x0000FF00) >> 8; 476 b = (colors[3] & 0x000000FF); 477 478 textFore = MotifColorUtilities.calculateForegroundFromBackground(r,g,b); 479 480 481 systemColors[SystemColor.ACTIVE_CAPTION_TEXT] = activeFore; 482 systemColors[SystemColor.INACTIVE_CAPTION_TEXT] = inactiveFore; 483 systemColors[SystemColor.WINDOW_TEXT] = inactiveFore; 484 systemColors[SystemColor.MENU_TEXT] = inactiveFore; 485 systemColors[SystemColor.TEXT_TEXT] = textFore; 486 systemColors[SystemColor.TEXT_HIGHLIGHT] = MotifColorUtilities.BLACK; 487 systemColors[SystemColor.TEXT_HIGHLIGHT_TEXT] = MotifColorUtilities.DEFAULT_COLOR; 488 systemColors[SystemColor.CONTROL_TEXT] = inactiveFore; 489 Color tmp = new Color(top_shadow); 490 systemColors[SystemColor.CONTROL_HIGHLIGHT] = top_shadow; 491 systemColors[SystemColor.CONTROL_LT_HIGHLIGHT] = tmp.brighter().getRGB(); 492 493 tmp = new Color(bottom_shadow); 494 systemColors[SystemColor.CONTROL_SHADOW] = bottom_shadow; 495 systemColors[SystemColor.CONTROL_DK_SHADOW] = tmp.darker().getRGB(); 496 497 } 498 499 static void loadMotifDefaultColors(int[] systemColors) { 500 //fix for 5092883. WINDOW should be light gray and TEXT should be WHITE to look similar to Motif 501 systemColors[SystemColor.WINDOW] = MotifColorUtilities.MOTIF_WINDOW_COLOR; 502 systemColors[SystemColor.TEXT] = MotifColorUtilities.WHITE; 503 systemColors[SystemColor.WINDOW_TEXT] = MotifColorUtilities.BLACK; 504 systemColors[SystemColor.MENU_TEXT] = MotifColorUtilities.BLACK; 505 systemColors[SystemColor.ACTIVE_CAPTION_TEXT] = MotifColorUtilities.BLACK; 506 systemColors[SystemColor.INACTIVE_CAPTION_TEXT] = MotifColorUtilities.BLACK; 507 systemColors[SystemColor.TEXT_TEXT] = MotifColorUtilities.BLACK; 508 systemColors[SystemColor.TEXT_HIGHLIGHT] = MotifColorUtilities.BLACK; 509 systemColors[SystemColor.TEXT_HIGHLIGHT_TEXT] = MotifColorUtilities.DEFAULT_COLOR; 510 systemColors[SystemColor.CONTROL_TEXT] = MotifColorUtilities.BLACK; 511 systemColors[SystemColor.WINDOW_BORDER] = MotifColorUtilities.DEFAULT_COLOR; 512 systemColors[SystemColor.MENU] = MotifColorUtilities.DEFAULT_COLOR; 513 systemColors[SystemColor.SCROLLBAR] = MotifColorUtilities.DEFAULT_COLOR; 514 systemColors[SystemColor.CONTROL] = MotifColorUtilities.MOTIF_WINDOW_COLOR; 515 516 int r = (MotifColorUtilities.DEFAULT_COLOR & 0x00FF0000) >> 16; 517 int g = (MotifColorUtilities.DEFAULT_COLOR & 0x0000FF00) >> 8; 518 int b = (MotifColorUtilities.DEFAULT_COLOR & 0x000000FF); 519 520 521 int top_shadow = MotifColorUtilities.calculateTopShadowFromBackground(r,g,b); 522 int bottom_shadow = MotifColorUtilities.calculateBottomShadowFromBackground(r,g,b); 523 524 Color tmp = new Color(top_shadow); 525 systemColors[SystemColor.CONTROL_HIGHLIGHT] = top_shadow; 526 systemColors[SystemColor.CONTROL_LT_HIGHLIGHT] = tmp.brighter().getRGB(); 527 528 tmp = new Color(bottom_shadow); 529 systemColors[SystemColor.CONTROL_SHADOW] = bottom_shadow; 530 systemColors[SystemColor.CONTROL_DK_SHADOW] = tmp.darker().getRGB(); 531 532 } 533 534 535 static void loadSystemColors(int[] systemColors) { 536 if ("Linux".equals(AccessController.doPrivileged(new GetPropertyAction("os.name")))) { // Load motif default colors on Linux. 537 loadMotifDefaultColors(systemColors); 538 } 539 else 540 { 541 try { 542 loadSystemColorsForCDE(systemColors); 543 } 544 catch (Exception e) // Failure to load CDE colors. 545 { 546 loadMotifDefaultColors(systemColors); 547 } 548 } 549 } 550 }