As well as grabbing the keyboard and mouse you can also hog resources.
This behaviour is most graphically displayed when clients create
colormaps
of their own. When the pointer goes into their window,
their colormap gets swopped in and the windows of other clients suddenly
have their colormap taken from under their feet, resulting in false
colors. If you do have to make your own colormap and manipulate it,
use
Colormap XCreateColormap(display,w,visual,alloc) Visual *visual; /* GrayScale, Pseudocolor etc */ int alloc; /* AllocAll or AllocNone. If visual is StaticGray or TrueColor then pick AllocNone, meaning none of colormap cells are writeable*/ Colormap XCopyColormapAndFree(display,cmap) /* This moves all of the client's existing allocations to a new colormap and frees the old ones. This is useful when the old colormap gets filled up*/ XFreeColormap(display,cmap) XSetWindowColormap(display,w,cmap)
Figure 3: Colors and bit planes
Read/Write Color Cells
- Using read/write colour cells is more involved than
the read-only cells in the earlier chapter. Allocating colorcells and Storing
colors in them involve separate commands.
N colors and planes can be allocated simultaneously. The idea is that
Status XAllocColorCells(display,cmap,contig,plane_masks,nplanes,pixels,ncolors); Bool contig; /* True if planes must be contiguous, else False */ unsigned long plane_masks[nplanes]; /*RETURN*/ unsigned int nplanes; /*supplies number of planes ( >=0 )*/ unsigned long pixels[ncolors]; /*RETURN*/ unsigned int ncolors; /*supplies number of colors ( >0 ) */allocates a number of pixel values to an client program. If nplanes is zero then the pixel array returned will contain the pixel values. Otherwise you will need to
OR
each element in the masks array with each element in the
pixels array to get all the pixel values.
No mask will have any bits in common with other masks or pixel values.
If you ask for 3 pixel values and 3 bits in the plane mask,
your bit plane
mask would be 7 containing the bits 1, 2 and 4 and you would be allocated
the pixel values 8, 16 and 24.
Thus from the pixel value 8 the values from 8 to 15
can be derived by ORing in one or more of these bits. Similarly 16 gives
(16 - 23) and 24 gives (24 - 31). Thus we have in fact been allocated
all the pixel values from 8 to 31 inclusive.
By ORing together masks and pixels, distinct pixels can be produced, all of which are writeable.
For GrayScale
or PseudoColor
each mask will have exactly 1 bit; for
DirectColor
each mask will have 3 bits.
The cells you allocate have no defined colors until
set with XLookupColor
then XStoreColor(s)
or
XStoreNamedColor
.
If no pixels are asked for then as many bit planes as possible are allocated. Such a request can succeed only once. See the example program at the end of this section for further clarification of read/write colour cells.
If you want to vary the number of bits that correspond to each primary color, use
Status XAllocColorPlanes(display,cmap,contig,pixels,ncolors, nreds,ngreens,nblues,rmask,gmask,bmask) Bool contig; /* True if planes must be contiguous, else False */ unsigned long pixels[nplanes]; /*RETURN*/ int ncolors; /* specifies number of colors needed ( >0 ) */ int nreds, ngreens, nblues; /* specifies the number of shades you want */ unsigned long *rmask, *gmask, *bmask; /*RETURN bit masks for planes*/No mask will have any bits in common with other masks. By ORing together masks and pixels, distinct pixels can be produced, but in the colormap there are only red entries, green entries and blues entries. To set colors, use
XStoreColor(display,cmap,screen_def) XColor *screen_def; XStoreColors(display,cmap,defs,ncolors) XColor defs[ncolors]; XStoreNamedColor(display,cmap,color,pixel,flags); char *color; int flags; /* DoRed, DoGreen,DoBlue */To free color cells or planes use
XFreeColors(display,cmap,pixels,npixels,planes); unsigned long pixels[npixels]; /* pixels you want to free */ unsigned long planes; /* planes you want to free */This is an example of using read/write colour cells. It is rather long winded in order to illustrate the way in which the pixel values are allocated. It eventually ends up with 24 different colours which it draws in a technicolor stripe across the screen and prints some detail of the pixels is has been given as it goes along.
#include <X11/cursorfont.h> #include <stdio.h> #include <X11/X.h> #include <X11/Xlib.h> #include <X11/Xutil.h> #define TRUE 1 #define FALSE 0 #define PLANELIM 65536 #define NUMPLANES 3 /* number of bit planes asked for */ #define NUMCOLS 3 /* number of colours asked for */ #define PLNUM (1 << NUMPLANES) /* pixel value factor from planes */ #define PIXNUM NUMCOLS * PLNUM /* total pixel values obtained */ main (argc, argv) char *argv[]; int argc; { XColor color_cell[PIXNUM]; /* must have room for pixnum */ XSetWindowAttributes attributes; int Red = 60000; int Green = 40000; int Blue = 20000; int i,j; int mask; Visual *visual; int depth; int which_color,which_cell,which_plane; Display *display; Visual *v; Window win; GC gc; Colormap cmap; XEvent event; int stat; long plane_masks[NUMPLANES]; long pixar[NUMCOLS]; char str0[50],str1[50],str2[50],str3[50], str4[50]; int ret; setbuf (stdout, NULL); setbuf (stderr, NULL); display = XOpenDisplay(NULL); visual = DefaultVisual(display,0); depth = DefaultDepth(display,0); attributes.background_pixel = XWhitePixel(display,0); attributes.border_pixel = XBlackPixel(display,0); attributes.override_redirect = 0; win = XCreateWindow(display,XRootWindow(display,0),0,0,507,426,5, depth, InputOutput,visual ,CWBackPixel+CWBorderPixel+CWOverrideRedirect, &attributes); XSelectInput(display,win,ExposureMask + ButtonPressMask+ KeyPressMask) ; gc=XCreateGC(display,win,NULL,NULL); XMapWindow(display,win); cmap= XDefaultColormap(display,0); stat = XAllocColorCells(display,cmap,FALSE,plane_masks, NUMPLANES, pixar, NUMCOLS); /* claim some colorcells */ do{ XNextEvent(display,&event); switch(event.type){ case Expose: sprintf(str0,"depth is = %d", depth); sprintf(str1,"there are %d colorcells", DisplayCells(display,0)); switch(XDoesBackingStore(display)){ case WhenMapped : sprintf(str2,"when mapped"); break; case NotUseful : sprintf(str2,"not useful"); break; case Always : sprintf(str2,"always"); break; default : sprintf (str2,"error in DoesBackingStore"); } XDrawImageString(display,win,gc,20,15,str0,strlen(str0)); XDrawImageString(display,win,gc,20,30,str1,strlen(str1)); XDrawImageString(display,win,gc,20,45,str2,strlen(str2)); sprintf(str2,"planes = %d, %d, %d", plane_masks[0], plane_masks[1],plane_masks[2]); sprintf(str3,"pixels = %d, %d, %d.", pixar[0], pixar[1], pixar[2]); XDrawImageString(display,win,gc,20,60,str2,strlen(str2)); XDrawImageString(display,win,gc,20,75,str3,strlen(str3)); v=DefaultVisual(display,0); switch(v->class){ case StaticGray:sprintf(str0,"static gray"); break; case GrayScale:sprintf(str0," gray scale"); break; case StaticColor:sprintf(str0,"static color"); break; case PseudoColor:sprintf(str0,"pseudocolor"); break; case TrueColor:sprintf(str0,"true color"); break; case DirectColor:sprintf(str0,"direct color"); break; } XDrawImageString(display,win,gc,250,20,str0,strlen(str0)); XDrawImageString(display,win,gc,400,30,"pix vals used",13); for(which_color = 0, which_cell = 0; which_color < NUMCOLS; which_color++){ color_cell[ which_cell++].pixel = pixar[which_color]; for(which_plane = 0; which_plane < PLNUM; which_plane++){ /* permute the bits to generate all the */ mask = 0; /* possible pixel values */ for(i = 1, j = 0; i < PLNUM; i <<= 1, j++) if(i & which_plane) mask |= plane_masks[j]; color_cell[ which_cell++].pixel = pixar[which_color] | mask; sprintf(str1," %d",(pixar[which_color] | mask)); XDrawImageString(display,win,gc,430,30+12*which_cell, str1,strlen(str1)); } } for(i = 0; i < PIXNUM; i++){ /* generate some arbitrary colours */ color_cell[i].flags= DoRed | DoGreen | DoBlue; color_cell[i].red = Red; color_cell[i].green = Green; color_cell[i].blue = Blue; Red = ((Red + 3000) % 65536); Green = ((Green + 3000) % 65536); Blue = ((Blue + 3000) % 65536); } XStoreColors(display,cmap, color_cell,PIXNUM); for(i = 0; i < PIXNUM; i++){ /* draw a multi-coloured stripe */ XSetForeground(display,gc, color_cell[i].pixel); XFillRectangle(display,win,gc,10 * i, 100, 10, 200); } XFlush(display); printf("now press button: \n"); break; case ButtonPress: printf("closing display\n"); XCloseDisplay(display); exit(0); } }while(1); }
XAllocColorCells
allows you to do quick overlays. By drawing into one plane,
you can change the displayed output without affecting the other planes and
restore the original quickly.