/* ** This utility attempts to reduce or even prevent colormap ** flashing by over-riding most of the X colour manipulation ** routines without the application being aware. ** ** HISTORY ** ** 26th March 1997. ** Written by David Tong, Sun Microsystems Inc. ** Performs a closest match when allocation fails. ** ** 17th August 1997. ** Override XCreateColormap and other functions to protect ** the lower pixels when an application allocates its own colormap ** ** 19th September 1997. ** Let's not allow the user to allocate any read-write colours. ** Instead, lets give him a fake pixel value, greater than 256. ** When the user tries to set the colour of that pixel we just ** change our look up table so it points to the nearest match ** in the default colormap. ** ** For this to work we need to trap every place where a pixel ** value is used and convert it as needed. Hopefully we can ** just do this by manipulating a few calls: ** XCreateGC, XChangeGC, XSetBackground, XSetForeground ** ** January 1998 ** Discovered that the FFB can report a colormap size of less than 256 ** when using an 8 bit visual with overlays. Implemented a fix for this. ** Now I'm wondering whether it may be possible to take advantage of it. ** ** --------------------------------------------------------------------- ** ** KNOWN BUGS ** Doesn't work well with Appl*x ** Causes Pro/Engineer to crash ** Impacts performance. This is minor, but can probably be improved. ** ** --------------------------------------------------------------------- ** ** To use, first build and then ** setenv LD_PRELOAD //libnoflash.so.1 ** ** Environmental variables: ** NOFLASH_DEBUG Used by me when investigating what a program is doing ** NOFLASH_FORCE Forces closest matching on all read-only colours. ** This prevents the default colormap from being consumed. ** NOFLASH_CUBE Allocate the 4x4x4 read-only color cube ** NOFLASH_PROTECT How many colours to protect from flashing (default 64) ** NOFLASH_NOALLOC Don't pre-allocate the protected colours ** as this upsets tools such as xcolor and stdinage. ** NOFLASH_NONAME Don't set defaults based on the program name. ** By default, noflash sets reset variables according ** to the name of the executable. ** NOFLASH_DISABLE Turn off the functionality without changing LD_PRELOAD ** ** Acknowledgement: ** The closest match algorithm used here was not developed by me. ** Its origins are obscure, but it is probably a derivation of the ** algorithm created by Jason Patterson (jason@reflections.com.au) ** and donated to the libXpm distribution. Thanks, Jason. ** ** 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 #include #include #include void *X11 = NULL; int PROTECT = 64; int NOALLOC = 0; int DEBUG = 0; int DISABLED = 0; int FORCE = 0; int LOOKUP = 1; Colormap default_cmap = NULL; typedef struct defaults { char *proc_name; int noalloc; int protect; int force; int lookup; } Defaults; /* ** Here we set up default values for non-standard applications. ** Remember, we are changing the way the X server behaves. ** Applications may make assumptions that we render invalid. */ Defaults def[] = { /* Applix does some very odd tricks, and there's no easy way round. */ /* The only solution is that Applix should be started first */ { "axmain", 1, 0, 0, 0 }, /* Applix */ /* Don't even THINK about trying to fix Doom. */ { "sundgadoom", 1, 0, 0, 0 }, /* DOOM */ { "sunxdoom", 1, 0, 0, 0 }, /* DOOM */ /* Xcolor assumes that the whole 256 colours are its for the taking */ { "xcolor", 1, 64, 0, 0 }, /* Xcolor */ /* As do imagetool and sdtimage (basically the same code) */ { "imagetool", 1, 64, 0, 0 }, /* OpenWin imagetool */ { "sdtimage", 1, 64, 0, 0 }, /* CDE imagetool */ /* I think Wabi does too, but as yet it's untested */ { "wabi", 1, 64, 0, 1 } /* Wabi */ }; typedef struct myXcolor { long pixel; long flags; } MyXcolor; /* TABLESIZE msut be a power of 2 minimum 256, eg 256, 512, 1024 */ #define TABLESIZE 256 MyXcolor *lookup_table = NULL; Colormap private_colormap = NULL; #define DEFMAX (sizeof(def)/sizeof(Defaults)) void init(); /* Declare the functions to be over-ridden */ Status (*_XAllocColor) (Display*, Colormap, XColor*); Status (*_XAllocNamedColor) (Display*, Colormap, char *, XColor*, XColor*); Status (*_XAllocColorCells) (Display *, Colormap, Bool, long[], int, long[], int); int (*_XFreeColors) (Display*, Colormap, long*, int, long); Colormap (*_XCreateColormap) (Display*, Window, Visual*, int); int (*_XQueryColor) (Display *, Colormap, XColor*); int (*_XQueryColors) (Display *, Colormap, XColor[], int); int (*_XStoreColor) (Display *, Colormap, XColor*); int (*_XStoreColors) (Display *, Colormap, XColor[], int); int (*_XStoreNamedColor) (Display *, Colormap, char *, long, int); int (*_XSetForeground) (Display *, GC, long); int (*_XSetBackground) (Display *, GC, long); int (*_XSetWindowForeground) (Display *, Window, long); int (*_XSetWindowBackground) (Display *, Window, long); GC (*_XCreateGC) (Display *, Drawable, unsigned long, XGCValues *); int (*_XChangeGC) (Display *, GC, unsigned long, XGCValues *); #define COLOR_FACTOR 3 #define BRIGHTNESS_FACTOR 1 Status XAllocColorCells(Display *dpy, Colormap map, Bool contig, long *plane_masks, int nplanes, long *pixels, int npixels) { Status stat; int i, j; if (DEBUG) fprintf(stderr," > XAllocColorCells: %d cells\n", npixels); if (X11 == NULL) { if (DEBUG) fprintf(stderr,"INIT \n"); init(dpy); } if ((map != private_colormap) || (npixels == 0) || (lookup_table == NULL)) { if (DEBUG) fprintf(stderr," >>> Call _XAllocColorCells\n"); stat = _XAllocColorCells(dpy, map, contig, plane_masks, nplanes, pixels, npixels); #if 0 if (stat) return stat; else { private_colormap = default_cmap; lookup_table = (MyXcolor * )calloc(TABLESIZE, sizeof(MyXcolor)); memset(lookup_table, -1, TABLESIZE * sizeof(MyXcolor)); } #else return stat; #endif } /* ** We have a private colormap, a lookup table, and a request for pixels. ** Look through the lookup table and see if we have space to allocate ** the new entries. If so, we do this by setting the flags in the table. ** The pixel values we return are the array indices plus the table size. ** This is fine, because a pixel is a long; we are unlikely to exceed a short. */ /* First see if we can */ for (i = 0, j = 0; i < npixels; i++) { if (j >= TABLESIZE) { if (DEBUG) fprintf(stderr," >>> (1) Return 0\n"); return 0; } while (lookup_table[j].flags > 0) { if (++j >= TABLESIZE) { if (DEBUG) fprintf(stderr," >>> (2) Return 0\n"); return 0; } } j++; } /* ** There is enough space in the lookup table. ** Now do the "allocation" */ for (i = 0, j = 0; i < npixels; i++) { while (lookup_table[j].flags > 0) { j++; } pixels[i] = j + TABLESIZE; lookup_table[j].flags = 1; j++; } stat = j; if (DEBUG) fprintf(stderr," >>> Return %d \n", stat); return stat; } int XFreeColors(Display *dpy, Colormap map, long* pixels, int count, long planes) { int stat = 1; int j, k; long *l, *lp1, *lp2; if (DEBUG) fprintf(stderr," > XFreeColors (%d) \n", count); if (X11 == NULL) init(dpy); /* ** Look for pixels >= TABLESIZE in our colormap. ** Those are not real, so we free them by clearing the flag ** our lookup table. Any other pixels must be freed normally. */ if ((map == private_colormap) && (lookup_table != NULL) && (count > 0)) { lp1 = pixels; lp2 = l = (long * )calloc(count, sizeof(long)); for (j = 0, k = 0; j < count; j++) { if (*lp1 >= TABLESIZE) { *lp2 = lookup_table[(*lp1) - TABLESIZE].pixel; if (*lp2 >= 0) { lp2++; k++; /* Has been used; need to call XFreeColors */ } lookup_table[(*lp1) - TABLESIZE].flags = 0; lookup_table[(*lp1) - TABLESIZE].pixel = -1; } else { if (*lp1 >= 0) { *lp2++ = *lp1; k++; } } lp1++; } if (k) stat = _XFreeColors(dpy, map, l, k, planes); free(l); } else stat = _XFreeColors(dpy, map, pixels, count, planes); return stat; } XQueryColor(Display *dpy, Colormap map, XColor* colour) { if (DEBUG) fprintf(stderr," > XQueryColor\n"); if (X11 == NULL) init(dpy); /* ** First, check if this is one of our "fake" pixels. */ if ((map == private_colormap) && (lookup_table != NULL)) { int offset = colour->pixel - TABLESIZE; if ((offset >= 0) && (offset < TABLESIZE)) { int save_pixel = colour->pixel; colour->pixel = lookup_table[offset].pixel; _XQueryColor(dpy, map, colour); colour->pixel = save_pixel; return 1; } } return _XQueryColor(dpy, map, colour); } XQueryColors(Display *dpy, Colormap map, XColor *colours, int count) { if (DEBUG) fprintf(stderr," > XQueryColors\n"); if (X11 == NULL) init(dpy); if ((map == private_colormap) && (lookup_table != NULL)) { long *savepixel = (long)calloc(count, sizeof(long)); int i; XColor *c = colours; long *l = savepixel; for (i = 0; i < count; i++, l++, c++) { int offset = c->pixel - TABLESIZE; *l = c->pixel; if ((offset >= 0) && (offset < TABLESIZE)) c->pixel = lookup_table[offset].pixel; } _XQueryColors(dpy, map, colours, count); l = savepixel; c = colours; for (i = 0; i < count; i++, l++, c++) { c->pixel = *l; } free (savepixel); } else _XQueryColors(dpy, map, colours, count); return 1; } XStoreColor(Display *dpy, Colormap map, XColor* colour) { if (DEBUG) fprintf(stderr," > XStoreColor: Pixel %x \n", colour->pixel); if (X11 == NULL) init(dpy); /* ** First, check if this is one of our "fake" pixels. */ if ((map == private_colormap) && (lookup_table != NULL)) { int pixel = colour->pixel; int offset = pixel - TABLESIZE; colour->pixel = 0; if ((offset >= 0) && (offset < TABLESIZE)) { if (lookup_table[offset].pixel >= 0) _XFreeColors(dpy, map, &lookup_table[offset].pixel, 1, NULL); XAllocColor(dpy, map, colour); if ((colour->pixel >= 0) && (colour->pixel < 256)) { if (DEBUG) fprintf(stderr," > Storing colour %X%X%X pixel %x at %x\n", colour->red, colour->green, colour->blue, colour->pixel, offset); lookup_table[offset].pixel = colour->pixel; colour->pixel = pixel; } return 1; } } /* ** If the colour cell is one of the ones we are protecting ** we just ignore the request */ if ((map == default_cmap) || (colour->pixel >= PROTECT)) return _XStoreColor(dpy, map, colour); return 1; } XStoreColors(Display *dpy, Colormap map, XColor *colours, int count) { int i; if (DEBUG) fprintf(stderr," > XStoreColors: Requesting %d Colours\n", count); if (X11 == NULL) init(dpy); if ((map == private_colormap) && (lookup_table != NULL)) { long *free_list = (long)calloc(count, sizeof(long)); long *f = free_list; int free_count = 0; for (i = 0; i < count; i++, colours++) { int pixel = colours->pixel; int offset = pixel - TABLESIZE; colours->pixel = 0; XAllocColor(dpy, map, colours); if ((offset >= 0) && (offset < TABLESIZE)) { if (lookup_table[offset].pixel >= 0) { *f++ = lookup_table[offset].pixel; free_count++; } if ((colours->pixel >= 0) && (colours->pixel < 256)) { if (DEBUG) fprintf(stderr," > Storing colour %X%X%X pixel %x at %x\n", colours->red, colours->green, colours->blue, colours->pixel, offset); lookup_table[offset].pixel = colours->pixel; colours->pixel = pixel; } } } if (free_count > 0) _XFreeColors(dpy, map, free_list, free_count, NULL); free(free_list); } else { for (i = 0; i < count; i++, colours++) { XStoreColor(dpy, map, colours); } if (DEBUG) fprintf(stderr," > XStoreColors: Optimise this bit \n"); } return 1; } XStoreNamedColor(Display *dpy, Colormap map, char *name, long pixel, int flag) { if (DEBUG) fprintf(stderr," > XStoreNamedColor\n"); if (X11 == NULL) init(dpy); /* ** First, check if this is one of our "fake" pixels. */ if ((map == private_colormap) && (lookup_table != NULL)) { if (pixel >= TABLESIZE) { XColor newcolour1, newcolour2; int offset = pixel - TABLESIZE; if (lookup_table[offset].pixel >= 0) _XFreeColors(dpy, map, &lookup_table[offset].pixel, 1, NULL); XAllocNamedColor(dpy, map, name, &newcolour1, &newcolour2); if ((newcolour1.pixel >= 0) && (newcolour1.pixel < 256)) lookup_table[offset].pixel = newcolour1.pixel; return 1; } } /* ** If the colour cell is one of the ones we are protecting ** we just ignore the request */ if ((map == default_cmap) || (pixel >= PROTECT)) return _XStoreNamedColor(dpy, map, name, pixel, flag); return 1; } Colormap XCreateColormap(register Display *dpy, Window w, Visual *visual, int alloc) { Colormap cmap; XColor *colours; long *pixels; int depth, ncolours, i; XVisualInfo visualTemp, *visualInfo; int staticVisual; Visual *viz; XVisualInfo vinfo_tmpl; XVisualInfo *return_vinfo = NULL; long vinfo_mask = VisualIDMask; int num_vinfos; if (DEBUG) fprintf(stderr," > XCreateColormap\n"); if (X11 == NULL) init(dpy); visualTemp.visualid = XVisualIDFromVisual(visual); visualInfo = XGetVisualInfo(dpy, VisualIDMask, &visualTemp, &i); staticVisual = ((visualInfo->class % 2) == 0); depth = DefaultDepth(dpy, DefaultScreen(dpy)); /* ** Create a new colormap, exactly as requested. ** We aren't interested in static or 24 bit visuals yet. */ if ((staticVisual) || (depth == 24)) { cmap = _XCreateColormap(dpy, w, visual, alloc); return cmap; } if (LOOKUP > 0) { if (DEBUG) fprintf(stderr," > XCreateColormap: Using lookup table\n"); private_colormap = default_cmap; lookup_table = (MyXcolor * )calloc(TABLESIZE, sizeof(MyXcolor)); memset(lookup_table, -1, TABLESIZE * sizeof(MyXcolor)); } else { if (DEBUG) fprintf(stderr," > XCreateColormap: NOT using lookup table\n"); private_colormap = _XCreateColormap(dpy, w, visual, AllocNone); /* ** The following is necessary because FFB2 can have a colormap size less than 256 - ** I think it's 224 + 32 for overlay. */ viz = DefaultVisual(dpy, DefaultScreen(dpy)); vinfo_tmpl.visualid = XVisualIDFromVisual(viz); return_vinfo = XGetVisualInfo(dpy, vinfo_mask, &vinfo_tmpl, &num_vinfos); ncolours = return_vinfo->colormap_size; colours = (XColor * )calloc(ncolours, sizeof(XColor)); pixels = (long * )calloc(ncolours, sizeof(long)); for (i = 0; i < ncolours; i++) { colours[i].pixel = i; } _XQueryColors(dpy, default_cmap, colours, ncolours); if (_XAllocColorCells(dpy, private_colormap, True, NULL, 0, pixels, ncolours)) _XStoreColors(dpy, private_colormap, &colours[0], ncolours); if (alloc == AllocNone) { _XFreeColors(dpy, private_colormap, pixels, ncolours, 0); if (!NOALLOC) _XAllocColorCells(dpy, private_colormap, True, NULL, 0, pixels, PROTECT); } free(colours); free(pixels); } return private_colormap; } Status XAllocNamedColor(Display* dpy, Colormap map, char *c, XColor*x1, XColor*x2) { Status retstat; if (DEBUG) fprintf(stderr," > XAllocNamedColor %s\n", c); if (X11 == NULL) init(dpy); /* ** This bit hasn't been well tested. ** I'm hoping that x2 gets updated with the right colours ** even if the allocation fails. */ if (!(retstat = _XAllocNamedColor(dpy, map, c, x1, x2))) { if (retstat = XLookupColor(dpy, map, c, x2, x1)) { x1->red = x2->red; x1->blue = x2->blue; x1->green = x2->green; x1->flags = DoRed | DoGreen | DoBlue; retstat = XAllocColor(dpy, map, x1); } } if (DEBUG) fprintf(stderr," Wanted Colour 0x%x%x%x\n", x2->red, x2->green, x2->blue); if (DEBUG) fprintf(stderr," Closest Match 0x%x%x%x Pixel %d\n", x1->red, x1->green, x1->blue, x1->pixel); return retstat; } Status XAllocColor(register Display *dpy, Colormap cmap, XColor *xcolor) { Status retstat = 0; Visual *viz; XVisualInfo vinfo_tmpl; XVisualInfo *return_vinfo = NULL; long vinfo_mask = VisualIDMask; int num_vinfos; if (DEBUG) fprintf(stderr," > XAllocColor 0x%x%x%x\n", xcolor->red, xcolor->green, xcolor->blue); if (X11 == NULL) init(dpy); if (!FORCE) retstat = _XAllocColor(dpy, cmap, xcolor); if (!retstat) { XColor *colours; int ncolours, i, closepix; long int closediff; /* ** The following is necessary because FFB2 can have a colormap size less than 256 - ** I think it's 224 + 32 for overlay. */ viz = DefaultVisual(dpy, DefaultScreen(dpy)); vinfo_tmpl.visualid = XVisualIDFromVisual(viz); return_vinfo = XGetVisualInfo(dpy, vinfo_mask, &vinfo_tmpl, &num_vinfos); ncolours = return_vinfo->colormap_size; /* ** Have to do this every time, because we don't know what has changed. */ colours = (XColor * )calloc(ncolours, sizeof(XColor)); for (i = 0; i < ncolours; ++i) colours[i].pixel = i; XQueryColors(dpy, cmap, colours, ncolours); /* ** Sooner or later this has to match against something, ** even if it's a choice between black or white! */ do { for (i = 0, closediff = 0x7FFFFFFF; i < ncolours; ++i) { long int newclosediff = COLOR_FACTOR *( abs((long)xcolor->red -(long)colours[i].red) + abs((long)xcolor->green -(long)colours[i].green) + abs((long)xcolor->blue -(long)colours[i].blue)) + BRIGHTNESS_FACTOR *abs( ((long)xcolor->red + (long)xcolor->green + (long)xcolor->blue) - ((long)colours[i].red + (long)colours[i].green + (long)colours[i].blue)); if (newclosediff < closediff) { closepix = i; closediff = newclosediff; } } xcolor->red = colours[closepix].red; xcolor->green = colours[closepix].green; xcolor->blue = colours[closepix].blue; /* ** Now paint it black so we don't loop ** in the case that this colour is read-write. */ colours[closepix].red = 0; colours[closepix].green = 0; colours[closepix].blue = 0; retstat = _XAllocColor(dpy, cmap, xcolor); } while (retstat == 0); free(colours); } if (DEBUG) fprintf(stderr," Closest Match 0x%x%x%x Pixel %d\n", xcolor->red, xcolor->green, xcolor->blue, xcolor->pixel); return(retstat); } XSetForeground(Display *dpy, GC gc, long pixel) { int offset = pixel - TABLESIZE; if (DEBUG) fprintf(stderr," > XSetForeground: pixel = %x \n", pixel); if (X11 == NULL) init(dpy); if ((lookup_table) && (offset >= 0) && (offset < TABLESIZE)) { if (DEBUG) fprintf(stderr," >>> Lookup: %x becomes %x \n", pixel, lookup_table[offset].pixel); pixel = lookup_table[offset].pixel; } _XSetForeground(dpy, gc, pixel); } XSetBackground(Display *dpy, GC gc, long pixel) { int offset = pixel - TABLESIZE; if (DEBUG) fprintf(stderr," > XSetBackground: pixel = %x \n", pixel); if (X11 == NULL) init(dpy); if ((lookup_table) && (offset >= 0) && (offset < TABLESIZE)) { if (DEBUG) fprintf(stderr," >>> Lookup: %x becomes %x \n", pixel, lookup_table[offset].pixel); pixel = lookup_table[offset].pixel; } _XSetBackground(dpy, gc, pixel); } XSetWindowForeground(Display *dpy, Window w, long pixel) { int offset = pixel - TABLESIZE; if (DEBUG) fprintf(stderr," > XSetWindowForeground: pixel = %x \n", pixel); if (X11 == NULL) init(dpy); if ((lookup_table) && (offset >= 0) && (offset < TABLESIZE)) { if (DEBUG) fprintf(stderr," >>> Lookup: %x becomes %x \n", pixel, lookup_table[offset].pixel); pixel = lookup_table[offset].pixel; } _XSetWindowForeground(dpy, w, pixel); } XSetWindowBackground(Display *dpy, Window w, long pixel) { int offset = pixel - TABLESIZE; if (DEBUG) fprintf(stderr," > XSetWindowBackground: pixel = %x \n", pixel); if (X11 == NULL) init(dpy); if ((lookup_table) && (offset >= 0) && (offset < TABLESIZE)) { if (DEBUG) fprintf(stderr," >>> Lookup: %x becomes %x \n", pixel, lookup_table[offset].pixel); pixel = lookup_table[offset].pixel; } _XSetWindowBackground(dpy, w, pixel); } GC XCreateGC(Display *dpy, Drawable d, long mask, XGCValues *values) { int offset; if (DEBUG) fprintf(stderr," > XCreateGC\n"); if (X11 == NULL) init(dpy); if (values) { if (mask & GCForeground) { if (DEBUG) fprintf(stderr," >>> Set foreground to %x\n", values->foreground); if (values->foreground == 0xffffffff) { values->foreground = 0; } offset = values->foreground - TABLESIZE; if ((lookup_table) && (offset >= 0) && (offset < TABLESIZE)) { if (DEBUG) fprintf(stderr," >>> Lookup: %x becomes %x \n", values->foreground, lookup_table[offset].pixel); values->foreground = lookup_table[offset].pixel; } } if (mask & GCBackground) { if (DEBUG) fprintf(stderr," >>> Set background to %x\n", values->background); if (values->background == 0xffffffff) values->background = 0; offset = values->background - TABLESIZE; if ((lookup_table) && (offset >= 0) && (offset < TABLESIZE)) { if (DEBUG) fprintf(stderr," >>> Lookup: %x becomes %x \n", values->background, lookup_table[offset].pixel); values->background = lookup_table[offset].pixel; } } } return _XCreateGC(dpy, d, mask, values); } XChangeGC(Display *dpy, GC gc, long mask, XGCValues *values) { int offset; if (DEBUG) fprintf(stderr," > XChangeGC\n"); if (X11 == NULL) init(dpy); if (values) { if (mask & GCForeground) { if (DEBUG) fprintf(stderr," >>> Set foreground to %x\n", values->foreground); if (values->foreground == 0xffffffff) values->foreground = 0; offset = values->foreground - TABLESIZE; if ((lookup_table) && (offset >= 0) && (offset < TABLESIZE)) { if (DEBUG) fprintf(stderr," >>> Lookup: %x becomes %x \n", values->foreground, lookup_table[offset].pixel); values->foreground = lookup_table[offset].pixel; } } if (mask & GCBackground) { if (DEBUG) fprintf(stderr," >>> Set background to %x\n", values->background); if (values->background == 0xffffffff) values->background = 0; offset = values->background - TABLESIZE; if ((lookup_table) && (offset >= 0) && (offset < TABLESIZE)) { if (DEBUG) fprintf(stderr," >>> Lookup: %x becomes %x \n", values->background, lookup_table[offset].pixel); values->background = lookup_table[offset].pixel; } } } return _XChangeGC(dpy, gc, mask, values); } void init(Display *dpy) { char *c; char pname[256]; int procfd; prpsinfo_t info; char *name = NULL; int i; if (!getenv("NOFLASH_NONAME")) { sprintf(pname, "/proc/%05ld", getpid()); if ((procfd = open(pname, O_RDONLY)) > 0) { if (ioctl(procfd, PIOCPSINFO, (char *) &info) != -1) { name = strdup(info.pr_psargs); if (c = strchr(name, ' ')) *c = '\0'; if ((c = strrchr(name, '/')) != NULL) name = ++c; } } (void) close(procfd); } printf("NoFlash V1.1.12 dated 98/03/14: Copyright 1997 David Tong and Sun Microsystems Inc.\n", 0, 0, 0, 0); printf("\nThis is a BETA VERSION and is made available for testing purposes ONLY\n"); printf("NoFlash is the subject of a patent application. In using this program you agree \n"); printf("to abide by the terms and conditions of Sun's standard non-disclosure agreement.\n"); printf("Unauthorised distribution of the source or binary is strictly prohibited.\n"); printf("Please send feedback to david.tong@corp.sun.com\n"); if (name) { printf("Running %s\n", name); for (i = 0; i < DEFMAX; i++) { if (!strcmp(name, def[i].proc_name)) { NOALLOC = def[i].noalloc; PROTECT = def[i].protect; FORCE = def[i].force; LOOKUP = def[i].lookup; break; } } } /* Tip from john.m.martin@Central - don't hard-code the library path */ /* C compiler hates this next bit, but it's good enough */ _XAllocColor = dlsym(RTLD_NEXT, "XAllocColor"); _XAllocNamedColor = dlsym(RTLD_NEXT, "XAllocNamedColor"); _XAllocColorCells = dlsym(RTLD_NEXT, "XAllocColorCells"); _XQueryColors = dlsym(RTLD_NEXT, "XQueryColors"); _XQueryColor = dlsym(RTLD_NEXT, "XQueryColor"); _XStoreColors = dlsym(RTLD_NEXT, "XStoreColors"); _XStoreColor = dlsym(RTLD_NEXT, "XStoreColor"); _XStoreNamedColor = dlsym(RTLD_NEXT, "XStoreNamedColor"); _XCreateColormap = dlsym(RTLD_NEXT, "XCreateColormap"); _XFreeColors = dlsym(RTLD_NEXT, "XFreeColors"); _XSetForeground = dlsym(RTLD_NEXT, "XSetForeground"); _XSetBackground = dlsym(RTLD_NEXT, "XSetBackground"); _XSetWindowForeground = dlsym(RTLD_NEXT, "XSetWindowForeground"); _XSetWindowBackground = dlsym(RTLD_NEXT, "XSetWindowBackground"); _XCreateGC = dlsym(RTLD_NEXT, "XCreateGC"); _XChangeGC = dlsym(RTLD_NEXT, "XChangeGC"); X11 = (void *) 1; if (c = getenv("NOFLASH_DISABLE")) { DISABLED = c; return; } if (c = getenv("NOFLASH_DEBUG")) DEBUG = c; if (c = getenv("NOFLASH_NOALLOC")) NOALLOC = c; if (c = getenv("NOFLASH_FORCE")) FORCE = c; if (c = getenv("NOFLASH_PROTECT")) PROTECT = atoi(c); default_cmap = DefaultColormap(dpy, DefaultScreen(dpy)); /* ** Try and create a 4x4x4 color cube ** If the cube exists we will match those colours. */ if (getenv("NOFLASH_CUBE")) { int depth = DefaultDepth(dpy, DefaultScreen(dpy)); int x, y, z; XColor colour; if (depth == 24) return; for (x = 0; x < 4; x++) { for (y = 0; y < 4; y++) { for (z = 0; z < 4; z++) { colour.flags = DoRed | DoGreen | DoBlue; colour.red = 21845 *x; colour.blue = 21845 *y; colour.green = 21845 *z; if (_XAllocColor(dpy, default_cmap, &colour)) { if (colour.pixel > PROTECT) { PROTECT = colour.pixel; } } } } } } /* ** The old-fashioned way - hard-code the library path ** ** 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"); */ }