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