/* ** A utility to prevent colormap flashing by performing ** a closest match when the allocation fails. ** ** V1.01 dated 26th March 1997. ** Written by David Tong, Sun Microsystems Inc. ** ** To use, first build and then ** setenv LD_PRELOAD //libnoflash.so.1 */ /* ** Makefile follows: ** all: libnoflash.so.1 libnoflash.so.1: preload.c cc -g -K PIC preload.c -c -I. -I/usr/openwin/include ld -G -ztext preload.o -R/usr/lib -ldl -lc -o libnoflash.so mv libnoflash.so libnoflash.so.1 ** */ #include #include #include #include #include #define NEED_REPLIES #include #include void *X11 = NULL; void init(); Status (*_XAllocColor) (Display*, Colormap, XColor*); int (*_XFreeColors) (Display*, Colormap, unsigned long*, int, unsigned long); #define COLOR_FACTOR 3 #define BRIGHTNESS_FACTOR 1 Status XAllocColor(register Display *dpy, Colormap cmap, XColor *xcolor) { Status retstat; if (!X11) init(); if (!(retstat = _XAllocColor(dpy, cmap, xcolor))) { XColor *cols; unsigned int ncols, i, closepix; long int closediff; ncols = 1 << DefaultDepth(dpy, DefaultScreen(dpy)); cols = (XColor * )calloc(ncols, sizeof(XColor)); for (i = 0; i < ncols; ++i) cols[i].pixel = i; XQueryColors(dpy, cmap, cols, ncols); do { for (i = 0, closediff = 0x7FFFFFFF; i < ncols; ++i) { long int newclosediff = COLOR_FACTOR *( abs((long)xcolor->red -(long)cols[i].red) + abs((long)xcolor->green -(long)cols[i].green) + abs((long)xcolor->blue -(long)cols[i].blue)) + BRIGHTNESS_FACTOR *abs( ((long)xcolor->red + (long)xcolor->green + (long)xcolor->blue) - ((long)cols[i].red + (long)cols[i].green + (long)cols[i].blue)); if (newclosediff < closediff) { closepix = i; closediff = newclosediff; } } xcolor->red = cols[closepix].red; xcolor->green = cols[closepix].green; xcolor->blue = cols[closepix].blue; /* ** Now paint it black so we don't loop ** in the case that this colour is read-write. */ cols[closepix].red = 0; cols[closepix].green = 0; cols[closepix].blue = 0; retstat = _XAllocColor(dpy, cmap, xcolor); } while (retstat == 0); free(cols); } return(retstat); } void init() { /* Tip from john.m.martin@Central - don't hard-code the library path */ _XAllocColor = dlsym(RTLD_NEXT, "XAllocColor"); _XFreeColors = dlsym(RTLD_NEXT, "XFreeColors"); /* Not currently used */ X11 = (void *) 1; /* ** if ((X11 = dlopen("/usr/openwin/lib/libX11.so.4", RTLD_LAZY)) == 0) { ** printf("%s\n", dlerror()); ** exit(1); ** } ** ** _XAllocColor = dlsym(X11, "XAllocColor"); ** _XFreeColors = dlsym(X11, "XFreeColors"); */ }