Back to index

plt-scheme  4.2.1
Classes | Defines | Functions | Variables
wxAllocColor.c File Reference
#include <stdlib.h>
#include <X11/Xcms.h>
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Classes

struct  ColorCache

Defines

#define COLOR_CACHE_SIZE   1000
#define OK   1

Functions

static int mask_length (unsigned long mask)
static int mask_start (unsigned long mask)
static unsigned short n_bits (unsigned short value, int nb)
Status wxAllocColor (Display *d, Colormap cm, XColor *c)
int wxQueryColor (Display *display, Colormap colormap, XColor *def_in_out)

Variables

static ColorCache cache [COLOR_CACHE_SIZE]
static int cache_end
static long alloc_size
static long alloc_count
static unsigned long * alloced
Screen * wxAPP_SCREEN
Display * wxAPP_DISPLAY
Visual * wxAPP_VISUAL
static Visual * tc
static int tc_known
static unsigned int r_length
static unsigned int g_length
static unsigned int b_length
static unsigned int r_start
static unsigned int g_start
static unsigned int b_start
int wx_simple_r_start
int wx_simple_g_start
int wx_simple_b_start
int wx_alloc_color_is_fast
Colormap fast_colormap = 0

Class Documentation

struct ColorCache

Definition at line 5 of file wxAllocColor.c.

Class Members
unsigned short blue_in
unsigned short blue_out
unsigned short green_in
unsigned short green_out
unsigned long pixel
unsigned short red_in
unsigned short red_out
int weight

Define Documentation

#define COLOR_CACHE_SIZE   1000

Definition at line 12 of file wxAllocColor.c.

#define OK   1

Definition at line 25 of file wxAllocColor.c.


Function Documentation

static int mask_length ( unsigned long  mask) [static]

Definition at line 30 of file wxAllocColor.c.

{
    int length = 0;

    while (mask) {
        length += mask & 1;
        mask >>= 1;
    }

    return length;
}

Here is the caller graph for this function:

static int mask_start ( unsigned long  mask) [static]

Definition at line 43 of file wxAllocColor.c.

{
    int pos = 0;

    while (!(mask & 0x1)) {
      pos++;
      mask >>= 1;
    }

    return pos;
}

Here is the caller graph for this function:

static unsigned short n_bits ( unsigned short  value,
int  nb 
) [inline, static]

Definition at line 56 of file wxAllocColor.c.

{
    /* length should be 16. */
    const int length = sizeof(unsigned short) * 8;
    unsigned short mask;

    /*        16 - nb bits
     *        vvvvvvvvvvv
     * mask = 0000000000011111
     *                   ^^^^^
     *                  nb bits
     */
    mask = (1 << nb) - 1;

    /* mask = 1111100000000000 */
    mask <<= length - nb;

    /* value = xxxxx00000000000 */
    value &= mask;

    /* value = 00000000000xxxxx */
    value >>= length - nb;

    return value;
}

Here is the caller graph for this function:

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:


Variable Documentation

long alloc_count [static]

Definition at line 18 of file wxAllocColor.c.

long alloc_size [static]

Definition at line 17 of file wxAllocColor.c.

unsigned long* alloced [static]

Definition at line 19 of file wxAllocColor.c.

unsigned int b_length [static]

Definition at line 86 of file wxAllocColor.c.

unsigned int b_start [static]

Definition at line 87 of file wxAllocColor.c.

Definition at line 14 of file wxAllocColor.c.

int cache_end [static]

Definition at line 15 of file wxAllocColor.c.

Colormap fast_colormap = 0

Definition at line 93 of file wxAllocColor.c.

unsigned int g_length [static]

Definition at line 86 of file wxAllocColor.c.

unsigned int g_start [static]

Definition at line 87 of file wxAllocColor.c.

unsigned int r_length [static]

Definition at line 86 of file wxAllocColor.c.

unsigned int r_start [static]

Definition at line 87 of file wxAllocColor.c.

Visual* tc [static]

Definition at line 82 of file wxAllocColor.c.

int tc_known [static]

Definition at line 84 of file wxAllocColor.c.

Definition at line 91 of file wxAllocColor.c.

Definition at line 89 of file wxAllocColor.c.

Definition at line 89 of file wxAllocColor.c.

Definition at line 89 of file wxAllocColor.c.

Display* wxAPP_DISPLAY

Definition at line 53 of file GlobalData.cc.

Screen* wxAPP_SCREEN

Definition at line 54 of file GlobalData.cc.

Visual* wxAPP_VISUAL

Definition at line 52 of file AppMain.cc.