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