Back to index

plt-scheme  4.2.1
Functions
wxAllocColor.h File Reference
#include "wx_visual.h"
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Functions

Status wxAllocColor (Display *d, Colormap cm, XColor *c)
int wxQueryColor (Display *display, Colormap colormap, XColor *def_in_out)

Function Documentation

Status wxAllocColor ( Display *  d,
Colormap  cm,
XColor *  c 
)

Definition at line 95 of file wxAllocColor.c.

{
  int i;
  int min_weight;
  int min_weight_pos;
  unsigned short ri, gi, bi;
  int p, w, o;
  unsigned long pixel;
  Status status;

  /* Check fast path first: */
  if (cm == fast_colormap) {
    c->red = n_bits(c->red, r_length);
    c->green = n_bits(c->green, g_length);
    c->blue = n_bits(c->blue, b_length);

    c->pixel = ((c->red << r_start)
              | (c->green << g_start)
              | (c->blue << b_start));

    return OK;
  }

  /* If we have a weird colormap, essentially give up (no
     deallocation). */
  if (cm != wx_default_colormap)
    return XAllocColor(d, cm, c);

  /* Is the default colormap TrueColor? */

  if (!tc_known) {
    tc = wxAPP_VISUAL;
    if (tc->class != TrueColor)
      tc = NULL;
    else {
      r_length = mask_length(tc->red_mask);
      g_length = mask_length(tc->green_mask);
      b_length = mask_length(tc->blue_mask);

      r_start = mask_start(tc->red_mask);
      g_start = mask_start(tc->green_mask);
      b_start = mask_start(tc->blue_mask);

      if ((r_length == 8) && (g_length == 8) && (b_length == 8)) {
       wx_simple_r_start = r_start;
       wx_simple_g_start = g_start;
       wx_simple_b_start = b_start;
       wx_alloc_color_is_fast = 2;
      } else
       wx_alloc_color_is_fast = 1;

      fast_colormap = wx_default_colormap;
    }
    tc_known = 1;

    /* Try again: */
    return wxAllocColor(d, cm, c);
  }
  
  /* Not TrueColor. Do things the difficult way... */

  /* Check for black: */
  if (!c->red && !c->green && !c->blue) {
    c->pixel = BlackPixelOfScreen(wxAPP_SCREEN);
    return OK;
  }
  
  /* Check for white: */
  if ((c->red >= 0xFF00) && (c->green >= 0xFF00) && (c->blue >= 0xFF00)) {
    c->pixel = WhitePixelOfScreen(wxAPP_SCREEN);
    c->red = 0xFFFF;
    c->green = 0xFFFF;
    c->blue = 0xFFFF;
    return OK;
  }

  ri = c->red;
  gi = c->green;
  bi = c->blue;

  /* Check in cache: */ 
  min_weight_pos = 0;
  min_weight = cache[0].weight;
  for (i = 0; i < cache_end; i++) {
    if (cache[i].red_in == ri
       && cache[i].green_in == gi
       && cache[i].blue_in == bi) {
      c->red = cache[i].red_out;
      c->green = cache[i].green_out;
      c->blue = cache[i].blue_out;
      c->pixel = cache[i].pixel;

      if (cache[i].weight < 10000)
       cache[i].weight++;

      return OK;
    } else if (cache[i].weight < min_weight) {
      min_weight = cache[i].weight;
      min_weight_pos = i;
    }
  }

  if (cache_end == COLOR_CACHE_SIZE) {
    /* Degrade weights: */
    if (cache[COLOR_CACHE_SIZE - 1].pixel) {
      for (i = 0; i < cache_end; i++) 
       if (cache[i].weight)
         --cache[i].weight;
    }
  } else
    min_weight_pos = cache_end++;

  status = XAllocColor(d, cm, c);

  if (status == OK) {
    /* Add to cache: */
    cache[min_weight_pos].red_in = ri;
    cache[min_weight_pos].green_in = gi;
    cache[min_weight_pos].blue_in = bi;
    cache[min_weight_pos].red_out = c->red;
    cache[min_weight_pos].green_out = c->green;
    cache[min_weight_pos].blue_out = c->blue;
    cache[min_weight_pos].pixel = c->pixel;
    cache[min_weight_pos].weight = 10;

    /* Record allocation */

    /* Binary search for pixel: */
    pixel = c->pixel;
    if (alloc_count) {
      o = 0;
      p = alloc_count >> 1;
      w = alloc_count;
      
      while (1) {
       unsigned long v;
       
       v = alloced[p];
       
       if (v == pixel) {
         /* Balance redundant Alloc with Free: */
         XFreeColors(d, cm, &pixel, 1, 0);
         return OK;
       }
       if (w == 1) {
         if (v < pixel)
           p++;
         break;
       }
       if (v < pixel) {
         w = o + w - p;
         o = p;
       } else {
         w = p - o;
       }
       p = o + (w >> 1);
      }
    } else
      p = 0;

    /* Not alloced before. */
    /* First make sure array is large enough: */
    if (alloc_count == alloc_size) {
      unsigned long *old = alloced;

      if (!alloc_size)
       alloc_size = 256;
      else
       alloc_size = alloc_size * 2;
      
      alloced = (unsigned long *)malloc(sizeof(unsigned long) * alloc_size);
      for (i = 0; i < alloc_count; i++)
       alloced[i] = old[i];
      free(old);
    }
    
    for (i = alloc_count; i-- > p; )
      alloced[i + 1] = alloced[i];
    alloced[p] = pixel;
    alloc_count++;
    
    return OK;
  } else
    return status;
}

Here is the call graph for this function:

Here is the caller graph for this function:

int wxQueryColor ( Display *  display,
Colormap  colormap,
XColor *  def_in_out 
)

Definition at line 281 of file wxAllocColor.c.

{
  if (tc && (colormap == wx_default_colormap)) {
    unsigned long pixel = def_in_out->pixel, red, green, blue;

    red = (pixel >> r_start) & ((1 << r_length) - 1);
    green = (pixel >> g_start) & ((1 << g_length) - 1);
    blue = (pixel >> b_start) & ((1 << b_length) - 1);

    def_in_out->red = (red << (16 - r_length));
    def_in_out->green = (green << (16 - g_length));
    def_in_out->blue = (blue << (16 - b_length));
    
    return 1; /* is this the right return value? */
  }

  return XQueryColor(display, colormap, def_in_out);
}

Here is the caller graph for this function: