1 /* 2 * Copyright (c) 1995, 2014, 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 /* 27 * Image dithering and rendering code for X11. 28 */ 29 30 #include <stdio.h> 31 #include <stdlib.h> 32 #include <string.h> 33 #include <math.h> 34 #include <sys/time.h> 35 #include <sys/resource.h> 36 #ifndef HEADLESS 37 #include <X11/Xlib.h> 38 #include <X11/Xatom.h> 39 #include <X11/Xutil.h> 40 #endif /* !HEADLESS */ 41 #include "awt_p.h" 42 #include "java_awt_Color.h" 43 #include "java_awt_SystemColor.h" 44 #include "java_awt_color_ColorSpace.h" 45 #include "java_awt_Transparency.h" 46 #include "java_awt_image_DataBuffer.h" 47 #include "img_colors.h" 48 #include "imageInitIDs.h" 49 #include "dither.h" 50 51 #include <jni.h> 52 #include <jni_util.h> 53 54 #ifdef DEBUG 55 static int debug_colormap = 0; 56 #endif 57 58 #define MAX_PALETTE8_SIZE (256) 59 #define MAX_PALETTE12_SIZE (4096) 60 #define MAX_PALETTE_SIZE MAX_PALETTE12_SIZE 61 62 /* returns the absolute value x */ 63 #define ABS(x) ((x) < 0 ? -(x) : (x)) 64 65 #define CLIP(val,min,max) ((val < min) ? min : ((val > max) ? max : val)) 66 67 #define RGBTOGRAY(r, g, b) ((int) (.299 * r + .587 * g + .114 * b + 0.5)) 68 69 enum { 70 FREE_COLOR = 0, 71 LIKELY_COLOR = 1, 72 UNAVAILABLE_COLOR = 2, 73 ALLOCATED_COLOR = 3 74 }; 75 76 /* 77 * Constants to control the filling of the colormap. 78 * By default, try to allocate colors in the default colormap until 79 * CMAP_ALLOC_DEFAULT colors are being used (by Java and/or other 80 * applications). 81 * For cases where the default colormap may already have a large 82 * number of colors in it, make sure that we ourselves try to add 83 * at least CMAP_ALLOC_MIN new colors, even if we need to allocate 84 * more than the DEFAULT to do that. 85 * Under no circumstances will the colormap be filled to more than 86 * CMAP_ALLOC_MAX colors. 87 */ 88 #define CMAP_ALLOC_MIN 100 /* minimum number of colors to "add" */ 89 #define CMAP_ALLOC_DEFAULT 200 /* default number of colors in cmap */ 90 #define CMAP_ALLOC_MAX 245 /* maximum number of colors in cmap */ 91 92 #ifdef __solaris__ 93 #include <sys/utsname.h> 94 95 struct { 96 char *machine; 97 int cubesize; 98 } machinemap[] = { 99 { "i86pc", LOOKUPSIZE / 4 }, /* BugTraq ID 4102599 */ 100 { "sun4c", LOOKUPSIZE / 4 }, 101 { "sun4m", LOOKUPSIZE / 2 }, 102 { "sun4d", LOOKUPSIZE / 2 }, 103 { "sun4u", LOOKUPSIZE / 1 }, 104 }; 105 106 #define MACHMAPSIZE (sizeof(machinemap) / sizeof(machinemap[0])) 107 108 int getVirtCubeSize() { 109 struct utsname name; 110 int i, ret; 111 112 ret = uname(&name); 113 if (ret < 0) { 114 #ifdef DEBUG 115 #include <errno.h> 116 jio_fprintf(stderr, "uname errno = %d, using default cubesize %d\n", 117 errno, LOOKUPSIZE); 118 #endif 119 return LOOKUPSIZE; 120 } 121 122 for (i = 0; i < MACHMAPSIZE; i++) { 123 if (strcmp(name.machine, machinemap[i].machine) == 0) { 124 #ifdef DEBUG 125 if (debug_colormap) { 126 jio_fprintf(stderr, "'%s'.cubesize = '%d'\n", 127 machinemap[i].machine, machinemap[i].cubesize); 128 } 129 #endif 130 return machinemap[i].cubesize; 131 } 132 } 133 134 #ifdef DEBUG 135 if (debug_colormap) { 136 jio_fprintf(stderr, "unknown machine '%s' using cubesize %d\n", 137 name.machine, LOOKUPSIZE); 138 } 139 #endif 140 return LOOKUPSIZE; 141 } 142 #else /* __solaris__ */ 143 #define getVirtCubeSize() (LOOKUPSIZE) 144 #endif /* __solaris__ */ 145 146 unsigned char img_bwgamma[256]; 147 uns_ordered_dither_array img_oda_alpha; 148 149 #ifdef NEED_IMAGE_CONVERT 150 ImgConvertFcn DirectImageConvert; 151 ImgConvertFcn Dir16IcmOpqUnsImageConvert; 152 ImgConvertFcn Dir16IcmTrnUnsImageConvert; 153 ImgConvertFcn Dir16IcmOpqSclImageConvert; 154 ImgConvertFcn Dir16DcmOpqUnsImageConvert; 155 ImgConvertFcn Dir16DcmTrnUnsImageConvert; 156 ImgConvertFcn Dir16DcmOpqSclImageConvert; 157 ImgConvertFcn Dir32IcmOpqUnsImageConvert; 158 ImgConvertFcn Dir32IcmTrnUnsImageConvert; 159 ImgConvertFcn Dir32IcmOpqSclImageConvert; 160 ImgConvertFcn Dir32DcmOpqUnsImageConvert; 161 ImgConvertFcn Dir32DcmTrnUnsImageConvert; 162 ImgConvertFcn Dir32DcmOpqSclImageConvert; 163 164 ImgConvertFcn PseudoImageConvert; 165 ImgConvertFcn PseudoFSImageConvert; 166 ImgConvertFcn FSColorIcmOpqUnsImageConvert; 167 ImgConvertFcn FSColorDcmOpqUnsImageConvert; 168 ImgConvertFcn OrdColorIcmOpqUnsImageConvert; 169 ImgConvertFcn OrdColorDcmOpqUnsImageConvert; 170 171 #endif /* NEED_IMAGE_CONVERT */ 172 173 #ifndef HEADLESS 174 /* 175 * Find the best color. 176 */ 177 int 178 awt_color_matchTC(int r, int g, int b, AwtGraphicsConfigDataPtr awt_data) 179 { 180 r = CLIP(r, 0, 255); 181 g = CLIP(g, 0, 255); 182 b = CLIP(b, 0, 255); 183 return (((r >> awt_data->awtImage->clrdata.rScale) 184 << awt_data->awtImage->clrdata.rOff) | 185 ((g >> awt_data->awtImage->clrdata.gScale) 186 << awt_data->awtImage->clrdata.gOff) | 187 ((b >> awt_data->awtImage->clrdata.bScale) 188 << awt_data->awtImage->clrdata.bOff)); 189 } 190 191 int 192 awt_color_matchGS(int r, int g, int b, AwtGraphicsConfigDataPtr awt_data) 193 { 194 r = CLIP(r, 0, 255); 195 g = CLIP(g, 0, 255); 196 b = CLIP(b, 0, 255); 197 return awt_data->color_data->img_grays[RGBTOGRAY(r, g, b)]; 198 } 199 200 int 201 awt_color_match(int r, int g, int b, AwtGraphicsConfigDataPtr awt_data) 202 { 203 int besti = 0; 204 int mindist, i, t, d; 205 ColorEntry *p = awt_data->color_data->awt_Colors; 206 207 r = CLIP(r, 0, 255); 208 g = CLIP(g, 0, 255); 209 b = CLIP(b, 0, 255); 210 211 /* look for pure gray match */ 212 if ((r == g) && (g == b)) { 213 mindist = 256; 214 for (i = 0 ; i < awt_data->awt_num_colors ; i++, p++) 215 if (p->flags == ALLOCATED_COLOR) { 216 if (! ((p->r == p->g) && (p->g == p->b)) ) 217 continue; 218 d = ABS(p->r - r); 219 if (d == 0) 220 return i; 221 if (d < mindist) { 222 besti = i; 223 mindist = d; 224 } 225 } 226 return besti; 227 } 228 229 /* look for non-pure gray match */ 230 mindist = 256 * 256 * 256; 231 for (i = 0 ; i < awt_data->awt_num_colors ; i++, p++) 232 if (p->flags == ALLOCATED_COLOR) { 233 t = p->r - r; 234 d = t * t; 235 if (d >= mindist) 236 continue; 237 t = p->g - g; 238 d += t * t; 239 if (d >= mindist) 240 continue; 241 t = p->b - b; 242 d += t * t; 243 if (d >= mindist) 244 continue; 245 if (d == 0) 246 return i; 247 if (d < mindist) { 248 besti = i; 249 mindist = d; 250 } 251 } 252 return besti; 253 } 254 255 /* 256 * Allocate a color in the X color map and return the pixel. 257 * If the "expected pixel" is non-negative then we will only 258 * accept the allocation if we get exactly that pixel value. 259 * This prevents us from seeing a bunch of ReadWrite pixels 260 * allocated by another imaging application and duplicating 261 * that set of inaccessible pixels in our precious remaining 262 * ReadOnly colormap cells. 263 */ 264 static int 265 alloc_col(Display *dpy, Colormap cm, int r, int g, int b, int pixel, 266 AwtGraphicsConfigDataPtr awt_data) 267 { 268 XColor col; 269 270 r = CLIP(r, 0, 255); 271 g = CLIP(g, 0, 255); 272 b = CLIP(b, 0, 255); 273 274 col.flags = DoRed | DoGreen | DoBlue; 275 col.red = (r << 8) | r; 276 col.green = (g << 8) | g; 277 col.blue = (b << 8) | b; 278 if (XAllocColor(dpy, cm, &col)) { 279 #ifdef DEBUG 280 if (debug_colormap) 281 jio_fprintf(stdout, "allocated %d (%d,%d, %d)\n", col.pixel, r, g, b); 282 #endif 283 if (pixel >= 0 && col.pixel != (unsigned long)pixel) { 284 /* 285 * If we were trying to allocate a shareable "ReadOnly" 286 * color then we would have gotten back the expected 287 * pixel. If the returned pixel was different, then 288 * the source color that we were attempting to gain 289 * access to must be some other application's ReadWrite 290 * private color. We free the returned pixel so that 291 * we won't waste precious colormap entries by duplicating 292 * that color in the as yet unallocated entries. We 293 * return -1 here to indicate the failure to get the 294 * expected pixel. 295 */ 296 #ifdef DEBUG 297 if (debug_colormap) 298 jio_fprintf(stdout, " used by other app, freeing\n"); 299 #endif 300 awt_data->color_data->awt_Colors[pixel].flags = UNAVAILABLE_COLOR; 301 XFreeColors(dpy, cm, &col.pixel, 1, 0); 302 return -1; 303 } 304 /* 305 * Our current implementation doesn't support pixels which 306 * don't fit in 8 bit (even for 12-bit visuals) 307 */ 308 if (col.pixel > 255) { 309 #ifdef DEBUG 310 if (debug_colormap) 311 jio_fprintf(stdout, "pixel %d for (%d,%d, %d) is > 8 bit, releasing.\n", 312 col.pixel, r, g, b); 313 #endif 314 XFreeColors(dpy, cm, &col.pixel, 1, 0); 315 return awt_color_match(r, g, b, awt_data); 316 } 317 318 awt_data->color_data->awt_Colors[col.pixel].flags = ALLOCATED_COLOR; 319 awt_data->color_data->awt_Colors[col.pixel].r = col.red >> 8; 320 awt_data->color_data->awt_Colors[col.pixel].g = col.green >> 8; 321 awt_data->color_data->awt_Colors[col.pixel].b = col.blue >> 8; 322 if (awt_data->color_data->awt_icmLUT != 0) { 323 awt_data->color_data->awt_icmLUT2Colors[col.pixel] = col.pixel; 324 awt_data->color_data->awt_icmLUT[col.pixel] = 325 0xff000000 | 326 (awt_data->color_data->awt_Colors[col.pixel].r<<16) | 327 (awt_data->color_data->awt_Colors[col.pixel].g<<8) | 328 (awt_data->color_data->awt_Colors[col.pixel].b); 329 } 330 return col.pixel; 331 #ifdef DEBUG 332 } else if (debug_colormap) { 333 jio_fprintf(stdout, "can't allocate (%d,%d, %d)\n", r, g, b); 334 #endif 335 } 336 337 return awt_color_match(r, g, b, awt_data); 338 } 339 340 void 341 awt_allocate_systemcolors(XColor *colorsPtr, int num_pixels, AwtGraphicsConfigDataPtr awtData) { 342 int i; 343 int r, g, b, pixel; 344 345 for (i=0; i < num_pixels; i++) { 346 r = colorsPtr[i].red >> 8; 347 g = colorsPtr[i].green >> 8; 348 b = colorsPtr[i].blue >> 8; 349 pixel = alloc_col(awt_display, awtData->awt_cmap, r, g, b, -1, awtData); 350 } 351 } 352 #endif /* !HEADLESS */ 353 354 void 355 awt_fill_imgcv(ImgConvertFcn **array, int mask, int value, ImgConvertFcn fcn) 356 { 357 int i; 358 359 for (i = 0; i < NUM_IMGCV; i++) { 360 if ((i & mask) == value) { 361 array[i] = fcn; 362 } 363 } 364 } 365 366 #ifndef HEADLESS 367 /* 368 * called from X11Server_create() in xlib.c 369 */ 370 int 371 awt_allocate_colors(AwtGraphicsConfigDataPtr awt_data) 372 { 373 Display *dpy; 374 unsigned long freecolors[MAX_PALETTE_SIZE], plane_masks[1]; 375 int paletteSize; 376 XColor cols[MAX_PALETTE_SIZE]; 377 unsigned char reds[256], greens[256], blues[256]; 378 int indices[256]; 379 Colormap cm; 380 int i, j, k, cmapsize, nfree, depth, bpp; 381 int allocatedColorsNum, unavailableColorsNum; 382 XPixmapFormatValues *pPFV; 383 int numpfv; 384 XVisualInfo *pVI; 385 char *forcemono; 386 char *forcegray; 387 388 make_uns_ordered_dither_array(img_oda_alpha, 256); 389 390 391 forcemono = getenv("FORCEMONO"); 392 forcegray = getenv("FORCEGRAY"); 393 if (forcemono && !forcegray) 394 forcegray = forcemono; 395 396 /* 397 * Get the colormap and make sure we have the right visual 398 */ 399 dpy = awt_display; 400 cm = awt_data->awt_cmap; 401 depth = awt_data->awt_depth; 402 pVI = &awt_data->awt_visInfo; 403 awt_data->awt_num_colors = awt_data->awt_visInfo.colormap_size; 404 awt_data->awtImage = (awtImageData *) calloc (1, sizeof (awtImageData)); 405 406 pPFV = XListPixmapFormats(dpy, &numpfv); 407 if (pPFV) { 408 for (i = 0; i < numpfv; i++) { 409 if (pPFV[i].depth == depth) { 410 awt_data->awtImage->wsImageFormat = pPFV[i]; 411 break; 412 } 413 } 414 XFree(pPFV); 415 } 416 bpp = awt_data->awtImage->wsImageFormat.bits_per_pixel; 417 if (bpp == 24) { 418 bpp = 32; 419 } 420 awt_data->awtImage->clrdata.bitsperpixel = bpp; 421 awt_data->awtImage->Depth = depth; 422 423 if ((bpp == 32 || bpp == 16) && pVI->class == TrueColor && depth >= 15) { 424 awt_data->AwtColorMatch = awt_color_matchTC; 425 awt_data->awtImage->clrdata.rOff = 0; 426 for (i = pVI->red_mask; (i & 1) == 0; i >>= 1) { 427 awt_data->awtImage->clrdata.rOff++; 428 } 429 awt_data->awtImage->clrdata.rScale = 0; 430 while (i < 0x80) { 431 awt_data->awtImage->clrdata.rScale++; 432 i <<= 1; 433 } 434 awt_data->awtImage->clrdata.gOff = 0; 435 for (i = pVI->green_mask; (i & 1) == 0; i >>= 1) { 436 awt_data->awtImage->clrdata.gOff++; 437 } 438 awt_data->awtImage->clrdata.gScale = 0; 439 while (i < 0x80) { 440 awt_data->awtImage->clrdata.gScale++; 441 i <<= 1; 442 } 443 awt_data->awtImage->clrdata.bOff = 0; 444 for (i = pVI->blue_mask; (i & 1) == 0; i >>= 1) { 445 awt_data->awtImage->clrdata.bOff++; 446 } 447 awt_data->awtImage->clrdata.bScale = 0; 448 while (i < 0x80) { 449 awt_data->awtImage->clrdata.bScale++; 450 i <<= 1; 451 } 452 #ifdef NEED_IMAGE_CONVERT 453 awt_fill_imgcv(awt_data->awtImage->convert, 0, 0, DirectImageConvert); 454 awt_fill_imgcv(awt_data->awtImage->convert, 455 (IMGCV_SCALEBITS | IMGCV_INSIZEBITS 456 | IMGCV_ALPHABITS | IMGCV_CMBITS), 457 (IMGCV_UNSCALED | IMGCV_BYTEIN 458 | IMGCV_OPAQUE | IMGCV_ICM), 459 (bpp == 32 460 ? Dir32IcmOpqUnsImageConvert 461 : Dir16IcmOpqUnsImageConvert)); 462 awt_fill_imgcv(awt_data->awtImage->convert, 463 (IMGCV_SCALEBITS | IMGCV_INSIZEBITS 464 | IMGCV_ALPHABITS | IMGCV_CMBITS), 465 (IMGCV_UNSCALED | IMGCV_BYTEIN 466 | IMGCV_ALPHA | IMGCV_ICM), 467 (bpp == 32 468 ? Dir32IcmTrnUnsImageConvert 469 : Dir16IcmTrnUnsImageConvert)); 470 awt_fill_imgcv(awt_data->awtImage->convert, 471 (IMGCV_SCALEBITS | IMGCV_INSIZEBITS 472 | IMGCV_ALPHABITS | IMGCV_CMBITS), 473 (IMGCV_SCALED | IMGCV_BYTEIN 474 | IMGCV_OPAQUE | IMGCV_ICM), 475 (bpp == 32 476 ? Dir32IcmOpqSclImageConvert 477 : Dir16IcmOpqSclImageConvert)); 478 awt_fill_imgcv(awt_data->awtImage->convert, 479 (IMGCV_SCALEBITS | IMGCV_INSIZEBITS 480 | IMGCV_ALPHABITS | IMGCV_CMBITS), 481 (IMGCV_UNSCALED | IMGCV_INTIN 482 | IMGCV_OPAQUE | IMGCV_DCM8), 483 (bpp == 32 484 ? Dir32DcmOpqUnsImageConvert 485 : Dir16DcmOpqUnsImageConvert)); 486 awt_fill_imgcv(awt_data->awtImage->convert, 487 (IMGCV_SCALEBITS | IMGCV_INSIZEBITS 488 | IMGCV_ALPHABITS | IMGCV_CMBITS), 489 (IMGCV_UNSCALED | IMGCV_INTIN 490 | IMGCV_ALPHA | IMGCV_DCM8), 491 (bpp == 32 492 ? Dir32DcmTrnUnsImageConvert 493 : Dir16DcmTrnUnsImageConvert)); 494 awt_fill_imgcv(awt_data->awtImage->convert, 495 (IMGCV_SCALEBITS | IMGCV_INSIZEBITS 496 | IMGCV_ALPHABITS | IMGCV_CMBITS), 497 (IMGCV_SCALED | IMGCV_INTIN 498 | IMGCV_OPAQUE | IMGCV_DCM8), 499 (bpp == 32 500 ? Dir32DcmOpqSclImageConvert 501 : Dir16DcmOpqSclImageConvert)); 502 #endif /* NEED_IMAGE_CONVERT */ 503 } else if (bpp <= 16 && (pVI->class == StaticGray 504 || pVI->class == GrayScale 505 || (pVI->class == PseudoColor && forcegray))) { 506 awt_data->AwtColorMatch = awt_color_matchGS; 507 awt_data->awtImage->clrdata.grayscale = 1; 508 awt_data->awtImage->clrdata.bitsperpixel = MAX(bpp, 8); 509 #ifdef NEED_IMAGE_CONVERT 510 awt_fill_imgcv(awt_data->awtImage->convert, 0, 0, PseudoImageConvert); 511 if (getenv("NOFSDITHER") == NULL) { 512 awt_fill_imgcv(awt_data->awtImage->convert, 513 IMGCV_ORDERBITS, IMGCV_TDLRORDER, 514 PseudoFSImageConvert); 515 } 516 #endif /* NEED_IMAGE_CONVERT */ 517 } else if (depth <= 12 && (pVI->class == PseudoColor 518 || pVI->class == TrueColor 519 || pVI->class == StaticColor)) { 520 if (pVI->class == TrueColor) 521 awt_data->awt_num_colors = (1 << pVI->depth); 522 awt_data->AwtColorMatch = awt_color_match; 523 awt_data->awtImage->clrdata.bitsperpixel = MAX(bpp, 8); 524 #ifdef NEED_IMAGE_CONVERT 525 awt_fill_imgcv(awt_data->awtImage->convert, 0, 0, PseudoImageConvert); 526 if (getenv("NOFSDITHER") == NULL) { 527 awt_fill_imgcv(awt_data->awtImage->convert, IMGCV_ORDERBITS, 528 IMGCV_TDLRORDER, PseudoFSImageConvert); 529 awt_fill_imgcv(awt_data->awtImage->convert, 530 (IMGCV_SCALEBITS | IMGCV_INSIZEBITS 531 | IMGCV_ALPHABITS | IMGCV_ORDERBITS 532 | IMGCV_CMBITS), 533 (IMGCV_UNSCALED | IMGCV_BYTEIN 534 | IMGCV_OPAQUE | IMGCV_TDLRORDER 535 | IMGCV_ICM), 536 FSColorIcmOpqUnsImageConvert); 537 awt_fill_imgcv(awt_data->awtImage->convert, 538 (IMGCV_SCALEBITS | IMGCV_INSIZEBITS 539 | IMGCV_ALPHABITS | IMGCV_ORDERBITS 540 | IMGCV_CMBITS), 541 (IMGCV_UNSCALED | IMGCV_INTIN 542 | IMGCV_OPAQUE | IMGCV_TDLRORDER 543 | IMGCV_DCM8), 544 FSColorDcmOpqUnsImageConvert); 545 } 546 awt_fill_imgcv(awt_data->awtImage->convert, 547 (IMGCV_SCALEBITS | IMGCV_INSIZEBITS | IMGCV_ALPHABITS 548 | IMGCV_ORDERBITS | IMGCV_CMBITS), 549 (IMGCV_UNSCALED | IMGCV_BYTEIN | IMGCV_OPAQUE 550 | IMGCV_RANDORDER | IMGCV_ICM), 551 OrdColorIcmOpqUnsImageConvert); 552 awt_fill_imgcv(awt_data->awtImage->convert, 553 (IMGCV_SCALEBITS | IMGCV_INSIZEBITS | IMGCV_ALPHABITS 554 | IMGCV_ORDERBITS | IMGCV_CMBITS), 555 (IMGCV_UNSCALED | IMGCV_INTIN | IMGCV_OPAQUE 556 | IMGCV_RANDORDER | IMGCV_DCM8), 557 OrdColorDcmOpqUnsImageConvert); 558 #endif /* NEED_IMAGE_CONVERT */ 559 } else { 560 free (awt_data->awtImage); 561 return 0; 562 } 563 564 if (depth > 12) { 565 return 1; 566 } 567 568 if (depth == 12) { 569 paletteSize = MAX_PALETTE12_SIZE; 570 } else { 571 paletteSize = MAX_PALETTE8_SIZE; 572 } 573 574 if (awt_data->awt_num_colors > paletteSize) { 575 free (awt_data->awtImage); 576 return 0; 577 } 578 579 /* Allocate ColorData structure */ 580 awt_data->color_data = ZALLOC (_ColorData); 581 awt_data->color_data->screendata = 1; /* This ColorData struct corresponds 582 to some AWT screen/visual, so when 583 any IndexColorModel using this 584 struct is finalized, don't free 585 the struct in freeICMColorData. 586 */ 587 588 /* 589 * Initialize colors array 590 */ 591 for (i = 0; i < awt_data->awt_num_colors; i++) { 592 cols[i].pixel = i; 593 } 594 595 awt_data->color_data->awt_Colors = 596 (ColorEntry *)calloc(paletteSize, sizeof (ColorEntry)); 597 598 XQueryColors(dpy, cm, cols, awt_data->awt_num_colors); 599 for (i = 0; i < awt_data->awt_num_colors; i++) { 600 awt_data->color_data->awt_Colors[i].r = cols[i].red >> 8; 601 awt_data->color_data->awt_Colors[i].g = cols[i].green >> 8; 602 awt_data->color_data->awt_Colors[i].b = cols[i].blue >> 8; 603 awt_data->color_data->awt_Colors[i].flags = LIKELY_COLOR; 604 } 605 606 /* 607 * Determine which colors in the colormap can be allocated and mark 608 * them in the colors array 609 */ 610 nfree = 0; 611 for (i = (paletteSize / 2); i > 0; i >>= 1) { 612 if (XAllocColorCells(dpy, cm, False, plane_masks, 0, 613 freecolors + nfree, i)) { 614 nfree += i; 615 } 616 } 617 618 for (i = 0; i < nfree; i++) { 619 awt_data->color_data->awt_Colors[freecolors[i]].flags = FREE_COLOR; 620 } 621 622 #ifdef DEBUG 623 if (debug_colormap) { 624 jio_fprintf(stdout, "%d free.\n", nfree); 625 } 626 #endif 627 628 XFreeColors(dpy, cm, freecolors, nfree, 0); 629 630 /* 631 * Allocate the colors that are already allocated by other 632 * applications 633 */ 634 for (i = 0; i < awt_data->awt_num_colors; i++) { 635 if (awt_data->color_data->awt_Colors[i].flags == LIKELY_COLOR) { 636 awt_data->color_data->awt_Colors[i].flags = FREE_COLOR; 637 alloc_col(dpy, cm, 638 awt_data->color_data->awt_Colors[i].r, 639 awt_data->color_data->awt_Colors[i].g, 640 awt_data->color_data->awt_Colors[i].b, i, awt_data); 641 } 642 } 643 #ifdef DEBUG 644 if (debug_colormap) { 645 jio_fprintf(stdout, "got the already allocated ones\n"); 646 } 647 #endif 648 649 /* 650 * Allocate more colors, filling the color space evenly. 651 */ 652 653 alloc_col(dpy, cm, 255, 255, 255, -1, awt_data); 654 alloc_col(dpy, cm, 0, 0, 0, -1, awt_data); 655 656 if (awt_data->awtImage->clrdata.grayscale) { 657 int g; 658 ColorEntry *p; 659 660 if (!forcemono) { 661 for (i = 128; i > 0; i >>= 1) { 662 for (g = i; g < 256; g += (i * 2)) { 663 alloc_col(dpy, cm, g, g, g, -1, awt_data); 664 } 665 } 666 } 667 668 awt_data->color_data->img_grays = 669 (unsigned char *)calloc(256, sizeof(unsigned char)); 670 for (g = 0; g < 256; g++) { 671 int mindist, besti; 672 int d; 673 674 p = awt_data->color_data->awt_Colors; 675 mindist = 256; 676 besti = 0; 677 for (i = 0 ; i < awt_data->awt_num_colors ; i++, p++) { 678 if (forcegray && (p->r != p->g || p->g != p->b)) 679 continue; 680 if (forcemono && p->g != 0 && p->g != 255) 681 continue; 682 if (p->flags == ALLOCATED_COLOR) { 683 d = p->g - g; 684 if (d < 0) d = -d; 685 if (d < mindist) { 686 besti = i; 687 if (d == 0) { 688 break; 689 } 690 mindist = d; 691 } 692 } 693 } 694 695 awt_data->color_data->img_grays[g] = besti; 696 } 697 698 699 if (forcemono || (depth == 1)) { 700 char *gammastr = getenv("HJGAMMA"); 701 double gamma = atof(gammastr ? gammastr : "1.6"); 702 if (gamma < 0.01) gamma = 1.0; 703 #ifdef DEBUG 704 if (debug_colormap) { 705 jio_fprintf(stderr, "gamma = %f\n", gamma); 706 } 707 #endif 708 for (i = 0; i < 256; i++) { 709 img_bwgamma[i] = (int) (pow(i/255.0, gamma) * 255); 710 #ifdef DEBUG 711 if (debug_colormap) { 712 jio_fprintf(stderr, "%3d ", img_bwgamma[i]); 713 if ((i & 7) == 7) 714 jio_fprintf(stderr, "\n"); 715 } 716 #endif 717 } 718 } else { 719 for (i = 0; i < 256; i++) { 720 img_bwgamma[i] = i; 721 } 722 } 723 724 #ifdef DEBUG 725 if (debug_colormap) { 726 jio_fprintf(stderr, "GrayScale initialized\n"); 727 jio_fprintf(stderr, "color table:\n"); 728 for (i = 0; i < awt_data->awt_num_colors; i++) { 729 jio_fprintf(stderr, "%3d: %3d %3d %3d\n", 730 i, awt_data->color_data->awt_Colors[i].r, 731 awt_data->color_data->awt_Colors[i].g, 732 awt_data->color_data->awt_Colors[i].b); 733 } 734 jio_fprintf(stderr, "gray table:\n"); 735 for (i = 0; i < 256; i++) { 736 jio_fprintf(stderr, "%3d ", awt_data->color_data->img_grays[i]); 737 if ((i & 7) == 7) 738 jio_fprintf(stderr, "\n"); 739 } 740 } 741 #endif 742 743 } else { 744 745 alloc_col(dpy, cm, 255, 0, 0, -1, awt_data); 746 alloc_col(dpy, cm, 0, 255, 0, -1,awt_data); 747 alloc_col(dpy, cm, 0, 0, 255, -1,awt_data); 748 alloc_col(dpy, cm, 255, 255, 0, -1,awt_data); 749 alloc_col(dpy, cm, 255, 0, 255, -1,awt_data); 750 alloc_col(dpy, cm, 0, 255, 255, -1,awt_data); 751 alloc_col(dpy, cm, 192, 192, 192, -1,awt_data); 752 alloc_col(dpy, cm, 255, 128, 128, -1,awt_data); 753 alloc_col(dpy, cm, 128, 255, 128, -1,awt_data); 754 alloc_col(dpy, cm, 128, 128, 255, -1,awt_data); 755 alloc_col(dpy, cm, 255, 255, 128, -1,awt_data); 756 alloc_col(dpy, cm, 255, 128, 255, -1,awt_data); 757 alloc_col(dpy, cm, 128, 255, 255, -1,awt_data); 758 } 759 760 allocatedColorsNum = 0; 761 unavailableColorsNum = 0; 762 /* we do not support more than 256 entries in the colormap 763 even for 12-bit PseudoColor visuals */ 764 for (i = 0; i < MAX_PALETTE8_SIZE; i++) { 765 if (awt_data->color_data->awt_Colors[i].flags == ALLOCATED_COLOR) 766 { 767 reds[allocatedColorsNum] = awt_data->color_data->awt_Colors[i].r; 768 greens[allocatedColorsNum] = awt_data->color_data->awt_Colors[i].g; 769 blues[allocatedColorsNum] = awt_data->color_data->awt_Colors[i].b; 770 allocatedColorsNum++; 771 } else if (awt_data->color_data->awt_Colors[i].flags == 772 UNAVAILABLE_COLOR) { 773 unavailableColorsNum++; 774 } 775 } 776 777 if (depth > 8) { 778 cmapsize = MAX_PALETTE8_SIZE - unavailableColorsNum; 779 } else { 780 cmapsize = 0; 781 if (getenv("CMAPSIZE") != 0) { 782 cmapsize = atoi(getenv("CMAPSIZE")); 783 } 784 785 if (cmapsize <= 0) { 786 cmapsize = CMAP_ALLOC_DEFAULT; 787 } 788 789 if (cmapsize < allocatedColorsNum + unavailableColorsNum + CMAP_ALLOC_MIN) { 790 cmapsize = allocatedColorsNum + unavailableColorsNum + CMAP_ALLOC_MIN; 791 } 792 793 if (cmapsize > CMAP_ALLOC_MAX) { 794 cmapsize = CMAP_ALLOC_MAX; 795 } 796 797 if (cmapsize < allocatedColorsNum) { 798 cmapsize = allocatedColorsNum; 799 } 800 cmapsize -= unavailableColorsNum; 801 } 802 803 k = 0; 804 if (getenv("VIRTCUBESIZE") != 0) { 805 k = atoi(getenv("VIRTCUBESIZE")); 806 } 807 if (k == 0 || (k & (k - 1)) != 0 || k > 32) { 808 k = getVirtCubeSize(); 809 } 810 awt_data->color_data->img_clr_tbl = 811 (unsigned char *)calloc(LOOKUPSIZE * LOOKUPSIZE * LOOKUPSIZE, 812 sizeof(unsigned char)); 813 img_makePalette(cmapsize, k, LOOKUPSIZE, 50, 250, 814 allocatedColorsNum, TRUE, reds, greens, blues, 815 awt_data->color_data->img_clr_tbl); 816 /*img_clr_tbl);*/ 817 818 for (i = 0; i < cmapsize; i++) { 819 indices[i] = alloc_col(dpy, cm, reds[i], greens[i], blues[i], -1, 820 awt_data); 821 } 822 for (i = 0; i < LOOKUPSIZE * LOOKUPSIZE * LOOKUPSIZE ; i++) { 823 awt_data->color_data->img_clr_tbl[i] = 824 indices[awt_data->color_data->img_clr_tbl[i]]; 825 } 826 827 awt_data->color_data->img_oda_red = &(std_img_oda_red[0][0]); 828 awt_data->color_data->img_oda_green = &(std_img_oda_green[0][0]); 829 awt_data->color_data->img_oda_blue = &(std_img_oda_blue[0][0]); 830 make_dither_arrays(cmapsize, awt_data->color_data); 831 std_odas_computed = 1; 832 833 #ifdef DEBUG 834 if (debug_colormap) { 835 int alloc_count = 0; 836 int reuse_count = 0; 837 int free_count = 0; 838 for (i = 0; i < awt_data->awt_num_colors; i++) { 839 switch (awt_data->color_data->awt_Colors[i].flags) { 840 case ALLOCATED_COLOR: 841 alloc_count++; 842 break; 843 case LIKELY_COLOR: 844 reuse_count++; 845 break; 846 case FREE_COLOR: 847 free_count++; 848 break; 849 } 850 } 851 jio_fprintf(stdout, "%d total, %d allocated, %d reused, %d still free.\n", 852 awt_data->awt_num_colors, alloc_count, reuse_count, free_count); 853 } 854 #endif 855 856 /* Fill in the ICM lut and lut2cmap mapping */ 857 awt_data->color_data->awt_numICMcolors = 0; 858 awt_data->color_data->awt_icmLUT2Colors = 859 (unsigned char *)calloc(paletteSize, sizeof (unsigned char)); 860 awt_data->color_data->awt_icmLUT = (int *)calloc(paletteSize, sizeof(int)); 861 for (i=0; i < paletteSize; i++) { 862 /* Keep the mapping between this lut and the actual cmap */ 863 awt_data->color_data->awt_icmLUT2Colors 864 [awt_data->color_data->awt_numICMcolors] = i; 865 866 if (awt_data->color_data->awt_Colors[i].flags == ALLOCATED_COLOR) { 867 /* Screen IndexColorModel LUTS are always xRGB */ 868 awt_data->color_data->awt_icmLUT 869 [awt_data->color_data->awt_numICMcolors++] = 0xff000000 | 870 (awt_data->color_data->awt_Colors[i].r<<16) | 871 (awt_data->color_data->awt_Colors[i].g<<8) | 872 (awt_data->color_data->awt_Colors[i].b); 873 } else { 874 /* Screen IndexColorModel LUTS are always xRGB */ 875 awt_data->color_data->awt_icmLUT 876 [awt_data->color_data->awt_numICMcolors++] = 0; 877 } 878 } 879 return 1; 880 } 881 #endif /* !HEADLESS */ 882 883 #define red(v) (((v) >> 16) & 0xFF) 884 #define green(v) (((v) >> 8) & 0xFF) 885 #define blue(v) (((v) >> 0) & 0xFF) 886 887 #ifndef HEADLESS 888 889 jobject getColorSpace(JNIEnv* env, jint csID) { 890 jclass clazz; 891 jobject cspaceL; 892 jmethodID mid; 893 894 clazz = (*env)->FindClass(env,"java/awt/color/ColorSpace"); 895 CHECK_NULL_RETURN(clazz, NULL); 896 mid = (*env)->GetStaticMethodID(env, clazz, "getInstance", 897 "(I)Ljava/awt/color/ColorSpace;"); 898 CHECK_NULL_RETURN(mid, NULL); 899 900 /* SECURITY: This is safe, because static methods cannot 901 * be overridden, and this method does not invoke 902 * client code 903 */ 904 905 return (*env)->CallStaticObjectMethod(env, clazz, mid, csID); 906 } 907 908 jobject awtJNI_GetColorModel(JNIEnv *env, AwtGraphicsConfigDataPtr aData) 909 { 910 jobject awt_colormodel = NULL; 911 jclass clazz; 912 jmethodID mid; 913 914 if ((*env)->PushLocalFrame(env, 16) < 0) 915 return NULL; 916 917 if ((aData->awt_visInfo.class == TrueColor) && 918 (aData->awt_depth >= 15)) 919 { 920 clazz = (*env)->FindClass(env,"java/awt/image/DirectColorModel"); 921 if (clazz == NULL) { 922 (*env)->PopLocalFrame(env, 0); 923 return NULL; 924 } 925 926 if (!aData->isTranslucencySupported) { 927 928 mid = (*env)->GetMethodID(env,clazz,"<init>","(IIIII)V"); 929 930 if (mid == NULL) { 931 (*env)->PopLocalFrame(env, 0); 932 return NULL; 933 } 934 awt_colormodel = (*env)->NewObject(env,clazz, mid, 935 aData->awt_visInfo.depth, 936 aData->awt_visInfo.red_mask, 937 aData->awt_visInfo.green_mask, 938 aData->awt_visInfo.blue_mask, 939 0); 940 } else { 941 clazz = (*env)->FindClass(env,"sun/awt/X11GraphicsConfig"); 942 if (clazz == NULL) { 943 (*env)->PopLocalFrame(env, 0); 944 return NULL; 945 } 946 947 if (aData->renderPictFormat.direct.red == 16) { 948 mid = (*env)->GetStaticMethodID( env,clazz,"createDCM32", 949 "(IIIIZ)Ljava/awt/image/DirectColorModel;"); 950 951 if (mid == NULL) { 952 (*env)->PopLocalFrame(env, 0); 953 return NULL; 954 } 955 956 awt_colormodel = (*env)->CallStaticObjectMethod( 957 env,clazz, mid, 958 aData->renderPictFormat.direct.redMask 959 << aData->renderPictFormat.direct.red, 960 aData->renderPictFormat.direct.greenMask 961 << aData->renderPictFormat.direct.green, 962 aData->renderPictFormat.direct.blueMask 963 << aData->renderPictFormat.direct.blue, 964 aData->renderPictFormat.direct.alphaMask 965 << aData->renderPictFormat.direct.alpha, 966 JNI_TRUE); 967 } else { 968 mid = (*env)->GetStaticMethodID( env,clazz,"createABGRCCM", 969 "()Ljava/awt/image/ComponentColorModel;"); 970 971 if (mid == NULL) { 972 (*env)->PopLocalFrame(env, 0); 973 return NULL; 974 } 975 976 awt_colormodel = (*env)->CallStaticObjectMethod( 977 env,clazz, mid); 978 } 979 } 980 981 if(awt_colormodel == NULL) 982 { 983 (*env)->PopLocalFrame(env, 0); 984 return NULL; 985 } 986 987 } 988 else if (aData->awt_visInfo.class == StaticGray && 989 aData->awt_num_colors == 256) { 990 jobject cspace = NULL; 991 jint bits[1]; 992 jintArray bitsArray; 993 jboolean falseboolean = JNI_FALSE; 994 995 cspace = getColorSpace(env, java_awt_color_ColorSpace_CS_GRAY); 996 997 if (cspace == NULL) { 998 (*env)->PopLocalFrame(env, 0); 999 return NULL; 1000 } 1001 1002 bits[0] = 8; 1003 bitsArray = (*env)->NewIntArray(env, 1); 1004 if (bitsArray == NULL) { 1005 (*env)->PopLocalFrame(env, 0); 1006 return NULL; 1007 } else { 1008 (*env)->SetIntArrayRegion(env, bitsArray, 0, 1, bits); 1009 } 1010 1011 clazz = (*env)->FindClass(env,"java/awt/image/ComponentColorModel"); 1012 if (clazz == NULL) { 1013 (*env)->PopLocalFrame(env, 0); 1014 return NULL; 1015 } 1016 1017 mid = (*env)->GetMethodID(env,clazz,"<init>", 1018 "(Ljava/awt/color/ColorSpace;[IZZII)V"); 1019 1020 if (mid == NULL) { 1021 (*env)->PopLocalFrame(env, 0); 1022 return NULL; 1023 } 1024 1025 awt_colormodel = (*env)->NewObject(env,clazz, mid, 1026 cspace, 1027 bitsArray, 1028 falseboolean, 1029 falseboolean, 1030 java_awt_Transparency_OPAQUE, 1031 java_awt_image_DataBuffer_TYPE_BYTE); 1032 1033 if(awt_colormodel == NULL) 1034 { 1035 (*env)->PopLocalFrame(env, 0); 1036 return NULL; 1037 } 1038 1039 } else { 1040 jint rgb[MAX_PALETTE_SIZE]; 1041 jbyte valid[MAX_PALETTE_SIZE / 8], *pValid; 1042 jintArray hArray; 1043 jobject validBits = NULL; 1044 ColorEntry *c; 1045 int i, allocAllGray, b, allvalid, paletteSize; 1046 jlong pData; 1047 1048 if (aData->awt_visInfo.depth == 12) { 1049 paletteSize = MAX_PALETTE12_SIZE; 1050 } else { 1051 paletteSize = MAX_PALETTE8_SIZE; 1052 } 1053 1054 c = aData->color_data->awt_Colors; 1055 pValid = &valid[sizeof(valid)]; 1056 allocAllGray = 1; 1057 b = 0; 1058 allvalid = 1; 1059 1060 for (i = 0; i < paletteSize; i++, c++) { 1061 if (c->flags == ALLOCATED_COLOR) { 1062 rgb[i] = (0xff000000 | 1063 (c->r << 16) | 1064 (c->g << 8) | 1065 (c->b << 0)); 1066 if (c->r != c->g || c->g != c->b) { 1067 allocAllGray = 0; 1068 } 1069 b |= (1 << (i % 8)); 1070 } else { 1071 rgb[i] = 0; 1072 b &= ~(1 << (i % 8)); 1073 allvalid = 0; 1074 } 1075 if ((i % 8) == 7) { 1076 *--pValid = b; 1077 /* b = 0; not needed as each bit is explicitly set */ 1078 } 1079 } 1080 1081 if (allocAllGray && (aData->awtImage->clrdata.grayscale == 0)) { 1082 /* 1083 Fix for 4351638 - Gray scale HW mode on Dome frame buffer 1084 crashes VM on Solaris. 1085 It is possible for an X11 frame buffer to advertise a 1086 PseudoColor visual, but to force all allocated colormap 1087 entries to be gray colors. The Dome card does this when the 1088 HW is jumpered for a grayscale monitor, but the default 1089 visual is set to PseudoColor. In that case awtJNI_GetColorModel 1090 will be called with aData->awtImage->clrdata.grayscale == 0, 1091 but the IndexColorModel created below will detect that only 1092 gray colors exist and expect the inverse gray LUT to exist. 1093 So above when filling the hR, hG, and hB arrays we detect 1094 whether all allocated colors are gray. If so, but 1095 aData->awtImage->clrdata.grayscale == 0, we fall into this 1096 code to set aData->awtImage->clrdata.grayscale = 1 and do 1097 other things needed for the grayscale case. 1098 */ 1099 1100 int i; 1101 int g; 1102 ColorEntry *p; 1103 1104 aData->awtImage->clrdata.grayscale = 1; 1105 1106 aData->color_data->img_grays = 1107 (unsigned char *)calloc(256, sizeof(unsigned char)); 1108 1109 if (aData->color_data->img_grays == NULL) { 1110 (*env)->PopLocalFrame(env, 0); 1111 return NULL; 1112 } 1113 1114 for (g = 0; g < 256; g++) { 1115 int mindist, besti; 1116 int d; 1117 1118 p = aData->color_data->awt_Colors; 1119 mindist = 256; 1120 besti = 0; 1121 for (i = 0 ; i < paletteSize; i++, p++) { 1122 if (p->flags == ALLOCATED_COLOR) { 1123 d = p->g - g; 1124 if (d < 0) d = -d; 1125 if (d < mindist) { 1126 besti = i; 1127 if (d == 0) { 1128 break; 1129 } 1130 mindist = d; 1131 } 1132 } 1133 } 1134 1135 aData->color_data->img_grays[g] = besti; 1136 } 1137 1138 for (i = 0; i < 256; i++) { 1139 img_bwgamma[i] = i; /* REMIND: what is img_bwgamma? 1140 * is it still used anywhere? 1141 */ 1142 } 1143 } 1144 1145 if (aData->awtImage->clrdata.grayscale) { 1146 int i; 1147 ColorEntry *p; 1148 1149 /* For purposes of creating an IndexColorModel, use 1150 transparent black for non-allocated or non-gray colors. 1151 */ 1152 p = aData->color_data->awt_Colors; 1153 b = 0; 1154 pValid = &valid[sizeof(valid)]; 1155 for (i = 0; i < paletteSize; i++, p++) { 1156 if ((p->flags != ALLOCATED_COLOR) || 1157 (p->r != p->g || p->g != p->b)) 1158 { 1159 rgb[i] = 0; 1160 b &= ~(1 << (i % 8)); 1161 allvalid = 0; 1162 } else { 1163 b |= (1 << (i % 8)); 1164 } 1165 if ((i % 8) == 7) { 1166 *--pValid = b; 1167 /* b = 0; not needed as each bit is explicitly set */ 1168 } 1169 } 1170 1171 if (aData->color_data->pGrayInverseLutData == NULL) { 1172 /* Compute the inverse gray LUT for this aData->color_data 1173 struct, if not already computed. 1174 */ 1175 initInverseGrayLut(rgb, aData->awt_num_colors, 1176 aData->color_data); 1177 } 1178 } 1179 1180 if (!allvalid) { 1181 jobject bArray = (*env)->NewByteArray(env, sizeof(valid)); 1182 if (bArray == NULL) 1183 { 1184 (*env)->PopLocalFrame(env, 0); 1185 return NULL; 1186 } 1187 else 1188 { 1189 (*env)->SetByteArrayRegion(env, bArray, 0, sizeof(valid), 1190 valid); 1191 } 1192 validBits = JNU_NewObjectByName(env, 1193 "java/math/BigInteger", 1194 "([B)V", bArray); 1195 if (validBits == NULL) 1196 { 1197 (*env)->PopLocalFrame(env, 0); 1198 return NULL; 1199 } 1200 } 1201 1202 hArray = (*env)->NewIntArray(env, paletteSize); 1203 if (hArray == NULL) 1204 { 1205 (*env)->PopLocalFrame(env, 0); 1206 return NULL; 1207 } 1208 else 1209 { 1210 (*env)->SetIntArrayRegion(env, hArray, 0, paletteSize, rgb); 1211 } 1212 1213 if (aData->awt_visInfo.depth == 8) { 1214 awt_colormodel = 1215 JNU_NewObjectByName(env, 1216 "java/awt/image/IndexColorModel", 1217 "(II[IIILjava/math/BigInteger;)V", 1218 8, 256, hArray, 0, 1219 java_awt_image_DataBuffer_TYPE_BYTE, 1220 validBits); 1221 } else { 1222 awt_colormodel = 1223 JNU_NewObjectByName(env, 1224 "java/awt/image/IndexColorModel", 1225 "(II[IIILjava/math/BigInteger;)V", 1226 12, 4096, hArray, 0, 1227 java_awt_image_DataBuffer_TYPE_USHORT, 1228 validBits); 1229 } 1230 1231 if (awt_colormodel == NULL) 1232 { 1233 (*env)->PopLocalFrame(env, 0); 1234 return NULL; 1235 } 1236 1237 /* Set pData field of ColorModel to point to ColorData */ 1238 JNU_SetLongFieldFromPtr(env, awt_colormodel, g_CMpDataID, 1239 aData->color_data); 1240 1241 } 1242 1243 return (*env)->PopLocalFrame(env, awt_colormodel); 1244 } 1245 #endif /* !HEADLESS */ 1246 1247 extern jfieldID colorValueID; 1248 1249 #ifndef HEADLESS 1250 int awtJNI_GetColor(JNIEnv *env,jobject this) 1251 { 1252 /* REMIND: should not be defaultConfig. */ 1253 return awtJNI_GetColorForVis (env, this, getDefaultConfig(DefaultScreen(awt_display))); 1254 } 1255 1256 int awtJNI_GetColorForVis (JNIEnv *env,jobject this, AwtGraphicsConfigDataPtr awt_data) 1257 { 1258 int col; 1259 jclass SYSCLR_class; 1260 1261 if (!JNU_IsNull(env,this)) 1262 { 1263 SYSCLR_class = (*env)->FindClass(env, "java/awt/SystemColor"); 1264 CHECK_NULL_RETURN(SYSCLR_class, 0); 1265 1266 if ((*env)->IsInstanceOf(env, this, SYSCLR_class)) { 1267 /* SECURITY: This is safe, because there is no way 1268 * for client code to insert an object 1269 * that is a subclass of SystemColor 1270 */ 1271 col = (int) JNU_CallMethodByName(env 1272 ,NULL 1273 ,this 1274 ,"getRGB" 1275 ,"()I").i; 1276 JNU_CHECK_EXCEPTION_RETURN(env, 0); 1277 } else { 1278 col = (int)(*env)->GetIntField(env,this,colorValueID); 1279 } 1280 1281 if (awt_data->awt_cmap == (Colormap) NULL) { 1282 awtJNI_CreateColorData (env, awt_data, 1); 1283 } 1284 1285 col = awt_data->AwtColorMatch(red(col), green(col), blue(col), 1286 awt_data); 1287 return col; 1288 } 1289 1290 return 0; 1291 } 1292 1293 void 1294 awt_allocate_systemrgbcolors (jint *rgbColors, int num_colors, 1295 AwtGraphicsConfigDataPtr awtData) { 1296 int i, pixel; 1297 for (i = 0; i < num_colors; i++) 1298 pixel = alloc_col (awt_display, awtData->awt_cmap, red (rgbColors [i]), 1299 green (rgbColors [i]), blue (rgbColors [i]), -1, 1300 awtData); 1301 } 1302 1303 int 1304 awtCreateX11Colormap(AwtGraphicsConfigDataPtr adata) { 1305 int screen = adata->awt_visInfo.screen; 1306 Colormap cmap = (Colormap)NULL; 1307 1308 if (adata->awt_visInfo.visual == DefaultVisual(awt_display, screen)) { 1309 cmap = DefaultColormap(awt_display, screen); 1310 } else { 1311 Window root = RootWindow(awt_display, screen); 1312 1313 if (adata->awt_visInfo.visual->class % 2) { 1314 Atom actual_type; 1315 int actual_format; 1316 unsigned long nitems, bytes_after; 1317 XStandardColormap *scm; 1318 1319 XGetWindowProperty (awt_display, root, XA_RGB_DEFAULT_MAP, 1320 0L, 1L, False, AnyPropertyType, &actual_type, 1321 &actual_format, &nitems, &bytes_after, 1322 (unsigned char **) &scm); 1323 1324 XGetWindowProperty (awt_display, root, XA_RGB_DEFAULT_MAP, 0L, 1325 bytes_after/4 + 1, False, AnyPropertyType, 1326 &actual_type, &actual_format, &nitems, 1327 &bytes_after, (unsigned char **) &scm); 1328 1329 nitems /= (sizeof (XStandardColormap)/4); 1330 for (; nitems > 0; ++scm, --nitems) 1331 if (scm->visualid == adata->awt_visInfo.visualid) { 1332 cmap = scm->colormap; 1333 break; 1334 } 1335 } 1336 if (!cmap) { 1337 cmap = XCreateColormap (awt_display, root, 1338 adata->awt_visInfo.visual, 1339 AllocNone); 1340 } 1341 } 1342 1343 adata->awt_cmap = cmap; 1344 if (!awt_allocate_colors(adata)) { 1345 XFreeColormap(awt_display, adata->awt_cmap); 1346 adata->awt_cmap = (Colormap)NULL; 1347 return 0; 1348 } 1349 return 1; 1350 } 1351 1352 void 1353 awtJNI_CreateColorData(JNIEnv *env, AwtGraphicsConfigDataPtr adata, 1354 int lock) { 1355 1356 /* Create Colormap */ 1357 if (lock) { 1358 AWT_LOCK (); 1359 } 1360 1361 awtCreateX11Colormap(adata); 1362 1363 /* If depth is 8, allocate system colors also... Here 1364 * we just get the array of System Colors and allocate 1365 * it which may be a bit wasteful (if only some were 1366 * changed). But we don't know which ones were changed 1367 * and alloc-ing a pixel that is already allocated won't 1368 * hurt. */ 1369 1370 if (adata->awt_depth == 8 || 1371 (adata->awt_depth == 12 && adata->awt_visInfo.class == PseudoColor)) 1372 { 1373 jint colorVals [java_awt_SystemColor_NUM_COLORS]; 1374 jclass sysColors; 1375 jfieldID colorID; 1376 jintArray colors; 1377 1378 /* Unlock now to initialize the SystemColor class */ 1379 if (lock) { 1380 AWT_UNLOCK_CHECK_EXCEPTION(env); 1381 } 1382 sysColors = (*env)->FindClass (env, "java/awt/SystemColor"); 1383 CHECK_NULL(sysColors); 1384 1385 if (lock) { 1386 AWT_LOCK (); 1387 } 1388 colorID = (*env)->GetStaticFieldID (env, sysColors, 1389 "systemColors", 1390 "[I"); 1391 1392 if (colorID == NULL) { 1393 if (lock) { 1394 AWT_UNLOCK(); 1395 } 1396 return; 1397 } 1398 1399 colors = (jintArray) (*env)->GetStaticObjectField 1400 (env, sysColors, colorID); 1401 1402 (*env)->GetIntArrayRegion (env, colors, 0, 1403 java_awt_SystemColor_NUM_COLORS, 1404 (jint *) colorVals); 1405 1406 awt_allocate_systemrgbcolors (colorVals, 1407 (java_awt_SystemColor_NUM_COLORS - 1), adata); 1408 1409 } 1410 1411 if (lock) { 1412 AWT_UNLOCK (); 1413 } 1414 } 1415 1416 #endif /* !HEADLESS */