# This is a shell archive. Remove anything before this line, # then unpack it by saving it in a file and typing "sh file". # # Wrapped by Bob Jewett on Wed Mar 2 14:47:12 1994 # # This archive contains: # Makefile.hwp Makefile.sun PEXUtCmap.c PEXUtCmap.h # PEXUtCmapint.c PEXUtCmapint.h PEXUtExt.h README # LANG=""; export LANG PATH=/bin:/usr/bin:$PATH; export PATH echo x - Makefile.hwp sed 's/^@//' >Makefile.hwp <<'@EOF' # Makefile for PEXUt utilities INCLUDES = -I. \ -I/usr/include/X11R5 \ -I/usr/include/Motif1.2 DEFINES = -DNeedFunctionPrototypes LDFLAGS = -L/usr/lib/X11R5 \ -L/usr/lib/Motif1.2 XHPCMAP_LIBS = -lX11 -lXext PEXUT_OBJECTS = PEXUtCmap.o \ PEXUtCmapint.o PEXUT_SOURCE = PEXUtCmap.c \ PEXUtCmapint.c @.c: $(CC) $< $(CFLAGS) -o $* $(LDFLAGS) all: archived shared archived: rm -f $(PEXUT_OBJECTS) make "CFLAGS= -O -Aa $(INCLUDES) $(DEFINES)" libPEXUt.a shared: rm -f $(PEXUT_OBJECTS) make "CFLAGS= -O +z -Aa $(INCLUDES) $(DEFINES)" libPEXUt.sl libPEXUt.a: $(PEXUT_OBJECTS) ar -rv libPEXUt.a $(PEXUT_OBJECTS) libPEXUt.sl: $(PEXUT_OBJECTS) ld -b -o libPEXUt.sl $(PEXUT_OBJECTS) chmod 755 libPEXUt.sl lint: /usr/bin/lint -u $(INCLUDES) $(PEXUT_SOURCE) | tee lint_out @EOF chmod 444 Makefile.hwp echo x - Makefile.sun sed 's/^@//' >Makefile.sun <<'@EOF' # Makefile for PEXUt utilities XHOME_INCLUDE:sh = echo ${OPENWINHOME:-/usr/openwin}/include PEXHOME_INCLUDE:sh = echo ${PEXLIBHOME:-/usr/openwin}/include INCLUDES = -I. -I$(XHOME_INCLUDE) -I$(PEXHOME_INCLUDE) DEFINES = -DNeedFunctionPrototypes CFLAGS = -O $(INCLUDES) $(DEFINES) PEXUT_SL = libPEXUt.so LDFLAGS = -G -z nodefs -h $(PEXUT_SL) \ -L$(OPENWINHOME)/lib -L$(PEXLIBHOME)/lib \ -R $(OPENWINHOME)/lib:$(PEXLIBHOME)/lib PEXUT_OBJECTS = PEXUtCmap.o PEXUtCmapint.o @.c: $(CC) $< $(CFLAGS) -o $* all: archived shared archived: rm -f $(PEXUT_OBJECTS) make libPEXUt.a shared: rm -f $(PEXUT_OBJECTS) make $(PEXUT_SL) libPEXUt.a: $(PEXUT_OBJECTS) ar -rv libPEXUt.a $(PEXUT_OBJECTS) $(PEXUT_SL): $(PEXUT_OBJECTS) ld -o $(PEXUT_SL) $(LDFLAGS) $(PEXUT_OBJECTS) @EOF chmod 444 Makefile.sun echo x - PEXUtCmap.c cat >PEXUtCmap.c <<'@EOF' /* (c) Copyright Hewlett-Packard Company, 1994, Fort Collins, Colorado (C) COPYRIGHT International Business Machines Corp. 1994 Copyright (c) 1994 by Sun Microsystems, Inc. All Rights Reserved Permission to use, copy, modify, and distribute this software and its documentation for any purpose and without fee is hereby granted, provided that the above copyright notices appear in all copies and that both the copyright notices and this permission notice appear in supporting documentation, and that the names of Hewlett-Packard, International Business Machines, or Sun Microsystems not be used in advertising or publicity pertaining to distribution of the software without specific, written prior permission. HEWLETT-PACKARD MAKES NO WARRANTY OF ANY KIND WITH REGARD TO THIS SOFTWARE, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. Hewlett-Packard shall not be liable for errors contained herein or direct, indirect, special, incidental or consequential damages in connection with the furnishing, performance or use of this software. INTERNATIONAL BUSINESS MACHINES CORPORATION PROVIDES THIS MATERIAL "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. SUN MICROSYSTEMS, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SUN MICROSYSTEMS, INC. BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. $Source: /src/rcs/PEX5/cge_utilities/PEXUtCmap.c,v $ $Date: 94/03/02 11:25:21 $ $Revision: 510.1.200.4 $ Description: Main interface implementation file for PEXUt colormap/visual utilities. Notes: */ static char PEXUtWhat[] = "@(#)CGE Version 1.0 Utilities Library \n @(#) \t $Revision: 510.1.200.4 $ \n @(#) \t $Date: 94/03/02 11:25:21 $"; #include #include #include #include #include #include #include #include "PEXUtExt.h" #include "PEXUtCmap.h" #include "PEXUtCmapint.h" int PEXUtSelectVisual ( display, screen, criteria_count, criteria, vis_info_return, cmap_info_return, capx_info_return, select_criteria_return, unmet_criteria_return, std_prop_atom_return ) Display *display; int screen; int criteria_count; PEXUtVisualCriteria *criteria; XVisualInfo *vis_info_return; XStandardColormap *cmap_info_return; PEXColorApproxEntry *capx_info_return; int *select_criteria_return; unsigned int *unmet_criteria_return; Atom *std_prop_atom_return; { int criteria_check, first_criteria_check; unsigned int first_unmet_criteria_return; int criteria_index; PEXUtVisualCriteria no_criteria; PEXExtensionInfo *ext_info; /* Get PEX extension information. */ if (NULL == (ext_info = PEXGetExtensionInfo (display))) { return PEXUtPEXFailure; } /* check the first criteria, so we have something to report on if all else fails. If no criteria are specified, take anything. */ criteria_index = 0; if ((criteria_count > 0) || (criteria == NULL)) { criteria_check = PEXUt_check_criteria ( display, screen, ext_info, &criteria[criteria_index], vis_info_return, cmap_info_return, capx_info_return, &first_unmet_criteria_return, std_prop_atom_return); first_criteria_check = criteria_check; } else { no_criteria.hard_criteria_mask = 0; no_criteria.soft_criteria_mask = 0; criteria_check = PEXUt_check_criteria ( display, screen, ext_info, &no_criteria, vis_info_return, cmap_info_return, capx_info_return, &first_unmet_criteria_return, std_prop_atom_return); first_criteria_check = criteria_check; } while ( (criteria_check != PEXUtSuccess) && (criteria_check != PEXUtQualifiedSuccess) && (++criteria_index < criteria_count)) { /* Check the other criteria until Success */ criteria_check = PEXUt_check_criteria ( display, screen, ext_info, &criteria[criteria_index], vis_info_return, cmap_info_return, capx_info_return, unmet_criteria_return, std_prop_atom_return); } if (criteria_index == criteria_count) { /* no visual found, report back on the first criteria */ *unmet_criteria_return = first_unmet_criteria_return; *select_criteria_return = 0; return first_criteria_check; } else { /* visual found, report its values */ *select_criteria_return = criteria_index; return criteria_check; } } /* PEXUtSelectVisual */ int PEXUtGetStandardColormapInfo ( display, vis_info, cmap_info_return, capx_info_return, std_prop_atom_return ) Display *display; XVisualInfo *vis_info; XStandardColormap *cmap_info_return; PEXColorApproxEntry *capx_info_return; Atom *std_prop_atom_return; { int entry_count; Atom property_atom; XStandardColormap *property_data; int prop_index; int entry_index; int result; /* For each property in the list of properties specified by the interoperability conventions, get the value of the property, and search it for the specified visual. */ for (prop_index=0; prop_indexscreen, &(interop_properties[prop_index]), &property_atom, &entry_count, &property_data); if (result != PEXUtSuccess) { return result; } for (entry_index=0; entry_index < entry_count; entry_index++) { if (property_data[entry_index].visualid == vis_info->visualid) { *cmap_info_return = property_data[entry_index]; PEXUt_load_color_approx_from_std_cmap ( PEXColorSpace, vis_info, cmap_info_return, capx_info_return); XFree (property_data); *std_prop_atom_return = property_atom; return PEXUtSuccess; } } if (entry_count > 0) { XFree (property_data); } } /* If the visual was not found in any property, synthesize colormap info from the visual. In other words, make an educated guess. */ PEXUt_synthesize_cmap_from_visual (vis_info, cmap_info_return); PEXUt_load_color_approx_from_std_cmap (-1, vis_info, cmap_info_return, capx_info_return); *std_prop_atom_return = None; return PEXUtSuccess; } /* PEXUtGetStandardColormapInfo */ int PEXUtCheckColorApproximation ( display, capx_info, vis_info, alternative_capx_info ) Display *display; PEXColorApproxEntry *capx_info; XVisualInfo *vis_info; PEXColorApproxEntry *alternative_capx_info; { int return_value; Window window; int reply; unsigned long count_return; int complete_list; int result; int inquiry_supported; PEXExtensionInfo *ext_info; PEXColorApproxEntry *alt_return; /* Create a temporary unmapped window in the visual. */ PEXUt_create_temporary_window (display, vis_info, &window); /* Verify that specified approx type is supported using PEXGetEnumTypeInfo. If not, return failure. */ result = PEXUt_verify_color_approx_type (display, window, capx_info->type); if (result != PEXUtSuccess) { PEXUt_destroy_temporary_window (display, vis_info, window); return result; } inquiry_supported = False; { int enum_types[1]; unsigned long *count; PEXEnumTypeDesc *enum_data; int enum_index; /* verify that the QueryColorApprox escape is supported using PEXGetEnumTypeInfo. If not, we just can't verify support. */ enum_types[0] = PEXETEscape; if (!PEXGetEnumTypeInfo (display, window, 1, enum_types, PEXETIndex, &count, &enum_data)) { PEXUt_destroy_temporary_window (display, vis_info, window); return PEXUtPEXFailure; } else { for (enum_index = 0; enum_index < *count; enum_index++) { if ((short) enum_data[enum_index].index == (short) PEXETEscapeQueryColorApprox) { inquiry_supported = True; break; } } PEXFreeEnumInfo (1, count, enum_data); } } if (inquiry_supported) { PEXEscapeQueryColorApproxData query; PEXEscapeQueryColorApproxReplyData *query_reply; unsigned long reply_length; query.drawable = window; query.capx = *capx_info; query_reply = (PEXEscapeQueryColorApproxReplyData *) PEXEscapeWithReply (display, PEXEscapeQueryColorApprox, sizeof(query), ((char *) &query), &reply_length); if (query_reply != NULL) { if (query_reply->capx_is_supported) { return_value = PEXUtSuccess; } else { return_value = PEXUtCriteriaFailure; } XFree ((char *) query_reply); } else { PEXUt_destroy_temporary_window (display, vis_info, window); return PEXUtPEXFailure; } } else { /* Can't determine support or non-support. */ return_value = PEXUtQualifiedSuccess; } /* Destroy the temporary window. */ PEXUt_destroy_temporary_window (display, vis_info, window); return return_value; } /* PEXUtCheckColorApproximation */ #define CALC(max,mult) (((offset / cmap_info->mult) % \ (cmap_info->max + 1)) * 65535.0) / (float)cmap_info->max #define LOWBIT(x) ((x) & (~(x) + 1)) #define COLOR_VALUE_EPSILON 5 #define NO_MATCH(a,b) ((a=COLOR_VALUE_EPSILON: \ (unsigned short)(a-b)>=COLOR_VALUE_EPSILON) int PEXUtMakeColormap ( display, vis_info, capx_info, colormap_id_return ) Display *display; XVisualInfo *vis_info; PEXColorApproxEntry *capx_info; Colormap *colormap_id_return; { Display *my_display; Colormap cmap_id; XColor *colors, *src_colors; unsigned long ncolors, delta, entry, offset; unsigned long i, pixel, *pixels; int okay_to_free_RO_cell; int default_visual, default_succeeded, default_read_only, done; int pixel_count, result, overhang; int screen = vis_info->screen; XStandardColormap cmap_data,*cmap_info; cmap_data.red_max = capx_info->max1; cmap_data.green_max = capx_info->max2; cmap_data.blue_max = capx_info->max3; cmap_data.red_mult = capx_info->mult1; cmap_data.green_mult = capx_info->mult2; cmap_data.blue_mult = capx_info->mult3; cmap_data.base_pixel = capx_info->base_pixel; cmap_info = &cmap_data; /* Open a private connection to the X server. */ XSync (display, 0); if ((my_display = XOpenDisplay(XDisplayString(display))) == NULL) { return PEXUtXFailure; } /* Determine if this Visual is the default Visual. */ default_visual = (vis_info->visualid == XVisualIDFromVisual(DefaultVisual(my_display, screen))); /* If the Visual is read/write, load a Colormap (either the default or a created one). Otherwise, just create a Colormap. */ if (vis_info->class == PseudoColor || vis_info->class == DirectColor) { /* Compute the number of colors in the ramp, and the stride through the pixel values. */ if (vis_info->class == DirectColor) { ncolors = cmap_info->red_max; if (cmap_info->green_max > ncolors) ncolors = cmap_info->green_max; if (cmap_info->blue_max > ncolors) ncolors = cmap_info->blue_max; ncolors++; delta = LOWBIT(vis_info->red_mask) + LOWBIT(vis_info->green_mask) + LOWBIT(vis_info->blue_mask); } else { ncolors = cmap_info->red_max * cmap_info->red_mult + cmap_info->green_max * cmap_info->green_mult + cmap_info->blue_max * cmap_info->blue_mult + 1; if ((overhang = (cmap_info->base_pixel + ncolors - vis_info->colormap_size)) > 0) ncolors -= overhang; delta = 1; } /* Allocate storage for a table of RGBs, one for each Colormap cell. */ colors = (XColor *) malloc (vis_info->colormap_size * sizeof(XColor)); if (colors == NULL) { XCloseDisplay(my_display); return PEXUtBadAlloc; } /* If the Visual is the default, capture colors outside the ramp from the default Colormap. This will make the user interface look right until somebody changes a read/write cell in the default Colormap, then there will be color flashing unless there's more than one hardware colormap. However, we're first going to try to allocate the ramp in the default Colormap, so we may end up not using these captured colors. */ if (default_visual) { src_colors = (XColor *) malloc (vis_info->colormap_size * sizeof(XColor)); if (src_colors == NULL) { free ((void *) colors); XCloseDisplay(my_display); return PEXUtBadAlloc; } for (i=0, offset=0; i < vis_info->colormap_size; i++, offset += delta) src_colors[i].pixel = offset; XQueryColors (my_display, DefaultColormap(my_display, vis_info->screen), src_colors, vis_info->colormap_size); for (i=0; i < cmap_info->base_pixel; i++) colors[i] = src_colors[i]; for (i=(cmap_info->base_pixel + ncolors); i < vis_info->colormap_size; i++) colors[i] = src_colors[i]; } /* Compute the ramp of RGBs to be set up, including the scrambling needed for the CRX device. */ for (i=0, offset=0; i < ncolors; i++, offset += delta) { entry = cmap_info->base_pixel + i; colors[entry].pixel = cmap_info->base_pixel + (entry - cmap_info->base_pixel) * delta; colors[entry].red = CALC(red_max, red_mult); colors[entry].green = CALC(green_max, green_mult); colors[entry].blue = CALC(blue_max, blue_mult); } /* Now actually go through the cells, trying to allocate each as a read-only cell with the desired RGB, but falling back to allocate read/write if necessary in order to get the right pixel value. If this happens to be the default Visual, and the ramp does not consume the entire Colormap, then we will first try to allocate the ramp in the default Colormap. If that fails, or if one of the other conditions is not met, then we'll allocate a separate Colormap and load all the cells, including the captured ones if it is the default Visual. */ done = False; if (default_visual && (ncolors < vis_info->colormap_size)) { cmap_id = DefaultColormap(my_display, vis_info->screen); /* Temporarily, allocate all the available cells less than the base pixel as read/write. We'll free them later. */ pixels = (unsigned long *) malloc (cmap_info->base_pixel * sizeof (unsigned long)); if (pixels == NULL) { free ((void *) src_colors); free ((void *) colors); XCloseDisplay(my_display); return PEXUtBadAlloc; } pixel_count = 0; for (i=0; ibase_pixel; i++) { pixel = colors[i].pixel; if (! XAllocColorCells(my_display, cmap_id, (Bool) 0, (unsigned long *) NULL, (unsigned) 0, &pixel, (unsigned) 1)) { /* A failure is construed to mean we couldn't get read/write cells. We'll go on to try the ramp allocation on the off chance that everything will match read-only cells. */ if (pixel_count) XFreeColors(my_display, cmap_id, pixels, pixel_count, (unsigned long) 0); pixel_count = 0; free ((void *) pixels); break; } if (pixel >= (colors[cmap_info->base_pixel].pixel)) { XFreeColors(my_display, cmap_id, &pixel, 1, (unsigned long) 0); break; } else { pixels[pixel_count++] = pixel; if (pixel == (colors[cmap_info->base_pixel-1].pixel)) break; } } default_succeeded = True; default_read_only = False; for (i = cmap_info->base_pixel; i < (cmap_info->base_pixel + ncolors); i++) { if (result = PEXUt_ROorRWcell(my_display, cmap_id, &(colors[i]), False)) { /* We'll try one last thing before giving up on the default Colormap. If all the cells in the ramp match what we inquired earlier, and an attempt to allocate a read-only cell in the middle of the ramp succeeds, then we'll take the chance that this one of the configurations where the X server has set up the ramp we need as read-only in the default Colormap. The first cell in the ramp often fails because it is black or white and finds a read-only cell elsewhere in the Colormap. */ default_succeeded = False; if (result == PEXUt_CMAP_RW_ALLOC) { int match, j; match = True; for (j=cmap_info->base_pixel; j<(cmap_info->base_pixel+ncolors); j++) { if ((colors[j].pixel != src_colors[j].pixel) || NO_MATCH(colors[j].red, src_colors[j].red) || NO_MATCH(colors[j].green, src_colors[j].green) || NO_MATCH(colors[j].blue, src_colors[j].blue)) { match = False; break; } } if (match) { XColor request; int index; index = cmap_info->base_pixel + ncolors/2; request = colors[index]; if (XAllocColor(my_display, cmap_id, &request)) if (request.pixel == colors[index].pixel) { default_succeeded = True; default_read_only = True; } } } break; } } /* Free any temporarily allocated cells, regardless of whether we succeeded or not. */ if (pixel_count) XFreeColors(my_display, cmap_id, pixels, pixel_count, (unsigned long) 0); pixel_count = 0; free ((void *) pixels); /* Record the Colormap ID in the property info. The killid is that of a Pixmap because we don't own the Colormap, just some cells of it. */ if (default_succeeded) { Window win; cmap_info->colormap = cmap_id; if (default_read_only) cmap_info->killid = None; else { win = XCreateWindow(my_display, RootWindow(my_display, screen), 1, 1, 1, 1, 0, 0, InputOnly, vis_info->visual, (unsigned long) 0, (XSetWindowAttributes *)NULL); cmap_info->killid = (XID) XCreatePixmap(my_display, win, 1, 1, vis_info->depth); XDestroyWindow(my_display, win); } done = True; } } if (default_visual) free ((void *) src_colors); if (!done) { /* For some reason we're not using the default Colormap, so allocate a Colormap. */ cmap_id = XCreateColormap(my_display, RootWindow(my_display, screen), vis_info->visual, AllocNone); if (cmap_id == None) { free ((void *) colors); XCloseDisplay(my_display); return PEXUtXFailure; } /* Now load all cells. */ for (i=0; i < vis_info->colormap_size; i++) { okay_to_free_RO_cell = ((i >= cmap_info->base_pixel) && (i < (cmap_info->base_pixel + ncolors))); if (PEXUt_ROorRWcell(my_display, cmap_id, &(colors[i]), okay_to_free_RO_cell)) { free ((void *) colors); XFreeColormap (my_display, cmap_id); XCloseDisplay(my_display); return PEXUtPEXFailure; } } /* Record the Colormap ID in the property info. */ cmap_info->colormap = cmap_id; cmap_info->killid = ReleaseByFreeingColormap; } } else { if (vis_info->class == GrayScale) { /* No support implemented for setting up a gray ramp. */ XCloseDisplay(my_display); return PEXUtPEXFailure; } else { /* This is a static Visual, so just allocate a Colormap, or if the default Visual then use the default Colormap. */ if (default_visual) { cmap_id = DefaultColormap(my_display, vis_info->screen); cmap_info->colormap = cmap_id; cmap_info->killid = None; } else { cmap_id = XCreateColormap(my_display, RootWindow(my_display, screen), vis_info->visual, AllocNone); if (cmap_id == None) { XCloseDisplay(my_display); return PEXUtXFailure; } cmap_info->colormap = cmap_id; cmap_info->killid = ReleaseByFreeingColormap; } } } /* Set retention of resources and close the private connection. */ XSetCloseDownMode(my_display, RetainPermanent); XCloseDisplay(my_display); *colormap_id_return = cmap_id; return PEXUtSuccess; } /* PEXUtMakeColormap */ int PEXUtMakeWindow ( display, screen, window_info, vis_info, window_return, background_color_return ) Display *display; int screen; PEXUtWindowSpecification *window_info; XVisualInfo *vis_info; Window *window_return; XColor *background_color_return; { unsigned long window_mask; XSetWindowAttributes window_attrs; unsigned long pixel_value; XColor screen_def; XColor exact_def; int need_color; /* Check the window specification. */ if (( !(window_info->attr_mask & CWColormap)) || (window_info->attrs.colormap == None)) { return PEXUtXFailure; } /* Look up colors for background and border. */ window_mask = window_info->attr_mask; window_attrs = window_info->attrs; if ( !(window_info->attr_mask & CWBackPixel)) { need_color = True; if (XParseColor (display, window_attrs.colormap, window_info->background_color_name, &exact_def)) { screen_def = exact_def; if (XAllocColor (display, window_attrs.colormap, &screen_def)) { pixel_value = screen_def.pixel; *background_color_return = screen_def; need_color = False; } } if (need_color) { if (XAllocNamedColor (display, window_attrs.colormap, "Black", &screen_def, &exact_def)) { pixel_value = screen_def.pixel; *background_color_return = screen_def; } else { pixel_value = 0; background_color_return->pixel = pixel_value; background_color_return->red = 0; background_color_return->green = 0; background_color_return->blue = 0; } } window_attrs.background_pixel = pixel_value; window_mask |= CWBackPixel; } if ( !(window_info->attr_mask & CWBorderPixel)) { need_color = True; if (XParseColor (display, window_attrs.colormap, window_info->border_color_name, &exact_def)) { screen_def = exact_def; if (XAllocColor (display, window_attrs.colormap, &screen_def)) { pixel_value = screen_def.pixel; need_color = False; } } if (need_color) { if (XAllocNamedColor (display, window_attrs.colormap, "White", &screen_def, &exact_def)) { pixel_value = screen_def.pixel; } else { pixel_value = 0; } } window_attrs.border_pixel = pixel_value; window_mask |= CWBorderPixel; } /* Create the window. */ *window_return = XCreateWindow ( display, window_info->parent, window_info->size_hints.x, window_info->size_hints.y, window_info->size_hints.width, window_info->size_hints.height, window_info->border_width, vis_info->depth, InputOutput, vis_info->visual, window_mask, &window_attrs); if (*window_return == None) { return PEXUtXFailure; } XSetNormalHints (display, *window_return, &(window_info->size_hints)); XStoreName (display, *window_return, window_info->title); XSync (display,0); return PEXUtSuccess; } /* PEXUtMakeWindow */ int PEXUtMakeWindowAndColormap ( display, screen, criteria_count, criteria, window_info, window_return, vis_info_return, cmap_info_return, capx_info_return, select_criteria_return, unmet_criteria_return, std_prop_atom_return, background_color_return, colormap_id_return ) Display *display; int screen; int criteria_count; PEXUtVisualCriteria *criteria; PEXUtWindowSpecification *window_info; Window *window_return; XVisualInfo *vis_info_return; XStandardColormap *cmap_info_return; PEXColorApproxEntry *capx_info_return; int *select_criteria_return; unsigned int *unmet_criteria_return; Atom *std_prop_atom_return; XColor *background_color_return; Colormap *colormap_id_return; { PEXColorApproxEntry alt_capx_info, *alternative_capx_info; Colormap cmap_id_from_property; Colormap created_cmap_id; PEXUtWindowSpecification local_window_info; int result, temp_result; /* Find visual. */ temp_result = PEXUtSelectVisual ( display, screen, criteria_count, criteria, vis_info_return, cmap_info_return, capx_info_return, select_criteria_return, unmet_criteria_return, std_prop_atom_return ); if ((temp_result != PEXUtSuccess) && (temp_result != PEXUtQualifiedSuccess)) { return temp_result; } cmap_id_from_property = cmap_info_return->colormap; /* Verify color approximation. */ alternative_capx_info = &alt_capx_info; temp_result = PEXUtCheckColorApproximation ( display, capx_info_return, vis_info_return, alternative_capx_info); if ((temp_result != PEXUtSuccess) && (temp_result != PEXUtAlternativeSuccess) && (temp_result != PEXUtQualifiedSuccess)) { return temp_result; } result = temp_result; /* If no colormap ID in returned info, create a colormap. Then reallocate the same colors as read-only, so XAllocColor has a chance of working. */ *colormap_id_return = None; if (cmap_id_from_property == None) { temp_result = PEXUtMakeColormap ( display, vis_info_return, capx_info_return, &created_cmap_id); if (temp_result != PEXUtSuccess) { return temp_result; } cmap_info_return->colormap = created_cmap_id; *colormap_id_return = created_cmap_id; } /* Load a local copy of the window info with an augmented set of items and create the window. */ local_window_info = *window_info; local_window_info.attrs.colormap = cmap_info_return->colormap; local_window_info.attr_mask |= CWColormap; local_window_info.attr_mask &= ~(CWBackPixel|CWBorderPixel); temp_result = PEXUtMakeWindow ( display, screen, &local_window_info, vis_info_return, window_return, background_color_return); if (temp_result == PEXUtSuccess) { XMapWindow (display, *window_return); XSync (display, 0); } else { return temp_result; } return result; } /* PEXUtMakeWindowAndColormap */ int PEXUtSimpleWindowAndColormap ( display, parent, x,y, width, height, border_width, background_color_name, border_color_name, window_return, capx_info_return, background_color_return, colormap_id_return ) Display *display; Window parent; int x; int y; unsigned int width; unsigned int height; unsigned int border_width; char *background_color_name; char *border_color_name; Window *window_return; PEXColorApproxEntry *capx_info_return; XColor *background_color_return; Colormap *colormap_id_return; { int result; Status status; int screen; PEXUtWindowSpecification local_window_info; XVisualInfo vis_info_return; XStandardColormap cmap_info_return; int select_criteria_return; unsigned int unmet_criteria_return; Atom std_prop_atom_return; XWindowAttributes window_attributes_return; PEXUtVisualCriteria criteria[] = { /* "Simple" criteria */ 0, /* hard criteria mask */ PEXUtStandardColormapProperty | /* soft criteria mask */ PEXUtLayer | PEXUtDBCapability, 0, /* depth */ 0, /* min colors */ 0, /* min red */ 0, /* min green */ 0, /* min blue */ 0, /* visual class */ PEXUtImage, /* layer */ True, /* standard colormap property */ 0, /* dynamic visual */ PEXUtDBPEX, /* double buffering capability */ 0 /* color approximation type */ }; /* Get the screen number of the parent window */ status = XGetWindowAttributes (display, parent, &window_attributes_return); if (!status) { return (PEXUtXFailure); } screen = XScreenNumberOfScreen (window_attributes_return.screen); /* Using the simple criteria, make a window and colormap */ local_window_info.attrs.event_mask = window_attributes_return.your_event_mask & ~(window_attributes_return.do_not_propagate_mask); local_window_info.attr_mask = CWEventMask; local_window_info.title = "PEXUtSimpleWindow"; local_window_info.size_hints.flags = USPosition | USSize ; local_window_info.size_hints.x = x; local_window_info.size_hints.y = y; local_window_info.size_hints.width = width; local_window_info.size_hints.height = height; local_window_info.parent = parent; local_window_info.border_width = border_width; local_window_info.background_color_name = background_color_name; local_window_info.border_color_name = border_color_name; result = PEXUtMakeWindowAndColormap ( display, screen, 1, criteria, &local_window_info, window_return, &vis_info_return, &cmap_info_return, capx_info_return, &select_criteria_return, &unmet_criteria_return, &std_prop_atom_return, background_color_return, colormap_id_return ); return result; } /* PEXUtSimpleWindowAndColormap */ @EOF chmod 444 PEXUtCmap.c echo x - PEXUtCmap.h cat >PEXUtCmap.h <<'@EOF' #ifndef PEXUTCMAP_H /* { */ #define PEXUTCMAP_H /* (c) Copyright Hewlett-Packard Company, 1994, Fort Collins, Colorado (C) COPYRIGHT International Business Machines Corp. 1994 Copyright (c) 1994 by Sun Microsystems, Inc. All Rights Reserved Permission to use, copy, modify, and distribute this software and its documentation for any purpose and without fee is hereby granted, provided that the above copyright notices appear in all copies and that both the copyright notices and this permission notice appear in supporting documentation, and that the names of Hewlett-Packard, International Business Machines, or Sun Microsystems not be used in advertising or publicity pertaining to distribution of the software without specific, written prior permission. HEWLETT-PACKARD MAKES NO WARRANTY OF ANY KIND WITH REGARD TO THIS SOFTWARE, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. Hewlett-Packard shall not be liable for errors contained herein or direct, indirect, special, incidental or consequential damages in connection with the furnishing, performance or use of this software. INTERNATIONAL BUSINESS MACHINES CORPORATION PROVIDES THIS MATERIAL "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. SUN MICROSYSTEMS, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SUN MICROSYSTEMS, INC. BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. $Source: /src/rcs/PEX5/cge_utilities/PEXUtCmap.h,v $ $Date: 94/03/02 11:28:28 $ $Revision: 510.1.200.3 $ Description: Interface header file for PEXUt colormap/visual utilities. Notes: */ #ifndef NeedFunctionPrototypes #if defined (FUNCPROTO) || \ defined (__STDC__) || \ defined (__cplusplus) || \ defined (c_plusplus) #define NeedFunctionPrototypes 1 #else #define NeedFunctionPrototypes 0 #endif /* FUNCPROTO, __STDC__, __cplusplus, c_plusplus */ #endif /* NeedFunctionPrototypes */ #ifdef __cplusplus /* do not leave open across includes */ extern "C" { /* for C++ V2.0 */ #endif /* PEXUtVisualCriteria is used to specify criteria for selecting a Visual. */ typedef struct { unsigned int hard_criteria_mask; unsigned int soft_criteria_mask; unsigned int depth; unsigned int min_colors; unsigned int min_red; unsigned int min_green; unsigned int min_blue; unsigned int visual_class; unsigned int layer; unsigned int standard_colormap_property; unsigned int dynamic_visual; unsigned int double_buffering_capability; PEXEnumTypeIndex color_approx_type; } PEXUtVisualCriteria; /* Mask bits for the hard and soft criteria. */ #define PEXUtDepth (1L<<0) #define PEXUtMinColors (1L<<1) #define PEXUtMinRed (1L<<2) #define PEXUtMinGreen (1L<<3) #define PEXUtMinBlue (1L<<4) #define PEXUtVisualClass (1L<<5) #define PEXUtLayer (1L<<6) #define PEXUtStandardColormapProperty (1L<<7) #define PEXUtDynamicVisual (1L<<8) #define PEXUtDBCapability (1L<<9) #define PEXUtColorApproxType (1L<<10) #define PEXUtAllCriteria ( \ PEXUtDepth |\ PEXUtMinColors |\ PEXUtMinRed |\ PEXUtMinGreen |\ PEXUtMinBlue |\ PEXUtVisualClass |\ PEXUtLayer |\ PEXUtStandardColormapProperty |\ PEXUtDynamicVisual |\ PEXUtDBCapability |\ PEXUtColorApproxType \ ) /* Values for the layer criterion. */ #define PEXUtOverlay 0 #define PEXUtImage 1 /* Values for the double_buffering_capability criterion. */ #define PEXUtDBNone 0 #define PEXUtDBPEX 1 #define PEXUtDBPEXAndX 2 /* Values for the integer error codes returned by the various utilities. */ #define PEXUtSuccess 0 #define PEXUtQualifiedSuccess 1 #define PEXUtAlternativeSuccess 2 #define PEXUtCriteriaFailure -1 #define PEXUtXFailure -2 #define PEXUtPEXFailure -3 #define PEXUtBadAlloc -4 /* PEXUtWindowSpecification is used to specify window size, location, title, and other attributes needed for window creation. */ typedef struct { unsigned long attr_mask; XSetWindowAttributes attrs; char *title; XSizeHints size_hints; Window parent; unsigned int border_width; char *background_color_name; char *border_color_name; } PEXUtWindowSpecification; /* Function prototypes */ extern int PEXUtSelectVisual ( #if NeedFunctionPrototypes Display *display, int screen, int criteria_count, PEXUtVisualCriteria *criteria, XVisualInfo *vis_info_return, XStandardColormap *cmap_info_return, PEXColorApproxEntry *capx_info_return, int *select_criteria_return, unsigned int *unmet_criteria_return, Atom *std_prop_atom_return #endif ); extern int PEXUtGetStandardColormapInfo ( #if NeedFunctionPrototypes Display *display, XVisualInfo *vis_info, XStandardColormap *cmap_info_return, PEXColorApproxEntry *capx_info_return, Atom *std_prop_atom_return #endif ); extern int PEXUtCheckColorApproximation ( #if NeedFunctionPrototypes Display *display, PEXColorApproxEntry *capx_info, XVisualInfo *vis_info, PEXColorApproxEntry *alternative_capx_info #endif ); extern int PEXUtMakeColormap ( #if NeedFunctionPrototypes Display *display, XVisualInfo *vis_info, PEXColorApproxEntry *capx_info, Colormap *colormap_id_return #endif ); extern int PEXUtMakeWindow ( #if NeedFunctionPrototypes Display *display, int screen, PEXUtWindowSpecification *window_info, XVisualInfo *vis_info, Window *window_return, XColor *background_color_return #endif ); extern int PEXUtMakeWindowAndColormap ( #if NeedFunctionPrototypes Display *display, int screen, int criteria_count, PEXUtVisualCriteria *criteria, PEXUtWindowSpecification *window_info, Window *window_return, XVisualInfo *vis_info_return, XStandardColormap *cmap_info_return, PEXColorApproxEntry *capx_info_return, int *select_criteria_return, unsigned int *unmet_criteria_return, Atom *std_prop_atom_return, XColor *background_color_return, Colormap *colormap_id_return #endif ); extern int PEXUtSimpleWindowAndColormap ( #if NeedFunctionPrototypes Display *display, Window parent, int x, int y, unsigned int width, unsigned int height, unsigned int border_width, char *background_color_name, char *border_color_name, Window *window_return, PEXColorApproxEntry *capx_info_return, XColor *background_color_return, Colormap *colormap_id_return #endif ); #ifdef __cplusplus } /* for C++ V2.0 */ #endif #endif /* } PEXUTCMAP_H */ @EOF chmod 444 PEXUtCmap.h echo x - PEXUtCmapint.c cat >PEXUtCmapint.c <<'@EOF' /* (c) Copyright Hewlett-Packard Company, 1994, Fort Collins, Colorado (C) COPYRIGHT International Business Machines Corp. 1994 Copyright (c) 1994 by Sun Microsystems, Inc. All Rights Reserved Permission to use, copy, modify, and distribute this software and its documentation for any purpose and without fee is hereby granted, provided that the above copyright notices appear in all copies and that both the copyright notices and this permission notice appear in supporting documentation, and that the names of Hewlett-Packard, International Business Machines, or Sun Microsystems not be used in advertising or publicity pertaining to distribution of the software without specific, written prior permission. HEWLETT-PACKARD MAKES NO WARRANTY OF ANY KIND WITH REGARD TO THIS SOFTWARE, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. Hewlett-Packard shall not be liable for errors contained herein or direct, indirect, special, incidental or consequential damages in connection with the furnishing, performance or use of this software. INTERNATIONAL BUSINESS MACHINES CORPORATION PROVIDES THIS MATERIAL "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. SUN MICROSYSTEMS, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SUN MICROSYSTEMS, INC. BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. $Source: /src/rcs/PEX5/cge_utilities/PEXUtCmapint.c,v $ $Date: 94/03/02 11:25:31 $ $Revision: 510.1.200.4 $ Description: Internal routine implementation file for PEXUt colormap/visual utilities. Notes: */ #include #include #include #include #include #include #include #include "PEXUtExt.h" #include "PEXUtCmap.h" #include "PEXUtCmapint.h" #include int PEXUt_check_criteria ( display, screen, ext_info, criteria, vis_info_return, cmap_info_return, capx_info_return, unmet_criteria_return, std_prop_atom_return ) Display *display; int screen; PEXExtensionInfo *ext_info; PEXUtVisualCriteria *criteria; XVisualInfo *vis_info_return; XStandardColormap *cmap_info_return; PEXColorApproxEntry *capx_info_return; unsigned int *unmet_criteria_return; Atom *std_prop_atom_return; /* Algorithm: Section I: Initialize and process input criteria masks. Section II: Fetch information from the server. Section III: Check each visual against the criteria Section IV: Generate return information. */ { PEXUtVisualCriteria local_criteria; int target_depth; unsigned long target_count = 0; PEXRenderingTarget *targets = NULL; XVisualInfo vis_template; unsigned int vis_mask; int visual_count = 0; XVisualInfo *visuals = NULL; int overlay_count = 0; overlay_visuals_type *overlay_data = NULL; int visual_info_count = 0; visual_info_type *visual_info = NULL; visual_info_type *p_info; int min_unmet_criteria_count; int soft_criteria_count; int supported_visual_count; visual_info_type *p_chosen_info, *p_min_unmet; int property_counts[NUM_INTEROP_PROPERTIES]; Atom property_atoms[NUM_INTEROP_PROPERTIES]; XStandardColormap *property_data[NUM_INTEROP_PROPERTIES]; int visual_index; int target_index; int prop_index; int entry_index; int met_hard_count; int result; int color_approx_type; int rendering_targets; unsigned long max_targets=32; /* This macro is used to clean up in case of an early exit. */ #define FREE_ALLOCATED_RESOURCES { \ int i; \ if (target_count) XFree (targets); \ if (visual_count > 0) XFree (visuals); \ for (i=0; i 0) XFree (property_data[i]); \ if (overlay_count > 0) XFree (overlay_data); \ if (visual_info_count > 0) free ((void *) visual_info); \ } /* ----------------------------------------------------------------------- Section I: Initialize and process input criteria masks. ----------------------------------------------------------------------- */ /* Initialize property data arrays to empty. */ for (prop_index=0; prop_indexmajor_version == 5) && (ext_info->minor_version >= 1)) { rendering_targets=PEXMatchRenderingTargets (display, RootWindow(display, screen), target_depth, PEXWindowDrawable, NULL, max_targets, &target_count, &targets); if (!rendering_targets) { if (local_criteria.hard_criteria_mask & PEXUtDepth) { FREE_ALLOCATED_RESOURCES return PEXUtPEXFailure; } /* it's soft and it failed, find any depth */ target_depth = 0; rendering_targets=PEXMatchRenderingTargets (display, RootWindow(display, screen), target_depth, PEXWindowDrawable, NULL, max_targets, &target_count, &targets); if (!rendering_targets) { FREE_ALLOCATED_RESOURCES return PEXUtPEXFailure; } vis_template.depth = 0; vis_mask &= ~VisualDepthMask; } else { if (target_count) { /* the criteria is met, clear its bit */ local_criteria.soft_criteria_mask &= ~PEXUtDepth; } else { /* it's soft and it failed, find any depth */ target_depth = 0; rendering_targets=PEXMatchRenderingTargets (display, RootWindow(display, screen), target_depth, PEXWindowDrawable, NULL, max_targets, &target_count, &targets); if (!rendering_targets) { FREE_ALLOCATED_RESOURCES return PEXUtPEXFailure; } vis_template.depth = 0; vis_mask &= ~VisualDepthMask; } } if ((!target_count) && (local_criteria.hard_criteria_mask & PEXUtDepth)) { FREE_ALLOCATED_RESOURCES *unmet_criteria_return = local_criteria.hard_criteria_mask | local_criteria.soft_criteria_mask; return PEXUtCriteriaFailure; } } /* Get list of visuals for the screen. If depth and/or visual class are specified as hard criteria, use them as filters. */ if ((local_criteria.hard_criteria_mask & PEXUtVisualClass) || (local_criteria.soft_criteria_mask & PEXUtVisualClass)) { vis_template.class = local_criteria.visual_class; vis_mask |= VisualClassMask; } visuals = XGetVisualInfo (display, vis_mask, &vis_template, &visual_count); if (visuals == NULL) { if (local_criteria.hard_criteria_mask & PEXUtVisualClass) { FREE_ALLOCATED_RESOURCES return PEXUtXFailure; } if (local_criteria.soft_criteria_mask & PEXUtVisualClass) { /* don't force a failed soft criteria */ vis_mask &= ~VisualClassMask; visuals = XGetVisualInfo (display, vis_mask, &vis_template, &visual_count); } } else { /* criteria met clear soft criteria mask */ local_criteria.soft_criteria_mask &= ~PEXUtVisualClass; } /* For each property in the list of properties specified by the interoperability conventions, get the value of the property. */ if ((PEXUtStandardColormapProperty) & (local_criteria.hard_criteria_mask | local_criteria.soft_criteria_mask)) { for (prop_index=0; prop_indexunmet_hard_criteria = 0; p_info->unmet_soft_criteria = 0; /* Search the colormap properties for the first match with the visual. The property data is used in evaluating color criteria as well as the standard colormap property criterion. If we get property data, and we did not have target data from which to give an order rating, then give a rating depending on the relative position of the property entry, including the possibility of a search process that involves more than one property. */ p_info->property_ptr = NULL; p_info->property_atom = None; if ((PEXUtStandardColormapProperty) & (local_criteria.hard_criteria_mask | local_criteria.soft_criteria_mask)) { found = False; for (prop_index=0; prop_indexproperty_ptr = &(property_data[prop_index][entry_index]); p_info->property_atom = property_atoms[prop_index]; break; } } if (found) { break; } } if ((PEXUtStandardColormapProperty & (local_criteria.hard_criteria_mask | local_criteria.soft_criteria_mask)) && (found != local_criteria.standard_colormap_property)) { p_info->unmet_hard_criteria |= (local_criteria.hard_criteria_mask & PEXUtStandardColormapProperty); p_info->unmet_soft_criteria |= (local_criteria.soft_criteria_mask & PEXUtStandardColormapProperty); } } /* Check the depth */ if (PEXUtDepth & (local_criteria.hard_criteria_mask | local_criteria.soft_criteria_mask)) { if (visuals[visual_index].depth != local_criteria.depth) { p_info->unmet_hard_criteria |= (local_criteria.hard_criteria_mask & PEXUtDepth); p_info->unmet_soft_criteria |= (local_criteria.soft_criteria_mask & PEXUtDepth); } } /* Color criteria are complicated, since they interact with property information. This procedure not only evaluates whether or not criteria are met, but also assigns a rating based on available color resolution and the sharable_colormap criterion. */ result = PEXUt_evaluate_color_criteria (display, &local_criteria, &(visuals[visual_index]), p_info); if (result != PEXUtSuccess) { FREE_ALLOCATED_RESOURCES return result; } if (PEXUtVisualClass & (local_criteria.hard_criteria_mask | local_criteria.soft_criteria_mask)) { if (visuals[visual_index].class != local_criteria.visual_class) { p_info->unmet_hard_criteria |= (local_criteria.hard_criteria_mask & PEXUtVisualClass); p_info->unmet_soft_criteria |= (local_criteria.soft_criteria_mask & PEXUtVisualClass); } } /* The Visual class is always a factor in rating: if the user does not specify a preference, static Visuals are preferred over dynamic Visuals, all else being equal. */ if (PEXUtDynamicVisual & (local_criteria.hard_criteria_mask | local_criteria.soft_criteria_mask)) { /* the user wants a dynamic visual */ if (local_criteria.dynamic_visual) { if ((visuals[visual_index].class == TrueColor) || (visuals[visual_index].class == StaticColor) || (visuals[visual_index].class == StaticGray)) { p_info->class_rating = 0; p_info->unmet_hard_criteria |= (local_criteria.hard_criteria_mask & PEXUtDynamicVisual); p_info->unmet_soft_criteria |= (local_criteria.soft_criteria_mask & PEXUtDynamicVisual); } else { p_info->class_rating = MAX_CLASS_RATING; } } } else { /* The user doesn't care, preference to static visuals */ if ((visuals[visual_index].class == TrueColor) || (visuals[visual_index].class == StaticColor) || (visuals[visual_index].class == StaticGray)) { p_info->class_rating = MAX_CLASS_RATING; } else { p_info->class_rating = 0; } } /* Layer is not currently used for any rating. */ if (PEXUtLayer & (local_criteria.hard_criteria_mask | local_criteria.soft_criteria_mask)) { switch (local_criteria.layer) { case PEXUtImage: found = True; for (prop_index=0; prop_index < overlay_count; prop_index++) { if (overlay_data[prop_index].visualid == visuals[visual_index].visualid) { found = False; break; } } break; case PEXUtOverlay: found = False; for (prop_index=0; prop_index < overlay_count; prop_index++) { if ((overlay_data[prop_index].visualid == visuals[visual_index].visualid) && (overlay_data[prop_index].transparent_type != None)) { found = True; break; } } break; default: found = False; break; } if (!found) { p_info->unmet_hard_criteria |= (local_criteria.hard_criteria_mask & PEXUtLayer); p_info->unmet_soft_criteria |= (local_criteria.soft_criteria_mask & PEXUtLayer); } } /* Determining double-buffering capability is a complicated affair. This procedure attempts to assess whether criteria are met and assign a rating. */ result = PEXUt_evaluate_double_buffering_capability (display, &local_criteria, &(visuals[visual_index]), p_info); if (result != PEXUtSuccess) { FREE_ALLOCATED_RESOURCES return result; } /* Determining support for color approximation types is straightforward but is done in a subprocedure in order to centralize it. This procedure attempts to assess whether criteria are met and assign a rating. */ result = PEXUt_evaluate_color_approx_type (display, &local_criteria, &(visuals[visual_index]), p_info); if (result != PEXUtSuccess) { FREE_ALLOCATED_RESOURCES return result; } /* At this point, all the criteria have been evaluated for this Visual. If it met all the hard criteria, it is a candidate for success, and we give a rating based on how many soft criteria have also been met. We keep a pointer to the last Visual that met all hard criteria, so we can avoid some work if there turns out to be only one. If not, we still keep track of the Visual that came closest to meeting all the hard criteria. */ if (p_info->unmet_hard_criteria == 0) { met_hard_count++; p_info->visual_ptr = &(visuals[visual_index]); p_chosen_info = p_info; if (soft_criteria_count) { unmet_criteria_count = PEXUt_count_bits_in_mask (p_info->unmet_soft_criteria); p_info->soft_rating = (int) ((((float) (soft_criteria_count - unmet_criteria_count)) /((float) soft_criteria_count)) * MAX_SOFT_RATING); } else p_info->soft_rating = 0; } else { unmet_criteria_count = PEXUt_count_bits_in_mask (p_info->unmet_hard_criteria); if (unmet_criteria_count < min_unmet_criteria_count) { min_unmet_criteria_count = unmet_criteria_count; p_min_unmet = p_info; } } p_info++; supported_visual_count++; } } /* ----------------------------------------------------------------------- Section IV: Evaluate candidates (Visuals that meet hard criteria). ----------------------------------------------------------------------- */ /* If no Visual has met the hard criteria, we have failed. We will return the criteria information for the Visual that came closest to being accepted. */ if (met_hard_count == 0) { if (p_min_unmet) { *unmet_criteria_return = p_min_unmet->unmet_hard_criteria | p_min_unmet->unmet_soft_criteria; } else { /* it failed them all */ *unmet_criteria_return = criteria->hard_criteria_mask | criteria->soft_criteria_mask; } FREE_ALLOCATED_RESOURCES return PEXUtCriteriaFailure; } /* If more than one Visual has met the hard criteria, make a pass to choose the best one. */ if (met_hard_count > 1) { unsigned int overall_rating; unsigned int max_rating = 0; p_info = visual_info; p_chosen_info = p_info; for (visual_index=0; visual_indexunmet_hard_criteria == 0) { overall_rating = PEXUt_compute_overall_rating (p_info); if (overall_rating > max_rating) { max_rating = overall_rating; p_chosen_info = p_info; } } p_info++; } } /* ----------------------------------------------------------------------- Section V: Copy or generate return information. ----------------------------------------------------------------------- */ /* If we have chosen a Visual, and we've got standard colormap information, and the caller requested it, we'll return that and the atom for the property. If we have chosen a Visual, but we don't have standard colormap information yet, then synthesize the info from the visual. This is just an "educated" guess at what kind of color ramp might be supported by PEX on the visual. */ if (((PEXUtStandardColormapProperty) & (local_criteria.hard_criteria_mask | local_criteria.soft_criteria_mask)) && (local_criteria.standard_colormap_property && (p_chosen_info->property_ptr != NULL))) { *cmap_info_return = *(p_chosen_info->property_ptr); *std_prop_atom_return = p_chosen_info->property_atom; color_approx_type = PEXColorSpace; } else { PEXUt_synthesize_cmap_from_visual (p_chosen_info->visual_ptr, cmap_info_return); *std_prop_atom_return = None; color_approx_type = -1; } *vis_info_return = *(p_chosen_info->visual_ptr); if (((PEXUtColorApproxType) & (local_criteria.hard_criteria_mask | local_criteria.soft_criteria_mask)) && (!(PEXUtColorApproxType & p_chosen_info->unmet_soft_criteria))) { color_approx_type = local_criteria.color_approx_type; } PEXUt_load_color_approx_from_std_cmap (color_approx_type, vis_info_return, cmap_info_return, capx_info_return); *unmet_criteria_return = p_chosen_info->unmet_soft_criteria; FREE_ALLOCATED_RESOURCES if (*unmet_criteria_return) return PEXUtQualifiedSuccess; else return PEXUtSuccess; #undef FREE_ALLOCATED_RESOURCES } /* PEXUt_check_criteria */ int PEXUt_get_standard_cmap_property ( display, screen, property_info, property_atom_return, property_count_return, property_data_return ) Display *display; int screen; interop_property_type *property_info; Atom *property_atom_return; int *property_count_return; XStandardColormap **property_data_return; { Atom actual_type; int actual_format; unsigned long item_count; unsigned long item_count_return, bytes_unread; int result; if ( !property_info->is_standard) { if (property_info->have_atom) { *property_atom_return = property_info->property_atom; } else { /* Get the atom from the X server. If it doesn't exist, neither does the property. This should not be considered a fatal error. */ *property_atom_return = XInternAtom(display, property_info->property_name, True); if (*property_atom_return == None) { *property_count_return = 0; return PEXUtSuccess; } } /* Property atom exists - fetch the property. */ bytes_unread = 0; item_count = sizeof(XStandardColormap)/4; do { item_count += (bytes_unread+3)/4; result = XGetWindowProperty (display, RootWindow(display, screen), *property_atom_return, 0, item_count, False, *property_atom_return, &actual_type, &actual_format, &item_count_return, &bytes_unread, (unsigned char **) property_data_return); } while ((result == Success) && (bytes_unread > 0)); if (result != Success) { return PEXUtXFailure; } *property_count_return = item_count_return/(sizeof(XStandardColormap)/4); return PEXUtSuccess; } else { /* Note that XGetRGBColormaps returns a zero status even if nothing is wrong but the property doesn't exist. */ *property_atom_return = property_info->property_atom; result = XGetRGBColormaps (display, RootWindow(display, screen), property_data_return, property_count_return, *property_atom_return); if (!result) { *property_count_return = 0; } return PEXUtSuccess; } } /* PEXUt_get_standard_cmap_property */ int PEXUt_get_overlay_visuals_property ( display, screen, property_count_return, property_data_return ) Display *display; int screen; int *property_count_return; overlay_visuals_type **property_data_return; { Atom property_atom; Atom actual_type; int actual_format; unsigned long item_count; unsigned long item_count_return, bytes_unread; int result; /* Get the atom from the X server. If it doesn't exist, neither does the property. */ property_atom = XInternAtom(display, "SERVER_OVERLAY_VISUALS", True); if (property_atom == None) { return PEXUtXFailure; } /* Property atom exists - fetch the property. */ bytes_unread = 0; item_count = sizeof(overlay_visuals_type)/4; do { item_count += (bytes_unread+3)/4; result = XGetWindowProperty (display, RootWindow(display, screen), property_atom, 0, item_count, False, property_atom, &actual_type, &actual_format, &item_count_return, &bytes_unread, (unsigned char **) property_data_return); } while ((result == Success) && (bytes_unread > 0)); if (result != Success) { return PEXUtXFailure; } *property_count_return = item_count_return/(sizeof(overlay_visuals_type)/4); return PEXUtSuccess; } /* PEXUt_get_overlay_visuals_property */ int PEXUt_evaluate_color_criteria ( display, criteria, vis_info, p_info ) Display *display; PEXUtVisualCriteria *criteria; XVisualInfo *vis_info; visual_info_type *p_info; /* Algorithm: Section I: Compute the color resolution numbers. If we have a property entry, use it to do this, otherwise use the Visual description. Section II: Mark the information block as criteria are tested for satisfaction. Also, keep numbers for the degree to which the available colors surpass the specified minima. Section III: Compute an overall color rating based on to what degree the colors exceed the minima. If no color criteria were specified, this rating comes out zero. If sharable_colormap was a criterion, Visuals that are not named in properties lose their color rating. Visuals that were named in a property, but whose ramps do not meet the criteria, also lose. */ { PEXEnumTypeIndex color_approx_type; int avail_reds, avail_greens, avail_blues; int avail_colors; int colors_excess, reds_excess, greens_excess, blues_excess; unsigned long temp; XStandardColormap *cmap_info; double total_excess; /* ----------------------------------------------------------------------- Section I: Compute the color resolution numbers. If we have a property entry, use it to do this, otherwise use the Visual description. ----------------------------------------------------------------------- */ if (PEXUtColorApproxType & (criteria->hard_criteria_mask|criteria->soft_criteria_mask)) { color_approx_type = criteria->color_approx_type; } else { color_approx_type = PEXColorSpace; } if ((p_info->property_ptr != NULL) && (color_approx_type == PEXColorSpace)) { cmap_info = p_info->property_ptr; avail_reds = cmap_info->red_max + 1; avail_greens = cmap_info->green_max + 1; avail_blues = cmap_info->blue_max + 1; avail_colors = avail_reds * avail_greens * avail_blues; } else { switch (vis_info->class) { case PseudoColor: case StaticColor: case GrayScale: case StaticGray: avail_colors = vis_info->colormap_size; avail_reds = vis_info->colormap_size; avail_greens = vis_info->colormap_size; avail_blues = vis_info->colormap_size; break; case DirectColor: case TrueColor: avail_reds = 1; for (temp = vis_info->red_mask; temp > 0; temp >>= 1) { if (temp & 1) avail_reds *= 2; } avail_greens = 1; for (temp = vis_info->green_mask; temp > 0; temp >>= 1) { if (temp & 1) avail_greens *= 2; } avail_blues = 1; for (temp = vis_info->blue_mask; temp > 0; temp >>= 1) { if (temp & 1) avail_blues *= 2; } avail_colors = avail_reds * avail_greens * avail_blues; break; } } /* ----------------------------------------------------------------------- Section II: Mark the information block as criteria are tested for satisfaction. Also, keep numbers for the degree to which the available colors surpass the specified minima. ----------------------------------------------------------------------- */ if (PEXUtMinColors & (criteria->hard_criteria_mask | criteria->soft_criteria_mask)) { if (avail_colors < criteria->min_colors) { p_info->unmet_hard_criteria |= (criteria->hard_criteria_mask & PEXUtMinColors); p_info->unmet_soft_criteria |= (criteria->soft_criteria_mask & PEXUtMinColors); } colors_excess = avail_colors - criteria->min_colors; } else { /* MinColors is *not* a criteria; set colors_excess to zero * if any of MinRed-Green-Blue are critera, otherwise set to * the number of available colors. * This allows "color richness" to be the tie breaker for * equally qualified visuals when no color criteria has * been specified. */ if ((PEXUtMinRed | PEXUtMinGreen | PEXUtMinBlue) & (criteria->hard_criteria_mask | criteria->soft_criteria_mask)) { colors_excess = 0; } else { colors_excess = avail_colors; } } if (PEXUtMinRed & (criteria->hard_criteria_mask | criteria->soft_criteria_mask)) { if (avail_reds < criteria->min_red) { p_info->unmet_hard_criteria |= (criteria->hard_criteria_mask & PEXUtMinRed); p_info->unmet_soft_criteria |= (criteria->soft_criteria_mask & PEXUtMinRed); } reds_excess = avail_reds - criteria->min_red; } else { reds_excess = 0; } if (PEXUtMinGreen & (criteria->hard_criteria_mask | criteria->soft_criteria_mask)) { if (avail_greens < criteria->min_green) { p_info->unmet_hard_criteria |= (criteria->hard_criteria_mask & PEXUtMinGreen); p_info->unmet_soft_criteria |= (criteria->soft_criteria_mask & PEXUtMinGreen); } greens_excess = avail_greens - criteria->min_green; } else { greens_excess = 0; if (PEXUtMinBlue & (criteria->hard_criteria_mask | criteria->soft_criteria_mask)) { if (avail_blues < criteria->min_blue) { p_info->unmet_hard_criteria |= (criteria->hard_criteria_mask & PEXUtMinBlue); p_info->unmet_soft_criteria |= (criteria->soft_criteria_mask & PEXUtMinBlue); } blues_excess = avail_blues - criteria->min_blue; } else { blues_excess = 0; } } /* ----------------------------------------------------------------------- Section III: Compute an overall color rating based on to what degree the colors exceed the minima. If no color criteria were specified, this rating comes out zero. If sharable_colormap was a criterion, Visuals that are not named in properties lose their color rating. Visuals that were named in a property, but whose ramps do not meet the criteria, also lose. ----------------------------------------------------------------------- */ /* The RGB and "color" excess values may be near the limit of what * an int can represent here. Therefore a little extra care is * taken to cast the excesses to doubles before summing them. * Note that total_excess is declared as double. The assumption is * that a double can safely hold the sum. In the case of IEEE * math, the double will effectively have 53 bits available to * represent the sum, ensuring no overflow or loss of precision. */ total_excess = ((double) colors_excess) + ((double) reds_excess) + ((double) greens_excess) + ((double) blues_excess); if (total_excess < 0) { /* hopelessly negative! */ p_info->color_rating = 0; } else { if (total_excess >= 0x10000) { /* 24 bits */ p_info->color_rating = MAX_COLOR_RATING; } else { if (total_excess >= 0x1000) { /* 16 bits */ p_info->color_rating = MAX_COLOR_RATING - 1; } else { if (total_excess >= 0x100) { /* 12 bits */ p_info->color_rating = MAX_COLOR_RATING - 2; } else { p_info->color_rating = total_excess; } } } } return PEXUtSuccess; } /* PEXUt_evaluate_color_criteria */ static Bool PEXUt_is_PEX_db_supported( dpy, win, db_x ) Display *dpy; Window win; int db_x; { PEXExtensionInfo *PEXinfo; XWindowAttributes wattrs; unsigned long count; PEXRenderingTarget *target; /* ** Verify the PEX server is major version 5. */ PEXinfo = PEXGetExtensionInfo( dpy ); if ( PEXinfo == (PEXExtensionInfo *)NULL ) { return( False ); } if ( PEXinfo->major_version != 5 ) { return( False ); } /* ** Get the window attributes for use in later inquiries. */ if ( ! XGetWindowAttributes( dpy, win, &wattrs )) { return( False ); } /* ** Try MBX. ** ** Verify rendering to MBX buffers is supported. ** Verify the MBX extension is supported and that it is major version 3. ** Verify the MBX extension supports at least 2 buffers for this drawable. */ { int first_event, first_error, num, dc, i; XmbufBufferInfo *buf_info, *dc_info; if ((PEXinfo->minor_version == 0 ) || ((PEXinfo->minor_version >= 1 ) && PEXMatchRenderingTargets( dpy, win, wattrs.depth, PEXBufferDrawable, wattrs.visual, 1, &count, &target ) && (count == 1))) { if (XmbufQueryExtension( dpy, &first_event, &first_error )) { if (XmbufGetScreenInfo( dpy, win, &num, &buf_info, &dc, &dc_info )) { /*** /*** NOTE: some implementations return 0 for max_buffers on /*** MBX devices to indicate no limit. This does not /*** seem to be documented as an option for XmbufGetScreenInfo /*** but we'll help 'em out and check for this too. /***/ for (i=0; imax_buffers >= 2) || (buf_info->max_buffers == 0)) && (buf_info->visualid == XVisualIDFromVisual(wattrs.visual))) { return( True ); } *buf_info++; } } } } } /* ** MBX not available, so try double-buffer escapes. ** ** The escapes are not usable if db_x; ** the escapes are not available on pre-5.1 servers (unless server is Sun). ** Verify the double-buffer escape is supported. */ if ( ! db_x ) { if ((PEXinfo->minor_version == 1) || (strncmp( PEXinfo->vendor_name, "SunPEX 2.0", 10 ) == 0 )) { int enumtypes, i; unsigned long *enum_counts; PEXEnumTypeDesc *enum_info; enumtypes = PEXETEscape; if ( PEXGetEnumTypeInfo( dpy, win, 1, &enumtypes, PEXETIndex, &enum_counts, &enum_info )) { for ( i = 0; i < *enum_counts; i++ ) { if ( (short)enum_info[i].index == (short)ES_ESCAPE_ET_DBLBUFFER ) { return( True ); /* assume rest of E&S escapes */ } } } } } /* ** Pixmaps are not considered support for double-buffering; rather, pixmaps ** are a mechanism for doing smooth animation when double-buffering is not ** supported. ** ** However, return True if rendering to pixmaps is supported ** this is acceptable because the PEXUtDB utilities will double-buffer ** using pixmaps if rendering to pixmaps is supported. */ if ( PEXMatchRenderingTargets( dpy, win, wattrs.depth, PEXPixmapDrawable, wattrs.visual, 1, &count, &target ) && ( count == 1 ) ) { return( True ); } /* ** No double-buffering is supported. */ return( False ); } /* PEXUt_is_PEX_db_supported */ int PEXUt_evaluate_double_buffering_capability ( display, criteria, vis_info, p_info ) Display *display; PEXUtVisualCriteria *criteria; XVisualInfo *vis_info; visual_info_type *p_info; { int actual_capabilities; Window window; int db_x; int result; if (PEXUtDBCapability & (criteria->hard_criteria_mask | criteria->soft_criteria_mask)) { /* Create a temporary unmapped window in the visual. */ PEXUt_create_temporary_window (display, vis_info, &window); /* Determine if the window's visual supports the desired capabilities. */ db_x = (criteria->double_buffering_capability == PEXUtDBPEXAndX); result = PEXUt_is_PEX_db_supported (display, window, db_x); if (result) { actual_capabilities = db_x ? PEXUtDBPEXAndX: PEXUtDBPEX; } else { actual_capabilities = PEXUtDBNone; } /* Destroy the temporary window. */ PEXUt_destroy_temporary_window (display, vis_info, window); if (actual_capabilities != criteria->double_buffering_capability) { p_info->unmet_hard_criteria |= (criteria->hard_criteria_mask & PEXUtDBCapability); p_info->unmet_soft_criteria |= (criteria->soft_criteria_mask & PEXUtDBCapability); } } return PEXUtSuccess; } /* PEXUt_evaluate_double_buffering_capability */ int PEXUt_evaluate_color_approx_type ( display, criteria, vis_info, p_info ) Display *display; PEXUtVisualCriteria *criteria; XVisualInfo *vis_info; visual_info_type *p_info; { Window window; int found; int result; if (PEXUtColorApproxType & (criteria->hard_criteria_mask | criteria->soft_criteria_mask)) { /* Create a temporary unmapped window in the visual. */ PEXUt_create_temporary_window (display, vis_info, &window); /* Determine support for the color approx type using GetEnumTypeInfo. */ result = PEXUt_verify_color_approx_type (display, window, criteria->color_approx_type); /* Destroy the temporary window. */ PEXUt_destroy_temporary_window (display, vis_info, window); if (result == PEXUtSuccess) { found = True; } else { if (result == PEXUtCriteriaFailure) { found = False; } else { return result; } } if (!found) { p_info->unmet_hard_criteria |= (criteria->hard_criteria_mask & PEXUtColorApproxType); p_info->unmet_soft_criteria |= (criteria->soft_criteria_mask & PEXUtColorApproxType); } } return PEXUtSuccess; } /* PEXUt_evaluate_color_approx_type */ unsigned int PEXUt_compute_overall_rating ( p_info ) visual_info_type *p_info; { unsigned int rating; rating = (p_info->soft_rating << SOFT_SHIFT) + (p_info->class_rating << CLASS_SHIFT) + (p_info->color_rating << COLOR_SHIFT); return rating; } /* PEXUt_compute_overall_rating */ int PEXUt_create_temporary_window ( display, vis_info, window_return ) Display *display; XVisualInfo *vis_info; Window *window_return; { unsigned long window_mask; XSetWindowAttributes window_attrs; Colormap cmap_id; /* Create a window using override-redirect. Do not map it. If the visual is the default, use the root window. Otherwise, create a colormap to use. */ if (vis_info->visual == DefaultVisual (display, vis_info->screen)) { *window_return = RootWindow (display, vis_info->screen); return PEXUtSuccess; } else { cmap_id = XCreateColormap (display, RootWindow(display, vis_info->screen), vis_info->visual, AllocNone ); if (cmap_id == None) { return PEXUtXFailure; } window_attrs.colormap = cmap_id; window_mask = CWColormap; window_attrs.override_redirect = True; window_mask |= CWOverrideRedirect; window_attrs.background_pixel = 0; window_mask |= CWBackPixel; window_attrs.border_pixel = 0; window_mask |= CWBorderPixel; *window_return = XCreateWindow (display, RootWindow (display, vis_info->screen), 10, 10, 1, 1, 0, vis_info->depth, InputOutput, vis_info->visual, window_mask, &(window_attrs)); if (*window_return == None) { return PEXUtXFailure; } else { return PEXUtSuccess; } } } /* PEXUt_create_temporary_window */ int PEXUt_destroy_temporary_window ( display, vis_info, window ) Display *display; XVisualInfo *vis_info; Window window; { XWindowAttributes window_attrs; /* If this window is not in the default Visual, the Colormap and Window need to be freed. */ if (vis_info->visual != DefaultVisual (display, vis_info->screen)) { if (XGetWindowAttributes (display, window, &window_attrs)) XFreeColormap (display, window_attrs.colormap); XDestroyWindow (display, window); } return PEXUtSuccess; } /* PEXUt_destroy_temporary_window */ int PEXUt_verify_color_approx_type #if NeedFunctionPrototypes ( Display *display, Window window, PEXEnumTypeIndex color_approx_type ) #else ( display, window, color_approx_type ) Display *display; Window window; PEXEnumTypeIndex color_approx_type; #endif { int enum_types[1]; unsigned long *count; PEXEnumTypeDesc *enum_data; int enum_index; int found; /* Verify that specified color approx type is supported using PEXGetEnumTypeInfo. If not, return failure. */ enum_types[0] = PEXETColorApproxType; if (!PEXGetEnumTypeInfo (display, window, 1, enum_types, PEXETIndex, &count, &enum_data)) { return PEXUtPEXFailure; } found = False; for (enum_index = 0; enum_index < *count; enum_index++) { if (enum_data[enum_index].index == color_approx_type) { found = True; break; } } PEXFreeEnumInfo (1, count, enum_data); if (found) { return PEXUtSuccess; } else { return PEXUtCriteriaFailure; } } /* PEXUt_verify_color_approx_type */ int PEXUt_synthesize_cmap_from_visual ( vis_info, cmap_info_return ) XVisualInfo *vis_info; XStandardColormap *cmap_info_return; { int num_reds, red_shift, red_mult; int num_greens, green_shift, green_mult; int num_blues, blue_shift, blue_mult; int base_pixel; unsigned long temp; int depth; int trial_value, overrun; switch (vis_info->class) { case PseudoColor: case StaticColor: /* Divide the number of planes into thirds, and then favor equal numbers of red and green planes at the expense of blue planes. Favor green at the expense of red in tight situations. This yields 121 in depth 4, 332 in depth 8, 444 in depth 12, and 888 in depth 24. */ depth = vis_info->depth; trial_value = depth / 3; overrun = depth % 3; if (overrun) trial_value += 1; num_greens = (1 << trial_value); num_reds = (1 << trial_value); if ((num_reds * num_greens) >= vis_info->colormap_size) num_reds = (1 << (trial_value-1)); num_blues = vis_info->colormap_size / (num_reds * num_greens); red_mult = num_greens * num_blues; green_mult = num_blues; blue_mult = 1; base_pixel = 0; break; case GrayScale: case StaticGray: /* PEXColorRange is advantageous in gray Visuals since it uses less cells to achieve the same effect. Here, use the entire colormap for gray levels. */ num_reds = vis_info->colormap_size; num_greens = vis_info->colormap_size; num_blues = vis_info->colormap_size; red_mult = 1; green_mult = 1; blue_mult = 1; base_pixel = 0; break; case DirectColor: case TrueColor: /* Determine the maximum number of color values for each of red, green, and blue, and the corresponding shifts. */ num_reds = 1; red_shift = 0; for (temp = vis_info->red_mask; temp > 0; temp >>= 1) { if (temp & 1) { num_reds *= 2; } else { red_shift++; } } red_mult = 1 << red_shift; num_greens = 1; green_shift = 0; for (temp = vis_info->green_mask; temp > 0; temp >>= 1) { if (temp & 1) { num_greens *= 2; } else { green_shift++; } } green_mult = 1 << green_shift; num_blues = 1; blue_shift = 0; for (temp = vis_info->blue_mask; temp > 0; temp >>= 1) { if (temp & 1) { num_blues *= 2; } else { blue_shift++; } } blue_mult = 1 << blue_shift; base_pixel = 0; break; } cmap_info_return->colormap = None; cmap_info_return->visualid = vis_info->visualid; cmap_info_return->killid = None; cmap_info_return->red_max = num_reds - 1; cmap_info_return->green_max = num_greens - 1; cmap_info_return->blue_max = num_blues - 1; cmap_info_return->red_mult = red_mult; cmap_info_return->green_mult = green_mult; cmap_info_return->blue_mult = blue_mult; cmap_info_return->base_pixel = base_pixel; return PEXUtSuccess; } /* PEXUt_synthesize_cmap_from_visual */ int PEXUt_load_color_approx_from_std_cmap ( color_approx_type, vis_info, cmap_info, capx_info_return ) int color_approx_type; XVisualInfo *vis_info; XStandardColormap *cmap_info; PEXColorApproxEntry *capx_info_return; { /* If color approx type was not specified, decide it based on the Visual class. */ if (color_approx_type == -1) { if ((vis_info->class == GrayScale) || (vis_info->class == StaticGray)) { color_approx_type = PEXColorRange; } else { color_approx_type = PEXColorSpace; } } /* Transfer information from the standard colormap property structure into the color approximation entry. */ if (color_approx_type == PEXColorRange) { capx_info_return->type = PEXColorRange; capx_info_return->model = PEXColorApproxRGB; capx_info_return->dither = PEXOn; capx_info_return->base_pixel = 0; capx_info_return->max1 = vis_info->colormap_size-1; capx_info_return->max2 = 0; capx_info_return->max3 = 0; capx_info_return->weight1 = 0.299; capx_info_return->weight2 = 0.587; capx_info_return->weight3 = 0.114; capx_info_return->mult1 = 1; capx_info_return->mult2 = 0; capx_info_return->mult3 = 0; } else { capx_info_return->type = PEXColorSpace; capx_info_return->model = PEXColorApproxRGB; capx_info_return->dither = PEXOn; capx_info_return->base_pixel = cmap_info->base_pixel; capx_info_return->max1 = cmap_info->red_max; capx_info_return->max2 = cmap_info->green_max; capx_info_return->max3 = cmap_info->blue_max; capx_info_return->weight1 = 0.0; capx_info_return->weight2 = 0.0; capx_info_return->weight3 = 0.0; capx_info_return->mult1 = cmap_info->red_mult; capx_info_return->mult2 = cmap_info->green_mult; capx_info_return->mult3 = cmap_info->blue_mult; } return PEXUtSuccess; } /* PEXUt_load_color_approx_from_std_cmap */ int PEXUt_count_bits_in_mask ( mask ) unsigned int mask; { int count = 0; while (mask) { if (mask & 0x1) count++; { mask >>= 1; } } return count; } /* PEXUt_count_bits_in_mask */ /* The following two routines are leveraged from Xmu code but have been modified for this application of them. */ int PEXUt_RWcell( Display *dpy, Colormap cmap, XColor *color, XColor *request, unsigned long *pixel, int okay_to_free_RO_cell) { unsigned long n = *pixel; if (okay_to_free_RO_cell) XFreeColors(dpy, cmap, &(request->pixel), 1, (unsigned long)0); if (! XAllocColorCells(dpy, cmap, (Bool) 0, (unsigned long *) NULL, (unsigned) 0, pixel, (unsigned) 1)) { return PEXUt_CMAP_RW_ALLOC; } if (*pixel != n) { XFreeColors(dpy, cmap, pixel, 1, (unsigned long) 0); return PEXUt_CMAP_RW_PIXEL; } request->pixel = *pixel; request->flags = DoRed | DoGreen | DoBlue; XStoreColors(dpy, cmap, request, 1); return 0; } /* PEXUt_RWcell */ int PEXUt_ROorRWcell( Display *dpy, Colormap cmap, XColor *color, int okay_to_free_RO_cell) { unsigned long pixel; XColor request; int result; /* Request a read only allocation of one cell in the colormap. If the read only allocation cannot be granted, give up, because there must be no free cells in the colormap. If the read only allocation is granted, but gives us a cell which is not the one that we just freed, it is probably the case that we are trying allocate White or Black or some other color which already has a read-only allocation in the map. So we try to allocate the previously freed cell with a read/write allocation, because we want contiguous cells for image processing algorithms. */ pixel = color->pixel; request.red = color->red; request.green = color->green; request.blue = color->blue; /* This next boolean expression relies heavily on the C rule that the expression is not evaluated farther than necessary to determine the value. Explanation of the logic in the expression: If XAllocColor returns non-zero, an error occurred in that call and we give up. If it returned a zero, then we check to see if it actually got the pixel we wanted. If so, everything is okay. Otherwise, we try RWcell to get a writeable cell. If that fails, we give up with an error. */ result = PEXUt_CMAP_RO_ALLOC; if (! XAllocColor(dpy, cmap, &request) || (request.pixel != pixel && (result = PEXUt_RWcell(dpy, cmap, color, &request, &pixel, okay_to_free_RO_cell)))) { return result; } return 0; } /* PEXUt_ROorRWcell */ @EOF chmod 444 PEXUtCmapint.c echo x - PEXUtCmapint.h cat >PEXUtCmapint.h <<'@EOF' #ifndef PEXUTCMAP_IH /* { */ #define PEXUTCMAP_IH /* (c) Copyright Hewlett-Packard Company, 1994, Fort Collins, Colorado (C) COPYRIGHT International Business Machines Corp. 1994 Copyright (c) 1994 by Sun Microsystems, Inc. All Rights Reserved Permission to use, copy, modify, and distribute this software and its documentation for any purpose and without fee is hereby granted, provided that the above copyright notices appear in all copies and that both the copyright notices and this permission notice appear in supporting documentation, and that the names of Hewlett-Packard, International Business Machines, or Sun Microsystems not be used in advertising or publicity pertaining to distribution of the software without specific, written prior permission. HEWLETT-PACKARD MAKES NO WARRANTY OF ANY KIND WITH REGARD TO THIS SOFTWARE, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. Hewlett-Packard shall not be liable for errors contained herein or direct, indirect, special, incidental or consequential damages in connection with the furnishing, performance or use of this software. INTERNATIONAL BUSINESS MACHINES CORPORATION PROVIDES THIS MATERIAL "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. SUN MICROSYSTEMS, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SUN MICROSYSTEMS, INC. BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. $Source: /src/rcs/PEX5/cge_utilities/PEXUtCmapint.h,v $ $Date: 94/03/02 11:25:00 $ $Revision: 510.1.200.3 $ Description: Internal header file for PEXUt cmap/visual utilities, not to be included by application programs. Notes: */ #ifndef NeedFunctionPrototypes #if defined(FUNCPROTO) || defined(__STDC__) || \ defined(__cplusplus) || defined(c_plusplus) #define NeedFunctionPrototypes 1 #else #define NeedFunctionPrototypes 0 #endif /* FUNCPROTO, __STDC__, __cplusplus, c_plusplus */ #endif /* NeedFunctionPrototypes */ #ifdef __cplusplus /* do not leave open across includes */ extern "C" { /* for C++ V2.0 */ #endif /* Color map creation returns */ #define PEXUt_CMAP_RO_ALLOC 1 #define PEXUt_CMAP_RW_PIXEL 2 #define PEXUt_CMAP_RW_ALLOC 3 /* This structure type is used to describe standard colormap properties that should searched as part of an interoperability convention. The ordering of entries in an array of these structures is the search order of the properties. The fields are used as follows: is_standard True if the colormap property is a current standard, i.e. supported by XGetRGBColormaps. False otherwise. have_atom True if the Atom in the property_atom field is valid, False if only the property_name string is valid. property_atom Atom value for the property name, which may be predefined or may have been fetched by an earlier call to XInternAtom. property_name the property name as a NULL-terminated character string. */ typedef struct { int is_standard; int have_atom; Atom property_atom; char *property_name; } interop_property_type; /* This structure describes each of the standard colormap properties to be searched when choosing a Visual, in priority order. Changing the interoperability convention should be a simple matter of adding or shuffling these entries. */ static interop_property_type interop_properties[] = { { True, True, XA_RGB_BEST_MAP, "" }, { True, True, XA_RGB_DEFAULT_MAP, "" }, }; #define NUM_INTEROP_PROPERTIES \ (sizeof(interop_properties)/sizeof(interop_property_type)) /* This structure type is the entry type for the SERVER_OVERLAY_VISUALS property. The property contains an entry for each Visual on the screen of the root window where it is attached. The fields are used as follows: visualid identifier of the Visual. transparent_type specifies the mechanism that controls transparency in the Visual: one of None, TransparentPixel, or TransparentMask. value pixel value that is transparent, if the transparent_type is TransparentPixel. layer specifies the layer of the Visual. Image layer is 0, overlay layer is 1. */ typedef struct { VisualID visualid; int transparent_type; int value; int layer; } overlay_visuals_type; /* This structure type is used internally by the PEXUt code to record information about each Visual that is considered. The central creator and user of the structure type is PEXUtFindVisual; it passes pointers to this structure type to several subsidiary routines. The fields are used as follows: unmet_hard_criteria a mask of the hard criteria that are not met by the Visual; if this is mask is non-zero, the Visual is not a candidate for selection. unmet_soft_criteria a mask of the soft criteria that are not met by the Visual; this mask is used in choosing among several Visuals that are candidates. property_ptr a pointer to the entry for the Visual in the first standard colormap property (in priority) that contains an entry for the Visual; if properties were not searched then this pointer is NULL. property_atom the atom for the property whose entry is addressed by property_ptr. visual_ptr a pointer to the description of the Visual. soft_rating, independent integers that represent the color_rating, relative rank of the Visual in the respective class_rating category: number of soft criteria that the Visual meets; level of color resolution; preference for Visual class. These fields are combined to form an overall rating in order to choose among several candidate Visuals. */ typedef struct { unsigned int unmet_hard_criteria; unsigned int unmet_soft_criteria; XStandardColormap *property_ptr; Atom property_atom; XVisualInfo *visual_ptr; unsigned int soft_rating; unsigned int color_rating; unsigned int class_rating; } visual_info_type; /* MAX_SOFT_RATING is the maximum value for the rating based on how well a Visual meets the soft criteria. It must be compatible with SOFT_SHIFT. And so on for the other factors used in rating Visuals. */ #define MAX_CLASS_RATING 0x1 #define CLASS_SHIFT 0 #define MAX_COLOR_RATING 0xFFFF #define COLOR_SHIFT 1 #define MAX_SOFT_RATING 0x1F #define SOFT_SHIFT 22 /* No specifications are provided for these internal utilities. For the most part, their names describe their functionality. */ extern int PEXUt_check_criteria ( #if NeedFunctionPrototypes Display *display, int screen, PEXExtensionInfo *ext_info, PEXUtVisualCriteria *criteria, XVisualInfo *vis_info_return, XStandardColormap *cmap_info_return, PEXColorApproxEntry *capx_info_return, unsigned int *unmet_criteria_return, Atom *std_prop_atom_return #endif ); extern int PEXUt_get_standard_cmap_property ( #if NeedFunctionPrototypes Display *display, int screen, interop_property_type *property_info, Atom *property_atom_return, int *property_count_return, XStandardColormap **property_data_return #endif ); extern int PEXUt_get_overlay_visuals_property ( #if NeedFunctionPrototypes Display *display, int screen, int *property_count_return, overlay_visuals_type **property_data_return #endif ); extern int PEXUt_evaluate_color_criteria ( #if NeedFunctionPrototypes Display *display, PEXUtVisualCriteria *criteria, XVisualInfo *vis_info, visual_info_type *p_info #endif ); extern int PEXUt_evaluate_double_buffering_capability ( #if NeedFunctionPrototypes Display *display, PEXUtVisualCriteria *criteria, XVisualInfo *vis_info, visual_info_type *p_info #endif ); extern int PEXUt_evaluate_color_approx_type ( #if NeedFunctionPrototypes Display *display, PEXUtVisualCriteria *criteria, XVisualInfo *vis_info, visual_info_type *p_info #endif ); extern unsigned int PEXUt_compute_overall_rating ( #if NeedFunctionPrototypes visual_info_type *p_info #endif ); extern int PEXUt_create_temporary_window ( #if NeedFunctionPrototypes Display *display, XVisualInfo *vis_info, Window *window_return #endif ); extern int PEXUt_destroy_temporary_window ( #if NeedFunctionPrototypes Display *display, XVisualInfo *vis_info, Window window #endif ); extern int PEXUt_verify_color_approx_type ( #if NeedFunctionPrototypes Display *display, Window window, PEXEnumTypeIndex color_approx_type #endif ); extern int PEXUt_synthesize_cmap_from_visual ( #if NeedFunctionPrototypes XVisualInfo *vis_info, XStandardColormap *cmap_info_return #endif ); extern int PEXUt_load_color_approx_from_std_cmap ( #if NeedFunctionPrototypes int color_approx_type, XVisualInfo *vis_info, XStandardColormap *cmap_info, PEXColorApproxEntry *capx_info_return #endif ); extern int PEXUt_match_color_approx_entry ( #if NeedFunctionPrototypes PEXColorApproxEntry *entry1, PEXColorApproxEntry *entry2 #endif ); extern int PEXUt_create_one_channel_map ( #if NeedFunctionPrototypes Display *display, XVisualInfo *vis_info, PEXColorApproxEntry *capx_info, Colormap *colormap_id_return #endif ); extern int PEXUt_create_three_channel_map ( #if NeedFunctionPrototypes Display *display, XVisualInfo *vis_info, PEXColorApproxEntry *capx_info, Colormap *colormap_id_return #endif ); extern int PEXUt_create_read_only_map ( #if NeedFunctionPrototypes Display *display, XVisualInfo *vis_info, PEXColorApproxEntry *capx_info, Colormap *colormap_id_return #endif ); extern int PEXUt_count_bits_in_mask ( #if NeedFunctionPrototypes unsigned int mask #endif ); #ifdef __cplusplus } /* for C++ V2.0 */ #endif #endif /* } PEXUTCMAP_IH */ @EOF chmod 444 PEXUtCmapint.h echo x - PEXUtExt.h cat >PEXUtExt.h <<'@EOF' #ifndef _PEXUTEXT_H_ /* [ */ #define _PEXUTEXT_H_ /* (c) Copyright Hewlett-Packard Company, 1994, Fort Collins, Colorado (C) COPYRIGHT International Business Machines Corp. 1994 Copyright (c) 1994 by Sun Microsystems, Inc. All Rights Reserved Permission to use, copy, modify, and distribute this software and its documentation for any purpose and without fee is hereby granted, provided that the above copyright notices appear in all copies and that both the copyright notices and this permission notice appear in supporting documentation, and that the names of Hewlett-Packard, International Business Machines, or Sun Microsystems not be used in advertising or publicity pertaining to distribution of the software without specific, written prior permission. HEWLETT-PACKARD MAKES NO WARRANTY OF ANY KIND WITH REGARD TO THIS SOFTWARE, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. Hewlett-Packard shall not be liable for errors contained herein or direct, indirect, special, incidental or consequential damages in connection with the furnishing, performance or use of this software. INTERNATIONAL BUSINESS MACHINES CORPORATION PROVIDES THIS MATERIAL "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. SUN MICROSYSTEMS, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SUN MICROSYSTEMS, INC. BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. $Source: /src/rcs/PEX5/cge_utilities/PEXUtExt.h,v $ $Date: 94/03/02 11:25:08 $ $Revision: 510.1.200.3 $ Description: Internal header file for PEXUt not to be included by application programs. Notes: */ /* ** Data structures and constants for escapes used in the utilities. ** This header file is intended to make the code more portable by eliminating ** the need to include vendor-specific extension header files. */ /* ** The following is to prevent multiple inclusion of escape information from ** any vendor specific header files. It relies on standard constant names ** for the escape opcode. */ #if !defined (ES_ESCAPE_DBLBUFFER) /* [ */ /* ** Constants for E&S double-buffering escapes */ #define ES_ESCAPE_DBLBUFFER 0x80040001 /* escape for db */ #define ES_RENDERER_SINGLEBUFFER 0 /* turn db off */ #define ES_RENDERER_DBLBUFFER 1 /* turn db on */ #define ES_ESCAPE_SWAPBUFFER 0x80040002 /* escape to swap buf */ #define ES_ESCAPE_SWAPBUFFERCONTENT 0x80040003 /* escape to inquire */ #define ES_DB_SWAP_CONTENT_UNDEFINED 0 /* what the content */ #define ES_DB_SWAP_CONTENT_CLEAR_TO_BACKGROUND 1 /* of the back buffer */ #define ES_DB_SWAP_CONTENT_UNCHANGED 2 /* will be after a */ #define ES_DB_SWAP_CONTENT_FRONTBUFFER 3 /* swap is done */ /* ** Constants for enumerated type descriptors returned from PEXGetEnumTypeInfo */ #define ES_ESCAPE_ET_DBLBUFFER 0x8401 #define ES_ESCAPE_ET_SWAPBUFFER 0x8402 #define ES_ESCAPE_ET_SWAPBUFFERCONTENT 0x8403 #define ES_ESCAPE_ETM_DBLBUFFER "ES_ESCAPE_DBLBUFFER" #define ES_ESCAPE_ETM_SWAPBUFFER "ES_ESCAPE_SWAPBUFFER" #define ES_ESCAPE_ETM_SWAPBUFFERCONTENT "ES_ESCAPE_SWAPBUFFERCONTENT" /* ** Data structures for E&S double-buffering. ** The PEXEscape function is defined in PEXlib.h. ** These define the data argument for PEXEscape. */ typedef struct { /* Data for ES_ESCAPE_DBLBUFFER in PEXEscape function */ Drawable drawable; unsigned long bufferMode; } esEscapeDblBuffer; typedef struct { /* Data for ES_ESCAPE_SWAPBUFFER in PEXEscape function*/ Drawable drawable; } esEscapeSwapBuffer; typedef struct {/* Data for ES_ESCAPE_SWAPBUFFERCONTENT in PEXEscapeWithReply */ Drawable drawable; } esEscapeSwapBufferContent; typedef struct {/* Return from PEXEscapeWithReply, ES_ESCAPE_SWAPBUFFERCONTENT*/ unsigned char type; unsigned char unused; unsigned short sequence_num; unsigned long length; unsigned long escapeId; unsigned long content; } esEscapeSwapBufferContentReply; #endif /* ] */ #if !defined (PEXEscapeQueryColorApprox) /* [ */ /* QueryColorApprox */ #define PEXEscapeQueryColorApprox 0x80010001 #define PEXETEscapeQueryColorApprox 0x8101 /* QueryColorApprox mnemonic */ #define PEXETMEscapeQueryColorApprox "QueryColorApprox" /* MIT types */ typedef struct { Drawable drawable; /* Drawable to compare capx against */ PEXColorApproxEntry capx; /* Color approx to check */ } PEXEscapeQueryColorApproxData; typedef struct { char capx_is_supported; /* True if given input approx supported */ char all_capxs; /* True if all alt capx's are returned */ char reserved1[2]; unsigned long count; /* Number of alternative color approx's */ unsigned int reserved2[3]; } PEXEscapeQueryColorApproxReplyData; /* CGE types */ typedef struct { short fpFormat; short unused; XID drawable; /* Drawable to compare capx against */ } pexExtQueryColorApproxData; typedef struct { unsigned char capxIsSupported; /* True if given input approx supported */ unsigned char allCapxs; /* True if all alt capx's are returned */ unsigned char unused1[2]; int count; /* Number of alternative color approx's */ char unused2[12]; } pexExtQueryColorApproxReplyData; #endif /* ] */ #endif /* _PEXUTEXT_H_ ] */ @EOF chmod 444 PEXUtExt.h echo x - README cat >README <<'@EOF' This is the README file for the CGE programming utilities. (c) Copyright Hewlett-Packard Company, 1994, Fort Collins, Colorado (C) COPYRIGHT International Business Machines Corp. 1994 Copyright (c) 1994 by Sun Microsystems, Inc. All Rights Reserved Permission to use, copy, modify, and distribute this documentation for any purpose and without fee is hereby granted, provided that the above copyright notices appear in all copies and that both the copyright notices and this permission notice appear in supporting documentation, and that the names of Hewlett-Packard, International Business Machines, or Sun Microsystems not be used in advertising or publicity pertaining to distribution of the software without specific, written prior permission. HEWLETT-PACKARD MAKES NO WARRANTY OF ANY KIND WITH REGARD TO THIS SOFTWARE, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. Hewlett-Packard shall not be liable for errors contained herein or direct, indirect, special, incidental or consequential damages in connection with the furnishing, performance or use of this software. INTERNATIONAL BUSINESS MACHINES CORPORATION PROVIDES THIS MATERIAL "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. SUNSOFT, INC. A SUN MICROSYSTEMS, INC. BUSINESS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SUNSOFT, INC. OR SUN MICROSYSTEMS, INC. BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. General Information ------------------- The CGE programming utilities provided in this directory are intended to ease the task of producing portable and interoperable CGE applications. The utilities are provided as C source. Please read the copyright notice above regarding this source code. Individual man pages for each utility function are provided in the on line manual pages. The entry points are: PEXUtSelectVisual PEXUtMakeWindowAndColormap PEXUtSimpleWindowAndColorMap PEXUtMakeColormap PEXUtMakeWindow PEXUtCheckColorApproximation PEXUtGetStandardColormapInfo The utilities may be made either shared or archived. To make the utilities into a shared library, enter: make shared To make the utilities into an archived library, enter: make archive To do both shared and archived libraries, enter: make @EOF chmod 664 README exit 0 .