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
55static 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
69enum {
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
95struct {
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
108int 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
146unsigned char img_bwgamma[256];
147uns_ordered_dither_array img_oda_alpha;
148
149#ifdef NEED_IMAGE_CONVERT
150ImgConvertFcn DirectImageConvert;
151ImgConvertFcn Dir16IcmOpqUnsImageConvert;
152ImgConvertFcn Dir16IcmTrnUnsImageConvert;
153ImgConvertFcn Dir16IcmOpqSclImageConvert;
154ImgConvertFcn Dir16DcmOpqUnsImageConvert;
155ImgConvertFcn Dir16DcmTrnUnsImageConvert;
156ImgConvertFcn Dir16DcmOpqSclImageConvert;
157ImgConvertFcn Dir32IcmOpqUnsImageConvert;
158ImgConvertFcn Dir32IcmTrnUnsImageConvert;
159ImgConvertFcn Dir32IcmOpqSclImageConvert;
160ImgConvertFcn Dir32DcmOpqUnsImageConvert;
161ImgConvertFcn Dir32DcmTrnUnsImageConvert;
162ImgConvertFcn Dir32DcmOpqSclImageConvert;
163
164ImgConvertFcn PseudoImageConvert;
165ImgConvertFcn PseudoFSImageConvert;
166ImgConvertFcn FSColorIcmOpqUnsImageConvert;
167ImgConvertFcn FSColorDcmOpqUnsImageConvert;
168ImgConvertFcn OrdColorIcmOpqUnsImageConvert;
169ImgConvertFcn OrdColorDcmOpqUnsImageConvert;
170
171#endif /* NEED_IMAGE_CONVERT */
172
173#ifndef HEADLESS
174/*
175 * Find the best color.
176 */
177int
178awt_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
191int
192awt_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
200int
201awt_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 */
264static int
265alloc_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
340void
341awt_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
354void
355awt_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 */
370int
371awt_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
889jobject 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
908jobject 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
1247extern jfieldID colorValueID;
1248
1249#ifndef HEADLESS
1250int 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
1256int 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
1293void
1294awt_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
1303int
1304awtCreateX11Colormap(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
1352void
1353awtJNI_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 */
1417