--- os/oscolor.c +++ os/oscolor.c @@ -48,8 +48,18 @@ #include #endif +#define USE_RGB_CF_FILE 1 + #include -#include "os.h" + +#if USE_RGB_CF_FILE +# define RGB_PATH "/usr/local/etc/X11/babolo-rgb.txt" +# include +# include "os.h" +# include "opaque.h" +#else +# include "os.h" +#endif /* USE_RGB_CF_FILE */ typedef struct _builtinColor { unsigned char red; @@ -1630,6 +1640,112 @@ #define NUM_BUILTIN_COLORS (sizeof (BuiltinColors) / sizeof (BuiltinColors[0])) +#if USE_RGB_CF_FILE + +#define HASHSIZE 63 + +typedef struct _dbEntry * dbEntryPtr; +typedef struct _dbEntry { + dbEntryPtr link; + unsigned short red; + unsigned short green; + unsigned short blue; + char name[1]; /* some compilers complain if [0] */ +} dbEntry; + +static unsigned char +ISOLatin1ToLower (unsigned char source) +{ + unsigned char dest; + if ((source >= 'A') && (source <= 'Z')) + dest = source + ('a' - 'A'); + else + dest = source; + return dest; +} + +static void +CopyISOLatin1Lowered(unsigned char *dest, unsigned char *source, int length) +{ + int i; + + for (i = 0; i < length; i++, source++, dest++) + *dest = ISOLatin1ToLower (*source); + *dest = '\0'; +} + +static dbEntryPtr hashTab[HASHSIZE]; + +static dbEntryPtr +lookup(char *name, int len, Bool create) { + unsigned int h = 0, g; + dbEntryPtr entry, *prev = NULL; + char *str = name; + + if (!(name = (char*)malloc(len +1))) return NULL; + CopyISOLatin1Lowered((unsigned char *)name, (unsigned char *)str, len); + name[len] = '\0'; + + for(str = name; *str; str++) { + h = (h << 4) + *str; + if ((g = h) & 0xf0000000) h ^= (g >> 24); + h &= g; + } + h %= HASHSIZE; + + if ((entry = hashTab[h])) { + for ( ; entry; prev = (dbEntryPtr*)entry, entry = entry->link ) + if (! strcmp(name, entry->name) ) break; + } else prev = &(hashTab[h]); + + if (!entry && create && (entry = (dbEntryPtr)malloc(sizeof(dbEntry) +len))) { + *prev = entry; + entry->link = NULL; + strcpy( entry->name, name ); + } + + free(name); + return entry; +} + +static int InitColors = 0; + +static int +OsInitColors(void) { + FILE *rgb; + char line[BUFSIZ]; + char name[BUFSIZ]; + int red, green, blue, lineno = 0; + dbEntryPtr entry; + + if (!(rgb = fopen(RGB_PATH, "r"))) { + ErrorF("Couldn't open RGB_DB '%s'\n", RGB_PATH); + return(-1); + } else { + while(fgets(line, sizeof(line), rgb)) { + lineno++; + if (sscanf(line,"%d %d %d %[^\n]\n", &red, &green, &blue, name) == 4) { + if ( red >= 0 && red <= 0xff + && green >= 0 && green <= 0xff + && blue >= 0 && blue <= 0xff + ) { + if ((entry = lookup(name, strlen(name), TRUE))) { + entry->red = (red * 65535) / 255; + entry->green = (green * 65535) / 255; + entry->blue = (blue * 65535) / 255; + } + } else { + ErrorF("Value out of range: %s:%d\n", RGB_PATH, lineno); + } + } else if (*line && *line != '#' && *line != '!') { + ErrorF("Syntax Error: %s:%d\n", RGB_PATH, lineno); + } } + fclose(rgb); + return(1); +} } + +#endif /* USE_RGB_CF_FILE */ + Bool OsLookupColor(int screen, char *name, @@ -1640,7 +1756,20 @@ const BuiltinColor *c; int low, mid, high; int r; +#if USE_RGB_CF_FILE + dbEntryPtr entry; + if (!InitColors) InitColors=OsInitColors(); + if (InitColors > 0) { + if ((entry = lookup(name, len, FALSE))) { + *pred = entry->red; + *pgreen = entry->green; + *pblue = entry->blue; + return TRUE; + } + return FALSE; + } +#endif /* USE_RGB_CF_FILE */ low = 0; high = NUM_BUILTIN_COLORS - 1; while (high >= low) {