| /* |
| * Copyright (c) 1995, 2014, Oracle and/or its affiliates. All rights reserved. |
| * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
| * |
| * This code is free software; you can redistribute it and/or modify it |
| * under the terms of the GNU General Public License version 2 only, as |
| * published by the Free Software Foundation. Oracle designates this |
| * particular file as subject to the "Classpath" exception as provided |
| * by Oracle in the LICENSE file that accompanied this code. |
| * |
| * This code is distributed in the hope that it will be useful, but WITHOUT |
| * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
| * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
| * version 2 for more details (a copy is included in the LICENSE file that |
| * accompanied this code). |
| * |
| * You should have received a copy of the GNU General Public License version |
| * 2 along with this work; if not, write to the Free Software Foundation, |
| * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. |
| * |
| * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
| * or visit www.oracle.com if you need additional information or have any |
| * questions. |
| */ |
| |
| /* |
| * Image dithering and rendering code for X11. |
| */ |
| |
| #include <stdio.h> |
| #include <stdlib.h> |
| #include <string.h> |
| #include <math.h> |
| #include <sys/time.h> |
| #include <sys/resource.h> |
| #ifndef HEADLESS |
| #include <X11/Xlib.h> |
| #include <X11/Xatom.h> |
| #include <X11/Xutil.h> |
| #endif /* !HEADLESS */ |
| #include "awt_p.h" |
| #include "java_awt_Color.h" |
| #include "java_awt_SystemColor.h" |
| #include "java_awt_color_ColorSpace.h" |
| #include "java_awt_Transparency.h" |
| #include "java_awt_image_DataBuffer.h" |
| #include "img_colors.h" |
| #include "imageInitIDs.h" |
| #include "dither.h" |
| |
| #include <jni.h> |
| #include <jni_util.h> |
| |
| #ifdef DEBUG |
| static int debug_colormap = 0; |
| #endif |
| |
| #define MAX_PALETTE8_SIZE (256) |
| #define MAX_PALETTE12_SIZE (4096) |
| #define MAX_PALETTE_SIZE MAX_PALETTE12_SIZE |
| |
| /* returns the absolute value x */ |
| #define ABS(x) ((x) < 0 ? -(x) : (x)) |
| |
| #define CLIP(val,min,max) ((val < min) ? min : ((val > max) ? max : val)) |
| |
| #define RGBTOGRAY(r, g, b) ((int) (.299 * r + .587 * g + .114 * b + 0.5)) |
| |
| enum { |
| FREE_COLOR = 0, |
| LIKELY_COLOR = 1, |
| UNAVAILABLE_COLOR = 2, |
| ALLOCATED_COLOR = 3 |
| }; |
| |
| /* |
| * Constants to control the filling of the colormap. |
| * By default, try to allocate colors in the default colormap until |
| * CMAP_ALLOC_DEFAULT colors are being used (by Java and/or other |
| * applications). |
| * For cases where the default colormap may already have a large |
| * number of colors in it, make sure that we ourselves try to add |
| * at least CMAP_ALLOC_MIN new colors, even if we need to allocate |
| * more than the DEFAULT to do that. |
| * Under no circumstances will the colormap be filled to more than |
| * CMAP_ALLOC_MAX colors. |
| */ |
| #define CMAP_ALLOC_MIN 100 /* minimum number of colors to "add" */ |
| #define CMAP_ALLOC_DEFAULT 200 /* default number of colors in cmap */ |
| #define CMAP_ALLOC_MAX 245 /* maximum number of colors in cmap */ |
| |
| #ifdef __solaris__ |
| #include <sys/utsname.h> |
| |
| struct { |
| char *machine; |
| int cubesize; |
| } machinemap[] = { |
| { "i86pc", LOOKUPSIZE / 4 }, /* BugTraq ID 4102599 */ |
| { "sun4c", LOOKUPSIZE / 4 }, |
| { "sun4m", LOOKUPSIZE / 2 }, |
| { "sun4d", LOOKUPSIZE / 2 }, |
| { "sun4u", LOOKUPSIZE / 1 }, |
| }; |
| |
| #define MACHMAPSIZE (sizeof(machinemap) / sizeof(machinemap[0])) |
| |
| int getVirtCubeSize() { |
| struct utsname name; |
| int i, ret; |
| |
| ret = uname(&name); |
| if (ret < 0) { |
| #ifdef DEBUG |
| #include <errno.h> |
| jio_fprintf(stderr, "uname errno = %d, using default cubesize %d\n", |
| errno, LOOKUPSIZE); |
| #endif |
| return LOOKUPSIZE; |
| } |
| |
| for (i = 0; i < MACHMAPSIZE; i++) { |
| if (strcmp(name.machine, machinemap[i].machine) == 0) { |
| #ifdef DEBUG |
| if (debug_colormap) { |
| jio_fprintf(stderr, "'%s'.cubesize = '%d'\n", |
| machinemap[i].machine, machinemap[i].cubesize); |
| } |
| #endif |
| return machinemap[i].cubesize; |
| } |
| } |
| |
| #ifdef DEBUG |
| if (debug_colormap) { |
| jio_fprintf(stderr, "unknown machine '%s' using cubesize %d\n", |
| name.machine, LOOKUPSIZE); |
| } |
| #endif |
| return LOOKUPSIZE; |
| } |
| #else /* __solaris__ */ |
| #define getVirtCubeSize() (LOOKUPSIZE) |
| #endif /* __solaris__ */ |
| |
| unsigned char img_bwgamma[256]; |
| uns_ordered_dither_array img_oda_alpha; |
| |
| #ifdef NEED_IMAGE_CONVERT |
| ImgConvertFcn DirectImageConvert; |
| ImgConvertFcn Dir16IcmOpqUnsImageConvert; |
| ImgConvertFcn Dir16IcmTrnUnsImageConvert; |
| ImgConvertFcn Dir16IcmOpqSclImageConvert; |
| ImgConvertFcn Dir16DcmOpqUnsImageConvert; |
| ImgConvertFcn Dir16DcmTrnUnsImageConvert; |
| ImgConvertFcn Dir16DcmOpqSclImageConvert; |
| ImgConvertFcn Dir32IcmOpqUnsImageConvert; |
| ImgConvertFcn Dir32IcmTrnUnsImageConvert; |
| ImgConvertFcn Dir32IcmOpqSclImageConvert; |
| ImgConvertFcn Dir32DcmOpqUnsImageConvert; |
| ImgConvertFcn Dir32DcmTrnUnsImageConvert; |
| ImgConvertFcn Dir32DcmOpqSclImageConvert; |
| |
| ImgConvertFcn PseudoImageConvert; |
| ImgConvertFcn PseudoFSImageConvert; |
| ImgConvertFcn FSColorIcmOpqUnsImageConvert; |
| ImgConvertFcn FSColorDcmOpqUnsImageConvert; |
| ImgConvertFcn OrdColorIcmOpqUnsImageConvert; |
| ImgConvertFcn OrdColorDcmOpqUnsImageConvert; |
| |
| #endif /* NEED_IMAGE_CONVERT */ |
| |
| #ifndef HEADLESS |
| /* |
| * Find the best color. |
| */ |
| int |
| awt_color_matchTC(int r, int g, int b, AwtGraphicsConfigDataPtr awt_data) |
| { |
| r = CLIP(r, 0, 255); |
| g = CLIP(g, 0, 255); |
| b = CLIP(b, 0, 255); |
| return (((r >> awt_data->awtImage->clrdata.rScale) |
| << awt_data->awtImage->clrdata.rOff) | |
| ((g >> awt_data->awtImage->clrdata.gScale) |
| << awt_data->awtImage->clrdata.gOff) | |
| ((b >> awt_data->awtImage->clrdata.bScale) |
| << awt_data->awtImage->clrdata.bOff)); |
| } |
| |
| int |
| awt_color_matchGS(int r, int g, int b, AwtGraphicsConfigDataPtr awt_data) |
| { |
| r = CLIP(r, 0, 255); |
| g = CLIP(g, 0, 255); |
| b = CLIP(b, 0, 255); |
| return awt_data->color_data->img_grays[RGBTOGRAY(r, g, b)]; |
| } |
| |
| int |
| awt_color_match(int r, int g, int b, AwtGraphicsConfigDataPtr awt_data) |
| { |
| int besti = 0; |
| int mindist, i, t, d; |
| ColorEntry *p = awt_data->color_data->awt_Colors; |
| |
| r = CLIP(r, 0, 255); |
| g = CLIP(g, 0, 255); |
| b = CLIP(b, 0, 255); |
| |
| /* look for pure gray match */ |
| if ((r == g) && (g == b)) { |
| mindist = 256; |
| for (i = 0 ; i < awt_data->awt_num_colors ; i++, p++) |
| if (p->flags == ALLOCATED_COLOR) { |
| if (! ((p->r == p->g) && (p->g == p->b)) ) |
| continue; |
| d = ABS(p->r - r); |
| if (d == 0) |
| return i; |
| if (d < mindist) { |
| besti = i; |
| mindist = d; |
| } |
| } |
| return besti; |
| } |
| |
| /* look for non-pure gray match */ |
| mindist = 256 * 256 * 256; |
| for (i = 0 ; i < awt_data->awt_num_colors ; i++, p++) |
| if (p->flags == ALLOCATED_COLOR) { |
| t = p->r - r; |
| d = t * t; |
| if (d >= mindist) |
| continue; |
| t = p->g - g; |
| d += t * t; |
| if (d >= mindist) |
| continue; |
| t = p->b - b; |
| d += t * t; |
| if (d >= mindist) |
| continue; |
| if (d == 0) |
| return i; |
| if (d < mindist) { |
| besti = i; |
| mindist = d; |
| } |
| } |
| return besti; |
| } |
| |
| /* |
| * Allocate a color in the X color map and return the pixel. |
| * If the "expected pixel" is non-negative then we will only |
| * accept the allocation if we get exactly that pixel value. |
| * This prevents us from seeing a bunch of ReadWrite pixels |
| * allocated by another imaging application and duplicating |
| * that set of inaccessible pixels in our precious remaining |
| * ReadOnly colormap cells. |
| */ |
| static int |
| alloc_col(Display *dpy, Colormap cm, int r, int g, int b, int pixel, |
| AwtGraphicsConfigDataPtr awt_data) |
| { |
| XColor col; |
| |
| r = CLIP(r, 0, 255); |
| g = CLIP(g, 0, 255); |
| b = CLIP(b, 0, 255); |
| |
| col.flags = DoRed | DoGreen | DoBlue; |
| col.red = (r << 8) | r; |
| col.green = (g << 8) | g; |
| col.blue = (b << 8) | b; |
| if (XAllocColor(dpy, cm, &col)) { |
| #ifdef DEBUG |
| if (debug_colormap) |
| jio_fprintf(stdout, "allocated %d (%d,%d, %d)\n", col.pixel, r, g, b); |
| #endif |
| if (pixel >= 0 && col.pixel != (unsigned long)pixel) { |
| /* |
| * If we were trying to allocate a shareable "ReadOnly" |
| * color then we would have gotten back the expected |
| * pixel. If the returned pixel was different, then |
| * the source color that we were attempting to gain |
| * access to must be some other application's ReadWrite |
| * private color. We free the returned pixel so that |
| * we won't waste precious colormap entries by duplicating |
| * that color in the as yet unallocated entries. We |
| * return -1 here to indicate the failure to get the |
| * expected pixel. |
| */ |
| #ifdef DEBUG |
| if (debug_colormap) |
| jio_fprintf(stdout, " used by other app, freeing\n"); |
| #endif |
| awt_data->color_data->awt_Colors[pixel].flags = UNAVAILABLE_COLOR; |
| XFreeColors(dpy, cm, &col.pixel, 1, 0); |
| return -1; |
| } |
| /* |
| * Our current implementation doesn't support pixels which |
| * don't fit in 8 bit (even for 12-bit visuals) |
| */ |
| if (col.pixel > 255) { |
| #ifdef DEBUG |
| if (debug_colormap) |
| jio_fprintf(stdout, "pixel %d for (%d,%d, %d) is > 8 bit, releasing.\n", |
| col.pixel, r, g, b); |
| #endif |
| XFreeColors(dpy, cm, &col.pixel, 1, 0); |
| return awt_color_match(r, g, b, awt_data); |
| } |
| |
| awt_data->color_data->awt_Colors[col.pixel].flags = ALLOCATED_COLOR; |
| awt_data->color_data->awt_Colors[col.pixel].r = col.red >> 8; |
| awt_data->color_data->awt_Colors[col.pixel].g = col.green >> 8; |
| awt_data->color_data->awt_Colors[col.pixel].b = col.blue >> 8; |
| if (awt_data->color_data->awt_icmLUT != 0) { |
| awt_data->color_data->awt_icmLUT2Colors[col.pixel] = col.pixel; |
| awt_data->color_data->awt_icmLUT[col.pixel] = |
| 0xff000000 | |
| (awt_data->color_data->awt_Colors[col.pixel].r<<16) | |
| (awt_data->color_data->awt_Colors[col.pixel].g<<8) | |
| (awt_data->color_data->awt_Colors[col.pixel].b); |
| } |
| return col.pixel; |
| #ifdef DEBUG |
| } else if (debug_colormap) { |
| jio_fprintf(stdout, "can't allocate (%d,%d, %d)\n", r, g, b); |
| #endif |
| } |
| |
| return awt_color_match(r, g, b, awt_data); |
| } |
| |
| void |
| awt_allocate_systemcolors(XColor *colorsPtr, int num_pixels, AwtGraphicsConfigDataPtr awtData) { |
| int i; |
| int r, g, b, pixel; |
| |
| for (i=0; i < num_pixels; i++) { |
| r = colorsPtr[i].red >> 8; |
| g = colorsPtr[i].green >> 8; |
| b = colorsPtr[i].blue >> 8; |
| pixel = alloc_col(awt_display, awtData->awt_cmap, r, g, b, -1, awtData); |
| } |
| } |
| #endif /* !HEADLESS */ |
| |
| void |
| awt_fill_imgcv(ImgConvertFcn **array, int mask, int value, ImgConvertFcn fcn) |
| { |
| int i; |
| |
| for (i = 0; i < NUM_IMGCV; i++) { |
| if ((i & mask) == value) { |
| array[i] = fcn; |
| } |
| } |
| } |
| |
| #ifndef HEADLESS |
| /* |
| * called from X11Server_create() in xlib.c |
| */ |
| int |
| awt_allocate_colors(AwtGraphicsConfigDataPtr awt_data) |
| { |
| Display *dpy; |
| unsigned long freecolors[MAX_PALETTE_SIZE], plane_masks[1]; |
| int paletteSize; |
| XColor cols[MAX_PALETTE_SIZE]; |
| unsigned char reds[256], greens[256], blues[256]; |
| int indices[256]; |
| Colormap cm; |
| int i, j, k, cmapsize, nfree, depth, bpp; |
| int allocatedColorsNum, unavailableColorsNum; |
| XPixmapFormatValues *pPFV; |
| int numpfv; |
| XVisualInfo *pVI; |
| char *forcemono; |
| char *forcegray; |
| |
| make_uns_ordered_dither_array(img_oda_alpha, 256); |
| |
| |
| forcemono = getenv("FORCEMONO"); |
| forcegray = getenv("FORCEGRAY"); |
| if (forcemono && !forcegray) |
| forcegray = forcemono; |
| |
| /* |
| * Get the colormap and make sure we have the right visual |
| */ |
| dpy = awt_display; |
| cm = awt_data->awt_cmap; |
| depth = awt_data->awt_depth; |
| pVI = &awt_data->awt_visInfo; |
| awt_data->awt_num_colors = awt_data->awt_visInfo.colormap_size; |
| awt_data->awtImage = (awtImageData *) calloc (1, sizeof (awtImageData)); |
| |
| pPFV = XListPixmapFormats(dpy, &numpfv); |
| if (pPFV) { |
| for (i = 0; i < numpfv; i++) { |
| if (pPFV[i].depth == depth) { |
| awt_data->awtImage->wsImageFormat = pPFV[i]; |
| break; |
| } |
| } |
| XFree(pPFV); |
| } |
| bpp = awt_data->awtImage->wsImageFormat.bits_per_pixel; |
| if (bpp == 24) { |
| bpp = 32; |
| } |
| awt_data->awtImage->clrdata.bitsperpixel = bpp; |
| awt_data->awtImage->Depth = depth; |
| |
| if ((bpp == 32 || bpp == 16) && pVI->class == TrueColor && depth >= 15) { |
| awt_data->AwtColorMatch = awt_color_matchTC; |
| awt_data->awtImage->clrdata.rOff = 0; |
| for (i = pVI->red_mask; (i & 1) == 0; i >>= 1) { |
| awt_data->awtImage->clrdata.rOff++; |
| } |
| awt_data->awtImage->clrdata.rScale = 0; |
| while (i < 0x80) { |
| awt_data->awtImage->clrdata.rScale++; |
| i <<= 1; |
| } |
| awt_data->awtImage->clrdata.gOff = 0; |
| for (i = pVI->green_mask; (i & 1) == 0; i >>= 1) { |
| awt_data->awtImage->clrdata.gOff++; |
| } |
| awt_data->awtImage->clrdata.gScale = 0; |
| while (i < 0x80) { |
| awt_data->awtImage->clrdata.gScale++; |
| i <<= 1; |
| } |
| awt_data->awtImage->clrdata.bOff = 0; |
| for (i = pVI->blue_mask; (i & 1) == 0; i >>= 1) { |
| awt_data->awtImage->clrdata.bOff++; |
| } |
| awt_data->awtImage->clrdata.bScale = 0; |
| while (i < 0x80) { |
| awt_data->awtImage->clrdata.bScale++; |
| i <<= 1; |
| } |
| #ifdef NEED_IMAGE_CONVERT |
| awt_fill_imgcv(awt_data->awtImage->convert, 0, 0, DirectImageConvert); |
| awt_fill_imgcv(awt_data->awtImage->convert, |
| (IMGCV_SCALEBITS | IMGCV_INSIZEBITS |
| | IMGCV_ALPHABITS | IMGCV_CMBITS), |
| (IMGCV_UNSCALED | IMGCV_BYTEIN |
| | IMGCV_OPAQUE | IMGCV_ICM), |
| (bpp == 32 |
| ? Dir32IcmOpqUnsImageConvert |
| : Dir16IcmOpqUnsImageConvert)); |
| awt_fill_imgcv(awt_data->awtImage->convert, |
| (IMGCV_SCALEBITS | IMGCV_INSIZEBITS |
| | IMGCV_ALPHABITS | IMGCV_CMBITS), |
| (IMGCV_UNSCALED | IMGCV_BYTEIN |
| | IMGCV_ALPHA | IMGCV_ICM), |
| (bpp == 32 |
| ? Dir32IcmTrnUnsImageConvert |
| : Dir16IcmTrnUnsImageConvert)); |
| awt_fill_imgcv(awt_data->awtImage->convert, |
| (IMGCV_SCALEBITS | IMGCV_INSIZEBITS |
| | IMGCV_ALPHABITS | IMGCV_CMBITS), |
| (IMGCV_SCALED | IMGCV_BYTEIN |
| | IMGCV_OPAQUE | IMGCV_ICM), |
| (bpp == 32 |
| ? Dir32IcmOpqSclImageConvert |
| : Dir16IcmOpqSclImageConvert)); |
| awt_fill_imgcv(awt_data->awtImage->convert, |
| (IMGCV_SCALEBITS | IMGCV_INSIZEBITS |
| | IMGCV_ALPHABITS | IMGCV_CMBITS), |
| (IMGCV_UNSCALED | IMGCV_INTIN |
| | IMGCV_OPAQUE | IMGCV_DCM8), |
| (bpp == 32 |
| ? Dir32DcmOpqUnsImageConvert |
| : Dir16DcmOpqUnsImageConvert)); |
| awt_fill_imgcv(awt_data->awtImage->convert, |
| (IMGCV_SCALEBITS | IMGCV_INSIZEBITS |
| | IMGCV_ALPHABITS | IMGCV_CMBITS), |
| (IMGCV_UNSCALED | IMGCV_INTIN |
| | IMGCV_ALPHA | IMGCV_DCM8), |
| (bpp == 32 |
| ? Dir32DcmTrnUnsImageConvert |
| : Dir16DcmTrnUnsImageConvert)); |
| awt_fill_imgcv(awt_data->awtImage->convert, |
| (IMGCV_SCALEBITS | IMGCV_INSIZEBITS |
| | IMGCV_ALPHABITS | IMGCV_CMBITS), |
| (IMGCV_SCALED | IMGCV_INTIN |
| | IMGCV_OPAQUE | IMGCV_DCM8), |
| (bpp == 32 |
| ? Dir32DcmOpqSclImageConvert |
| : Dir16DcmOpqSclImageConvert)); |
| #endif /* NEED_IMAGE_CONVERT */ |
| } else if (bpp <= 16 && (pVI->class == StaticGray |
| || pVI->class == GrayScale |
| || (pVI->class == PseudoColor && forcegray))) { |
| awt_data->AwtColorMatch = awt_color_matchGS; |
| awt_data->awtImage->clrdata.grayscale = 1; |
| awt_data->awtImage->clrdata.bitsperpixel = MAX(bpp, 8); |
| #ifdef NEED_IMAGE_CONVERT |
| awt_fill_imgcv(awt_data->awtImage->convert, 0, 0, PseudoImageConvert); |
| if (getenv("NOFSDITHER") == NULL) { |
| awt_fill_imgcv(awt_data->awtImage->convert, |
| IMGCV_ORDERBITS, IMGCV_TDLRORDER, |
| PseudoFSImageConvert); |
| } |
| #endif /* NEED_IMAGE_CONVERT */ |
| } else if (depth <= 12 && (pVI->class == PseudoColor |
| || pVI->class == TrueColor |
| || pVI->class == StaticColor)) { |
| if (pVI->class == TrueColor) |
| awt_data->awt_num_colors = (1 << pVI->depth); |
| awt_data->AwtColorMatch = awt_color_match; |
| awt_data->awtImage->clrdata.bitsperpixel = MAX(bpp, 8); |
| #ifdef NEED_IMAGE_CONVERT |
| awt_fill_imgcv(awt_data->awtImage->convert, 0, 0, PseudoImageConvert); |
| if (getenv("NOFSDITHER") == NULL) { |
| awt_fill_imgcv(awt_data->awtImage->convert, IMGCV_ORDERBITS, |
| IMGCV_TDLRORDER, PseudoFSImageConvert); |
| awt_fill_imgcv(awt_data->awtImage->convert, |
| (IMGCV_SCALEBITS | IMGCV_INSIZEBITS |
| | IMGCV_ALPHABITS | IMGCV_ORDERBITS |
| | IMGCV_CMBITS), |
| (IMGCV_UNSCALED | IMGCV_BYTEIN |
| | IMGCV_OPAQUE | IMGCV_TDLRORDER |
| | IMGCV_ICM), |
| FSColorIcmOpqUnsImageConvert); |
| awt_fill_imgcv(awt_data->awtImage->convert, |
| (IMGCV_SCALEBITS | IMGCV_INSIZEBITS |
| | IMGCV_ALPHABITS | IMGCV_ORDERBITS |
| | IMGCV_CMBITS), |
| (IMGCV_UNSCALED | IMGCV_INTIN |
| | IMGCV_OPAQUE | IMGCV_TDLRORDER |
| | IMGCV_DCM8), |
| FSColorDcmOpqUnsImageConvert); |
| } |
| awt_fill_imgcv(awt_data->awtImage->convert, |
| (IMGCV_SCALEBITS | IMGCV_INSIZEBITS | IMGCV_ALPHABITS |
| | IMGCV_ORDERBITS | IMGCV_CMBITS), |
| (IMGCV_UNSCALED | IMGCV_BYTEIN | IMGCV_OPAQUE |
| | IMGCV_RANDORDER | IMGCV_ICM), |
| OrdColorIcmOpqUnsImageConvert); |
| awt_fill_imgcv(awt_data->awtImage->convert, |
| (IMGCV_SCALEBITS | IMGCV_INSIZEBITS | IMGCV_ALPHABITS |
| | IMGCV_ORDERBITS | IMGCV_CMBITS), |
| (IMGCV_UNSCALED | IMGCV_INTIN | IMGCV_OPAQUE |
| | IMGCV_RANDORDER | IMGCV_DCM8), |
| OrdColorDcmOpqUnsImageConvert); |
| #endif /* NEED_IMAGE_CONVERT */ |
| } else { |
| free (awt_data->awtImage); |
| return 0; |
| } |
| |
| if (depth > 12) { |
| return 1; |
| } |
| |
| if (depth == 12) { |
| paletteSize = MAX_PALETTE12_SIZE; |
| } else { |
| paletteSize = MAX_PALETTE8_SIZE; |
| } |
| |
| if (awt_data->awt_num_colors > paletteSize) { |
| free (awt_data->awtImage); |
| return 0; |
| } |
| |
| /* Allocate ColorData structure */ |
| awt_data->color_data = ZALLOC (_ColorData); |
| awt_data->color_data->screendata = 1; /* This ColorData struct corresponds |
| to some AWT screen/visual, so when |
| any IndexColorModel using this |
| struct is finalized, don't free |
| the struct in freeICMColorData. |
| */ |
| |
| /* |
| * Initialize colors array |
| */ |
| for (i = 0; i < awt_data->awt_num_colors; i++) { |
| cols[i].pixel = i; |
| } |
| |
| awt_data->color_data->awt_Colors = |
| (ColorEntry *)calloc(paletteSize, sizeof (ColorEntry)); |
| |
| XQueryColors(dpy, cm, cols, awt_data->awt_num_colors); |
| for (i = 0; i < awt_data->awt_num_colors; i++) { |
| awt_data->color_data->awt_Colors[i].r = cols[i].red >> 8; |
| awt_data->color_data->awt_Colors[i].g = cols[i].green >> 8; |
| awt_data->color_data->awt_Colors[i].b = cols[i].blue >> 8; |
| awt_data->color_data->awt_Colors[i].flags = LIKELY_COLOR; |
| } |
| |
| /* |
| * Determine which colors in the colormap can be allocated and mark |
| * them in the colors array |
| */ |
| nfree = 0; |
| for (i = (paletteSize / 2); i > 0; i >>= 1) { |
| if (XAllocColorCells(dpy, cm, False, plane_masks, 0, |
| freecolors + nfree, i)) { |
| nfree += i; |
| } |
| } |
| |
| for (i = 0; i < nfree; i++) { |
| awt_data->color_data->awt_Colors[freecolors[i]].flags = FREE_COLOR; |
| } |
| |
| #ifdef DEBUG |
| if (debug_colormap) { |
| jio_fprintf(stdout, "%d free.\n", nfree); |
| } |
| #endif |
| |
| XFreeColors(dpy, cm, freecolors, nfree, 0); |
| |
| /* |
| * Allocate the colors that are already allocated by other |
| * applications |
| */ |
| for (i = 0; i < awt_data->awt_num_colors; i++) { |
| if (awt_data->color_data->awt_Colors[i].flags == LIKELY_COLOR) { |
| awt_data->color_data->awt_Colors[i].flags = FREE_COLOR; |
| alloc_col(dpy, cm, |
| awt_data->color_data->awt_Colors[i].r, |
| awt_data->color_data->awt_Colors[i].g, |
| awt_data->color_data->awt_Colors[i].b, i, awt_data); |
| } |
| } |
| #ifdef DEBUG |
| if (debug_colormap) { |
| jio_fprintf(stdout, "got the already allocated ones\n"); |
| } |
| #endif |
| |
| /* |
| * Allocate more colors, filling the color space evenly. |
| */ |
| |
| alloc_col(dpy, cm, 255, 255, 255, -1, awt_data); |
| alloc_col(dpy, cm, 0, 0, 0, -1, awt_data); |
| |
| if (awt_data->awtImage->clrdata.grayscale) { |
| int g; |
| ColorEntry *p; |
| |
| if (!forcemono) { |
| for (i = 128; i > 0; i >>= 1) { |
| for (g = i; g < 256; g += (i * 2)) { |
| alloc_col(dpy, cm, g, g, g, -1, awt_data); |
| } |
| } |
| } |
| |
| awt_data->color_data->img_grays = |
| (unsigned char *)calloc(256, sizeof(unsigned char)); |
| for (g = 0; g < 256; g++) { |
| int mindist, besti; |
| int d; |
| |
| p = awt_data->color_data->awt_Colors; |
| mindist = 256; |
| besti = 0; |
| for (i = 0 ; i < awt_data->awt_num_colors ; i++, p++) { |
| if (forcegray && (p->r != p->g || p->g != p->b)) |
| continue; |
| if (forcemono && p->g != 0 && p->g != 255) |
| continue; |
| if (p->flags == ALLOCATED_COLOR) { |
| d = p->g - g; |
| if (d < 0) d = -d; |
| if (d < mindist) { |
| besti = i; |
| if (d == 0) { |
| break; |
| } |
| mindist = d; |
| } |
| } |
| } |
| |
| awt_data->color_data->img_grays[g] = besti; |
| } |
| |
| |
| if (forcemono || (depth == 1)) { |
| char *gammastr = getenv("HJGAMMA"); |
| double gamma = atof(gammastr ? gammastr : "1.6"); |
| if (gamma < 0.01) gamma = 1.0; |
| #ifdef DEBUG |
| if (debug_colormap) { |
| jio_fprintf(stderr, "gamma = %f\n", gamma); |
| } |
| #endif |
| for (i = 0; i < 256; i++) { |
| img_bwgamma[i] = (int) (pow(i/255.0, gamma) * 255); |
| #ifdef DEBUG |
| if (debug_colormap) { |
| jio_fprintf(stderr, "%3d ", img_bwgamma[i]); |
| if ((i & 7) == 7) |
| jio_fprintf(stderr, "\n"); |
| } |
| #endif |
| } |
| } else { |
| for (i = 0; i < 256; i++) { |
| img_bwgamma[i] = i; |
| } |
| } |
| |
| #ifdef DEBUG |
| if (debug_colormap) { |
| jio_fprintf(stderr, "GrayScale initialized\n"); |
| jio_fprintf(stderr, "color table:\n"); |
| for (i = 0; i < awt_data->awt_num_colors; i++) { |
| jio_fprintf(stderr, "%3d: %3d %3d %3d\n", |
| i, awt_data->color_data->awt_Colors[i].r, |
| awt_data->color_data->awt_Colors[i].g, |
| awt_data->color_data->awt_Colors[i].b); |
| } |
| jio_fprintf(stderr, "gray table:\n"); |
| for (i = 0; i < 256; i++) { |
| jio_fprintf(stderr, "%3d ", awt_data->color_data->img_grays[i]); |
| if ((i & 7) == 7) |
| jio_fprintf(stderr, "\n"); |
| } |
| } |
| #endif |
| |
| } else { |
| |
| alloc_col(dpy, cm, 255, 0, 0, -1, awt_data); |
| alloc_col(dpy, cm, 0, 255, 0, -1,awt_data); |
| alloc_col(dpy, cm, 0, 0, 255, -1,awt_data); |
| alloc_col(dpy, cm, 255, 255, 0, -1,awt_data); |
| alloc_col(dpy, cm, 255, 0, 255, -1,awt_data); |
| alloc_col(dpy, cm, 0, 255, 255, -1,awt_data); |
| alloc_col(dpy, cm, 192, 192, 192, -1,awt_data); |
| alloc_col(dpy, cm, 255, 128, 128, -1,awt_data); |
| alloc_col(dpy, cm, 128, 255, 128, -1,awt_data); |
| alloc_col(dpy, cm, 128, 128, 255, -1,awt_data); |
| alloc_col(dpy, cm, 255, 255, 128, -1,awt_data); |
| alloc_col(dpy, cm, 255, 128, 255, -1,awt_data); |
| alloc_col(dpy, cm, 128, 255, 255, -1,awt_data); |
| } |
| |
| allocatedColorsNum = 0; |
| unavailableColorsNum = 0; |
| /* we do not support more than 256 entries in the colormap |
| even for 12-bit PseudoColor visuals */ |
| for (i = 0; i < MAX_PALETTE8_SIZE; i++) { |
| if (awt_data->color_data->awt_Colors[i].flags == ALLOCATED_COLOR) |
| { |
| reds[allocatedColorsNum] = awt_data->color_data->awt_Colors[i].r; |
| greens[allocatedColorsNum] = awt_data->color_data->awt_Colors[i].g; |
| blues[allocatedColorsNum] = awt_data->color_data->awt_Colors[i].b; |
| allocatedColorsNum++; |
| } else if (awt_data->color_data->awt_Colors[i].flags == |
| UNAVAILABLE_COLOR) { |
| unavailableColorsNum++; |
| } |
| } |
| |
| if (depth > 8) { |
| cmapsize = MAX_PALETTE8_SIZE - unavailableColorsNum; |
| } else { |
| cmapsize = 0; |
| if (getenv("CMAPSIZE") != 0) { |
| cmapsize = atoi(getenv("CMAPSIZE")); |
| } |
| |
| if (cmapsize <= 0) { |
| cmapsize = CMAP_ALLOC_DEFAULT; |
| } |
| |
| if (cmapsize < allocatedColorsNum + unavailableColorsNum + CMAP_ALLOC_MIN) { |
| cmapsize = allocatedColorsNum + unavailableColorsNum + CMAP_ALLOC_MIN; |
| } |
| |
| if (cmapsize > CMAP_ALLOC_MAX) { |
| cmapsize = CMAP_ALLOC_MAX; |
| } |
| |
| if (cmapsize < allocatedColorsNum) { |
| cmapsize = allocatedColorsNum; |
| } |
| cmapsize -= unavailableColorsNum; |
| } |
| |
| k = 0; |
| if (getenv("VIRTCUBESIZE") != 0) { |
| k = atoi(getenv("VIRTCUBESIZE")); |
| } |
| if (k == 0 || (k & (k - 1)) != 0 || k > 32) { |
| k = getVirtCubeSize(); |
| } |
| awt_data->color_data->img_clr_tbl = |
| (unsigned char *)calloc(LOOKUPSIZE * LOOKUPSIZE * LOOKUPSIZE, |
| sizeof(unsigned char)); |
| img_makePalette(cmapsize, k, LOOKUPSIZE, 50, 250, |
| allocatedColorsNum, TRUE, reds, greens, blues, |
| awt_data->color_data->img_clr_tbl); |
| /*img_clr_tbl);*/ |
| |
| for (i = 0; i < cmapsize; i++) { |
| indices[i] = alloc_col(dpy, cm, reds[i], greens[i], blues[i], -1, |
| awt_data); |
| } |
| for (i = 0; i < LOOKUPSIZE * LOOKUPSIZE * LOOKUPSIZE ; i++) { |
| awt_data->color_data->img_clr_tbl[i] = |
| indices[awt_data->color_data->img_clr_tbl[i]]; |
| } |
| |
| awt_data->color_data->img_oda_red = &(std_img_oda_red[0][0]); |
| awt_data->color_data->img_oda_green = &(std_img_oda_green[0][0]); |
| awt_data->color_data->img_oda_blue = &(std_img_oda_blue[0][0]); |
| make_dither_arrays(cmapsize, awt_data->color_data); |
| std_odas_computed = 1; |
| |
| #ifdef DEBUG |
| if (debug_colormap) { |
| int alloc_count = 0; |
| int reuse_count = 0; |
| int free_count = 0; |
| for (i = 0; i < awt_data->awt_num_colors; i++) { |
| switch (awt_data->color_data->awt_Colors[i].flags) { |
| case ALLOCATED_COLOR: |
| alloc_count++; |
| break; |
| case LIKELY_COLOR: |
| reuse_count++; |
| break; |
| case FREE_COLOR: |
| free_count++; |
| break; |
| } |
| } |
| jio_fprintf(stdout, "%d total, %d allocated, %d reused, %d still free.\n", |
| awt_data->awt_num_colors, alloc_count, reuse_count, free_count); |
| } |
| #endif |
| |
| /* Fill in the ICM lut and lut2cmap mapping */ |
| awt_data->color_data->awt_numICMcolors = 0; |
| awt_data->color_data->awt_icmLUT2Colors = |
| (unsigned char *)calloc(paletteSize, sizeof (unsigned char)); |
| awt_data->color_data->awt_icmLUT = (int *)calloc(paletteSize, sizeof(int)); |
| for (i=0; i < paletteSize; i++) { |
| /* Keep the mapping between this lut and the actual cmap */ |
| awt_data->color_data->awt_icmLUT2Colors |
| [awt_data->color_data->awt_numICMcolors] = i; |
| |
| if (awt_data->color_data->awt_Colors[i].flags == ALLOCATED_COLOR) { |
| /* Screen IndexColorModel LUTS are always xRGB */ |
| awt_data->color_data->awt_icmLUT |
| [awt_data->color_data->awt_numICMcolors++] = 0xff000000 | |
| (awt_data->color_data->awt_Colors[i].r<<16) | |
| (awt_data->color_data->awt_Colors[i].g<<8) | |
| (awt_data->color_data->awt_Colors[i].b); |
| } else { |
| /* Screen IndexColorModel LUTS are always xRGB */ |
| awt_data->color_data->awt_icmLUT |
| [awt_data->color_data->awt_numICMcolors++] = 0; |
| } |
| } |
| return 1; |
| } |
| #endif /* !HEADLESS */ |
| |
| #define red(v) (((v) >> 16) & 0xFF) |
| #define green(v) (((v) >> 8) & 0xFF) |
| #define blue(v) (((v) >> 0) & 0xFF) |
| |
| #ifndef HEADLESS |
| |
| jobject getColorSpace(JNIEnv* env, jint csID) { |
| jclass clazz; |
| jobject cspaceL; |
| jmethodID mid; |
| |
| clazz = (*env)->FindClass(env,"java/awt/color/ColorSpace"); |
| CHECK_NULL_RETURN(clazz, NULL); |
| mid = (*env)->GetStaticMethodID(env, clazz, "getInstance", |
| "(I)Ljava/awt/color/ColorSpace;"); |
| CHECK_NULL_RETURN(mid, NULL); |
| |
| /* SECURITY: This is safe, because static methods cannot |
| * be overridden, and this method does not invoke |
| * client code |
| */ |
| |
| return (*env)->CallStaticObjectMethod(env, clazz, mid, csID); |
| } |
| |
| jobject awtJNI_GetColorModel(JNIEnv *env, AwtGraphicsConfigDataPtr aData) |
| { |
| jobject awt_colormodel = NULL; |
| jclass clazz; |
| jmethodID mid; |
| |
| if ((*env)->PushLocalFrame(env, 16) < 0) |
| return NULL; |
| |
| if ((aData->awt_visInfo.class == TrueColor) && |
| (aData->awt_depth >= 15)) |
| { |
| clazz = (*env)->FindClass(env,"java/awt/image/DirectColorModel"); |
| if (clazz == NULL) { |
| (*env)->PopLocalFrame(env, 0); |
| return NULL; |
| } |
| |
| if (!aData->isTranslucencySupported) { |
| |
| mid = (*env)->GetMethodID(env,clazz,"<init>","(IIIII)V"); |
| |
| if (mid == NULL) { |
| (*env)->PopLocalFrame(env, 0); |
| return NULL; |
| } |
| awt_colormodel = (*env)->NewObject(env,clazz, mid, |
| aData->awt_visInfo.depth, |
| aData->awt_visInfo.red_mask, |
| aData->awt_visInfo.green_mask, |
| aData->awt_visInfo.blue_mask, |
| 0); |
| } else { |
| clazz = (*env)->FindClass(env,"sun/awt/X11GraphicsConfig"); |
| if (clazz == NULL) { |
| (*env)->PopLocalFrame(env, 0); |
| return NULL; |
| } |
| |
| if (aData->renderPictFormat.direct.red == 16) { |
| mid = (*env)->GetStaticMethodID( env,clazz,"createDCM32", |
| "(IIIIZ)Ljava/awt/image/DirectColorModel;"); |
| |
| if (mid == NULL) { |
| (*env)->PopLocalFrame(env, 0); |
| return NULL; |
| } |
| |
| awt_colormodel = (*env)->CallStaticObjectMethod( |
| env,clazz, mid, |
| aData->renderPictFormat.direct.redMask |
| << aData->renderPictFormat.direct.red, |
| aData->renderPictFormat.direct.greenMask |
| << aData->renderPictFormat.direct.green, |
| aData->renderPictFormat.direct.blueMask |
| << aData->renderPictFormat.direct.blue, |
| aData->renderPictFormat.direct.alphaMask |
| << aData->renderPictFormat.direct.alpha, |
| JNI_TRUE); |
| } else { |
| mid = (*env)->GetStaticMethodID( env,clazz,"createABGRCCM", |
| "()Ljava/awt/image/ComponentColorModel;"); |
| |
| if (mid == NULL) { |
| (*env)->PopLocalFrame(env, 0); |
| return NULL; |
| } |
| |
| awt_colormodel = (*env)->CallStaticObjectMethod( |
| env,clazz, mid); |
| } |
| } |
| |
| if(awt_colormodel == NULL) |
| { |
| (*env)->PopLocalFrame(env, 0); |
| return NULL; |
| } |
| |
| } |
| else if (aData->awt_visInfo.class == StaticGray && |
| aData->awt_num_colors == 256) { |
| jobject cspace = NULL; |
| jint bits[1]; |
| jintArray bitsArray; |
| jboolean falseboolean = JNI_FALSE; |
| |
| cspace = getColorSpace(env, java_awt_color_ColorSpace_CS_GRAY); |
| |
| if (cspace == NULL) { |
| (*env)->PopLocalFrame(env, 0); |
| return NULL; |
| } |
| |
| bits[0] = 8; |
| bitsArray = (*env)->NewIntArray(env, 1); |
| if (bitsArray == NULL) { |
| (*env)->PopLocalFrame(env, 0); |
| return NULL; |
| } else { |
| (*env)->SetIntArrayRegion(env, bitsArray, 0, 1, bits); |
| } |
| |
| clazz = (*env)->FindClass(env,"java/awt/image/ComponentColorModel"); |
| if (clazz == NULL) { |
| (*env)->PopLocalFrame(env, 0); |
| return NULL; |
| } |
| |
| mid = (*env)->GetMethodID(env,clazz,"<init>", |
| "(Ljava/awt/color/ColorSpace;[IZZII)V"); |
| |
| if (mid == NULL) { |
| (*env)->PopLocalFrame(env, 0); |
| return NULL; |
| } |
| |
| awt_colormodel = (*env)->NewObject(env,clazz, mid, |
| cspace, |
| bitsArray, |
| falseboolean, |
| falseboolean, |
| java_awt_Transparency_OPAQUE, |
| java_awt_image_DataBuffer_TYPE_BYTE); |
| |
| if(awt_colormodel == NULL) |
| { |
| (*env)->PopLocalFrame(env, 0); |
| return NULL; |
| } |
| |
| } else { |
| jint rgb[MAX_PALETTE_SIZE]; |
| jbyte valid[MAX_PALETTE_SIZE / 8], *pValid; |
| jintArray hArray; |
| jobject validBits = NULL; |
| ColorEntry *c; |
| int i, allocAllGray, b, allvalid, paletteSize; |
| jlong pData; |
| |
| if (aData->awt_visInfo.depth == 12) { |
| paletteSize = MAX_PALETTE12_SIZE; |
| } else { |
| paletteSize = MAX_PALETTE8_SIZE; |
| } |
| |
| c = aData->color_data->awt_Colors; |
| pValid = &valid[sizeof(valid)]; |
| allocAllGray = 1; |
| b = 0; |
| allvalid = 1; |
| |
| for (i = 0; i < paletteSize; i++, c++) { |
| if (c->flags == ALLOCATED_COLOR) { |
| rgb[i] = (0xff000000 | |
| (c->r << 16) | |
| (c->g << 8) | |
| (c->b << 0)); |
| if (c->r != c->g || c->g != c->b) { |
| allocAllGray = 0; |
| } |
| b |= (1 << (i % 8)); |
| } else { |
| rgb[i] = 0; |
| b &= ~(1 << (i % 8)); |
| allvalid = 0; |
| } |
| if ((i % 8) == 7) { |
| *--pValid = b; |
| /* b = 0; not needed as each bit is explicitly set */ |
| } |
| } |
| |
| if (allocAllGray && (aData->awtImage->clrdata.grayscale == 0)) { |
| /* |
| Fix for 4351638 - Gray scale HW mode on Dome frame buffer |
| crashes VM on Solaris. |
| It is possible for an X11 frame buffer to advertise a |
| PseudoColor visual, but to force all allocated colormap |
| entries to be gray colors. The Dome card does this when the |
| HW is jumpered for a grayscale monitor, but the default |
| visual is set to PseudoColor. In that case awtJNI_GetColorModel |
| will be called with aData->awtImage->clrdata.grayscale == 0, |
| but the IndexColorModel created below will detect that only |
| gray colors exist and expect the inverse gray LUT to exist. |
| So above when filling the hR, hG, and hB arrays we detect |
| whether all allocated colors are gray. If so, but |
| aData->awtImage->clrdata.grayscale == 0, we fall into this |
| code to set aData->awtImage->clrdata.grayscale = 1 and do |
| other things needed for the grayscale case. |
| */ |
| |
| int i; |
| int g; |
| ColorEntry *p; |
| |
| aData->awtImage->clrdata.grayscale = 1; |
| |
| aData->color_data->img_grays = |
| (unsigned char *)calloc(256, sizeof(unsigned char)); |
| |
| if (aData->color_data->img_grays == NULL) { |
| (*env)->PopLocalFrame(env, 0); |
| return NULL; |
| } |
| |
| for (g = 0; g < 256; g++) { |
| int mindist, besti; |
| int d; |
| |
| p = aData->color_data->awt_Colors; |
| mindist = 256; |
| besti = 0; |
| for (i = 0 ; i < paletteSize; i++, p++) { |
| if (p->flags == ALLOCATED_COLOR) { |
| d = p->g - g; |
| if (d < 0) d = -d; |
| if (d < mindist) { |
| besti = i; |
| if (d == 0) { |
| break; |
| } |
| mindist = d; |
| } |
| } |
| } |
| |
| aData->color_data->img_grays[g] = besti; |
| } |
| |
| for (i = 0; i < 256; i++) { |
| img_bwgamma[i] = i; /* REMIND: what is img_bwgamma? |
| * is it still used anywhere? |
| */ |
| } |
| } |
| |
| if (aData->awtImage->clrdata.grayscale) { |
| int i; |
| ColorEntry *p; |
| |
| /* For purposes of creating an IndexColorModel, use |
| transparent black for non-allocated or non-gray colors. |
| */ |
| p = aData->color_data->awt_Colors; |
| b = 0; |
| pValid = &valid[sizeof(valid)]; |
| for (i = 0; i < paletteSize; i++, p++) { |
| if ((p->flags != ALLOCATED_COLOR) || |
| (p->r != p->g || p->g != p->b)) |
| { |
| rgb[i] = 0; |
| b &= ~(1 << (i % 8)); |
| allvalid = 0; |
| } else { |
| b |= (1 << (i % 8)); |
| } |
| if ((i % 8) == 7) { |
| *--pValid = b; |
| /* b = 0; not needed as each bit is explicitly set */ |
| } |
| } |
| |
| if (aData->color_data->pGrayInverseLutData == NULL) { |
| /* Compute the inverse gray LUT for this aData->color_data |
| struct, if not already computed. |
| */ |
| initInverseGrayLut(rgb, aData->awt_num_colors, |
| aData->color_data); |
| } |
| } |
| |
| if (!allvalid) { |
| jobject bArray = (*env)->NewByteArray(env, sizeof(valid)); |
| if (bArray == NULL) |
| { |
| (*env)->PopLocalFrame(env, 0); |
| return NULL; |
| } |
| else |
| { |
| (*env)->SetByteArrayRegion(env, bArray, 0, sizeof(valid), |
| valid); |
| } |
| validBits = JNU_NewObjectByName(env, |
| "java/math/BigInteger", |
| "([B)V", bArray); |
| if (validBits == NULL) |
| { |
| (*env)->PopLocalFrame(env, 0); |
| return NULL; |
| } |
| } |
| |
| hArray = (*env)->NewIntArray(env, paletteSize); |
| if (hArray == NULL) |
| { |
| (*env)->PopLocalFrame(env, 0); |
| return NULL; |
| } |
| else |
| { |
| (*env)->SetIntArrayRegion(env, hArray, 0, paletteSize, rgb); |
| } |
| |
| if (aData->awt_visInfo.depth == 8) { |
| awt_colormodel = |
| JNU_NewObjectByName(env, |
| "java/awt/image/IndexColorModel", |
| "(II[IIILjava/math/BigInteger;)V", |
| 8, 256, hArray, 0, |
| java_awt_image_DataBuffer_TYPE_BYTE, |
| validBits); |
| } else { |
| awt_colormodel = |
| JNU_NewObjectByName(env, |
| "java/awt/image/IndexColorModel", |
| "(II[IIILjava/math/BigInteger;)V", |
| 12, 4096, hArray, 0, |
| java_awt_image_DataBuffer_TYPE_USHORT, |
| validBits); |
| } |
| |
| if (awt_colormodel == NULL) |
| { |
| (*env)->PopLocalFrame(env, 0); |
| return NULL; |
| } |
| |
| /* Set pData field of ColorModel to point to ColorData */ |
| JNU_SetLongFieldFromPtr(env, awt_colormodel, g_CMpDataID, |
| aData->color_data); |
| |
| } |
| |
| return (*env)->PopLocalFrame(env, awt_colormodel); |
| } |
| #endif /* !HEADLESS */ |
| |
| extern jfieldID colorValueID; |
| |
| #ifndef HEADLESS |
| int awtJNI_GetColor(JNIEnv *env,jobject this) |
| { |
| /* REMIND: should not be defaultConfig. */ |
| return awtJNI_GetColorForVis (env, this, getDefaultConfig(DefaultScreen(awt_display))); |
| } |
| |
| int awtJNI_GetColorForVis (JNIEnv *env,jobject this, AwtGraphicsConfigDataPtr awt_data) |
| { |
| int col; |
| jclass SYSCLR_class; |
| |
| if (!JNU_IsNull(env,this)) |
| { |
| SYSCLR_class = (*env)->FindClass(env, "java/awt/SystemColor"); |
| CHECK_NULL_RETURN(SYSCLR_class, 0); |
| |
| if ((*env)->IsInstanceOf(env, this, SYSCLR_class)) { |
| /* SECURITY: This is safe, because there is no way |
| * for client code to insert an object |
| * that is a subclass of SystemColor |
| */ |
| col = (int) JNU_CallMethodByName(env |
| ,NULL |
| ,this |
| ,"getRGB" |
| ,"()I").i; |
| JNU_CHECK_EXCEPTION_RETURN(env, 0); |
| } else { |
| col = (int)(*env)->GetIntField(env,this,colorValueID); |
| } |
| |
| if (awt_data->awt_cmap == (Colormap) NULL) { |
| awtJNI_CreateColorData (env, awt_data, 1); |
| } |
| |
| col = awt_data->AwtColorMatch(red(col), green(col), blue(col), |
| awt_data); |
| return col; |
| } |
| |
| return 0; |
| } |
| |
| void |
| awt_allocate_systemrgbcolors (jint *rgbColors, int num_colors, |
| AwtGraphicsConfigDataPtr awtData) { |
| int i, pixel; |
| for (i = 0; i < num_colors; i++) |
| pixel = alloc_col (awt_display, awtData->awt_cmap, red (rgbColors [i]), |
| green (rgbColors [i]), blue (rgbColors [i]), -1, |
| awtData); |
| } |
| |
| int |
| awtCreateX11Colormap(AwtGraphicsConfigDataPtr adata) { |
| int screen = adata->awt_visInfo.screen; |
| Colormap cmap = (Colormap)NULL; |
| |
| if (adata->awt_visInfo.visual == DefaultVisual(awt_display, screen)) { |
| cmap = DefaultColormap(awt_display, screen); |
| } else { |
| Window root = RootWindow(awt_display, screen); |
| |
| if (adata->awt_visInfo.visual->class % 2) { |
| Atom actual_type; |
| int actual_format; |
| unsigned long nitems, bytes_after; |
| XStandardColormap *scm; |
| |
| XGetWindowProperty (awt_display, root, XA_RGB_DEFAULT_MAP, |
| 0L, 1L, False, AnyPropertyType, &actual_type, |
| &actual_format, &nitems, &bytes_after, |
| (unsigned char **) &scm); |
| |
| XGetWindowProperty (awt_display, root, XA_RGB_DEFAULT_MAP, 0L, |
| bytes_after/4 + 1, False, AnyPropertyType, |
| &actual_type, &actual_format, &nitems, |
| &bytes_after, (unsigned char **) &scm); |
| |
| nitems /= (sizeof (XStandardColormap)/4); |
| for (; nitems > 0; ++scm, --nitems) |
| if (scm->visualid == adata->awt_visInfo.visualid) { |
| cmap = scm->colormap; |
| break; |
| } |
| } |
| if (!cmap) { |
| cmap = XCreateColormap (awt_display, root, |
| adata->awt_visInfo.visual, |
| AllocNone); |
| } |
| } |
| |
| adata->awt_cmap = cmap; |
| if (!awt_allocate_colors(adata)) { |
| XFreeColormap(awt_display, adata->awt_cmap); |
| adata->awt_cmap = (Colormap)NULL; |
| return 0; |
| } |
| return 1; |
| } |
| |
| void |
| awtJNI_CreateColorData(JNIEnv *env, AwtGraphicsConfigDataPtr adata, |
| int lock) { |
| |
| /* Create Colormap */ |
| if (lock) { |
| AWT_LOCK (); |
| } |
| |
| awtCreateX11Colormap(adata); |
| |
| /* If depth is 8, allocate system colors also... Here |
| * we just get the array of System Colors and allocate |
| * it which may be a bit wasteful (if only some were |
| * changed). But we don't know which ones were changed |
| * and alloc-ing a pixel that is already allocated won't |
| * hurt. */ |
| |
| if (adata->awt_depth == 8 || |
| (adata->awt_depth == 12 && adata->awt_visInfo.class == PseudoColor)) |
| { |
| jint colorVals [java_awt_SystemColor_NUM_COLORS]; |
| jclass sysColors; |
| jfieldID colorID; |
| jintArray colors; |
| |
| /* Unlock now to initialize the SystemColor class */ |
| if (lock) { |
| AWT_UNLOCK_CHECK_EXCEPTION(env); |
| } |
| sysColors = (*env)->FindClass (env, "java/awt/SystemColor"); |
| CHECK_NULL(sysColors); |
| |
| if (lock) { |
| AWT_LOCK (); |
| } |
| colorID = (*env)->GetStaticFieldID (env, sysColors, |
| "systemColors", |
| "[I"); |
| |
| if (colorID == NULL) { |
| if (lock) { |
| AWT_UNLOCK(); |
| } |
| return; |
| } |
| |
| colors = (jintArray) (*env)->GetStaticObjectField |
| (env, sysColors, colorID); |
| |
| (*env)->GetIntArrayRegion (env, colors, 0, |
| java_awt_SystemColor_NUM_COLORS, |
| (jint *) colorVals); |
| |
| awt_allocate_systemrgbcolors (colorVals, |
| (java_awt_SystemColor_NUM_COLORS - 1), adata); |
| |
| } |
| |
| if (lock) { |
| AWT_UNLOCK (); |
| } |
| } |
| |
| #endif /* !HEADLESS */ |