1 /***********************************************************************/
2 /* Open Visualization Data Explorer */
3 /* (C) Copyright IBM Corp. 1989,1999 */
4 /* ALL RIGHTS RESERVED */
5 /* This code licensed under the */
6 /* "IBM PUBLIC LICENSE - Open Visualization Data Explorer" */
7 /***********************************************************************/
8 /*********************************************************************/
9 /* I.B.M. CONFIENTIAL */
10 /*********************************************************************/
11
12 #include <dxconfig.h>
13
14
15 /******************************************************************************
16 * These functions were provided by HP with /usr/lib/starbase/demos/SBUTILS
17 *
18 * This file contains a set of example utility procedures; procedures that can
19 * help a "window-smart" Starbase or PHIGS program determine information about
20 * a device, and create image and overlay plane windows. To use these
21 * utilities, #include "wsutils.h" and compile this file and link the results
22 * with your program.
23 *
24 ******************************************************************************/
25 /*
26 $Header: /src/master/dx/src/exec/hwrender/starbase/wsutils.c,v 1.3 1999/05/10 15:45:39 gda Exp $
27 */
28
29 #include <X11/X.h>
30 #include <X11/Xlib.h>
31 #include <X11/Xutil.h>
32 #include <X11/XHPlib.h>
33 #include <stdio.h>
34 #include "hwDeclarations.h"
35 #include "wsutils.h"
36 #include "hwInteractor.h"
37
38 #ifndef STANDALONE
39 #include "hwMemory.h"
40 #endif
41
42 #include "hwPortLayer.h"
43
44 #include "hwDebug.h"
45
46 #define STATIC_GRAY 0x01
47 #define GRAY_SCALE 0x02
48 #define PSEUDO_COLOR 0x04
49 #define TRUE_COLOR 0x10
50 #define DIRECT_COLOR 0x11
51
52 /******************************************************************************
53 *
54 * GetXVisualInfo()
55 *
56 * This routine takes an X11 Display, screen number, and returns whether the
57 * screen supports transparent overlays and three arrays:
58 *
59 * 1) All of the XVisualInfo struct's for the screen.
60 * 2) All of the OverlayInfo struct's for the screen.
61 * 3) An array of pointers to the screen's image plane XVisualInfo
62 * structs.
63 *
64 * The code below obtains the array of all the screen's visuals, and obtains
65 * the array of all the screen's overlay visual information. It then processes
66 * the array of the screen's visuals, determining whether the visual is an
67 * overlay or image visual.
68 *
69 * If the routine sucessfully obtained the visual information, it returns zero.
70 * If the routine didn't obtain the visual information, it returns non-zero.
71 *
72 ******************************************************************************/
73
GetXVisualInfo(Display * display,int screen,int * transparentOverlays,int * numVisuals,XVisualInfo ** pVisuals,int * numOverlayVisuals,OverlayInfo ** pOverlayVisuals,int * numImageVisuals,XVisualInfo *** pImageVisuals)74 int GetXVisualInfo(Display *display, int screen,
75 int *transparentOverlays, int *numVisuals, XVisualInfo **pVisuals,
76 int *numOverlayVisuals, OverlayInfo **pOverlayVisuals,
77 int *numImageVisuals, XVisualInfo ***pImageVisuals)
78
79 {
80 XVisualInfo getVisInfo; /* Paramters of XGetVisualInfo */
81 int mask;
82 XVisualInfo *pVis, **pIVis; /* Faster, local copies */
83 OverlayInfo *pOVis;
84 OverlayVisualPropertyRec *pOOldVis;
85 int nVisuals, nOVisuals, nIVisuals;
86 Atom overlayVisualsAtom; /* Parameters for XGetWindowProperty */
87 Atom actualType;
88 unsigned long numLongs, bytesAfter;
89 int actualFormat;
90 int nImageVisualsAlloced; /* Values to process the XVisualInfo */
91 int imageVisual; /* array */
92
93
94 ENTRY(("GetXVisualInfo(0x%x, %d, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x)",
95 display, screen, transparentOverlays, numVisuals, pVisuals,
96 numOverlayVisuals, pOverlayVisuals, numImageVisuals, pImageVisuals));
97
98 /* First, get the list of visuals for this screen. */
99 getVisInfo.screen = screen;
100 mask = VisualScreenMask;
101
102 *pVisuals = XGetVisualInfo(display, mask, &getVisInfo, numVisuals);
103 if ((nVisuals = *numVisuals) <= 0)
104 {
105 /* Return that the information wasn't sucessfully obtained: */
106 EXIT(("1"));
107 return(1);
108 }
109 pVis = *pVisuals;
110
111
112 /* Now, get the overlay visual information for this screen. To obtain
113 * this information, get the SERVER_OVERLAY_VISUALS property.
114 */
115 overlayVisualsAtom = XInternAtom(display, "SERVER_OVERLAY_VISUALS", True);
116 if (overlayVisualsAtom != None)
117 {
118 /* Since the Atom exists, we can request the property's contents. The
119 * do-while loop makes sure we get the entire list from the X server.
120 */
121 bytesAfter = 0;
122 numLongs = sizeof(OverlayVisualPropertyRec) / 4;
123 do
124 {
125 numLongs += bytesAfter * 4;
126 XGetWindowProperty(display, RootWindow(display, screen),
127 overlayVisualsAtom, 0, numLongs, False,
128 overlayVisualsAtom, &actualType, &actualFormat,
129 &numLongs, &bytesAfter, (unsigned char **)pOverlayVisuals);
130 } while (bytesAfter > 0);
131
132
133 /* Calculate the number of overlay visuals in the list. */
134 *numOverlayVisuals = numLongs / (sizeof(OverlayVisualPropertyRec) / 4);
135 }
136 else
137 {
138 /* This screen doesn't have overlay planes. */
139 *numOverlayVisuals = 0;
140 *pOverlayVisuals = NULL;
141 *transparentOverlays = 0;
142 }
143
144
145 /* Process the pVisuals array. */
146 *numImageVisuals = 0;
147 nImageVisualsAlloced = 1;
148 pIVis = *pImageVisuals = (XVisualInfo **) tdmAllocateLocal(4);
149
150 while (--nVisuals >= 0)
151 {
152 nOVisuals = *numOverlayVisuals;
153 pOVis = *pOverlayVisuals;
154 imageVisual = True;
155 while (--nOVisuals >= 0)
156 {
157 pOOldVis = (OverlayVisualPropertyRec *) pOVis;
158 if (pVis->visualid == pOOldVis->visualID)
159 {
160 imageVisual = False;
161 pOVis->pOverlayVisualInfo = pVis;
162 if (pOVis->transparentType == TransparentPixel)
163 *transparentOverlays = 1;
164 }
165 pOVis++;
166 }
167 if (imageVisual)
168 {
169 if ((*numImageVisuals += 1) > nImageVisualsAlloced)
170 {
171 nImageVisualsAlloced++ ;
172 *pImageVisuals = (XVisualInfo **)
173 tdmReAllocate(*pImageVisuals, nImageVisualsAlloced * 4) ;
174 pIVis = *pImageVisuals + (*numImageVisuals - 1) ;
175 }
176 *pIVis++ = pVis;
177 }
178 pVis++;
179 }
180
181
182 /* Return that the information was sucessfully obtained: */
183 EXIT(("0"));
184 return(0);
185 } /* GetXVisualInfo() */
186
187 /******************************************************************************
188 *
189 * FindImagePlanesVisual()
190 *
191 * This routine attempts to find a visual to use to create an image planes
192 * window based upon the information passed in.
193 *
194 * The "Hint" values give guides to the routine as to what the program wants.
195 * The "depthFlexibility" value tells the routine how much the program wants
196 * the actual "depthHint" specified. If the program can't live with the
197 * screen's image planes visuals, the routine returns non-zero, and the
198 * "depthObtained" and "pImageVisualToUse" return parameters are NOT valid.
199 * Otherwise, the "depthObtained" and "pImageVisualToUse" return parameters
200 * are valid and the routine returns zero.
201 *
202 * NOTE: This is just an example of what can be done. It may or may not be
203 * useful for any specific application.
204 *
205 ******************************************************************************/
206
FindImagePlanesVisual(Display * display,int screen,int numImageVisuals,XVisualInfo ** pImageVisuals,int sbCmapHint,int depthHint,int depthFlexibility,Visual ** pImageVisualToUse,int * depthObtained)207 int FindImagePlanesVisual(Display *display, int screen, int numImageVisuals,
208 XVisualInfo **pImageVisuals, int sbCmapHint, int depthHint,
209 int depthFlexibility, Visual **pImageVisualToUse, int *depthObtained)
210 {
211 XVisualInfo *pVisualInfoToUse; /* The current best visual to use. */
212 int i;
213 int visMask;
214 int curDelta, newDelta;
215
216 ENTRY(("FindImagePlanesVisual(0x%x, %d, %d, 0x%x, %d, %d, %d, 0x%x, 0x%x)",
217 display, screen, numImageVisuals, pImageVisuals, sbCmapHint,
218 depthHint, depthFlexibility, pImageVisualToUse, depthObtained));
219
220 switch (sbCmapHint)
221 {
222 case SB_CMAP_TYPE_NORMAL:
223 case SB_CMAP_TYPE_NORMAL | SB_CMAP_TYPE_MONOTONIC:
224 case SB_CMAP_TYPE_NORMAL | SB_CMAP_TYPE_MONOTONIC | SB_CMAP_TYPE_FULL:
225 case SB_CMAP_TYPE_NORMAL | SB_CMAP_TYPE_FULL:
226 visMask = GRAY_SCALE | PSEUDO_COLOR;
227 break;
228 case SB_CMAP_TYPE_MONOTONIC:
229 visMask = STATIC_GRAY | GRAY_SCALE | PSEUDO_COLOR;
230 break;
231 case SB_CMAP_TYPE_MONOTONIC | SB_CMAP_TYPE_FULL:
232 visMask = GRAY_SCALE | PSEUDO_COLOR;
233 break;
234 case SB_CMAP_TYPE_FULL:
235 visMask = GRAY_SCALE | PSEUDO_COLOR | TRUE_COLOR | DIRECT_COLOR;
236 break;
237 default:
238 /* The caller didn't specify a valid combination of CMAP_ type: */
239 EXIT(("1"));
240 return(1);
241 } /* switch (sbCmapHint) */
242
243
244 pVisualInfoToUse = NULL;
245
246 for (i = 0 ; i < numImageVisuals ; i++)
247 {
248 switch (pImageVisuals[i]->class)
249 {
250 case StaticGray:
251 if (visMask & STATIC_GRAY)
252 {
253 if (pVisualInfoToUse == NULL)
254 {
255 if ((pImageVisuals[i]->depth == depthHint) ||
256 depthFlexibility)
257 {
258 pVisualInfoToUse = pImageVisuals[i];
259 }
260 }
261 else
262 {
263 if (pImageVisuals[i]->depth == depthHint)
264 pVisualInfoToUse = pImageVisuals[i];
265 else if (depthFlexibility)
266 {
267 /* The basic hueristic used is to find the closest
268 * depth to "depthHint" that's also greater than
269 * "depthHint", or just the closest depth:
270 */
271 if ((curDelta = pVisualInfoToUse->depth -
272 depthHint) > 0)
273 {
274 /* Only choose this new visual if it's also
275 * deeper than "depthHint" and closer to
276 * "depthHint" than the currently chosen visual:
277 */
278 if (((newDelta = pImageVisuals[i]->depth -
279 depthHint) > 0) && (newDelta < curDelta))
280 {
281 pVisualInfoToUse = pImageVisuals[i];
282 }
283 }
284 else
285 {
286 /* Choose this new visual if it's deeper than
287 * "depthHint" or closer to "depthHint" than
288 * the currently chosen visual:
289 */
290 if (((newDelta = pImageVisuals[i]->depth -
291 depthHint) > 0) ||
292 (-newDelta < -curDelta))
293 {
294 pVisualInfoToUse = pImageVisuals[i];
295 }
296 }
297 }
298 }
299 }
300 break;
301 case GrayScale:
302 if (visMask & GRAY_SCALE)
303 {
304 if (pVisualInfoToUse == NULL)
305 {
306 if ((pImageVisuals[i]->depth == depthHint) ||
307 depthFlexibility)
308 {
309 pVisualInfoToUse = pImageVisuals[i];
310 }
311 }
312 else if (!((sbCmapHint & SB_CMAP_TYPE_FULL) &&
313 (pVisualInfoToUse->class == DirectColor)))
314 {
315 if (pImageVisuals[i]->depth == depthHint)
316 pVisualInfoToUse = pImageVisuals[i];
317 else if (depthFlexibility)
318 {
319 /* The basic hueristic used is to find the closest
320 * depth to "depthHint" that's also greater than
321 * "depthHint", or just the closest depth:
322 */
323 if ((curDelta = pVisualInfoToUse->depth -
324 depthHint) > 0)
325 {
326 /* Only choose this new visual if it's also
327 * deeper than "depthHint" and closer to
328 * "depthHint" than the currently chosen visual:
329 */
330 if (((newDelta = pImageVisuals[i]->depth -
331 depthHint) > 0) && (newDelta < curDelta))
332 {
333 pVisualInfoToUse = pImageVisuals[i];
334 }
335 }
336 else
337 {
338 /* Choose this new visual if it's deeper than
339 * "depthHint" or closer to "depthHint" than
340 * the currently chosen visual:
341 */
342 if (((newDelta = pImageVisuals[i]->depth -
343 depthHint) > 0) ||
344 (-newDelta < -curDelta))
345 {
346 pVisualInfoToUse = pImageVisuals[i];
347 }
348 }
349 }
350 }
351 }
352 break;
353 case PseudoColor:
354 if (visMask & PSEUDO_COLOR)
355 {
356 if (pVisualInfoToUse == NULL)
357 {
358 if ((pImageVisuals[i]->depth == depthHint) ||
359 depthFlexibility)
360 {
361 pVisualInfoToUse = pImageVisuals[i];
362 }
363 }
364 else if (!((sbCmapHint & SB_CMAP_TYPE_FULL) &&
365 (pVisualInfoToUse->class == DirectColor)))
366 {
367 if (pImageVisuals[i]->depth == depthHint)
368 pVisualInfoToUse = pImageVisuals[i];
369 else if (depthFlexibility)
370 {
371 /* The basic hueristic used is to find the closest
372 * depth to "depthHint" that's also greater than
373 * "depthHint", or just the closest depth:
374 */
375 if ((curDelta = pVisualInfoToUse->depth -
376 depthHint) > 0)
377 {
378 /* Only choose this new visual if it's also
379 * deeper than "depthHint" and closer to
380 * "depthHint" than the currently chosen visual:
381 */
382 if (((newDelta = pImageVisuals[i]->depth -
383 depthHint) > 0) && (newDelta < curDelta))
384 {
385 pVisualInfoToUse = pImageVisuals[i];
386 }
387 }
388 else
389 {
390 /* Choose this new visual if it's deeper than
391 * "depthHint" or closer to "depthHint" than
392 * the currently chosen visual:
393 */
394 if (((newDelta = pImageVisuals[i]->depth -
395 depthHint) > 0) ||
396 (-newDelta < -curDelta))
397 {
398 pVisualInfoToUse = pImageVisuals[i];
399 }
400 }
401 }
402 }
403 }
404 break;
405 case StaticColor:
406 /* Starbase doesn't work well with StaticColor visuals: */
407 break;
408 case TrueColor:
409 if (visMask & TRUE_COLOR)
410 {
411 /* The only Starbase cmap type that TrueColor works with
412 * is SB_CMAP_TYPE_FULL, so we know that SB_CMAP_TYPE_FULL
413 * is what the program wants:
414 */
415 if (pVisualInfoToUse == NULL)
416 {
417 if ((pImageVisuals[i]->depth == depthHint) ||
418 depthFlexibility)
419 {
420 pVisualInfoToUse = pImageVisuals[i];
421 }
422 }
423 /* This example code prefers DirectColor to TrueColor: */
424 else if (pVisualInfoToUse->class != DirectColor)
425 {
426 if (pImageVisuals[i]->depth == depthHint)
427 pVisualInfoToUse = pImageVisuals[i];
428 else if (depthFlexibility)
429 {
430 /* The basic hueristic used is to find the closest
431 * depth to "depthHint" that's also greater than
432 * "depthHint", or just the closest depth:
433 */
434 if ((curDelta = pVisualInfoToUse->depth -
435 depthHint) > 0)
436 {
437 /* Only choose this new visual if it's also
438 * deeper than "depthHint" and closer to
439 * "depthHint" than the currently chosen visual:
440 */
441 if (((newDelta = pImageVisuals[i]->depth -
442 depthHint) > 0) && (newDelta < curDelta))
443 {
444 pVisualInfoToUse = pImageVisuals[i];
445 }
446 }
447 else
448 {
449 /* Choose this new visual if it's deeper than
450 * "depthHint" or closer to "depthHint" than
451 * the currently chosen visual:
452 */
453 if (((newDelta = pImageVisuals[i]->depth -
454 depthHint) > 0) ||
455 (-newDelta < -curDelta))
456 {
457 pVisualInfoToUse = pImageVisuals[i];
458 }
459 }
460 }
461 }
462 }
463 break;
464 case DirectColor:
465 if (visMask & DIRECT_COLOR)
466 {
467 if (pVisualInfoToUse == NULL)
468 {
469 if ((pImageVisuals[i]->depth == depthHint) ||
470 depthFlexibility)
471 {
472 pVisualInfoToUse = pImageVisuals[i];
473 }
474 }
475 else
476 {
477 if (pImageVisuals[i]->depth == depthHint)
478 pVisualInfoToUse = pImageVisuals[i];
479 else if (depthFlexibility)
480 {
481 /* The basic hueristic used is to find the closest
482 * depth to "depthHint" that's also greater than
483 * "depthHint", or just the closest depth:
484 */
485 if ((curDelta = pVisualInfoToUse->depth -
486 depthHint) > 0)
487 {
488 /* Only choose this new visual if it's also
489 * deeper than "depthHint" and closer to
490 * "depthHint" than the currently chosen visual:
491 */
492 if (((newDelta = pImageVisuals[i]->depth -
493 depthHint) > 0) && (newDelta < curDelta))
494 {
495 pVisualInfoToUse = pImageVisuals[i];
496 }
497 }
498 else
499 {
500 /* Choose this new visual if it's deeper than
501 * "depthHint" or closer to "depthHint" than
502 * the currently chosen visual:
503 */
504 if (((newDelta = pImageVisuals[i]->depth -
505 depthHint) > 0) ||
506 (-newDelta < -curDelta))
507 {
508 pVisualInfoToUse = pImageVisuals[i];
509 }
510 }
511 }
512 }
513 }
514 break;
515 } /* switch (pImageVisuals[i]->class) */
516 } /* for (i = 0 ; i < numImageVisuals ; i++) */
517
518
519 if (pVisualInfoToUse != NULL)
520 {
521 *pImageVisualToUse = pVisualInfoToUse->visual;
522 *depthObtained = pVisualInfoToUse->depth;
523 EXIT(("0"));
524 return(0);
525 }
526 else
527 {
528 /* Couldn't find an appropriate visual class: */
529 EXIT(("1"));
530 return(1);
531 }
532 } /* FindImagePlanesVisual() */
533
534 /******************************************************************************
535 *
536 * CreateImagePlanesWindow()
537 *
538 * This routine creates an image planes window, potentially creates a colormap
539 * for the window to use, and sets the window's standard properties, based
540 * upon the information passed in to the routine. While "created," the window
541 * has not been mapped.
542 *
543 * If the routine suceeds, it returns zero and the return parameters
544 * "imageWindow", "imageColormap" and "mustFreeImageColormap" are valid.
545 * Otherwise, the routine returns non-zero and the return parameters are
546 * NOT valid.
547 *
548 * NOTE: This is just an example of what can be done. It may or may not be
549 * useful for any specific application.
550 *
551 ******************************************************************************/
552
CreateImagePlanesWindow(Display * display,int screen,Window parentWindow,int windowX,int windowY,int windowWidth,int windowHeight,int windowDepth,Visual * pImageVisualToUse,int argc,char * argv[],char * windowName,char * iconName,Window * imageWindow,Colormap * imageColormap,int * mustFreeImageColormap)553 int CreateImagePlanesWindow(Display *display, int screen, Window parentWindow,
554 int windowX, int windowY, int windowWidth, int windowHeight,
555 int windowDepth, Visual *pImageVisualToUse,
556 int argc, char *argv[], char *windowName, char *iconName,
557 Window *imageWindow, Colormap *imageColormap,
558 int *mustFreeImageColormap)
559 {
560 XSetWindowAttributes winAttributes; /* Attributes for window creation */
561 XSizeHints hints;
562
563 ENTRY(("CreateImagePlanesWindow(0x%x, %d, 0x%x, %d, %d, %d, %d, %d,
564 0x%x, %d, 0x%x, \"%s\", \"%s\", 0x%x, 0x%x, 0x%x)",
565 display, screen, parentWindow,
566 windowX, windowY, windowWidth, windowHeight, windowDepth,
567 pImageVisualToUse, argc, argv, windowName, iconName,
568 imageWindow, imageColormap, mustFreeImageColormap));
569
570 if (pImageVisualToUse == DefaultVisual(display, screen))
571 {
572 *mustFreeImageColormap = False;
573 *imageColormap = winAttributes.colormap = DefaultColormap(display,
574 screen);
575 winAttributes.background_pixel = BlackPixel(display, screen);
576 winAttributes.border_pixel = WhitePixel(display, screen);
577 }
578 else
579 {
580 XColor actualColor, databaseColor;
581
582 *mustFreeImageColormap = True;
583 *imageColormap = winAttributes.colormap =
584 XCreateColormap(display, RootWindow(display, screen),
585 pImageVisualToUse, AllocNone);
586 XAllocNamedColor(display, winAttributes.colormap, "Black",
587 &actualColor, &databaseColor);
588 winAttributes.background_pixel = actualColor.pixel;
589 XAllocNamedColor(display, winAttributes.colormap, "White",
590 &actualColor, &databaseColor);
591 winAttributes.border_pixel = actualColor.pixel;
592 }
593 winAttributes.event_mask = ExposureMask;
594 winAttributes.backing_store = WhenMapped ;
595
596 *imageWindow = XCreateWindow(display, parentWindow,
597 0, 0, windowWidth, windowHeight, 2,
598 windowDepth, InputOutput, pImageVisualToUse,
599 (CWBackPixel | CWColormap |
600 CWBorderPixel | CWEventMask | CWBackingStore),
601 &winAttributes);
602
603 hints.flags = (USSize | USPosition);
604 hints.x = windowX;
605 hints.y = windowY;
606 hints.width = windowWidth;
607 hints.height = windowHeight;
608
609 XSetStandardProperties(display, *imageWindow, (char *)windowName, iconName,
610 None, argv, argc, &hints);
611
612 EXIT((""));
613 return(0);
614 } /* CreateImagePlanesWindow() */
615
616