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