I maintain this FAQ purely for the fun of it, and because if I didn't it wouldn't get done. If you've found it helpful, please let me know. Or better still, let my manager Kenneth.Kadonaga@Corp.Sun.COM know!
I am keen to receive any corrections, updates, suggestions, etc.
I can be contacted by email as David.Tong@sun.com
or by post at
UMTV16-218, 901 San Antonio Road Palo Alto, California 94303
To use, simply set the LD_PRELOAD environmental variable, thus:
% setenv LD_PRELOAD /(mydir)/libnoflash.so.1and the library will be picked up automagically.
NB: If you are using Java applications this library can cause Java to crash with a segmentation violation. This is related to bug 4028760, but fortunately there's a simple work-around; it does not crash if you also preload the Motif library, thus:
% setenv LD_PRELOAD "/(mydir)/libnoflash.so.1 /usr/dt/lib/libXm.so.3"
Note for Sun Internal users: You will have to register one of the mirror sites.
I do try to maintain the accuracy of the information; your assistance is appreciated. No responsibility is taken for any inaccuracies.
2. How can I tell how many colours are allocated?
3. How do I stop the colours flashing as I move the cursor around?
4. Can I protect any of the colours against flashing?
5. Why do I get white or coloured text when I exit OpenWindows?
6. How does XView handle colour?
7. My canvas requires a lot of colours. How can I reduce flashing?
8. Can I guarantee the pixel values of any colours, e.g. Black and White?
9. Can I share colormaps across different frame buffers?
10. Lines drawn using logical operations appear in odd colours.
11. How does Display PostScript handle colour?
12. Where is clear_colormap for Solaris 2.3?
13. Why do Imagetool and Pageview flash?
14. How does NeWS handle colour?
15. Does the X server support the Standard colormaps?
16. How does Wabi access the colormap?
17. How do I find out what visuals are available?
18. How does CDE handle colour?
19. How can I reduce colormap flashing with Netscape?
20. How do PC based X servers handle colours?
Is there anything else I should look at?
B. Allocating and using the RGB_BEST_MAP standard colormap
If an application attempts to allocate a new colour and there is no space in the colormap, it will get an error returned from the server. At this point the application has two alternatives: to accept the limitation and use only those colours which are already defined, or to create a new colormap for its sole use.
Assuming that the latter approach is taken, whenever the user moves the mouse cursor over the application window the server will automatically switch in the custom colormap to replace the default. In doing so, the colours of various items and windows may well be affected. In some cases other windows may become illegible, due to odd combinations of foreground and background colours - making it difficult to view multiple windows simultaneously.
xcolor
which is in the OpenWindows bin directory.
When an application frees a colour, the server does not necessarily
reset that colour back to any default value; it retains its value until
over-written by another application.
When you move your cursor into the xcolor window, it will load a new colormap
which contains a band of bright colours. When you move the cursor out again,
those colours which are currently unallocated will keep the bright colour,
those which are allocated will revert to the correct colour. If you do not
want to use this function you can disable it with the option
-noinst
.Xdefaults
file.
Remember to run
xrdb -merge
or to restart OpenWindows after editing the file or the changes will not take effect.olwm
.)
olwm.ColorFocusLocked:
If True, this instructs the server to keep the current colormap locked into the
hardware, and not to change it as the mouse is moved around.
The default is False.
olwm.AutoColorFocus:
If True, this instructs the server to load the colormap for a new window into
the hardware as it is displayed, regardless of whether the mouse is over it.
The default is False.
olwm.KeyboardCommand.LockColormap:
This allows the user to change the key sequence which locks the window's
colormap into the hardware. The default is Control-L2.
olwm.KeyboardCommand.UnlockColormap:
This allows the user to change the key sequence which unlocks the colormap.
The default is Control-L4.
cmap_compact
which is automatically executed by the
script $OPENWINHOME/lib/openwin-sys
when OpenWindows is started.
This program will look for a file
.owcolors
in your home directory, and if found will load those colours at the top end
of the colormap, thus reducing the likelihood of their being over-written.
.owcolors
is a binary file, and thus is difficult for the user to edit.
It is created by calling
cmap_compact
with the argument save
- this will
store ALL the currently allocated colours in your home directory.
The best way to use this is to run
cmap_compact save
as soon as you start
OpenWindows - this will save only those colours which are used by applications
in your .openwin-init
file. (Note however that if you invoke any NeWS applications on startup, the entire NeWS cube will also be saved unless you free it first - see below).
If you want to add extra colours to the protected set (for example, the six
primary and secondary colours Red, Green, Blue, Cyan, Magenta, Yellow - this
can be very helpful if you intend to run NeWS applications) it is necessary
to first get them into the colourmap. The easiest way I have found is to
simply start additional shelltools with the appropriate colours as their
foreground or background colours
(ie shelltool -fg blue -bg yellow &
)
before calling
cmap_compact
- it's inelegant but it works.
It's worth pointing out that the .owcolors
file may not be
portable across all platforms, and that other users will most likely have
changed the colours of their background or window borders, so the file
should be treated as any other user-defined configuration file.
If XView can fit all the available colours within the default colormap it will do so, otherwise it will create a new colormap and will copy all the colours into it. Unfortunately it will copy these colours to the beginning of the colormap, which makes the effects of flashing more obvious - the colours which handle background, foreground, backdrop (ie root window) and window decoration tend to be at the start of the default colormap, since they are among the first to be allocated.
cmap_compact
you will make things worse, not better.)Under XView, the only way to do this is by bypassing the CMS and using Xlib calls to create and install a colormap. There are one or two "gotcha"s here, in particular the use of an X atom to instruct the server to load the colormap when the cursor is moved over the window.
Consequently an example demonstrating how to do this has been written and is attached ath the end of this document. (All the usual disclaimers apply)
This is a fairly drastic solution, and should only be considered in situations
where the previously mentioned solutions of setting resources or using
cmap_compact
have been rejected.
The example works by automatically installing a special colormap for the canvas paint window. This colormap is not used by the rest of the XView application, so if you wish to set colours for individual panel items, such as buttons, then you must do so by creating a CMS. This is likely to cause flashing, so you may wish to reconsider whether or not this is a good idea.
-whitepixel
and
-blackpixel
. These allow you to specify index values for black
and white (in the range 0-255).
Prior to 3.3 you could only guarantee that "black" and "white" colours
would be allocated, and that
BlackPixel
and
WhitePixel
would return the appropriate pixel values.
Depending on whether or not
cmap_compact
has been run, the default pixel values will
almost certainly be either 0 and 1 or 254 and 255,
but these values cannot be relied on.
Other colours will need to be allocated by the user.
This can cause problems if an application intends to create windows on multiple screens and wants to use the same pixel values on each. One solution would be to attempt to allocate a large number of cells on each screen, and then only to use those cells which were common to both. Another solution would be to allocate a custom colormap on each screen and then to lock it using the techniques detailed above.
xcolor
is running it will probably contain a red value.More significantly, this colour cell is either unallocated or is owned by another program - either way, its value can change at any time, causing unexpected effects to be seen.
The way around this is to ensure that the appropriate colour cell is allocated and contains the expected colour. To prevent colormap flashing it may be preferable to allocate a block of colours in the centre of the colormap, since in an 8 bit environment the negation of 127 is 128.
DPSColorCube."visualname"."depth"."color": "size"for example:
DPSColorCube.PseudoColor.8.reds: 6See Adobe's Orange Book page CLX-9 for more information.
DPS does not use a "closest match" algorithm for choosing colours as NeWS did. Instead, it uses colour halftoning to produce the best possible representation of the requested colour for a device. This is why DPS has to have a proper colour cube rather than miscellaneous colour cells.
In the simplest case, DPS uses the X Standard Colormap RGB_DEFAULT_CMAP mechanism to leave a pointer to the colour cube it creates in the default colormap. This is done "in a valiant attempt to share its colormap resources with other applications, both DPS and non-DPS". As a consequence, the colormap entries are not cleared when the client is exited.
To force the server to clear this data, enter the command
xstdcmap -delete defaultThis will delete the cube, regardless of whether any clients are using it, so this mechanism must be used with care. However, unlike NeWS applications, subsequent DPS clients will re-allocate this cube.
An advantage to using the "simple" connection which uses the default colormap, is that it will automatically be able to run in CDE's allocation of the default colormap and probably OpenStep's as well (given that it's based on DPS). This will (hopefully) be a good example of where DPS's colormap sharing scheme works to it's best advantage.
DPS must have a gray ramp, even if it is only black and white. Color, on the other hand, it considers optional. If you don't have your colour cube allocated in the same colormap as your gray ramp, it will go with the gray ramp. It uses the non-standard property "DEFAULT_GRAY" for all colormap types except GrayScale, for which it uses RGB_DEFAULT_GRAY, due to a caveat in the Xlib specification. If you need to delete the gray ramp, use the command
xprop -root -remove DEFAULT_GRAYThe same caveats apply.
Thanks to Richard.Goldstein@eng.sun.com and John.Helm@corp.sun.com for these tips.
John has written a utility called rst_dcmap which will search for and delete colormap cells that have been allocated and recorded as standard colormaps.
clear_colormap
is no longer supplied as part of OpenWindows.
Carl.Fish@west.sun.com has written a small utility,
cmap
to perform the same function.Carl has also provided a utility called cls, which will turn off the white screen on a second display when exiting OpenWindows.
By default a "small" cube is allocated, using 140 of the 256 colormap entries.
If the user is concerned primarily with NeWS applications it is possible to
allocate a large colour cube, which will take up 240 of the 256 colours.
This is done by invoking the xnews server or openwin with the option
-cubesize large
.
This will improve the rendering of NeWS images, but will greatly increase
the likelihood of colormap flashing. For further details see the manual
page for
xnews
.
Once allocated, the NeWS colour cube can be freed using the following script (taken from the text of bug ID 1101904):
#!/bin/sh psh << '%EOF' /NeWS 3 0 findpackage beginpackage framebuffer /Colormap get freecube %EOF(Note: This script will not work if openwin/xnews was started with the
-favorstatic
option.)However, once freed it will NOT be re-allocated. The "closest match" algorithm doesn't seem to be too smart, and many NeWS programs will suffer as a result. In particular, CG3270 and Frame Maker are adversely affected. CG3270 may display in barely readable characters, while Frame Maker may exhibit corruption of the Frame logo, the buttons and the grid among others.
This may also be evident if there is not sufficient space in the default colormap to allocate the NeWS cube. NeWS applications will not create a custom colormap, and therefore will not in themselves exhibit colormap flashing.
You can alleviate this problem by using
cmap_compact
described above.
(If you intend to run CG3270, you are advised to save the 6 Primary and
Secondary colours, otherwise the display will be poor.)
By default, neither xnews nor Xsun allocate any of these colormaps, however the user may create his/her own and associate them with these defined atoms. There are a couple of tricks to doing this, so an example routine is given at the end of this document.
Unfortunately, when XAllocColor returns saying that it could not allocate the colour, rather than accept this "close match" practically every application ever written goes away and allocates a private colormap. Few of them use the techniques outlined in this document, so the net result is that colormap flashing is exacerbated rather than reduced! The solution therefore is to start Wabi after all other colormap intensive programs have been started (particularly SunPC, and DPS or NeWS applications)
Newer releases of Wabi (1.1 and later) use a much better technique. They still allocate the entire colormap as far as they can, but they then create a private colormap, copy in the default colormap, and finally free a percentage of the colours in the default colormap. This value defaults to 50% but is user configurable from 0% (ie the current situation) to 100% (freeing all colours).
Programatically, if you are not concerned about the visual, you can use
the DefaultVisual macro - this value is dependent on the frame buffer and
any options that the user gave when starting the
Xsun
or
xnews
server. If you want a particular depth or visual which may not be the default
but is supported by the frame buffer, you should use the command
XMatchVisualInfo
.
The command
xdpyinfo
will list all the visual types and depths that the current display
device supports. This is dependent on the frame buffer available.
The GX series frame buffers support PseudoColor, DirectColor, StaticColor, TrueColor, StaticGray and GrayScale visuals with a depth of 8 bits. 24 bit frame buffers, such as the ZX and SX, support 24 bit TrueColor visuals. Under Solaris 2.4, the ZX and A24 frame buffers also support 24 bit DirectColor visuals.
For more information on frame buffers, see the Frame Buffer FAQ. For more information on why software should choose its visual rather than accept the default, see the Multimedia Ambassadors OpenWindows page.
I'm still looking for a new copy of the CDE FAQ.
openwin -dev /dev/fb defclass StaticColoryou can then instruct Netscape to use the StaticColor visual (by default it will still try to use PseudoColor) with the command
netscape -visual 0x25Alternatively, you can ask Netscape to use fewer colours initially, with the command
netscape -ncols number_of_colours
PC based X servers usually use the MS Windows palette to handle colours. As far as I know this is how all the servers I have heard of work: eXceed, Xoftware, XVision, PCXware and EXTRA! X. This imposes some restrictions on what can be done with colormaps on such servers; in particular it is not possible to overwrite cells 0 and 255 which Windows reserves for black and white respectively.
Because some applications require to have the ability to write over these reserved cells, some servers actually pretend to the application that the write is successful while in reality no colour changes occur. As far as I know this is e.g. what the eXceed server does and also XVision (which has an explicit configuration option to enable this feature - I am currently in the process of getting more information on this).
Related to this is the so-called "white pixel option" which some servers posses and which defines black and white at positions 0 and 1 in the colormap. At present I am aware of only one server which provides this feature explicitly as a configuration option: Xoftware. The configuration option is called: "Change White Value". When selected, it reserves pixel position 1 for white (black is already at 0 as Windows default). It should be noted that the following help text associated with this option in Xoftware is incorrect and confusing:
I am not really certain why the white pixel option is provided, other than either:
reservecolors
and
xstdcmap
-
these are used to allocate entries
in the default colormap which are not freed when the program exits.There is also an additional colormap information document, written by Tony.Brooks@west.sun.com.
#include <sys/types.h> #include <xview/xview.h> #include <xview/canvas.h> #include <xview/cms.h> #include <xview/xv_xrect.h> #include <X11/Xatom.h> #define FAILED -1 #define IMAGEWIDTH 512 #define IMAGEHEIGHT 64 #define CMAPSIZE 64 #define OFFSET 128 unsigned long *colours; u_char *malloc(); void quit(); void canvas_repaint(); Frame frame; Canvas canvas; u_char *image; u_char *cmap; XImage *ximage; Atom catom; /* * GetImage supplies two pointers, one to the image we want to display * and the other to an array of rgb values. */ u_char GetImage() { int width, height; int i, n; u_char *im; /* * Now generate an image, this entirely artificial but good enough * to demonstrate the principles involved. */ image = malloc((unsigned)(IMAGEHEIGHT * IMAGEWIDTH * sizeof(u_char))); if (image == NULL) { perror("Image data 'malloc' failed, giving up!\n"); exit(FAILED); } /* * Get some space for the colour map data. */ cmap = malloc((unsigned) ((CMAPSIZE) * 3 * sizeof(u_char))); if (cmap == NULL) { perror("Colour map data 'malloc' failed, giving up!\n"); exit(FAILED); } /* * We now have an empty array 512 * 64 * Now fill it with some image data * This will render as 64 level grey scale image * with the correct colourmap installed. */ im = image; for (height = 1; height <= IMAGEHEIGHT; height++) { for (width = 0; width < IMAGEWIDTH; width++) { *im++ = (u_char)((CMAPSIZE + OFFSET) - height); } } /* * Now generate colour map, this information would normally * be extracted from the image data. * This colour map will display the image as a 64 level grey scale, * the principles are the same for a colour image. */ n = 0; for (i = 0; i < CMAPSIZE; i++) { cmap[n++] = (CMAPSIZE - i) * 4; cmap[n++] = (CMAPSIZE - i) * 4; cmap[n++] = (CMAPSIZE - i) * 4; } } main(argc, argv) int argc; char *argv[]; { Display *display; XID win; int scrn; Colormap ycmap, xcmap; XColor xcolours[CMAPSIZE + OFFSET]; XColor xc; unsigned long pixels[CMAPSIZE + OFFSET]; int plane_masks[1]; int i, n; XSetWindowAttributes window_attr; Window pw; /* * Get image data. */ GetImage(); /* * initalize Xview, create frame and canvas. */ xv_init(XV_INIT_ARGC_PTR_ARGV, &argc, argv, NULL); frame = (Frame)xv_create(NULL, FRAME, FRAME_SHOW_HEADER, TRUE, FRAME_LABEL, argv[0], XV_HEIGHT, IMAGEHEIGHT, XV_WIDTH, IMAGEWIDTH, NULL); canvas = xv_create(frame, CANVAS, CANVAS_HEIGHT, IMAGEHEIGHT, CANVAS_WIDTH, IMAGEWIDTH, CANVAS_REPAINT_PROC, canvas_repaint, CANVAS_X_PAINT_WINDOW, TRUE, WIN_DYNAMIC_VISUAL, TRUE, NULL); /* * Get the XID's for various X objects that we need. * Most of the colour/drawing work will be done with Xlib * call rather than Xview. */ pw = (Window)xv_get(frame, XV_XID); display = (Display *)xv_get(frame, XV_DISPLAY); win = (XID)xv_get(canvas_paint_window(canvas), XV_XID); scrn = DefaultScreen(display); /* * Create an X pixmap. */ ximage = XCreateImage(display, DefaultVisual(display,scrn), 8, ZPixmap, 0, image, IMAGEWIDTH, IMAGEHEIGHT, 8, IMAGEWIDTH); /* * Create an X colour map */ xcmap = XCreateColormap(display, win, DefaultVisual(display, scrn), AllocNone); ycmap = DefaultColormap(display, DefaultScreen(display)); for (n = 0; n < OFFSET + CMAPSIZE; n++) xcolours[n].pixel = (long) n; XQueryColors(display, ycmap, &xcolours[0], OFFSET); /* * Get colour cells */ if (!XAllocColorCells(display, xcmap, TRUE, NULL, 0, pixels, CMAPSIZE + OFFSET)) printf("Failed to allocate colour map info\n"); /* * Now we need to install the colour map values extracted from the image. * We need to translate these values into an XColor structure. */ i = 0; for (n = OFFSET; n < CMAPSIZE + OFFSET; n++) { xcolours[n].red = (u_short)(cmap[i++] << 8); xcolours[n].blue = (u_short)(cmap[i++] << 8); xcolours[n].green = (u_short)(cmap[i++] << 8); xcolours[n].flags = DoRed | DoGreen | DoBlue; } XStoreColors(display, xcmap, &xcolours[0], CMAPSIZE + OFFSET); catom = XInternAtom (display, "WM_COLORMAP_WINDOWS", False); XChangeProperty (display, xv_get(frame, XV_XID), catom, XA_WINDOW, 32, PropModeAppend, &win, 1); /* associate it with the window */ window_attr.colormap = xcmap ; XChangeWindowAttributes(display, win, CWColormap, &window_attr); xv_main_loop(frame); exit(0); } void canvas_repaint(canvas, pw, display, xid, xrects) Canvas canvas; Xv_window pw; Display *display; Window xid; Xv_xrectlist *xrects; { GC gc = DefaultGC(display, DefaultScreen(display)); XPutImage(display, xid, gc, ximage, 0, 0, 0, 0, IMAGEWIDTH, IMAGEHEIGHT); }
create_rgb_colormap() { int i, j, k, maps, base; XStandardColormap *mapinfo; XColor *exact; Pixel pix; Visual *viz; Window win; Display *display; Widget w; /* ** Check if the RGB_BEST_MAP resource has already been defined */ display = XOpenDisplay(NULL); win = RootWindow(display, 0); viz = DefaultVisual(display, 0); /* ** If XGetRGBColormaps returns non-zero then the colormap ** is returned in mapinfo->colormap. ** This can then be used as detailed in the previous example. */ if (XGetRGBColormaps(display, win, &mapinfo, &maps, XA_RGB_BEST_MAP)) { printf("XA_RGB_BEST_MAP is already defined \n"); XCloseDisplay(display); return; } /* ** Allocate the XStandardColormap structure and create the Colormap */ mapinfo = (XStandardColormap *) malloc(sizeof(XStandardColormap)); mapinfo->colormap = XCreateColormap(display, win, viz, AllocAll); /* ** The following values are specific to the user's needs */ mapinfo->red_max = 7; mapinfo->green_max = 7; mapinfo->blue_max = 3; mapinfo->red_mult = 32; mapinfo->green_mult = 4; mapinfo->blue_mult = 1; mapinfo->base_pixel = 0; /* ** These are necessary. */ mapinfo->visualid = XVisualIDFromVisual(viz); mapinfo->killid = (XID) mapinfo->colormap; /* ** Now we create the RGB colour cube. */ exact = (XColor *) calloc(sizeof(XColor), 256); base = mapinfo->base_pixel; for (i = 0; i < mapinfo->red_max + 1; i++) { for (j = 0; j < mapinfo->green_max + 1; j++) { for (k = 0; k < mapinfo->blue_max + 1; k++) { exact[base].blue = 65535 * k / mapinfo->blue_max; exact[base].green = 65535 * j/mapinfo->green_max; exact[base].red = 65535 * i / mapinfo->red_max; exact[base].flags = DoRed | DoGreen | DoBlue; exact[base].pixel = base++; } } } /* ** Transfer the RGB values to the colormap */ XStoreColors(display, mapinfo->colormap, exact, 256); /* ** Tell the server to use this colormap as the RGB BEST MAP */ XSetRGBColormaps(display, win, mapinfo, 1, XA_RGB_BEST_MAP); /* ** Mark this clients resources as permanent, then return. */ XSetCloseDownMode(display, RetainPermanent); XCloseDisplay(display); return; }To use the colormap, you will need to calculate the pixel values using a "Best Match" algorithm such as the one given below. In this example, values are in the range 0 to 1. This colour is a kind of Magenta: 90% red, 70% blue, 10% green
pix = mapinfo->base_pixel + ((unsigned long) (0.5 + 0.9 * mapinfo->red_max)) * mapinfo->red_mult + ((unsigned long) (0.5 + 0.7 * mapinfo->blue_max)) * mapinfo->blue_mult + ((unsigned long) (0.5 + 0.1 * mapinfo->green_max)) * mapinfo->green_mult;
/* ** 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 Martin - 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"); */ }
SunService TS
Created and maintained using vi.