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 if (awt_data->awtImage == NULL) { 406 return 0; 407 } 408 409 pPFV = XListPixmapFormats(dpy, &numpfv); 410 if (pPFV) { 411 for (i = 0; i < numpfv; i++) { 412 if (pPFV[i].depth == depth) { 413 awt_data->awtImage->wsImageFormat = pPFV[i]; 414 break; 415 } 416 } 417 XFree(pPFV); 418 } 419 bpp = awt_data->awtImage->wsImageFormat.bits_per_pixel; 420 if (bpp == 24) { 421 bpp = 32; 422 } 423 awt_data->awtImage->clrdata.bitsperpixel = bpp; 424 awt_data->awtImage->Depth = depth; 425 426 if ((bpp == 32 || bpp == 16) && pVI->class == TrueColor && depth >= 15) { 427 awt_data->AwtColorMatch = awt_color_matchTC; 428 awt_data->awtImage->clrdata.rOff = 0; 429 for (i = pVI->red_mask; (i & 1) == 0; i >>= 1) { 430 awt_data->awtImage->clrdata.rOff++; 431 } 432 awt_data->awtImage->clrdata.rScale = 0; 433 while (i < 0x80) { 434 awt_data->awtImage->clrdata.rScale++; 435 i <<= 1; 436 } 437 awt_data->awtImage->clrdata.gOff = 0; 438 for (i = pVI->green_mask; (i & 1) == 0; i >>= 1) { 439 awt_data->awtImage->clrdata.gOff++; 440 } 441 awt_data->awtImage->clrdata.gScale = 0; 442 while (i < 0x80) { 443 awt_data->awtImage->clrdata.gScale++; 444 i <<= 1; 445 } 446 awt_data->awtImage->clrdata.bOff = 0; 447 for (i = pVI->blue_mask; (i & 1) == 0; i >>= 1) { 448 awt_data->awtImage->clrdata.bOff++; 449 } 450 awt_data->awtImage->clrdata.bScale = 0; 451 while (i < 0x80) { 452 awt_data->awtImage->clrdata.bScale++; 453 i <<= 1; 454 } 455 #ifdef NEED_IMAGE_CONVERT 456 awt_fill_imgcv(awt_data->awtImage->convert, 0, 0, DirectImageConvert); 457 awt_fill_imgcv(awt_data->awtImage->convert, 458 (IMGCV_SCALEBITS | IMGCV_INSIZEBITS 459 | IMGCV_ALPHABITS | IMGCV_CMBITS), 460 (IMGCV_UNSCALED | IMGCV_BYTEIN 461 | IMGCV_OPAQUE | IMGCV_ICM), 462 (bpp == 32 463 ? Dir32IcmOpqUnsImageConvert 464 : Dir16IcmOpqUnsImageConvert)); 465 awt_fill_imgcv(awt_data->awtImage->convert, 466 (IMGCV_SCALEBITS | IMGCV_INSIZEBITS 467 | IMGCV_ALPHABITS | IMGCV_CMBITS), 468 (IMGCV_UNSCALED | IMGCV_BYTEIN 469 | IMGCV_ALPHA | IMGCV_ICM), 470 (bpp == 32 471 ? Dir32IcmTrnUnsImageConvert 472 : Dir16IcmTrnUnsImageConvert)); 473 awt_fill_imgcv(awt_data->awtImage->convert, 474 (IMGCV_SCALEBITS | IMGCV_INSIZEBITS 475 | IMGCV_ALPHABITS | IMGCV_CMBITS), 476 (IMGCV_SCALED | IMGCV_BYTEIN 477 | IMGCV_OPAQUE | IMGCV_ICM), 478 (bpp == 32 479 ? Dir32IcmOpqSclImageConvert 480 : Dir16IcmOpqSclImageConvert)); 481 awt_fill_imgcv(awt_data->awtImage->convert, 482 (IMGCV_SCALEBITS | IMGCV_INSIZEBITS 483 | IMGCV_ALPHABITS | IMGCV_CMBITS), 484 (IMGCV_UNSCALED | IMGCV_INTIN 485 | IMGCV_OPAQUE | IMGCV_DCM8), 486 (bpp == 32 487 ? Dir32DcmOpqUnsImageConvert 488 : Dir16DcmOpqUnsImageConvert)); 489 awt_fill_imgcv(awt_data->awtImage->convert, 490 (IMGCV_SCALEBITS | IMGCV_INSIZEBITS 491 | IMGCV_ALPHABITS | IMGCV_CMBITS), 492 (IMGCV_UNSCALED | IMGCV_INTIN 493 | IMGCV_ALPHA | IMGCV_DCM8), 494 (bpp == 32 495 ? Dir32DcmTrnUnsImageConvert 496 : Dir16DcmTrnUnsImageConvert)); 497 awt_fill_imgcv(awt_data->awtImage->convert, 498 (IMGCV_SCALEBITS | IMGCV_INSIZEBITS 499 | IMGCV_ALPHABITS | IMGCV_CMBITS), 500 (IMGCV_SCALED | IMGCV_INTIN 501 | IMGCV_OPAQUE | IMGCV_DCM8), 502 (bpp == 32 503 ? Dir32DcmOpqSclImageConvert 504 : Dir16DcmOpqSclImageConvert)); 505 #endif /* NEED_IMAGE_CONVERT */ 506 } else if (bpp <= 16 && (pVI->class == StaticGray 507 || pVI->class == GrayScale 508 || (pVI->class == PseudoColor && forcegray))) { 509 awt_data->AwtColorMatch = awt_color_matchGS; 510 awt_data->awtImage->clrdata.grayscale = 1; 511 awt_data->awtImage->clrdata.bitsperpixel = MAX(bpp, 8); 512 #ifdef NEED_IMAGE_CONVERT 513 awt_fill_imgcv(awt_data->awtImage->convert, 0, 0, PseudoImageConvert); 514 if (getenv("NOFSDITHER") == NULL) { 515 awt_fill_imgcv(awt_data->awtImage->convert, 516 IMGCV_ORDERBITS, IMGCV_TDLRORDER, 517 PseudoFSImageConvert); 518 } 519 #endif /* NEED_IMAGE_CONVERT */ 520 } else if (depth <= 12 && (pVI->class == PseudoColor 521 || pVI->class == TrueColor 522 || pVI->class == StaticColor)) { 523 if (pVI->class == TrueColor) 524 awt_data->awt_num_colors = (1 << pVI->depth); 525 awt_data->AwtColorMatch = awt_color_match; 526 awt_data->awtImage->clrdata.bitsperpixel = MAX(bpp, 8); 527 #ifdef NEED_IMAGE_CONVERT 528 awt_fill_imgcv(awt_data->awtImage->convert, 0, 0, PseudoImageConvert); 529 if (getenv("NOFSDITHER") == NULL) { 530 awt_fill_imgcv(awt_data->awtImage->convert, IMGCV_ORDERBITS, 531 IMGCV_TDLRORDER, PseudoFSImageConvert); 532 awt_fill_imgcv(awt_data->awtImage->convert, 533 (IMGCV_SCALEBITS | IMGCV_INSIZEBITS 534 | IMGCV_ALPHABITS | IMGCV_ORDERBITS 535 | IMGCV_CMBITS), 536 (IMGCV_UNSCALED | IMGCV_BYTEIN 537 | IMGCV_OPAQUE | IMGCV_TDLRORDER 538 | IMGCV_ICM), 539 FSColorIcmOpqUnsImageConvert); 540 awt_fill_imgcv(awt_data->awtImage->convert, 541 (IMGCV_SCALEBITS | IMGCV_INSIZEBITS 542 | IMGCV_ALPHABITS | IMGCV_ORDERBITS 543 | IMGCV_CMBITS), 544 (IMGCV_UNSCALED | IMGCV_INTIN 545 | IMGCV_OPAQUE | IMGCV_TDLRORDER 546 | IMGCV_DCM8), 547 FSColorDcmOpqUnsImageConvert); 548 } 549 awt_fill_imgcv(awt_data->awtImage->convert, 550 (IMGCV_SCALEBITS | IMGCV_INSIZEBITS | IMGCV_ALPHABITS 551 | IMGCV_ORDERBITS | IMGCV_CMBITS), 552 (IMGCV_UNSCALED | IMGCV_BYTEIN | IMGCV_OPAQUE 553 | IMGCV_RANDORDER | IMGCV_ICM), 554 OrdColorIcmOpqUnsImageConvert); 555 awt_fill_imgcv(awt_data->awtImage->convert, 556 (IMGCV_SCALEBITS | IMGCV_INSIZEBITS | IMGCV_ALPHABITS 557 | IMGCV_ORDERBITS | IMGCV_CMBITS), 558 (IMGCV_UNSCALED | IMGCV_INTIN | IMGCV_OPAQUE 559 | IMGCV_RANDORDER | IMGCV_DCM8), 560 OrdColorDcmOpqUnsImageConvert); 561 #endif /* NEED_IMAGE_CONVERT */ 562 } else { 563 free (awt_data->awtImage); 564 return 0; 565 } 566 567 if (depth > 12) { 568 free (awt_data->awtImage); 569 return 1; 570 } 571 572 if (depth == 12) { 573 paletteSize = MAX_PALETTE12_SIZE; 574 } else { 575 paletteSize = MAX_PALETTE8_SIZE; 576 } 577 578 if (awt_data->awt_num_colors > paletteSize) { 579 free (awt_data->awtImage); 580 return 0; 581 } 582 583 /* Allocate ColorData structure */ 584 awt_data->color_data = ZALLOC (_ColorData); 585 awt_data->color_data->screendata = 1; /* This ColorData struct corresponds 586 to some AWT screen/visual, so when 587 any IndexColorModel using this 588 struct is finalized, don't free 589 the struct in freeICMColorData. 590 */ 591 592 /* 593 * Initialize colors array 594 */ 595 for (i = 0; i < awt_data->awt_num_colors; i++) { 596 cols[i].pixel = i; 597 } 598 599 awt_data->color_data->awt_Colors = 600 (ColorEntry *)calloc(paletteSize, sizeof (ColorEntry)); 601 if (awt_data->color_data->awt_Colors == NULL) { 602 free (awt_data->awtImage); 603 return 0; 604 } 605 606 XQueryColors(dpy, cm, cols, awt_data->awt_num_colors); 607 for (i = 0; i < awt_data->awt_num_colors; i++) { 608 awt_data->color_data->awt_Colors[i].r = cols[i].red >> 8; 609 awt_data->color_data->awt_Colors[i].g = cols[i].green >> 8; 610 awt_data->color_data->awt_Colors[i].b = cols[i].blue >> 8; 611 awt_data->color_data->awt_Colors[i].flags = LIKELY_COLOR; 612 } 613 614 /* 615 * Determine which colors in the colormap can be allocated and mark 616 * them in the colors array 617 */ 618 nfree = 0; 619 for (i = (paletteSize / 2); i > 0; i >>= 1) { 620 if (XAllocColorCells(dpy, cm, False, plane_masks, 0, 621 freecolors + nfree, i)) { 622 nfree += i; 623 } 624 } 625 626 for (i = 0; i < nfree; i++) { 627 awt_data->color_data->awt_Colors[freecolors[i]].flags = FREE_COLOR; 628 } 629 630 #ifdef DEBUG 631 if (debug_colormap) { 632 jio_fprintf(stdout, "%d free.\n", nfree); 633 } 634 #endif 635 636 XFreeColors(dpy, cm, freecolors, nfree, 0); 637 638 /* 639 * Allocate the colors that are already allocated by other 640 * applications 641 */ 642 for (i = 0; i < awt_data->awt_num_colors; i++) { 643 if (awt_data->color_data->awt_Colors[i].flags == LIKELY_COLOR) { 644 awt_data->color_data->awt_Colors[i].flags = FREE_COLOR; 645 alloc_col(dpy, cm, 646 awt_data->color_data->awt_Colors[i].r, 647 awt_data->color_data->awt_Colors[i].g, 648 awt_data->color_data->awt_Colors[i].b, i, awt_data); 649 } 650 } 651 #ifdef DEBUG 652 if (debug_colormap) { 653 jio_fprintf(stdout, "got the already allocated ones\n"); 654 } 655 #endif 656 657 /* 658 * Allocate more colors, filling the color space evenly. 659 */ 660 661 alloc_col(dpy, cm, 255, 255, 255, -1, awt_data); 662 alloc_col(dpy, cm, 0, 0, 0, -1, awt_data); 663 664 if (awt_data->awtImage->clrdata.grayscale) { 665 int g; 666 ColorEntry *p; 667 668 if (!forcemono) { 669 for (i = 128; i > 0; i >>= 1) { 670 for (g = i; g < 256; g += (i * 2)) { 671 alloc_col(dpy, cm, g, g, g, -1, awt_data); 672 } 673 } 674 } 675 676 awt_data->color_data->img_grays = 677 (unsigned char *)calloc(256, sizeof(unsigned char)); 678 if ( awt_data->color_data->img_grays == NULL) { 679 return 0; 680 } 681 for (g = 0; g < 256; g++) { 682 int mindist, besti; 683 int d; 684 685 p = awt_data->color_data->awt_Colors; 686 mindist = 256; 687 besti = 0; 688 for (i = 0 ; i < awt_data->awt_num_colors ; i++, p++) { 689 if (forcegray && (p->r != p->g || p->g != p->b)) 690 continue; 691 if (forcemono && p->g != 0 && p->g != 255) 692 continue; 693 if (p->flags == ALLOCATED_COLOR) { 694 d = p->g - g; 695 if (d < 0) d = -d; 696 if (d < mindist) { 697 besti = i; 698 if (d == 0) { 699 break; 700 } 701 mindist = d; 702 } 703 } 704 } 705 706 awt_data->color_data->img_grays[g] = besti; 707 } 708 709 710 if (forcemono || (depth == 1)) { 711 char *gammastr = getenv("HJGAMMA"); 712 double gamma = atof(gammastr ? gammastr : "1.6"); 713 if (gamma < 0.01) gamma = 1.0; 714 #ifdef DEBUG 715 if (debug_colormap) { 716 jio_fprintf(stderr, "gamma = %f\n", gamma); 717 } 718 #endif 719 for (i = 0; i < 256; i++) { 720 img_bwgamma[i] = (int) (pow(i/255.0, gamma) * 255); 721 #ifdef DEBUG 722 if (debug_colormap) { 723 jio_fprintf(stderr, "%3d ", img_bwgamma[i]); 724 if ((i & 7) == 7) 725 jio_fprintf(stderr, "\n"); 726 } 727 #endif 728 } 729 } else { 730 for (i = 0; i < 256; i++) { 731 img_bwgamma[i] = i; 732 } 733 } 734 735 #ifdef DEBUG 736 if (debug_colormap) { 737 jio_fprintf(stderr, "GrayScale initialized\n"); 738 jio_fprintf(stderr, "color table:\n"); 739 for (i = 0; i < awt_data->awt_num_colors; i++) { 740 jio_fprintf(stderr, "%3d: %3d %3d %3d\n", 741 i, awt_data->color_data->awt_Colors[i].r, 742 awt_data->color_data->awt_Colors[i].g, 743 awt_data->color_data->awt_Colors[i].b); 744 } 745 jio_fprintf(stderr, "gray table:\n"); 746 for (i = 0; i < 256; i++) { 747 jio_fprintf(stderr, "%3d ", awt_data->color_data->img_grays[i]); 748 if ((i & 7) == 7) 749 jio_fprintf(stderr, "\n"); 750 } 751 } 752 #endif 753 754 } else { 755 756 alloc_col(dpy, cm, 255, 0, 0, -1, awt_data); 757 alloc_col(dpy, cm, 0, 255, 0, -1,awt_data); 758 alloc_col(dpy, cm, 0, 0, 255, -1,awt_data); 759 alloc_col(dpy, cm, 255, 255, 0, -1,awt_data); 760 alloc_col(dpy, cm, 255, 0, 255, -1,awt_data); 761 alloc_col(dpy, cm, 0, 255, 255, -1,awt_data); 762 alloc_col(dpy, cm, 192, 192, 192, -1,awt_data); 763 alloc_col(dpy, cm, 255, 128, 128, -1,awt_data); 764 alloc_col(dpy, cm, 128, 255, 128, -1,awt_data); 765 alloc_col(dpy, cm, 128, 128, 255, -1,awt_data); 766 alloc_col(dpy, cm, 255, 255, 128, -1,awt_data); 767 alloc_col(dpy, cm, 255, 128, 255, -1,awt_data); 768 alloc_col(dpy, cm, 128, 255, 255, -1,awt_data); 769 } 770 771 allocatedColorsNum = 0; 772 unavailableColorsNum = 0; 773 /* we do not support more than 256 entries in the colormap 774 even for 12-bit PseudoColor visuals */ 775 for (i = 0; i < MAX_PALETTE8_SIZE; i++) { 776 if (awt_data->color_data->awt_Colors[i].flags == ALLOCATED_COLOR) 777 { 778 reds[allocatedColorsNum] = awt_data->color_data->awt_Colors[i].r; 779 greens[allocatedColorsNum] = awt_data->color_data->awt_Colors[i].g; 780 blues[allocatedColorsNum] = awt_data->color_data->awt_Colors[i].b; 781 allocatedColorsNum++; 782 } else if (awt_data->color_data->awt_Colors[i].flags == 783 UNAVAILABLE_COLOR) { 784 unavailableColorsNum++; 785 } 786 } 787 788 if (depth > 8) { 789 cmapsize = MAX_PALETTE8_SIZE - unavailableColorsNum; 790 } else { 791 cmapsize = 0; 792 if (getenv("CMAPSIZE") != 0) { 793 cmapsize = atoi(getenv("CMAPSIZE")); 794 } 795 796 if (cmapsize <= 0) { 797 cmapsize = CMAP_ALLOC_DEFAULT; 798 } 799 800 if (cmapsize < allocatedColorsNum + unavailableColorsNum + CMAP_ALLOC_MIN) { 801 cmapsize = allocatedColorsNum + unavailableColorsNum + CMAP_ALLOC_MIN; 802 } 803 804 if (cmapsize > CMAP_ALLOC_MAX) { 805 cmapsize = CMAP_ALLOC_MAX; 806 } 807 808 if (cmapsize < allocatedColorsNum) { 809 cmapsize = allocatedColorsNum; 810 } 811 cmapsize -= unavailableColorsNum; 812 } 813 814 k = 0; 815 if (getenv("VIRTCUBESIZE") != 0) { 816 k = atoi(getenv("VIRTCUBESIZE")); 817 } 818 if (k == 0 || (k & (k - 1)) != 0 || k > 32) { 819 k = getVirtCubeSize(); 820 } 821 awt_data->color_data->img_clr_tbl = 822 (unsigned char *)calloc(LOOKUPSIZE * LOOKUPSIZE * LOOKUPSIZE, 823 sizeof(unsigned char)); 824 if (awt_data->color_data->img_clr_tbl == NULL) { 825 return 0; 826 } 827 img_makePalette(cmapsize, k, LOOKUPSIZE, 50, 250, 828 allocatedColorsNum, TRUE, reds, greens, blues, 829 awt_data->color_data->img_clr_tbl); 830 /*img_clr_tbl);*/ 831 832 for (i = 0; i < cmapsize; i++) { 833 indices[i] = alloc_col(dpy, cm, reds[i], greens[i], blues[i], -1, 834 awt_data); 835 } 836 for (i = 0; i < LOOKUPSIZE * LOOKUPSIZE * LOOKUPSIZE ; i++) { 837 awt_data->color_data->img_clr_tbl[i] = 838 indices[awt_data->color_data->img_clr_tbl[i]]; 839 } 840 841 awt_data->color_data->img_oda_red = &(std_img_oda_red[0][0]); 842 awt_data->color_data->img_oda_green = &(std_img_oda_green[0][0]); 843 awt_data->color_data->img_oda_blue = &(std_img_oda_blue[0][0]); 844 make_dither_arrays(cmapsize, awt_data->color_data); 845 std_odas_computed = 1; 846 847 #ifdef DEBUG 848 if (debug_colormap) { 849 int alloc_count = 0; 850 int reuse_count = 0; 851 int free_count = 0; 852 for (i = 0; i < awt_data->awt_num_colors; i++) { 853 switch (awt_data->color_data->awt_Colors[i].flags) { 854 case ALLOCATED_COLOR: 855 alloc_count++; 856 break; 857 case LIKELY_COLOR: 858 reuse_count++; 859 break; 860 case FREE_COLOR: 861 free_count++; 862 break; 863 } 864 } 865 jio_fprintf(stdout, "%d total, %d allocated, %d reused, %d still free.\n", 866 awt_data->awt_num_colors, alloc_count, reuse_count, free_count); 867 } 868 #endif 869 870 /* Fill in the ICM lut and lut2cmap mapping */ 871 awt_data->color_data->awt_numICMcolors = 0; 872 awt_data->color_data->awt_icmLUT2Colors = 873 (unsigned char *)calloc(paletteSize, sizeof (unsigned char)); 874 awt_data->color_data->awt_icmLUT = (int *)calloc(paletteSize, sizeof(int)); 875 if (awt_data->color_data->awt_icmLUT2Colors == NULL || awt_data->color_data->awt_icmLUT == NULL) { 876 return 0; 877 } 878 879 for (i=0; i < paletteSize; i++) { 880 /* Keep the mapping between this lut and the actual cmap */ 881 awt_data->color_data->awt_icmLUT2Colors 882 [awt_data->color_data->awt_numICMcolors] = i; 883 884 if (awt_data->color_data->awt_Colors[i].flags == ALLOCATED_COLOR) { 885 /* Screen IndexColorModel LUTS are always xRGB */ 886 awt_data->color_data->awt_icmLUT 887 [awt_data->color_data->awt_numICMcolors++] = 0xff000000 | 888 (awt_data->color_data->awt_Colors[i].r<<16) | 889 (awt_data->color_data->awt_Colors[i].g<<8) | 890 (awt_data->color_data->awt_Colors[i].b); 891 } else { 892 /* Screen IndexColorModel LUTS are always xRGB */ 893 awt_data->color_data->awt_icmLUT 894 [awt_data->color_data->awt_numICMcolors++] = 0; 895 } 896 } 897 return 1; 898 } 899 #endif /* !HEADLESS */ 900 901 #define red(v) (((v) >> 16) & 0xFF) 902 #define green(v) (((v) >> 8) & 0xFF) 903 #define blue(v) (((v) >> 0) & 0xFF) 904 905 #ifndef HEADLESS 906 907 jobject getColorSpace(JNIEnv* env, jint csID) { 908 jclass clazz; 909 jobject cspaceL; 910 jmethodID mid; 911 912 clazz = (*env)->FindClass(env,"java/awt/color/ColorSpace"); 913 CHECK_NULL_RETURN(clazz, NULL); 914 mid = (*env)->GetStaticMethodID(env, clazz, "getInstance", 915 "(I)Ljava/awt/color/ColorSpace;"); 916 CHECK_NULL_RETURN(mid, NULL); 917 918 /* SECURITY: This is safe, because static methods cannot 919 * be overridden, and this method does not invoke 920 * client code 921 */ 922 923 return (*env)->CallStaticObjectMethod(env, clazz, mid, csID); 924 } 925 926 jobject awtJNI_GetColorModel(JNIEnv *env, AwtGraphicsConfigDataPtr aData) 927 { 928 jobject awt_colormodel = NULL; 929 jclass clazz; 930 jmethodID mid; 931 932 if ((*env)->PushLocalFrame(env, 16) < 0) 933 return NULL; 934 935 if ((aData->awt_visInfo.class == TrueColor) && 936 (aData->awt_depth >= 15)) 937 { 938 clazz = (*env)->FindClass(env,"java/awt/image/DirectColorModel"); 939 if (clazz == NULL) { 940 (*env)->PopLocalFrame(env, 0); 941 return NULL; 942 } 943 944 if (!aData->isTranslucencySupported) { 945 946 mid = (*env)->GetMethodID(env,clazz,"<init>","(IIIII)V"); 947 948 if (mid == NULL) { 949 (*env)->PopLocalFrame(env, 0); 950 return NULL; 951 } 952 awt_colormodel = (*env)->NewObject(env,clazz, mid, 953 aData->awt_visInfo.depth, 954 aData->awt_visInfo.red_mask, 955 aData->awt_visInfo.green_mask, 956 aData->awt_visInfo.blue_mask, 957 0); 958 } else { 959 clazz = (*env)->FindClass(env,"sun/awt/X11GraphicsConfig"); 960 if (clazz == NULL) { 961 (*env)->PopLocalFrame(env, 0); 962 return NULL; 963 } 964 965 if (aData->renderPictFormat.direct.red == 16) { 966 mid = (*env)->GetStaticMethodID( env,clazz,"createDCM32", 967 "(IIIIZ)Ljava/awt/image/DirectColorModel;"); 968 969 if (mid == NULL) { 970 (*env)->PopLocalFrame(env, 0); 971 return NULL; 972 } 973 974 awt_colormodel = (*env)->CallStaticObjectMethod( 975 env,clazz, mid, 976 aData->renderPictFormat.direct.redMask 977 << aData->renderPictFormat.direct.red, 978 aData->renderPictFormat.direct.greenMask 979 << aData->renderPictFormat.direct.green, 980 aData->renderPictFormat.direct.blueMask 981 << aData->renderPictFormat.direct.blue, 982 aData->renderPictFormat.direct.alphaMask 983 << aData->renderPictFormat.direct.alpha, 984 JNI_TRUE); 985 } else { 986 mid = (*env)->GetStaticMethodID( env,clazz,"createABGRCCM", 987 "()Ljava/awt/image/ComponentColorModel;"); 988 989 if (mid == NULL) { 990 (*env)->PopLocalFrame(env, 0); 991 return NULL; 992 } 993 994 awt_colormodel = (*env)->CallStaticObjectMethod( 995 env,clazz, mid); 996 } 997 } 998 999 if(awt_colormodel == NULL) 1000 { 1001 (*env)->PopLocalFrame(env, 0); 1002 return NULL; 1003 } 1004 1005 } 1006 else if (aData->awt_visInfo.class == StaticGray && 1007 aData->awt_num_colors == 256) { 1008 jobject cspace = NULL; 1009 jint bits[1]; 1010 jintArray bitsArray; 1011 jboolean falseboolean = JNI_FALSE; 1012 1013 cspace = getColorSpace(env, java_awt_color_ColorSpace_CS_GRAY); 1014 1015 if (cspace == NULL) { 1016 (*env)->PopLocalFrame(env, 0); 1017 return NULL; 1018 } 1019 1020 bits[0] = 8; 1021 bitsArray = (*env)->NewIntArray(env, 1); 1022 if (bitsArray == NULL) { 1023 (*env)->PopLocalFrame(env, 0); 1024 return NULL; 1025 } else { 1026 (*env)->SetIntArrayRegion(env, bitsArray, 0, 1, bits); 1027 } 1028 1029 clazz = (*env)->FindClass(env,"java/awt/image/ComponentColorModel"); 1030 if (clazz == NULL) { 1031 (*env)->PopLocalFrame(env, 0); 1032 return NULL; 1033 } 1034 1035 mid = (*env)->GetMethodID(env,clazz,"<init>", 1036 "(Ljava/awt/color/ColorSpace;[IZZII)V"); 1037 1038 if (mid == NULL) { 1039 (*env)->PopLocalFrame(env, 0); 1040 return NULL; 1041 } 1042 1043 awt_colormodel = (*env)->NewObject(env,clazz, mid, 1044 cspace, 1045 bitsArray, 1046 falseboolean, 1047 falseboolean, 1048 java_awt_Transparency_OPAQUE, 1049 java_awt_image_DataBuffer_TYPE_BYTE); 1050 1051 if(awt_colormodel == NULL) 1052 { 1053 (*env)->PopLocalFrame(env, 0); 1054 return NULL; 1055 } 1056 1057 } else { 1058 jint rgb[MAX_PALETTE_SIZE]; 1059 jbyte valid[MAX_PALETTE_SIZE / 8], *pValid; 1060 jintArray hArray; 1061 jobject validBits = NULL; 1062 ColorEntry *c; 1063 int i, allocAllGray, b, allvalid, paletteSize; 1064 jlong pData; 1065 1066 if (aData->awt_visInfo.depth == 12) { 1067 paletteSize = MAX_PALETTE12_SIZE; 1068 } else { 1069 paletteSize = MAX_PALETTE8_SIZE; 1070 } 1071 1072 c = aData->color_data->awt_Colors; 1073 pValid = &valid[sizeof(valid)]; 1074 allocAllGray = 1; 1075 b = 0; 1076 allvalid = 1; 1077 1078 for (i = 0; i < paletteSize; i++, c++) { 1079 if (c->flags == ALLOCATED_COLOR) { 1080 rgb[i] = (0xff000000 | 1081 (c->r << 16) | 1082 (c->g << 8) | 1083 (c->b << 0)); 1084 if (c->r != c->g || c->g != c->b) { 1085 allocAllGray = 0; 1086 } 1087 b |= (1 << (i % 8)); 1088 } else { 1089 rgb[i] = 0; 1090 b &= ~(1 << (i % 8)); 1091 allvalid = 0; 1092 } 1093 if ((i % 8) == 7) { 1094 *--pValid = b; 1095 /* b = 0; not needed as each bit is explicitly set */ 1096 } 1097 } 1098 1099 if (allocAllGray && (aData->awtImage->clrdata.grayscale == 0)) { 1100 /* 1101 Fix for 4351638 - Gray scale HW mode on Dome frame buffer 1102 crashes VM on Solaris. 1103 It is possible for an X11 frame buffer to advertise a 1104 PseudoColor visual, but to force all allocated colormap 1105 entries to be gray colors. The Dome card does this when the 1106 HW is jumpered for a grayscale monitor, but the default 1107 visual is set to PseudoColor. In that case awtJNI_GetColorModel 1108 will be called with aData->awtImage->clrdata.grayscale == 0, 1109 but the IndexColorModel created below will detect that only 1110 gray colors exist and expect the inverse gray LUT to exist. 1111 So above when filling the hR, hG, and hB arrays we detect 1112 whether all allocated colors are gray. If so, but 1113 aData->awtImage->clrdata.grayscale == 0, we fall into this 1114 code to set aData->awtImage->clrdata.grayscale = 1 and do 1115 other things needed for the grayscale case. 1116 */ 1117 1118 int i; 1119 int g; 1120 ColorEntry *p; 1121 1122 aData->awtImage->clrdata.grayscale = 1; 1123 1124 aData->color_data->img_grays = 1125 (unsigned char *)calloc(256, sizeof(unsigned char)); 1126 1127 if (aData->color_data->img_grays == NULL) { 1128 (*env)->PopLocalFrame(env, 0); 1129 return NULL; 1130 } 1131 1132 for (g = 0; g < 256; g++) { 1133 int mindist, besti; 1134 int d; 1135 1136 p = aData->color_data->awt_Colors; 1137 mindist = 256; 1138 besti = 0; 1139 for (i = 0 ; i < paletteSize; i++, p++) { 1140 if (p->flags == ALLOCATED_COLOR) { 1141 d = p->g - g; 1142 if (d < 0) d = -d; 1143 if (d < mindist) { 1144 besti = i; 1145 if (d == 0) { 1146 break; 1147 } 1148 mindist = d; 1149 } 1150 } 1151 } 1152 1153 aData->color_data->img_grays[g] = besti; 1154 } 1155 1156 for (i = 0; i < 256; i++) { 1157 img_bwgamma[i] = i; /* REMIND: what is img_bwgamma? 1158 * is it still used anywhere? 1159 */ 1160 } 1161 } 1162 1163 if (aData->awtImage->clrdata.grayscale) { 1164 int i; 1165 ColorEntry *p; 1166 1167 /* For purposes of creating an IndexColorModel, use 1168 transparent black for non-allocated or non-gray colors. 1169 */ 1170 p = aData->color_data->awt_Colors; 1171 b = 0; 1172 pValid = &valid[sizeof(valid)]; 1173 for (i = 0; i < paletteSize; i++, p++) { 1174 if ((p->flags != ALLOCATED_COLOR) || 1175 (p->r != p->g || p->g != p->b)) 1176 { 1177 rgb[i] = 0; 1178 b &= ~(1 << (i % 8)); 1179 allvalid = 0; 1180 } else { 1181 b |= (1 << (i % 8)); 1182 } 1183 if ((i % 8) == 7) { 1184 *--pValid = b; 1185 /* b = 0; not needed as each bit is explicitly set */ 1186 } 1187 } 1188 1189 if (aData->color_data->pGrayInverseLutData == NULL) { 1190 /* Compute the inverse gray LUT for this aData->color_data 1191 struct, if not already computed. 1192 */ 1193 initInverseGrayLut(rgb, aData->awt_num_colors, 1194 aData->color_data); 1195 } 1196 } 1197 1198 if (!allvalid) { 1199 jobject bArray = (*env)->NewByteArray(env, sizeof(valid)); 1200 if (bArray == NULL) 1201 { 1202 (*env)->PopLocalFrame(env, 0); 1203 return NULL; 1204 } 1205 else 1206 { 1207 (*env)->SetByteArrayRegion(env, bArray, 0, sizeof(valid), 1208 valid); 1209 } 1210 validBits = JNU_NewObjectByName(env, 1211 "java/math/BigInteger", 1212 "([B)V", bArray); 1213 if (validBits == NULL) 1214 { 1215 (*env)->PopLocalFrame(env, 0); 1216 return NULL; 1217 } 1218 } 1219 1220 hArray = (*env)->NewIntArray(env, paletteSize); 1221 if (hArray == NULL) 1222 { 1223 (*env)->PopLocalFrame(env, 0); 1224 return NULL; 1225 } 1226 else 1227 { 1228 (*env)->SetIntArrayRegion(env, hArray, 0, paletteSize, rgb); 1229 } 1230 1231 if (aData->awt_visInfo.depth == 8) { 1232 awt_colormodel = 1233 JNU_NewObjectByName(env, 1234 "java/awt/image/IndexColorModel", 1235 "(II[IIILjava/math/BigInteger;)V", 1236 8, 256, hArray, 0, 1237 java_awt_image_DataBuffer_TYPE_BYTE, 1238 validBits); 1239 } else { 1240 awt_colormodel = 1241 JNU_NewObjectByName(env, 1242 "java/awt/image/IndexColorModel", 1243 "(II[IIILjava/math/BigInteger;)V", 1244 12, 4096, hArray, 0, 1245 java_awt_image_DataBuffer_TYPE_USHORT, 1246 validBits); 1247 } 1248 1249 if (awt_colormodel == NULL) 1250 { 1251 (*env)->PopLocalFrame(env, 0); 1252 return NULL; 1253 } 1254 1255 /* Set pData field of ColorModel to point to ColorData */ 1256 JNU_SetLongFieldFromPtr(env, awt_colormodel, g_CMpDataID, 1257 aData->color_data); 1258 1259 } 1260 1261 return (*env)->PopLocalFrame(env, awt_colormodel); 1262 } 1263 #endif /* !HEADLESS */ 1264 1265 extern jfieldID colorValueID; 1266 1267 #ifndef HEADLESS 1268 int awtJNI_GetColor(JNIEnv *env,jobject this) 1269 { 1270 /* REMIND: should not be defaultConfig. */ 1271 return awtJNI_GetColorForVis (env, this, getDefaultConfig(DefaultScreen(awt_display))); 1272 } 1273 1274 int awtJNI_GetColorForVis (JNIEnv *env,jobject this, AwtGraphicsConfigDataPtr awt_data) 1275 { 1276 int col; 1277 jclass SYSCLR_class; 1278 1279 if (!JNU_IsNull(env,this)) 1280 { 1281 SYSCLR_class = (*env)->FindClass(env, "java/awt/SystemColor"); 1282 CHECK_NULL_RETURN(SYSCLR_class, 0); 1283 1284 if ((*env)->IsInstanceOf(env, this, SYSCLR_class)) { 1285 /* SECURITY: This is safe, because there is no way 1286 * for client code to insert an object 1287 * that is a subclass of SystemColor 1288 */ 1289 col = (int) JNU_CallMethodByName(env 1290 ,NULL 1291 ,this 1292 ,"getRGB" 1293 ,"()I").i; 1294 JNU_CHECK_EXCEPTION_RETURN(env, 0); 1295 } else { 1296 col = (int)(*env)->GetIntField(env,this,colorValueID); 1297 } 1298 1299 if (awt_data->awt_cmap == (Colormap) NULL) { 1300 awtJNI_CreateColorData (env, awt_data, 1); 1301 } 1302 1303 col = awt_data->AwtColorMatch(red(col), green(col), blue(col), 1304 awt_data); 1305 return col; 1306 } 1307 1308 return 0; 1309 } 1310 1311 void 1312 awt_allocate_systemrgbcolors (jint *rgbColors, int num_colors, 1313 AwtGraphicsConfigDataPtr awtData) { 1314 int i, pixel; 1315 for (i = 0; i < num_colors; i++) 1316 pixel = alloc_col (awt_display, awtData->awt_cmap, red (rgbColors [i]), 1317 green (rgbColors [i]), blue (rgbColors [i]), -1, 1318 awtData); 1319 } 1320 1321 int 1322 awtCreateX11Colormap(AwtGraphicsConfigDataPtr adata) { 1323 int screen = adata->awt_visInfo.screen; 1324 Colormap cmap = (Colormap)NULL; 1325 1326 if (adata->awt_visInfo.visual == DefaultVisual(awt_display, screen)) { 1327 cmap = DefaultColormap(awt_display, screen); 1328 } else { 1329 Window root = RootWindow(awt_display, screen); 1330 1331 if (adata->awt_visInfo.visual->class % 2) { 1332 Atom actual_type; 1333 int actual_format; 1334 unsigned long nitems, bytes_after; 1335 XStandardColormap *scm; 1336 1337 XGetWindowProperty (awt_display, root, XA_RGB_DEFAULT_MAP, 1338 0L, 1L, False, AnyPropertyType, &actual_type, 1339 &actual_format, &nitems, &bytes_after, 1340 (unsigned char **) &scm); 1341 1342 XGetWindowProperty (awt_display, root, XA_RGB_DEFAULT_MAP, 0L, 1343 bytes_after/4 + 1, False, AnyPropertyType, 1344 &actual_type, &actual_format, &nitems, 1345 &bytes_after, (unsigned char **) &scm); 1346 1347 nitems /= (sizeof (XStandardColormap)/4); 1348 for (; nitems > 0; ++scm, --nitems) 1349 if (scm->visualid == adata->awt_visInfo.visualid) { 1350 cmap = scm->colormap; 1351 break; 1352 } 1353 } 1354 if (!cmap) { 1355 cmap = XCreateColormap (awt_display, root, 1356 adata->awt_visInfo.visual, 1357 AllocNone); 1358 } 1359 } 1360 1361 adata->awt_cmap = cmap; 1362 if (!awt_allocate_colors(adata)) { 1363 XFreeColormap(awt_display, adata->awt_cmap); 1364 adata->awt_cmap = (Colormap)NULL; 1365 return 0; 1366 } 1367 return 1; 1368 } 1369 1370 void 1371 awtJNI_CreateColorData(JNIEnv *env, AwtGraphicsConfigDataPtr adata, 1372 int lock) { 1373 1374 /* Create Colormap */ 1375 if (lock) { 1376 AWT_LOCK (); 1377 } 1378 1379 awtCreateX11Colormap(adata); 1380 1381 /* If depth is 8, allocate system colors also... Here 1382 * we just get the array of System Colors and allocate 1383 * it which may be a bit wasteful (if only some were 1384 * changed). But we don't know which ones were changed 1385 * and alloc-ing a pixel that is already allocated won't 1386 * hurt. */ 1387 1388 if (adata->awt_depth == 8 || 1389 (adata->awt_depth == 12 && adata->awt_visInfo.class == PseudoColor)) 1390 { 1391 jint colorVals [java_awt_SystemColor_NUM_COLORS]; 1392 jclass sysColors; 1393 jfieldID colorID; 1394 jintArray colors; 1395 1396 /* Unlock now to initialize the SystemColor class */ 1397 if (lock) { 1398 AWT_UNLOCK_CHECK_EXCEPTION(env); 1399 } 1400 sysColors = (*env)->FindClass (env, "java/awt/SystemColor"); 1401 CHECK_NULL(sysColors); 1402 1403 if (lock) { 1404 AWT_LOCK (); 1405 } 1406 colorID = (*env)->GetStaticFieldID (env, sysColors, 1407 "systemColors", 1408 "[I"); 1409 1410 if (colorID == NULL) { 1411 if (lock) { 1412 AWT_UNLOCK(); 1413 } 1414 return; 1415 } 1416 1417 colors = (jintArray) (*env)->GetStaticObjectField 1418 (env, sysColors, colorID); 1419 1420 (*env)->GetIntArrayRegion (env, colors, 0, 1421 java_awt_SystemColor_NUM_COLORS, 1422 (jint *) colorVals); 1423 1424 awt_allocate_systemrgbcolors (colorVals, 1425 (java_awt_SystemColor_NUM_COLORS - 1), adata); 1426 1427 } 1428 1429 if (lock) { 1430 AWT_UNLOCK (); 1431 } 1432 } 1433 1434 #endif /* !HEADLESS */