2: /*
3: Code for managing color the X implementation of the PetscDraw routines.
5: Currently we default to using cmapping[0 to PETSC_DRAW_BASIC_COLORS-1] for the basic colors and
6: cmapping[DRAW_BASIC_COLORS to 255] for countour plots.
8: */
9: #include <../src/sys/classes/draw/impls/x/ximpl.h>
10: #include <X11/Xatom.h>
12: static const char *(colornames[PETSC_DRAW_BASIC_COLORS]) = {"white",
13: "black",
14: "red",
15: "green",
16: "cyan",
17: "blue",
18: "magenta",
19: "aquamarine",
20: "forestgreen",
21: "orange",
22: "violet",
23: "brown",
24: "pink",
25: "coral",
26: "gray",
27: "yellow",
28: "gold",
29: "lightpink",
30: "mediumturquoise",
31: "khaki",
32: "dimgray",
33: "yellowgreen",
34: "skyblue",
35: "darkgreen",
36: "navyblue",
37: "sandybrown",
38: "cadetblue",
39: "powderblue",
40: "deeppink",
41: "thistle",
42: "limegreen",
43: "lavenderblush",
44: "plum"};
46: /*
47: Sets up a color map for a display. This is shared by all the windows
48: opened on that display; this is to save time when windows are open so
49: each one does not have to create its own color map which can take 15 to 20 seconds
51: This is new code written 2/26/1999 Barry Smith,I hope it can replace
52: some older,rather confusing code.
54: The calls to XAllocNamedColor() and XAllocColor() are very slow
55: because we have to request from the X server for each
56: color. Could not figure out a way to request a large number at the
57: same time.
59: IMPORTANT: this code will fail if user opens windows on two different
60: displays: should add error checking to detect this. This is because all windows
61: share the same gColormap and gCmapping.
63: */
64: static Colormap gColormap = 0;
65: static PetscDrawXiPixVal gCmapping[256];
66: static unsigned char gCpalette[256][3];
70: PetscErrorCode PetscDrawSetUpColormap_Shared(Display *display,int screen,Visual *visual,Colormap colormap) 71: {
72: int i,k,ncolors = 256-PETSC_DRAW_BASIC_COLORS;
73: unsigned char R[256-PETSC_DRAW_BASIC_COLORS];
74: unsigned char G[256-PETSC_DRAW_BASIC_COLORS];
75: unsigned char B[256-PETSC_DRAW_BASIC_COLORS];
76: XColor colordef,ecolordef;
77: PetscBool fast = PETSC_FALSE;
81: if (colormap) gColormap = colormap;
82: else gColormap = DefaultColormap(display,screen);
85: /* set the basic colors into the color map */
86: for (i=0; i<PETSC_DRAW_BASIC_COLORS; i++) {
87: XAllocNamedColor(display,gColormap,colornames[i],&colordef,&ecolordef);
88: gCmapping[i] = colordef.pixel;
89: gCpalette[i][0] = (unsigned char)(colordef.red >> 8);
90: gCpalette[i][1] = (unsigned char)(colordef.green >> 8);
91: gCpalette[i][2] = (unsigned char)(colordef.blue >> 8);
92: }
94: /* set the contour colors into the colormap */
95: PetscOptionsGetBool(NULL,NULL,"-draw_fast",&fast,NULL);
96: PetscDrawUtilitySetCmap(NULL,ncolors,R,G,B);
97: for (i=0, k=PETSC_DRAW_BASIC_COLORS; i<ncolors; i++, k++) {
98: colordef.red = (unsigned short)(R[i] << 8);
99: colordef.green = (unsigned short)(G[i] << 8);
100: colordef.blue = (unsigned short)(B[i] << 8);
101: colordef.flags = DoRed|DoGreen|DoBlue;
102: colordef.pixel = gCmapping[PETSC_DRAW_BLACK];
103: if (!fast) XAllocColor(display,gColormap,&colordef);
104: gCmapping[k] = colordef.pixel;
105: gCpalette[k][0] = R[i];
106: gCpalette[k][1] = G[i];
107: gCpalette[k][2] = B[i];
108: }
110: PetscInfo(0,"Successfully allocated colors\n");
111: return(0);
112: }
114: /*
115: Keep a record of which pixel numbers in the cmap have been
116: used so far; this is to allow us to try to reuse as much of the current
117: colormap as possible.
118: */
119: static PetscBool cmap_pixvalues_used[256];
120: static int cmap_base = 0;
124: PetscErrorCode PetscDrawSetUpColormap_Private(Display *display,int screen,Visual *visual,Colormap colormap)125: {
126: int found,i,k,ncolors = 256-PETSC_DRAW_BASIC_COLORS;
127: unsigned char R[256-PETSC_DRAW_BASIC_COLORS];
128: unsigned char G[256-PETSC_DRAW_BASIC_COLORS];
129: unsigned char B[256-PETSC_DRAW_BASIC_COLORS];
130: Colormap defaultmap = DefaultColormap(display,screen);
131: XColor colordef;
132: PetscBool fast = PETSC_FALSE;
136: if (colormap) gColormap = colormap;
137: else gColormap = XCreateColormap(display,RootWindow(display,screen),visual,AllocAll);
139: cmap_base = 0;
141: PetscMemzero(cmap_pixvalues_used,256*sizeof(PetscBool));
143: /* set the basic colors into the color map */
144: for (i=0; i<PETSC_DRAW_BASIC_COLORS; i++) {
145: XParseColor(display,gColormap,colornames[i],&colordef);
146: /* try to allocate the color in the default-map */
147: found = XAllocColor(display,defaultmap,&colordef);
148: /* use it, if it it exists and is not already used in the new colormap */
149: if (found && colordef.pixel < 256 && !cmap_pixvalues_used[colordef.pixel]) {
150: cmap_pixvalues_used[colordef.pixel] = PETSC_TRUE;
151: /* otherwise search for the next available slot */
152: } else {
153: while (cmap_pixvalues_used[cmap_base]) cmap_base++;
154: colordef.pixel = cmap_base;
155: cmap_pixvalues_used[cmap_base++] = PETSC_TRUE;
156: }
157: XStoreColor(display,gColormap,&colordef);
158: gCmapping[i] = colordef.pixel;
159: gCpalette[i][0] = (unsigned char)(colordef.red >> 8);
160: gCpalette[i][1] = (unsigned char)(colordef.green >> 8);
161: gCpalette[i][2] = (unsigned char)(colordef.blue >> 8);
162: }
164: /* set the contour colors into the colormap */
165: PetscOptionsGetBool(NULL,NULL,"-draw_fast",&fast,NULL);
166: PetscDrawUtilitySetCmap(NULL,ncolors,R,G,B);
167: for (i=0, k=PETSC_DRAW_BASIC_COLORS; i<ncolors; i++, k++) {
168: colordef.red = (unsigned short)(R[i] << 8);
169: colordef.green = (unsigned short)(G[i] << 8);
170: colordef.blue = (unsigned short)(B[i] << 8);
171: colordef.flags = DoRed|DoGreen|DoBlue;
172: colordef.pixel = gCmapping[PETSC_DRAW_BLACK];
173: if (!fast) {
174: /* try to allocate the color in the default-map */
175: found = XAllocColor(display,defaultmap,&colordef);
176: /* use it, if it it exists and is not already used in the new colormap */
177: if (found && colordef.pixel < 256 && !cmap_pixvalues_used[colordef.pixel]) {
178: cmap_pixvalues_used[colordef.pixel] = PETSC_TRUE;
179: /* otherwise search for the next available slot */
180: } else {
181: while (cmap_pixvalues_used[cmap_base]) cmap_base++;
182: colordef.pixel = cmap_base;
183: cmap_pixvalues_used[cmap_base++] = PETSC_TRUE;
184: }
185: XStoreColor(display,gColormap,&colordef);
186: }
187: gCmapping[k] = colordef.pixel;
188: gCpalette[k][0] = R[i];
189: gCpalette[k][1] = G[i];
190: gCpalette[k][2] = B[i];
191: }
193: PetscInfo(0,"Successfully allocated colors\n");
194: return(0);
195: }
199: PetscErrorCode PetscDrawSetUpColormap_X(Display *display,int screen,Visual *visual,Colormap colormap)200: {
202: PetscBool sharedcolormap = PETSC_FALSE;
203: XVisualInfo vinfo;
206: PetscOptionsGetBool(NULL,NULL,"-draw_x_shared_colormap",&sharedcolormap,NULL);
207: /*
208: Need to determine if window supports allocating a private colormap,
209: */
210: if (XMatchVisualInfo(display,screen,24,StaticColor,&vinfo) ||
211: XMatchVisualInfo(display,screen,24,TrueColor,&vinfo) ||
212: XMatchVisualInfo(display,screen,16,StaticColor,&vinfo) ||
213: XMatchVisualInfo(display,screen,16,TrueColor,&vinfo) ||
214: XMatchVisualInfo(display,screen,15,StaticColor,&vinfo) ||
215: XMatchVisualInfo(display,screen,15,TrueColor,&vinfo)) sharedcolormap = PETSC_TRUE;
216: /*
217: Generate the X colormap object
218: */
219: if (sharedcolormap) {
220: PetscDrawSetUpColormap_Shared(display,screen,visual,colormap);
221: } else {
222: PetscDrawSetUpColormap_Private(display,screen,visual,colormap);
223: }
224: return(0);
225: }
227: PETSC_INTERN PetscErrorCode PetscDrawSetColormap_X(PetscDraw_X*,Colormap);
231: PetscErrorCode PetscDrawSetColormap_X(PetscDraw_X *XiWin,Colormap colormap)232: {
233: PetscBool fast = PETSC_FALSE;
237: PetscOptionsGetBool(NULL,NULL,"-draw_fast",&fast,NULL);
238: if (XiWin->depth < 8) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP_SYS,"PETSc Graphics require monitors with at least 8 bit color (256 colors)");
239: if (!gColormap) {
240: PetscDrawSetUpColormap_X(XiWin->disp,XiWin->screen,XiWin->vis,colormap);
241: }
242: XiWin->cmap = gColormap;
243: XiWin->cmapsize = fast ? PETSC_DRAW_BASIC_COLORS : 256;
244: PetscMemcpy(XiWin->cmapping,gCmapping,sizeof(XiWin->cmapping));
245: PetscMemcpy(XiWin->cpalette,gCpalette,sizeof(XiWin->cpalette));
246: XiWin->background = XiWin->cmapping[PETSC_DRAW_WHITE];
247: XiWin->foreground = XiWin->cmapping[PETSC_DRAW_BLACK];
248: return(0);
249: }
253: PetscErrorCode PetscDrawXiColormap(PetscDraw_X *XiWin)254: { return PetscDrawSetColormap_X(XiWin,(Colormap)0); }
256: /*
257: Color in X is many-layered. The first layer is the "visual",a
258: immutable attribute of a window set when the window is
259: created.
261: The next layer is the colormap. The installation of colormaps is
262: the buisness of the window manager (in some distant later release).
263: */
265: /*
266: This routine gets the visual class (PseudoColor, etc) and returns
267: it. It finds the default visual. Possible returns are
268: PseudoColor
269: StaticColor
270: DirectColor
271: TrueColor
272: GrayScale
273: StaticGray
274: */
277: PetscErrorCode PetscDrawXiSetVisualClass(PetscDraw_X *XiWin)278: {
279: XVisualInfo vinfo;
282: if (XMatchVisualInfo(XiWin->disp,XiWin->screen,24,DirectColor,&vinfo)) {
283: XiWin->vis = vinfo.visual;
284: } else if (XMatchVisualInfo(XiWin->disp,XiWin->screen,8,PseudoColor,&vinfo)) {
285: XiWin->vis = vinfo.visual;
286: } else if (XMatchVisualInfo(XiWin->disp,XiWin->screen,DefaultDepth(XiWin->disp,XiWin->screen),PseudoColor,&vinfo)) {
287: XiWin->vis = vinfo.visual;
288: } else {
289: XiWin->vis = DefaultVisual(XiWin->disp,XiWin->screen);
290: }
291: return(0);
292: }
296: PetscErrorCode PetscDrawXiSetColormap(PetscDraw_X *XiWin)297: {
299: XSetWindowColormap(XiWin->disp,XiWin->win,XiWin->cmap);
300: return(0);
301: }
303: /*
304: Get RGB color entries out of the X colormap
305: */
308: PetscErrorCode PetscDrawXiGetPalette(PetscDraw_X *XiWin,unsigned char palette[256][3])
309: {
310: int k;
311: XColor colordef[256];
314: for (k=0; k<256; k++) {
315: colordef[k].pixel = XiWin->cmapping[k];
316: colordef[k].flags = DoRed|DoGreen|DoBlue;
317: }
318: XQueryColors(XiWin->disp,XiWin->cmap,colordef,256);
319: for (k=0; k<256; k++) {
320: palette[k][0] = (unsigned char)(colordef[k].red >> 8);
321: palette[k][1] = (unsigned char)(colordef[k].green >> 8);
322: palette[k][2] = (unsigned char)(colordef[k].blue >> 8);
323: }
324: return(0);
325: }