Beispiel #1
0
void wxAllocNearestColor(Display *d,Colormap cmp,XColor *xc)
{
#if !wxUSE_NANOX
    int llp;

    int screen = DefaultScreen(d);
    int num_colors = DisplayCells(d,screen);

    XColor *color_defs = new XColor[num_colors];
#if defined(__INTEL_COMPILER) && 1 /* VDM auto patch */
#   pragma ivdep
#   pragma swp
#   pragma unroll
#   pragma prefetch
#   if 0
#       pragma simd noassert
#   endif
#endif /* VDM auto patch */
    for(llp = 0;llp < num_colors;llp++) color_defs[llp].pixel = llp;
    XQueryColors(d,cmp,color_defs,num_colors);

    wxHSV hsv_defs, hsv;
    wxXColorToHSV(&hsv,xc);

    int diff, min_diff = 0, pixel = 0;

#if defined(__INTEL_COMPILER) && 1 /* VDM auto patch */
#   pragma ivdep
#   pragma swp
#   pragma unroll
#   pragma prefetch
#   if 0
#       pragma simd noassert
#   endif
#endif /* VDM auto patch */
    for(llp = 0;llp < num_colors;llp++)
    {
        wxXColorToHSV(&hsv_defs,&color_defs[llp]);
        diff = wxSIGN(wxH_WEIGHT * (hsv.h - hsv_defs.h)) +
            wxSIGN(wxS_WEIGHT * (hsv.s - hsv_defs.s)) +
            wxSIGN(wxV_WEIGHT * (hsv.v - hsv_defs.v));
        if (llp == 0) min_diff = diff;
        if (min_diff > diff) { min_diff = diff; pixel = llp; }
        if (min_diff == 0) break;
    }

    xc -> red = color_defs[pixel].red;
    xc -> green = color_defs[pixel].green;
    xc -> blue = color_defs[pixel].blue;
    xc -> flags = DoRed | DoGreen | DoBlue;

/*  FIXME, TODO
    if (!XAllocColor(d,cmp,xc))
        cout << "wxAllocNearestColor : Warning : Cannot find nearest color !\n";
*/

    delete[] color_defs;
#endif
}
Beispiel #2
0
static long search_near_color(Display *disp, int r, int g, int b)
{
    double d, mind;
    int scr;
    static XColor *xc = NULL;
    static int xc_size = 0;
    long i, k;

    scr = DefaultScreen(disp);

    if(depth == 1)		/* black or white */
    {
	d = (double)r * r
	  + (double)g * g
	  + (double)b * b;

	if(d > 3.0 * 32768.0 * 32768.0)
	    return (long)WhitePixel(disp, scr);
	return (long)BlackPixel(disp, scr);
    }

    if(xc_size == 0)
    {
	xc_size = DisplayCells(disp, scr);
	if(xc_size > 256)
	    return 0; /* Colormap size is too large */
	xc = (XColor *)safe_malloc(sizeof(XColor) * xc_size);
	for(i = 0; i < xc_size; i++)
	    xc[i].pixel = i;
    }
    XQueryColors(disp, DefaultColormap(disp, scr), xc, xc_size);

    mind = calc_color_diff(r, g, b, xc[0].red, xc[0].green, xc[0].blue);
    k = 0;
    for(i = 1; i < xc_size; i++)
    {
	d = calc_color_diff(r, g, b, xc[i].red, xc[i].green, xc[i].blue);
	if(d < mind)
	{
	    mind = d;
	    k = i;
	    if(mind == 0.0)
		break;
	}
    }

#ifdef DEBUG
    fprintf(stderr, "color [%04x %04x %04x]->[%04x %04x %04x] (d^2=%f, k=%d)\n",
	   r, g, b,
	   xc[k].red, xc[k].green, xc[k].blue,
	   mind, (int)k);
#endif

    return k;
}
Beispiel #3
0
static void InitGlobals(void)
{
   theScreen = DefaultScreen(theDisp);
   theCmap   = DefaultColormap(theDisp, theScreen);
   rootW     = RootWindow(theDisp, theScreen);
   theGC     = DefaultGC(theDisp, theScreen);
   theVisual = DefaultVisual(theDisp, theScreen);
   ncells    = DisplayCells(theDisp, theScreen);
   dispWIDE  = DisplayWidth(theDisp, theScreen);
   dispHIGH  = DisplayHeight(theDisp, theScreen);
   dispDEEP  = DisplayPlanes(theDisp, theScreen);
   white     = WhitePixel(theDisp,theScreen);
   black     = BlackPixel(theDisp,theScreen);
}
Beispiel #4
0
XBR_IMAGE *XbrGfxGIF(Display *display, unsigned char *data, int size, int html,
                     XColor *backcol, char **errmsg)
{
    register unsigned char  ch, ch1;
    register unsigned char *ptr, *ptr1;
    register int   i;
    unsigned char *raster,	/* The raster data stream, unblocked */
                  *image;	/* The image data */
    int BitOffset = 0,		/* Bit Offset of next code */
    Prefix[4096],               /* Prefix table used for decoding */
    Suffix[4096],               /* Suffix table used for decoding */
    OutCode[1025],              /* Hash table used by the decompressor */
    OutCount = 0,		/* Decompressor output 'stack count' */
    RWidth, RHeight,		/* screen dimensions */
    LeftOfs, TopOfs,		/* image offset */
    BitsPerPixel,		/* Bits per pixel, read from GIF header */
    ColorMapSize,		/* number of colors */
    Background,			/* background color */
    Transparent = 0,		/* Transparent background? */
    TransparentColour,		/* The colour that is transparent. */
    CodeSize,			/* Code size, read from GIF header */
    InitCodeSize,		/* Starting code size, used during Clear */
    Code,			/* Value returned by XbrGfxReadCode */
    MaxCode,			/* limiting value for current code size */
    ClearCode,			/* GIF clear code */
    EOFCode,			/* GIF end-of-information code */
    CurCode, OldCode, InCode,	/* Decompressor variables */
    FirstFree,			/* First free code, generated per GIF spec */
    FreeCode,			/* Decompressor, next free slot in hash table */
    FinChar,			/* Decompressor variable */
    BitMask,			/* AND mask for data size */
    ReadMask,			/* Code AND mask for current code size */
    DispCells,			/* Number of display cells */
    screen;                     /* Default screen of display */
    Colormap colormap;          /* The colour map the get colours from */
    XImage *theImage;		/* The image to build up */
    Visual *theVisual;          /* Screen visual type */
    XBR_IMAGE *retval;
    GC gc;

    DispCells = DisplayCells(display, DefaultScreen(display));
    colormap = DefaultColormap(display, DefaultScreen(display));
    theVisual = DefaultVisual(display, DefaultScreen(display));
    screen = DefaultScreen(display);

    XC = 0, YC = 0; Pass = 0; alloc = 0;

    /* Allocate memory for raster data */
    if((raster = (unsigned char *) malloc(size)) == NULL) {
        if(errmsg) *errmsg = "Out of memory!";
        return(NULL);
    }

    ptr = data;

    if(strncmp((char *)ptr, "GIF87a", 6) && strncmp((char *)ptr, "GIF89a", 6)) {
        if(errmsg) *errmsg = "Not a GIF image!";
        return(NULL);
    }
    ptr += 6;

    /* Get variables from the GIF screen descriptor */
    ch = NEXTBYTE;
    RWidth = ch + 0x100 * NEXTBYTE;
    ch = NEXTBYTE;
    RHeight = ch + 0x100 * NEXTBYTE;

    ch = NEXTBYTE;
    HasColormap = ((ch & COLORMAPMASK) ? True : False);

    BitsPerPixel = (ch & 7) + 1;
    numcols = ColorMapSize = 1 << BitsPerPixel;
    BitMask = ColorMapSize - 1;

    Background = NEXTBYTE;

    /* Supposed to be NULL */
    if(NEXTBYTE) {
        if(errmsg) *errmsg = "GIF image corrupt!";
        return(NULL);
    }

    /* Read in global colormap. */
    if(HasColormap) {
	for (i = 0; i < ColorMapSize; i++) {
	    Red[i] = NEXTBYTE;
	    Green[i] = NEXTBYTE;
	    Blue[i] = NEXTBYTE;
            used[i] = 0;
	}
        numused = 0;
    }
    else {
        if(!numcols) numcols=256;
        for (i=0; i<numcols; i++)
            cols[i] = (unsigned long) i;
    }

    /* Chomp extensions. */
    while((ch = NEXTBYTE) == GIF_EXTENSION) {
        if(NEXTBYTE == GIF_GFXBLOCK) {
	    ch = NEXTBYTE;	/* Block size */
	    Transparent = ((NEXTBYTE & GIF_TRANSMASK) ? True : False);
	    ptr += 2;
	    TransparentColour = NEXTBYTE;
	    ch = NEXTBYTE;
	} else {
	    ch = NEXTBYTE;
	    ptr += ch;
	    while((ch = NEXTBYTE) != GIF_BLOCKEND)
		ptr += ch;
	}
    }
    
    /* Check for image seperator */
    if (ch != IMAGESEP) {
        if(errmsg) *errmsg = "Corrupt GIF file: *no image separator*";
        return(NULL);
    }

    /* Now read in values from the image descriptor */
    ch = NEXTBYTE;
    LeftOfs = ch + 0x100 * NEXTBYTE;
    ch = NEXTBYTE;
    TopOfs = ch + 0x100 * NEXTBYTE;
    ch = NEXTBYTE;
    Width = ch + 0x100 * NEXTBYTE;
    ch = NEXTBYTE;
    Height = ch + 0x100 * NEXTBYTE;
    Interlace = ((NEXTBYTE & INTERLACEMASK) ? True : False);

/*
    xbrimage_resize(Width, Height);
    xbrimage_dimensions(Width, Height);
*/

    /* Note that I ignore the possible existence of a local color map.
     * I'm told there aren't many files around that use them, and the spec
     * says it's defined for future use.  This could lead to an error
     * reading some files. 
     */

    /* Start reading the raster data. First we get the intial code size
     * and compute decompressor constant values, based on this code size.
     */
    CodeSize = NEXTBYTE;
    ClearCode = (1 << CodeSize);
    EOFCode = ClearCode + 1;
    FreeCode = FirstFree = ClearCode + 2;

    /* The GIF spec has it that the code size is the code size used to
     * compute the above values is the code size given in the file, but the
     * code size used in compression/decompression is the code size given in
     * the file plus one. (thus the ++).
     */
    CodeSize++;
    InitCodeSize = CodeSize;
    MaxCode = (1 << CodeSize);
    ReadMask = MaxCode - 1;

    /* Read the raster data.  Here we just transpose it from the GIF array
     * to the raster array, turning it from a series of blocks into one long
     * data stream, which makes life much easier for XbrGfxReadCode().
     */
    ptr1 = raster;
    do {
	ch = ch1 = NEXTBYTE;
	while (ch--) *ptr1++ = NEXTBYTE;
	if ((raster - ptr1) > size) {
	    if(errmsg) *errmsg = "Corrupt GIF file\n*unblock*";
            return(NULL);
        }
    } while(ch1);


    /* Allocate the X image */
    image = (unsigned char *) malloc(Width*Height);
    if (image == NULL) {
        if(errmsg) *errmsg = "Not enough memory for Ximage!";
        return(NULL);
    }
    if(!html) {
        theImage = XCreateImage(display,theVisual,8,ZPixmap,0,(char *)image,
          Width, Height,8,Width);

        if(theImage == NULL) {
            if(errmsg) *errmsg = "Unable to create Ximage!";
             return(NULL);
       }
    }

    BytesPerScanline = Width;

    /* Decompress the file, continuing until you see the GIF EOF code.
       One obvious enhancement is to add checking for corrupt files here.
    */
    Code = XbrGfxReadCode(&BitOffset, raster, CodeSize, ReadMask);
    while (Code != EOFCode) {

        /* Clear code sets everything back to its initial value, then reads the
          immediately subsequent code as uncompressed data.
        */
	if (Code == ClearCode) {
	    CodeSize = InitCodeSize;
	    MaxCode = (1 << CodeSize);
	    ReadMask = MaxCode - 1;
	    FreeCode = FirstFree;
	    CurCode = OldCode = Code = XbrGfxReadCode(&BitOffset, raster,
              CodeSize, ReadMask);
	    FinChar = CurCode & BitMask;
	    XbrGfxAddtoPixel(FinChar, image);
	}
	else {

            /* If not a clear code, then must be data:save same as CurCode and
               InCode
            */
	    CurCode = InCode = Code;

            /* If greater or equal to FreeCode, not in the hash table yet;
               repeat the last character decoded
            */
	    if (CurCode >= FreeCode) {
		CurCode = OldCode;
		OutCode[OutCount++] = FinChar;
	    }

            /* Unless this code is raw data, pursue the chain pointed to by
              CurCode through the hash table to its end; each code in the chain
              puts its associated output code on the output queue.
            */
	    while (CurCode > BitMask) {
		if (OutCount > 1024) {
		    if(errmsg) *errmsg = "Corrupt GIF file!*OutCount*";
                    if(!html) XDestroyImage(theImage);
                    theImage = NULL;
                    return(NULL);
                    }
		OutCode[OutCount++] = Suffix[CurCode];
		CurCode = Prefix[CurCode];
	    }

            /* The last code in the chain is treated as raw data. */
	    FinChar = CurCode & BitMask;
	    OutCode[OutCount++] = FinChar;

            /* Now we put the data out to the Output routine.
               It's been stacked LIFO, so deal with it that way...
            */
            for (i = OutCount - 1; i >= 0; i--)
		XbrGfxAddtoPixel(OutCode[i], image);
	    OutCount = 0;

            /* Build the hash table on-the-fly. No table is stored in the
               file.
            */
	    Prefix[FreeCode] = OldCode;
	    Suffix[FreeCode] = FinChar;
	    OldCode = InCode;

            /* Point to the next slot in the table.  If we exceed the current
               MaxCode value, increment the code size unless it's already 12.
               If it is, do nothing: the next code decompressed better be CLEAR
            */
	    FreeCode++;
	    if (FreeCode >= MaxCode) {
		if (CodeSize < 12) {
		    CodeSize++;
		    MaxCode *= 2;
		    ReadMask = (1 << CodeSize) - 1;
		}
	    }
	}
	Code = XbrGfxReadCode(&BitOffset, raster, CodeSize, ReadMask);
    }

    free(raster);
/*
    xbrimage_colours(numused, ColorMapSize);
*/

    retval = XtNew(XBR_IMAGE);
    retval->size = size;
    retval->width = Width;
    retval->height = Height;
    retval->data = (char *)data;

    if(html) {
        retval->pixmap = (Pixmap)NULL;
        retval->num_colors = numcols;
        retval->reds = (int *) XtMalloc(sizeof(int)*numcols);
        retval->greens = (int *) XtMalloc(sizeof(int)*numcols);
        retval->blues = (int *) XtMalloc(sizeof(int)*numcols);
        for(i = 0; i < numcols; i++) {
            retval->reds[i] = Red[i] << 8;
            retval->greens[i] = Green[i] << 8;
            retval->blues[i] = Blue[i] << 8;
        }
	if(Transparent) {
	    retval->reds[TransparentColour] = backcol->red;
	    retval->greens[TransparentColour] = backcol->green;
	    retval->blues[TransparentColour] = backcol->blue;
	}
        retval->image_data = image;
        retval->npixels = 0;
    } else {
        retval->pixmap = XCreatePixmap(display, DefaultRootWindow(display),
          Width, Height, DefaultDepth(display, screen));
        retval->num_colors = numcols;
        retval->reds = NULL;
        retval->greens = NULL;
        retval->blues = NULL;
        retval->image_data = NULL;
        if(!XbrGfxGetColours(display, colormap,DispCells, image,backcol,Transparent,TransparentColour)) {
            if(errmsg) *errmsg = "Error allocating colours!";
            XDestroyImage(theImage);
            theImage = NULL;
            return(NULL);
        }

        for(i = 0; i < alloc; i++) {
            retval->pixels[i] = alloced[i];
        }
        retval->npixels = alloc-1;

        gc = XCreateGC(display, retval->pixmap,  0, NULL);
        XPutImage(display, retval->pixmap, gc, theImage, 0, 0, 0, 0, Width,
          Height);
        XFreeGC(display, gc);
        XDestroyImage(theImage);
    }

    theImage = NULL;

    return(retval);
}
Beispiel #5
0
XMenu *
XMenuCreate(Display *display, Window parent, register char const *def_env)
                                /* ID of previously opened display */
                  		/* Window ID of the menu's parent window. */
                           	/* X Defaults program environment name. */
{
  register char *def_val;	/* X Default value temp variable. */

  register XMenu *menu;		/* Pointer to the new menu. */
  XMStyle menu_style;		/* Menu display style. */
  XMMode menu_mode;		/* Menu display mode. */
  XMPane *pane;			/* Pane list header. */
  XAssocTable *assoc_tab;	/* XAssocTable pointer. */

  int freeze;			/* Freeze server mode. */
  int reverse;			/* Reverse video mode. */

  XMStyle p_style;		/* Pane display style. */
  char const *p_fnt_name;	/* Flag font name. */
  XFontStruct *p_fnt_info;	/* Flag font structure */
  int p_fnt_pad;		/* Flag font padding in pixels. */
  double p_spread;		/* Pane spread in flag height fractions. */
  int p_fnt_height;		/* Pane character height. */
  int p_bdr_width;		/* Pane border width. */
  int flag_height;		/* Flag window height. */
  int p_height;			/* Pane window height. */
  int p_x_off;			/* Pane X offset. */
  int p_y_off;			/* Pane Y offset. */
  GC pane_GC;			/* Pane graphics context. */

  XMStyle s_style;		/* Selection display style. */
  char const *s_fnt_name;	/* Selection font name. */
  XFontStruct *s_fnt_info;	/* Selection font structure. */
  int s_fnt_pad;		/* Selection font padding in pixels. */
  int s_fnt_height;		/* Selection font character height */
  double s_spread;		/* Select spread in line height fractions. */
  int s_bdr_width;		/* Highlight border width. */
  int s_height;			/* Selection window height. */
  int s_x_off;			/* Selection window X offset. */
  int s_y_off;			/* Selection window Y offset. */
  GC normal_select_GC;		/* GC used for normal video selection. */
  GC inverse_select_GC;		/* GC used for inverse video selection. */
  GC inact_GC;			/* GC for inactive pane header and */
  /* selections. */

  XColor color_def;		/* Temp color definition holder. */
  XColor p_bdr_color;		/* Color of border. */
  XColor s_bdr_color;		/* Color of highlight. */
  XColor p_frg_color;		/* Color of pane foreground color. */
  XColor s_frg_color;		/* Color of selection foreground. */
  XColor bkgnd_color;		/* Color of background.. */
  XColor mouse_color;		/* Color of mouse cursor. */
  Cursor mouse_cursor;		/* Mouse cursor. */
  Pixmap inact_bitmap;		/* Menu inactive pixmap. */

  int inact_pnum;		/* Inactive background pattern number. */

  Pixmap cursor;		/* Cursor pixmap holder. */
  Pixmap cursor_mask;		/* Cursor mask pixmap holder. */
  Pixmap stipple_pixmap;	/* Stipple mask for half-tone text. */
  unsigned long valuemask;
  XGCValues *values;

  Window root = RootWindow (display, DefaultScreen (display));

  /*
   * Calloc the XMenu structure and the initial pane.
   */
  menu = (XMenu *)calloc(1, sizeof(XMenu));
  if (menu == NULL) {
    _XMErrorCode = XME_CALLOC;
    return(NULL);
  }
  pane = (XMPane *)calloc(1, sizeof(XMPane));
  if (pane == NULL) {
    _XMErrorCode = XME_CALLOC;
    return(NULL);
  }

  /*
   * Create the XAssocTable
   */
  assoc_tab = (XAssocTable *)XCreateAssocTable(XASSOC_TABLE_SIZE);
  if(assoc_tab == NULL) {
    _XMErrorCode= XME_CREATE_ASSOC;
    return(NULL);
  }

  /*
   * Set up the default environment name.
   */
  if (def_env == NULL || *def_env == '\0') def_env = "XMenu";

  /*
   * Set up internal fail-safe defaults.
   */
  freeze = DEF_FREEZE;
  reverse = DEF_REVERSE;
  menu_style = DEF_MENU_STYLE;
  menu_mode = DEF_MENU_MODE;
  inact_pnum = DEF_INACT_PNUM;

  p_style = DEF_P_STYLE;
  p_spread = DEF_P_SPREAD;
  p_fnt_name = DEF_P_FNT_NAME;
  p_bdr_width = DEF_P_BDR_WIDTH;

  s_style = DEF_S_STYLE;
  s_spread = DEF_S_SPREAD;
  s_fnt_name = DEF_S_FNT_NAME;
  s_bdr_width = DEF_S_BDR_WIDTH;

  /*
   * Get default values from X.
   */
  def_val = x_get_resource_string ("menuFreeze", "MenuFreeze");
  if (def_val != NULL) {
    if (strcmp(def_val, "on") == 0) freeze = 1;
    else if (strcmp(def_val, "off") == 0) freeze = 0;
  }

  def_val = x_get_resource_string ("menuReverseVideo", "MenuReverseVideo");
  if (def_val != NULL) {
    if (strcmp(def_val, "on") == 0) reverse = 1;
    else if (strcmp(def_val, "off") == 0) reverse = 0;
  }

  def_val = x_get_resource_string ("menuStyle", "MenuStyle");
  if (def_val != NULL) {
    if (strcmp(def_val, "right_hand") == 0) menu_style = RIGHT;
    else if (strcmp(def_val, "left_hand") == 0) menu_style = LEFT;
    else if (strcmp(def_val, "center") == 0) menu_style = CENTER;
  }

  def_val = x_get_resource_string ("menuMode", "MenuMode");
  if (def_val != NULL) {
    if (strcmp(def_val, "box") == 0) menu_mode = BOX;
    else if (strcmp(def_val, "invert") == 0) menu_mode = INVERT;
  }

  def_val = x_get_resource_string ("menuMouse", "MenuMouse");
  if (
      def_val != NULL &&
      DisplayCells(display, DefaultScreen(display)) > 2 &&
      XAllocDisplayColor(display,
			 DefaultColormap(display, DefaultScreen(display)),
			 def_val,
			 &mouse_color, &color_def)
      );
  else if (reverse &&
	   XAllocDisplayColor(display,
			      DefaultColormap(display, DefaultScreen(display)),
			      "white",
			      &mouse_color, &color_def)
	   );

  else if (XAllocDisplayColor(display,
			      DefaultColormap(display, DefaultScreen(display)),
			      "black",
			      &mouse_color, &color_def)
	   );

  else {}

  def_val = x_get_resource_string ("menuBackground", "MenuBackground");
  if (
      def_val != NULL &&
      DisplayCells(display, DefaultScreen(display)) > 2 &&
      XAllocDisplayColor(display,
			 DefaultColormap(display, DefaultScreen(display)),
			 def_val,
			 &bkgnd_color, &color_def)
      );
  else if (reverse &&
	   XAllocDisplayColor(display,
			      DefaultColormap(display, DefaultScreen(display)),
			      "black",
			      &bkgnd_color, &color_def)
	   );
  else if (XAllocDisplayColor(display,
			      DefaultColormap(display, DefaultScreen(display)),
			      "white",
			      &bkgnd_color, &color_def)
	   );
  else {}

  def_val = x_get_resource_string ("menuInactivePattern", "MenuInactivePattern");
  if (def_val != NULL) {
    if (strcmp(def_val, "dimple1") == 0) inact_pnum = 0;
    else if (strcmp(def_val, "dimple3") == 0) inact_pnum = 1;
    else if (strcmp(def_val, "gray1") == 0) inact_pnum = 2;
    else if (strcmp(def_val, "gray3") == 0) inact_pnum = 3;
    else if (strcmp(def_val, "cross_weave") == 0) inact_pnum = 4;
  }

  def_val = x_get_resource_string ("paneStyle", "PaneStyle");
  if (def_val != NULL) {
    if (strcmp(def_val, "flush_left") == 0) p_style = LEFT;
    else if (strcmp(def_val, "flush_right") == 0) p_style = RIGHT;
    else if (strcmp(def_val, "center") == 0) p_style = CENTER;
  }

  def_val = x_get_resource_string ("paneFont", "PaneFont");
  if (def_val != NULL) p_fnt_name = def_val;

  def_val = x_get_resource_string ("paneForeground", "PaneForeground");
  if (
      def_val != NULL &&
      DisplayCells(display, DefaultScreen(display)) > 2
      )
    XAllocDisplayColor(display, DefaultColormap(display,
						DefaultScreen(display)),
		       def_val,
		       &p_frg_color, &color_def);

  else if (reverse) XAllocDisplayColor(display,
				       DefaultColormap(display,
						       DefaultScreen(display)),
				       "white",
				       &p_frg_color, &color_def);
  else XAllocDisplayColor(display,
			  DefaultColormap(display, DefaultScreen(display)),
			  "black",
			  &p_frg_color, &color_def);

  def_val = x_get_resource_string ("paneBorder", "PaneBorder");
  if (
      def_val != NULL &&
      DisplayCells(display, DefaultScreen(display)) > 2 &&
      XAllocDisplayColor(display,
			 DefaultColormap(display, DefaultScreen(display)),
			 def_val,
			 &p_bdr_color, &color_def)
      );
  else if (reverse &&
	   XAllocDisplayColor(display,
			      DefaultColormap(display, DefaultScreen(display)),
			      "white",
			      &p_bdr_color, &color_def)
	   );
  else XAllocDisplayColor(display,
			  DefaultColormap(display, DefaultScreen(display)),
			  "black",
			  &p_bdr_color, &color_def);

  def_val = x_get_resource_string ("paneBorderWidth", "PaneBorderWidth");
  if (def_val != NULL) p_bdr_width = atoi(def_val);

  def_val = x_get_resource_string ("paneSpread", "PaneSpread");
  if (def_val != NULL) p_spread = atof(def_val);

  def_val = x_get_resource_string ("selectionStyle", "SelectionStyle");
  if (def_val != NULL) {
    if (strcmp(def_val, "flush_left") == 0) s_style = LEFT;
    else if (strcmp(def_val, "flush_right") == 0) s_style = RIGHT;
    else if (strcmp(def_val, "center") == 0) s_style = CENTER;
  }

  def_val = x_get_resource_string ("selectionFont", "SelectionFont");
  if (def_val != NULL) s_fnt_name = def_val;

  def_val = x_get_resource_string ("selectionForeground", "SelectionForeground");
  if (
      def_val != NULL &&
      DisplayCells(display, DefaultScreen(display)) > 2 &&
      XAllocDisplayColor(display,
			 DefaultColormap(display, DefaultScreen(display)),
			 def_val,
			 &s_frg_color, &color_def)
      );
  else if (reverse &&
	   XAllocDisplayColor(display,
			      DefaultColormap(display, DefaultScreen(display)),
			      "white",
			      &s_frg_color, &color_def)
	   ) ;
  else if (XAllocDisplayColor(display,
			      DefaultColormap(display, DefaultScreen(display)),
			      "black",
			      &s_frg_color, &color_def)
	   ) ;
  else {}


  def_val = x_get_resource_string ("selectionBorder", "SelectionBorder");
  if (
      def_val != NULL &&
      DisplayCells(display, DefaultScreen(display)) > 2 &&
      XAllocDisplayColor(display,
			 DefaultColormap(display, DefaultScreen(display)),
			 def_val,
			 &s_bdr_color, &color_def)
      ) ;
  else if (reverse &&
	   XAllocDisplayColor(display,
			      DefaultColormap(display, DefaultScreen(display)),
			      "white",
			      &s_bdr_color, &color_def)
	   ) ;
  else if (XAllocDisplayColor(display,
			      DefaultColormap(display, DefaultScreen(display)),
			      "black",
			      &s_bdr_color, &color_def)
	   ) ;
  else {}

  def_val = x_get_resource_string ("selectionBorderWidth", "SelectionBorderWidth");
  if (def_val != NULL) s_bdr_width = atoi(def_val);

  def_val = x_get_resource_string ("selectionSpread", "SelectionSpread");
  if (def_val != NULL) s_spread = atof(def_val);

  /*
   * Create and store the inactive pattern pixmap.
   */
  {
    char *data = NULL;
    int width, height;

    switch (inact_pnum)
      {
      case 0:
	data = (char *)dimple1_bits;
	width = dimple1_width;
	height = dimple1_height;
	break;

      case 1:
	data = (char *)dimple3_bits;
	width = dimple3_width;
	height = dimple3_height;
	break;

      case 2:
	data = (char *)gray1_bits;
	width = gray1_width;
	height = gray1_height;
	break;

      case 3:
	data = (char *)gray3_bits;
	width = gray3_width;
	height = gray3_height;
	break;

      case 4:
	data = (char *)cross_weave_bits;
	width = cross_weave_width;
	height = cross_weave_height;
	break;
      }

    if (! data)
      {
	_XMErrorCode = XME_STORE_BITMAP;
	return(NULL);
      }

    inact_bitmap =
      XCreatePixmapFromBitmapData
	(display, root, data, width, height,
	 p_frg_color.pixel, bkgnd_color.pixel,
	 DisplayPlanes (display, DefaultScreen (display)));
  }

  /*
   * Load the mouse cursor.
   */

  switch (menu_style) {
  case LEFT:
    cursor = XCreateBitmapFromData(display,
				   root,
				   left_ptr_bits,
				   left_ptr_width,
				   left_ptr_height);
    cursor_mask = XCreateBitmapFromData(display,
					root,
					left_ptrmsk_bits,
					left_ptrmsk_width,
					left_ptrmsk_height);
    mouse_cursor = XCreatePixmapCursor(
				       display,
				       cursor, cursor_mask,
				       &mouse_color, &bkgnd_color,
				       left_ptr_x_hot,
				       left_ptr_y_hot
				       );
    XFreePixmap(display, cursor);
    XFreePixmap(display, cursor_mask);
    break;
  case RIGHT:
    cursor = XCreateBitmapFromData(display,
				   root,
				   right_ptr_bits,
				   right_ptr_width,
				   right_ptr_height);
    cursor_mask = XCreateBitmapFromData(display,
					root,
					right_ptrmsk_bits,
					right_ptrmsk_width,
					right_ptrmsk_height);
    mouse_cursor = XCreatePixmapCursor(
				       display,
				       cursor, cursor_mask,
				       &mouse_color, &bkgnd_color,
				       right_ptr_x_hot,
				       right_ptr_y_hot
				       );
    XFreePixmap(display, cursor);
    XFreePixmap(display, cursor_mask);
    break;
  case CENTER:
    cursor = XCreateBitmapFromData(display,
				   root,
				   cntr_ptr_bits,
				   cntr_ptr_width,
				   cntr_ptr_height);
    cursor_mask = XCreateBitmapFromData(display,
					root,
					cntr_ptrmsk_bits,
					cntr_ptrmsk_width,
					cntr_ptrmsk_height);
    mouse_cursor = XCreatePixmapCursor(
				       display,
				       cursor, cursor_mask,
				       &mouse_color, &bkgnd_color,
				       cntr_ptr_x_hot,
				       cntr_ptr_y_hot
				       );
    XFreePixmap(display, cursor);
    XFreePixmap(display, cursor_mask);
    break;
  default:
    /* Error! Invalid style parameter. */
    _XMErrorCode = XME_STYLE_PARAM;
    return(NULL);
  }
  if (mouse_cursor == _X_FAILURE) {
    _XMErrorCode = XME_CREATE_CURSOR;
    return(NULL);
  }

  /*
   * Open the pane and selection fonts.
   */

  p_fnt_info = XLoadQueryFont(display, p_fnt_name);
  if (p_fnt_info == NULL) {
    _XMErrorCode = XME_OPEN_FONT;
    return(NULL);

  }

  s_fnt_info = XLoadQueryFont(display, s_fnt_name);
  if (s_fnt_info == NULL) {
    _XMErrorCode = XME_OPEN_FONT;
    return(NULL);
  }
  /*
   * Calculate the fixed padding value in pixels for each font.
   */
  p_fnt_height = p_fnt_info->max_bounds.ascent + p_fnt_info->max_bounds.descent;
  s_fnt_height = s_fnt_info->max_bounds.ascent + s_fnt_info->max_bounds.descent;
  p_fnt_pad = s_spread * p_fnt_height;
  s_fnt_pad = s_spread * s_fnt_height;

  /*
   * Calculate fixed height and offset requirements.
   */
  flag_height = p_fnt_height + (p_fnt_pad << 1);

  p_height = 0;
  p_y_off = flag_height + p_bdr_width;
  p_x_off = p_y_off * p_spread;

  s_height = s_fnt_height + (s_fnt_pad << 1) + (s_bdr_width << 1);
  s_y_off = s_height;
  s_x_off = p_x_off;

  /*
   * Set up the pane list header.
   */
  pane->next = pane;
  pane->prev = pane;
  pane->type = PL_HEADER;
  pane->serial = -1;

  /*
   * Initialize the internal pane and selection creation queues.
   */
  _XMWinQueInit();

  /*
   * Create pane, active, and inactive GC's.
   */
  values = (XGCValues *)malloc(sizeof(XGCValues));
  valuemask = (GCForeground | GCBackground | GCFont | GCLineWidth);

  /*
   * First, pane.
   */

  values->foreground = p_frg_color.pixel;
  values->background = bkgnd_color.pixel;
  values->font = p_fnt_info->fid;
  values->line_width = p_bdr_width;

  pane_GC = XCreateGC(
		      display,
		      root,
		      valuemask,
		      values);
  /*
   * Then normal video selection.
   */

  values->foreground = s_frg_color.pixel;
  values->background = bkgnd_color.pixel;
  values->font = s_fnt_info->fid;
  values->line_width = s_bdr_width;
  normal_select_GC = XCreateGC(display,
			       root,
			       valuemask,
			       values);
  /*
   * Inverse video selection.
   */

  values->foreground = bkgnd_color.pixel;
  values->background = s_frg_color.pixel;
  values->font = s_fnt_info->fid;
  values->line_width = s_bdr_width;
  inverse_select_GC = XCreateGC(display,
				root,
				valuemask,
				values);
  stipple_pixmap = XCreateBitmapFromData(display,
					 root,
					 stipple_bits,
					 stipple_width,
					 stipple_height);

  /*
   * Finally, inactive pane header and selections
   */
  valuemask |= (GCFillStyle | GCStipple);
  values->foreground = s_frg_color.pixel;
  values->background = bkgnd_color.pixel;
  values->font = s_fnt_info->fid;
  values->line_width = s_bdr_width;
  values->fill_style = FillStippled;
  values->stipple = stipple_pixmap;

  inact_GC = XCreateGC(display,
		       root,
		       valuemask,
		       values);

  valuemask |= (GCGraphicsExposures);
  values->graphics_exposures = False;


  /*
   * Construct the XMenu object.
   */
  /* -------------------- Menu data -------------------- */
  menu->menu_style = menu_style;
  menu->menu_mode = menu_mode;
  menu->freeze = freeze;
  menu->aeq = 0;
  menu->recompute = 1;
  menu->parent = parent;
  menu->height = 0;
  menu->width = 0;
  menu->mouse_cursor = mouse_cursor;
  menu->assoc_tab = assoc_tab;
  menu->p_list = pane;
  /* -------------------- Pane window data -------------------- */
  menu->p_style = p_style;
  menu->p_events = DEF_P_EVENTS;
  menu->p_fnt_info = p_fnt_info;
  menu->p_fnt_pad = p_fnt_pad;
  menu->p_spread = p_spread;
  menu->p_bdr_width = p_bdr_width;
  menu->flag_height = flag_height;
  menu->p_width = 0;
  menu->p_height = p_height;
  menu->p_x_off = p_x_off;
  menu->p_y_off = p_y_off;
  menu->p_count = 0;
  menu->pane_GC = pane_GC;
  menu->x_pos = 0;
  menu->y_pos = 0;
  /* -------------------- Selection window data -------------------- */
  menu->s_style = s_style;
  menu->s_events = DEF_S_EVENTS;
  menu->s_fnt_info = s_fnt_info;
  menu->s_fnt_pad = s_fnt_pad;
  menu->s_spread = s_spread;
  menu->s_bdr_width = s_bdr_width; /* unnecessary */
  menu->s_width = 0;
  menu->s_height = s_height;
  menu->s_x_off = s_x_off;
  menu->s_y_off = s_y_off;
  menu->s_count = 0;
  menu->normal_select_GC = normal_select_GC;
  menu->inverse_select_GC = inverse_select_GC;
  menu->inact_GC = inact_GC;
  /* -------------------- Color data -------------------- */
  menu->p_bdr_color = p_bdr_color.pixel;
  menu->s_bdr_color = s_bdr_color.pixel;
  menu->p_frg_color = p_frg_color.pixel;
  menu->s_frg_color = s_frg_color.pixel;
  menu->bkgnd_color = bkgnd_color.pixel;
  /* -------------------- Pixmap data -------------------- */
  menu->p_bdr_pixmap = None;
  menu->s_bdr_pixmap = None;
  menu->p_frg_pixmap = None;
  menu->s_frg_pixmap = None;
  menu->bkgnd_pixmap = None;
  menu->inact_pixmap = inact_bitmap;

  /*
   * Return the completed XMenu.
   */
  _XMErrorCode = XME_NO_ERROR;
  return(menu);
}
Beispiel #6
0
enum _DtGrLoadStatus InitGifObject (
    GifObj               *go, 
    Display              *dpy, 
    Drawable             drawable,
    Screen               *screen,
    int                  depth,
    Colormap             colormap,
    Visual               *visual,
    GC                   gc,
    enum _DtGrColorModel colorModel, 
    Boolean              allowReducedColors)
{
    int r, g, b, i, visualsMatched;
    XVisualInfo vTemplate, *visualList;

    /* 
    ** Initialize structure values
    */
    go->bits_per_pixel = 2;
    go->colors_per_pixel = (int) pow (2, go->bits_per_pixel);
    go->total_colors = (int) pow (go->colors_per_pixel, 3);
    go->f_color_map_constructed = 0;
    go->f_total_greys = 2;
    go->f_ximage    = NULL;
    go->f_dpy       = dpy;
    go->f_drawable  = drawable;
    go->f_screen    = XScreenNumberOfScreen(screen);
    go->f_dft_depth = depth;
    go->f_cmap      = colormap;
    go->f_gc        = gc;
    go->f_visual    = visual;
    go->f_ncells    = DisplayCells(go->f_dpy, go->f_screen);
    go->f_nplanes   = DisplayPlanes(go->f_dpy,go->f_screen);
    go->f_white     = WhitePixel(go->f_dpy, go->f_screen); 
    go->f_black     = BlackPixel(go->f_dpy, go->f_screen);
    go->f_allow_reduced_colors = allowReducedColors;
    go->f_color_reduction_used = FALSE;

    /*
    ** Initialize color allocation fields according to the color model
    ** specified by the caller.
    */
    switch (colorModel)
    {
        case _DtGrCOLOR:
             go->f_do_visual = DO_COLOR;
             go->f_init_total_greys = 32;
             break;
        case _DtGrGRAY_SCALE:
             go->f_do_visual = DO_GREY;
             go->f_init_total_greys = 32;
             break;
        case _DtGrBITONAL:
             go->f_do_visual = DO_GREY;
             go->f_init_total_greys = 2;
             break;
        default:
	    /* Should never get here */
             go->f_do_visual = DO_COLOR;
             go->f_init_total_greys = 32;
    }

    /* Return if the colormap is already allocated */
    if ( go->f_color_map_constructed )
        return (_DtGrSUCCESS);

    /* find the visual class code */

    vTemplate.screen = go->f_screen;
    vTemplate.depth = go->f_dft_depth;

    visualList = XGetVisualInfo( go->f_dpy, 
                                 VisualScreenMask | VisualDepthMask,
                                 &vTemplate, &visualsMatched );

    /* Return failure if we can't find a matching visual */
    if ( visualsMatched == 0 ) 
        return (_DtGrCONVERT_FAILURE);

    go->f_visual_class = StaticGray;

    for ( i=0; i<visualsMatched; i++ ) 
    {
        if ( visualList[i].visual == go->f_visual ) 
        {
            go->f_visual_class = visualList[i].class;
            break;
        }
    }
Beispiel #7
0
int
main(int argc, char *argv[])
{
    Visual visual;
    XSetWindowAttributes xswa;
    int i;
    char *displayname = NULL;
    Display *dpy;
    Colormap cmap;
    enum e_action action = doDefault;
    unsigned long mask;
    int screen;
    int x, y, width, height;
    char *geom = NULL;
    int geom_result;
    int display_width, display_height;
    char *solidcolor = NULL;
    XColor cdef;

    ProgramName = argv[0];

    for (i = 1; i < argc; i++) {
        char *arg = argv[i];

        if (arg[0] == '-') {
            if (isabbreviation ("-display", arg, 2)) {
                if (++i >= argc) Syntax ();
                displayname = argv[i];
                continue;
            } else if (isabbreviation ("-geometry", arg, 2)) {
                if (++i >= argc) Syntax ();
                geom = argv[i];
                continue;
            } else if (isabbreviation ("-black", arg, 2)) {
                action = doBlack;
                continue;
            } else if (isabbreviation ("-white", arg, 2)) {
                action = doWhite;
                continue;
            } else if (isabbreviation ("-solid", arg, 2)) {
                if (++i >= argc) Syntax ();
                solidcolor = argv[i];
                action = doSolid;
                continue;
            } else if (isabbreviation ("-none", arg, 2)) {
                action = doNone;
                continue;
            } else if (isabbreviation ("-root", arg, 2)) {
                action = doRoot;
                continue;
            } else
                Syntax ();
        } else if (arg[0] == '=')			/* obsolete */
            geom = arg;
        else
            Syntax ();
    }

    if ((dpy = XOpenDisplay(displayname)) == NULL) {
        fprintf (stderr, "%s:  unable to open display '%s'\n",
                 ProgramName, XDisplayName (displayname));
        exit (1);
    }

    if (action == doDefault) {
        char *def;

        if ((def = XGetDefault (dpy, ProgramName, "Solid")) != NULL) {
            solidcolor = strdup (def);
            if (solidcolor == NULL) {
                fprintf (stderr,
                         "%s:  unable to allocate memory for string.\n",
                         ProgramName);
                exit (1);
            }
            action = doSolid;
        } else {
            struct s_pair *pp;

            for (pp = pair_table; pp->resource_name != NULL; pp++) {
                def = XGetDefault (dpy, ProgramName, pp->resource_name);
                if (def && parse_boolean_option (def) == 1) {
                    action = pp->action;
                }
            }
        }
    }

    if (geom == NULL) geom = XGetDefault (dpy, ProgramName, "Geometry");

    screen = DefaultScreen (dpy);
    display_width = DisplayWidth (dpy, screen);
    display_height = DisplayHeight (dpy, screen);
    x = y = 0;
    width = display_width;
    height = display_height;

    if (DisplayCells (dpy, screen) <= 2 && action == doSolid) {
        if (strcmp (solidcolor, "black") == 0)
            action = doBlack;
        else if (strcmp (solidcolor, "white") == 0)
            action = doWhite;
        else {
            fprintf (stderr,
                     "%s:  can't use colors on a monochrome display.\n",
                     ProgramName);
            action = doNone;
        }
    }

    if (geom)
        geom_result = XParseGeometry (geom, &x, &y,
                                      (unsigned int *)&width,
                                      (unsigned int *)&height);
    else
        geom_result = NoValue;

    /*
     * For parsing geometry, we want to have the following
     *
     *     =                (0,0) for (display_width,display_height)
     *     =WxH+X+Y         (X,Y) for (W,H)
     *     =WxH-X-Y         (display_width-W-X,display_height-H-Y) for (W,H)
     *     =+X+Y            (X,Y) for (display_width-X,display_height-Y)
     *     =WxH             (0,0) for (W,H)
     *     =-X-Y            (0,0) for (display_width-X,display_height-Y)
     *
     * If we let any missing values be taken from (0,0) for
     * (display_width,display_height) we just have to deal with the
     * negative offsets.
     */

    if (geom_result & XNegative) {
        if (geom_result & WidthValue) {
            x = display_width - width + x;
        } else {
            width = display_width + x;
            x = 0;
        }
    }
    if (geom_result & YNegative) {
        if (geom_result & HeightValue) {
            y = display_height - height + y;
        } else {
            height = display_height + y;
            y = 0;
        }
    }

    mask = 0;
    switch (action) {
    case doBlack:
        xswa.background_pixel = BlackPixel (dpy, screen);
        mask |= CWBackPixel;
        break;
    case doWhite:
        xswa.background_pixel = WhitePixel (dpy, screen);
        mask |= CWBackPixel;
        break;
    case doSolid:
        cmap = DefaultColormap (dpy, screen);
        if (XParseColor (dpy, cmap, solidcolor, &cdef) &&
                XAllocColor (dpy, cmap, &cdef)) {
            xswa.background_pixel = cdef.pixel;
            mask |= CWBackPixel;
        } else {
            fprintf (stderr,"%s:  unable to allocate color '%s'.\n",
                     ProgramName, solidcolor);
            action = doNone;
        }
        break;
    case doDefault:
    case doNone:
        xswa.background_pixmap = None;
        mask |= CWBackPixmap;
        break;
    case doRoot:
        xswa.background_pixmap = ParentRelative;
        mask |= CWBackPixmap;
        break;
    }
    xswa.override_redirect = True;
    xswa.backing_store = NotUseful;
    xswa.save_under = False;
    mask |= (CWOverrideRedirect | CWBackingStore | CWSaveUnder);
    visual.visualid = CopyFromParent;
    win = XCreateWindow(dpy, DefaultRootWindow(dpy), x, y, width, height,
                        0, DefaultDepth(dpy, screen), InputOutput, &visual, mask, &xswa);

    /*
     * at some point, we really ought to go walk the tree and turn off
     * backing store;  or do a ClearArea generating exposures on all windows
     */
    XMapWindow (dpy, win);
    /* the following will free the color that we might have allocateded */
    XCloseDisplay (dpy);
    exit (0);
}
Beispiel #8
0
static int InitXColors() {
    int i, j;
    long d = 0x7FFFFFFF, d1;
    XColor clr;
    unsigned long pix;
    int num;
    long d_red, d_green, d_blue;
    long u_red, u_green, u_blue;

    for (i = 0; i < 16; i++) {
        SetColor(i);
        if (XAllocColor(display, colormap, &Colors[i]) == 0) {
            SetColor(i);
            pix = 0xFFFFFFFF;
            num = DisplayCells(display, DefaultScreen(display));
            for (j = 0; j < num; j++) {
                clr.pixel = j;
                XQueryColor(display, colormap, &clr);

                d_red = (clr.red - Colors[i].red) >> 3;
                d_green = (clr.green - Colors[i].green) >> 3;
                d_blue = (clr.blue - Colors[i].blue) >> 3;

                //fprintf(stderr, "%d:%d dr:%d, dg:%d, db:%d\n", i, j, d_red, d_green, d_blue);

                u_red = d_red / 100 * d_red * 3;
                u_green = d_green / 100 * d_green * 4;
                u_blue = d_blue / 100 * d_blue * 2;

                //fprintf(stderr, "%d:%d dr:%u, dg:%u, db:%u\n", i, j, u_red, u_green, u_blue);

                d1 = u_red + u_blue + u_green;

                if (d1 < 0)
                    d1 = -d1;
                if (pix == ~0UL || d1 < d) {
                    pix = j;
                    d = d1;
                }
            }
            if (pix == 0xFFFFFFFF) {
                fprintf(stderr, "Color search failed for #%04X%04X%04X\n",
                        Colors[i].red,
                        Colors[i].green,
                        Colors[i].blue);
            }
            clr.pixel = pix;
            XQueryColor(display, colormap, &clr);
            Colors[i] = clr;
            if (XAllocColor(display, colormap, &Colors[i]) == 0) {
                fprintf(stderr, "Color alloc failed for #%04X%04X%04X\n",
                        Colors[i].red,
                        Colors[i].green,
                        Colors[i].blue);
            }
            /*colormap = XCreateColormap(display, win, DefaultVisual(display, screen), AllocNone);
             for (i = 0; i < 16; i++) {
             SetColor(i);
             XAllocColor(display, colormap, &Colors[i]);
             }
             XSetWindowColormap(display, win, colormap);
             return 0;*/
        }
    }
Beispiel #9
0
int XDisplayCells(Display *dpy, int scr)
{
    return (DisplayCells (dpy, scr));
}
Beispiel #10
0
/******************************************************************************
* Routine to allocate the requested colors from the X server.		      *
* Two stages are performed:						      *
* 1. Colors are requested directly.					      *
* 2. If not enough colors can be allocated, the closest current color	      *
*    in current table is selected instead.				      *
* This allocation is not optimal as when fail to allocate all colors one      *
* should pick the right colors to do allocate in order to minimize the        *
* closest distance from the unallocated ones under some norm (what is a good  *
* norm for the RGB space?). Improve it if you are bored.		      *
******************************************************************************/
static void AllocateColors2(void)
{
    int i, j, Index = 0, Count = 0, XNumOfColors;
    char Msg[80];
    unsigned long D, Distance, AvgDistance = 0, Red, Green, Blue;
    GifBooleanType Failed = FALSE;
    XColor *XOldColorTable;

    for (i = 0; i < 256; i++) {
	if (i < ColorMapSize) {          /* Prepere color entry in X format. */
	    XColorTable[i].red = ColorMap[i].Red << 8;
	    XColorTable[i].green = ColorMap[i].Green << 8;
	    XColorTable[i].blue = ColorMap[i].Blue << 8;
	    XColorTable[i].flags = DoRed | DoGreen | DoBlue;
	    XPixelTable[i] = -1;		       /* Not allocated yet. */
	}
	else
	    XPixelTable[i] = 0;    /* Put reasonable color for out of range. */
    }

    for (i = 0; i < ColorMapSize; i++)	      /* Allocate the colors from X: */
	if (XAllocColor(XDisplay, XColorMap, &XColorTable[i]))
	    XPixelTable[i] = XColorTable[i].pixel;
	else
	    Failed = TRUE;

    if (Failed) {
	XNumOfColors = DisplayCells(XDisplay, XScreen);
	XOldColorTable = (XColor *) malloc(sizeof(XColor) * XNumOfColors);
	for (i = 0; i < XNumOfColors; i++) XOldColorTable[i].pixel = i;
	XQueryColors(XDisplay, XColorMap, XOldColorTable, XNumOfColors);
	
	for (i = 0; i < ColorMapSize; i++) {
	    /* Allocate closest colors from X: */
	    if (XPixelTable[i] == -1) {      /* Failed to allocate this one. */
		Distance = 0xffffffff;

		Red = XColorTable[i].red;
		Green = XColorTable[i].green;
		Blue = XColorTable[i].blue;

		for (j = 0; j < XNumOfColors; j++) {
		    /* Find the closest color in 3D RGB space using L1 norm. */
		    if ((D = ABS(Red - XOldColorTable[j].red) +
			     ABS(Green - XOldColorTable[j].green) +
			     ABS(Blue - XOldColorTable[j].blue)) < Distance) {
			Distance = D;
			Index = j;
		    }
		}
	        XPixelTable[i] = Index;

		AvgDistance += Distance;
		Count++;
	    }
	}
	free(XOldColorTable);

	sprintf(Msg, "Colors will be approximated (average error = %d).\n",
		AvgDistance / Count);
	GIF_MESSAGE(Msg);
    }
}
Beispiel #11
0
/*************************************************************
  Allocate all needed colors given in the array.
*************************************************************/
void alloc_colors(XColor *colors, int ncols)
{
  int i;

  if (!cmap) {
    cmap = DefaultColormap(display, screen_number);
  }

  for (i = 0; i < ncols; i++) {
    if (!XAllocColor(display, cmap, &colors[i])) {
      /* We're out of colors.  For the rest of the palette, just
       * find the closest match and use it.  We could instead try
       * to use a private colormap, but this is ugly, takes extra
       * code, and has no guarantee of getting better performance
       * unless we do a lot of work to optimize the colormap. */
      XColor *cells;
      int ncells, j;

      ncells = DisplayCells(display, screen_number);
      cells = fc_malloc(sizeof(XColor) * ncells);

      for (j = 0; j < ncells; j++) {
        cells[j].pixel = j;
      }

      /* We need to lock the server so that the colors don't change
       * while we're searching through them. */
      XGrabServer(display);

      XQueryColors(display, cmap, cells, ncells);

      for (; i < ncols; i++) {
        int best = INT_MAX;
        unsigned long pixel = 0;

	/* Find the best match among all available colors. */
        for (j = 0; j < ncells; j++) {
          int rd, gd, bd, dist;
          
          rd = (cells[j].red - colors[i].red) >> 8;
          gd = (cells[j].green - colors[i].green) >> 8;
          bd = (cells[j].blue - colors[i].blue) >> 8;
          dist = rd * rd + gd * gd + bd * bd;
          
          if (dist < best) {
            best = dist;
            pixel = j;
          }
        }

  	XAllocColor(display, cmap, &cells[pixel]);
        colors[i].pixel = pixel;
      }

      /* Unlock the server, since we're done querying it. */
      XUngrabServer(display);

      free(cells);
      break;
    }
  }