/* book_utils.c 1.4 */ /* Copyright 1992, 1993 O'Reilly and Associates, Inc. Permission to use, copy, and modify this program is hereby granted, as long as this copyright notice appears in each copy of the program source code. */ #include "book_utils.h" Display* ora_init_pex( argv, pexinfo ) char *argv[]; PEXExtensionInfo **pexinfo; { char *dpy_name, err[80]; Display *dpy = (Display *)NULL; if ( argv[1] && strcmp( "-display", argv[1] ) == 0 ) dpy_name = XDisplayName( argv[2] ); else dpy_name = XDisplayName( NULL ); if ( !(dpy = XOpenDisplay( dpy_name )) ){ fprintf ( stderr, "Could not open display %s\n", dpy_name ); } else if ( PEXInitialize( dpy, pexinfo, 80, err ) != 0 ) { fprintf( stderr, "No PEX extension on %s.\n", dpy_name ); fprintf( stderr, "%s\n", err ); XCloseDisplay( dpy ); dpy = (Display *)NULL; } return dpy; } static void find_best_visual_5_0( dpy, chosen_vis ) Display *dpy; XVisualInfo *chosen_vis; { int i, size, num_vis, cmap_size; XVisualInfo vis_templ, *vis_list; /* Get all the visuals for the screen. */ vis_templ.screen = DefaultScreen( dpy ); vis_list = XGetVisualInfo( dpy, VisualScreenMask, &vis_templ, &num_vis ); /* Determine the best visual available. The best one is the */ /* one with the most colors and highest capabilities. */ cmap_size = 0; chosen_vis->class = -1; for ( i = 0; i < num_vis; i++ ) { /* Determine the number of colors available. */ switch ( vis_list[i].class ) { case TrueColor: case DirectColor: size = vis_list[i].red_mask | vis_list[i].green_mask | vis_list[i].blue_mask + 1; break; default: size = vis_list[i].colormap_size; } /* Choose this one if it supports more colors or is a higher */ /* class, but favor TrueColor over DirectColor. */ if ( size >= cmap_size ) { switch ( vis_list[i].class ) { case TrueColor: /* Choose TrueColor over anything else. */ *chosen_vis = vis_list[i]; cmap_size = size; break; case DirectColor: /* Don't choose DirectColor over TrueColor. */ if ( chosen_vis->class != TrueColor ) { *chosen_vis = vis_list[i]; cmap_size = size; } break; default: /* Choose the highest class. */ if ( vis_list[i].class >= chosen_vis->class ) { *chosen_vis = vis_list[i]; cmap_size = size; } break; } } } } static void find_best_visual_5_1( dpy, chosen_vis ) Display *dpy; XVisualInfo *chosen_vis; { int i, depth = 0, size, cmap_size = 0; int chosen_class; unsigned long num_targets, max_targets = 100; PEXRenderingTarget *targets, chosen_target; Visual *visual = (Visual *)NULL; /* Get all visuals the PEX extension on this server supports. */ PEXMatchRenderingTargets( dpy, RootWindow(dpy,DefaultScreen(dpy)), depth, PEXWindowDrawable, visual, max_targets, &num_targets, &targets ); /* Find the one with the most colors and capabilities. */ chosen_class = -1; for ( i = 0; i < num_targets; i++ ) { visual = targets[i].visual; /* Determine the number of colors available. */ switch ( visual->class ) { case TrueColor: case DirectColor: size = visual->red_mask | visual->green_mask | visual->blue_mask + 1; break; default: size = visual->map_entries; } /* Choose this one if it supports more colors or is a higher */ /* class, but favor TrueColor over DirectColor. */ if ( size >= cmap_size ) { switch ( visual->class ) { case TrueColor: /* Choose TrueColor over anything else. */ chosen_target = targets[i]; chosen_class = visual->class; cmap_size = size; break; case DirectColor: /* Don't choose DirectColor over TrueColor. */ if ( chosen_class != TrueColor ) { chosen_target = targets[i]; chosen_class = visual->class; cmap_size = size; } break; default: /* Choose the highest class. */ if ( visual->class >= chosen_class ) { chosen_target = targets[i]; chosen_class = visual->class; cmap_size = size; } break; } } } if ( num_targets > 0 ) { chosen_vis->visual = chosen_target.visual; chosen_vis->visualid = chosen_target.visual->visualid; chosen_vis->class = chosen_target.visual->class; chosen_vis->red_mask = chosen_target.visual->red_mask; chosen_vis->green_mask = chosen_target.visual->green_mask; chosen_vis->blue_mask = chosen_target.visual->blue_mask; chosen_vis->colormap_size = chosen_target.visual->map_entries; chosen_vis->bits_per_rgb = chosen_target.visual->bits_per_rgb; chosen_vis->screen = DefaultScreen(dpy); chosen_vis->depth = chosen_target.depth; XFree( (char *)targets ); } } void ora_find_best_visual( dpy, vis_info ) Display *dpy; XVisualInfo *vis_info; { PEXExtensionInfo *pex_info; pex_info = PEXGetExtensionInfo( dpy ); if ( VERSION_5_0( pex_info ) ) find_best_visual_5_0( dpy, vis_info ); else if ( VERSION_5_1( pex_info ) ) find_best_visual_5_1( dpy, vis_info ); } int ora_get_standard_colormap( dpy, vis_info, cmap_info ) Display *dpy; XVisualInfo *vis_info; XStandardColormap *cmap_info; { XStandardColormap *std_cmaps; Atom property; int i, num_cmaps; switch ( vis_info->class ) { case TrueColor: case StaticColor: property = XA_RGB_BEST_MAP; break; case PseudoColor: case DirectColor: default: property = XA_RGB_DEFAULT_MAP; break; case StaticGray: case GrayScale: property = XA_RGB_GRAY_MAP; break; } /* Ensure that the property is defined. */ if ( XmuLookupStandardColormap( dpy, vis_info->screen, vis_info->visualid, vis_info->depth, property, False, True ) ) { /* Get the standard colormap properties. */ if ( XGetRGBColormaps( dpy, RootWindow( dpy, DefaultScreen( dpy ) ), &std_cmaps, &num_cmaps, property ) ) { /* Find the properties for the specified visual. */ for ( i = 0; i < num_cmaps; i++ ) { if ( vis_info->visualid == std_cmaps[i].visualid ) { *cmap_info = std_cmaps[i]; return 1; } } XFree( (char *)std_cmaps ); } } return 0; } void ora_set_stdcmap_approx( vis_info, cmap_info, capx_info ) XVisualInfo *vis_info; XStandardColormap *cmap_info; PEXColorApproxEntry *capx_info; { switch ( vis_info->class ) { case DirectColor: case TrueColor: case PseudoColor: case StaticColor: default: capx_info->type = PEXColorSpace; capx_info->model = PEXColorApproxRGB; capx_info->dither = PEXOn; capx_info->base_pixel = cmap_info->base_pixel; capx_info->max1 = cmap_info->red_max; capx_info->max2 = cmap_info->green_max; capx_info->max3 = cmap_info->blue_max; capx_info->weight1 = 0; /* not used by PEXColorSpace */ capx_info->weight2 = 0; /* not used by PEXColorSpace */ capx_info->weight3 = 0; /* not used by PEXColorSpace */ capx_info->mult1 = cmap_info->red_mult; capx_info->mult2 = cmap_info->green_mult; capx_info->mult3 = cmap_info->blue_mult; break; case GrayScale: case StaticGray: capx_info->type = PEXColorRange; capx_info->model = PEXColorApproxRGB; capx_info->dither = PEXOn; capx_info->base_pixel = cmap_info->base_pixel; capx_info->max1 = cmap_info->red_max; capx_info->max2 = 0; /* not used by PEXColorRange */ capx_info->max3 = 0; /* not used by PEXColorRange */ /* Give the weights the NTSC intensity coefficients. */ capx_info->weight1 = 0.299; capx_info->weight2 = 0.587; capx_info->weight3 = 0.114; capx_info->mult1 = cmap_info->red_mult; capx_info->mult2 = 0; capx_info->mult3 = 0; break; } } Window ora_create_window( dpy, vis_info, cmap_info, geom, bkgd_colr ) Display *dpy; XVisualInfo *vis_info; XStandardColormap *cmap_info; char *geom; XColor *bkgd_colr; { Window window; XSetWindowAttributes wattrs; int x = 0, y = 0; unsigned int width = 300, height = 300; /* Determine the pixel value for the background. */ if ( XAllocColor( dpy, cmap_info->colormap, bkgd_colr ) == 0 ) /* Colormap is read/write and no more entries left. So use */ /* the colormap's base pixel, which will probably be black. */ bkgd_colr->pixel = cmap_info->base_pixel; /* Create the output window. */ wattrs.background_pixel = bkgd_colr->pixel; wattrs.border_pixel = bkgd_colr->pixel; wattrs.backing_store = NotUseful; wattrs.event_mask = ExposureMask; wattrs.colormap = cmap_info->colormap; XParseGeometry( geom, &x, &y, &width, &height ); window = XCreateWindow( dpy, RootWindow( dpy, vis_info->screen ), x, y, width, height, 1, vis_info->depth, InputOutput, vis_info->visual, CWBackPixel | CWBorderPixel | CWBackingStore | CWEventMask | CWColormap, &wattrs ); XMapWindow( dpy, window ); return window; } static void load_all_available_fonts( dpy, window, table ) Display *dpy; Window window; PEXLookupTable table; { int i, max; unsigned long num_fonts; char **font_names; PEXFont *font_ids; PEXTextFontEntry *entries; PEXTableInfo table_info; PEXExtensionInfo *pex_info; /* The X Consortium's sample server crashes when attempting to */ /* load fonts, and has them pre-loaded anyway. So return if */ /* that's the server we're dealing with. */ pex_info = PEXGetExtensionInfo( dpy ); if ( strstr( pex_info->vendor_name, "Sample Implementation" ) ) return; /* Determine the font table limit. */ if ( !PEXGetTableInfo( dpy, window, PEXLUTTextFont, &table_info ) ) return; /* bad display pointer or window */ max = table_info.definable_entries; /* Allocate space for the font ids and table entries. */ font_ids = (PEXFont *) malloc( max * sizeof(PEXFont) ); entries = (PEXTextFontEntry *) malloc( max * sizeof(PEXTextFontEntry) ); /* Get the font names, load the fonts, and store in the table. */ if ( font_names = PEXListFonts( dpy, "*", max, &num_fonts ) ) { for ( i = 0; i < num_fonts; i++ ) { font_ids[i] = PEXLoadFont( dpy, font_names[i] ); entries[i].count = 1; entries[i].fonts = &font_ids[i]; } PEXSetTableEntries( dpy, table, 1, num_fonts, PEXLUTTextFont, (PEXPointer) entries ); PEXFreeFontNames( num_fonts, font_names ); } free( font_ids ); free( entries ); } int ora_enum_type_supported( dpy, window, enum_type, value ) Display *dpy; Window window; int enum_type; int value; { int enum_types[1], i, found = 0; unsigned long *num_values; PEXEnumTypeDesc *values; enum_types[0] = enum_type; if ( PEXGetEnumTypeInfo( dpy, window, 1, enum_types, PEXETIndex, &num_values, &values ) ) { for ( i = 0; i < *num_values; i++ ) { if ( values[i].index == ((short)value) ) { found = 1; /* found it! */ break; /* out of for loop */ } } PEXFreeEnumInfo( 1, num_values, values ); } return found; } PEXRenderer ora_setup_renderer( dpy, window, capx_info, attrs ) Display *dpy; Window window; PEXColorApproxEntry *capx_info; PEXRendererAttributes *attrs; { unsigned long mask = 0; PEXRenderer renderer; /* Create all the bundle tables. */ mask |= PEXRALineBundle; attrs->line_bundle = PEXCreateLookupTable( dpy, window, PEXLUTLineBundle ); mask |= PEXRAMarkerBundle; attrs->marker_bundle = PEXCreateLookupTable( dpy, window, PEXLUTMarkerBundle ); mask |= PEXRATextBundle; attrs->text_bundle = PEXCreateLookupTable( dpy, window, PEXLUTTextBundle ); mask |= PEXRAInteriorBundle; attrs->interior_bundle = PEXCreateLookupTable( dpy, window, PEXLUTInteriorBundle ); mask |= PEXRAEdgeBundle; attrs->edge_bundle = PEXCreateLookupTable( dpy, window, PEXLUTEdgeBundle ); /* Conditionally create the pattern table. */ if ( ora_enum_type_supported( dpy, window, PEXETInteriorStyle, PEXInteriorStylePattern ) ) { mask |= PEXRAPatternTable; attrs->pattern_table = PEXCreateLookupTable( dpy, window, PEXLUTPattern ); } /* Create a font table. */ mask |= PEXRATextFontTable; attrs->text_font_table = PEXCreateLookupTable( dpy, window, PEXLUTTextFont ); load_all_available_fonts( dpy, window, attrs->text_font_table ); /* Create a color table. */ mask |= PEXRAColorTable; attrs->color_table = PEXCreateLookupTable( dpy, window, PEXLUTColor ); /* Create a view table. */ mask |= PEXRAViewTable; attrs->view_table = PEXCreateLookupTable( dpy, window, PEXLUTView ); /* Create a light table. */ mask |= PEXRALightTable; attrs->light_table = PEXCreateLookupTable( dpy, window, PEXLUTLight ); /* Create a depth cue table. */ mask |= PEXRADepthCueTable; attrs->depth_cue_table = PEXCreateLookupTable( dpy, window, PEXLUTDepthCue ); /* Create a color approximation table and set the default */ /* entry, entry 0, to the colormap approximation specified. */ mask |= PEXRAColorApproxTable; attrs->color_approx_table = PEXCreateLookupTable( dpy, window, PEXLUTColorApprox ); PEXSetTableEntries( dpy, attrs->color_approx_table, 0, 1, PEXLUTColorApprox, capx_info ); /* Create the highlighting, invisibility, and pick name sets. */ mask |= PEXRAHighlightIncl | PEXRAHighlightExcl; attrs->highlight_incl = PEXCreateNameSet( dpy ); attrs->highlight_excl = PEXCreateNameSet( dpy ); mask |= PEXRAInvisibilityIncl | PEXRAInvisibilityExcl; attrs->invisibility_incl = PEXCreateNameSet( dpy ); attrs->invisibility_excl = PEXCreateNameSet( dpy ); mask |= PEXRAPickIncl | PEXRAPickExcl; attrs->pick_incl = PEXCreateNameSet( dpy ); attrs->pick_excl = PEXCreateNameSet( dpy ); /* Create the renderer */ renderer = PEXCreateRenderer( dpy, window, mask, attrs ); return renderer; } int ora_get_colormap_and_visual( dpy, property, vis_info, cmap_info ) Display *dpy; Atom property; XVisualInfo *vis_info; XStandardColormap *cmap_info; { XStandardColormap *std_cmaps; XVisualInfo vis_templ, *visual; int num_cmaps, num_vis, i, cmap_size, size; char buf[256]; Status st; /* Get the colormap properties of the requested maps. */ st = XGetRGBColormaps( dpy, RootWindow( dpy, DefaultScreen( dpy ) ), &std_cmaps, &num_cmaps, property ); if ( st == 0 ) { /* The standard colormaps are not loaded. Try to load. */ XmuAllStandardColormaps( dpy ); /* Try again to get the properties. */ st = XGetRGBColormaps( dpy, RootWindow( dpy, DefaultScreen( dpy ) ), &std_cmaps, &num_cmaps, property ); if ( st == 0 ) { fprintf( stderr, "Sorry, the standard colormap is not" ); fprintf( stderr, " set and cannot be loaded.\n" ); return 0; } } /* Determine the best visual available. The best one is the */ /* one with the largest colormap size (the most colors). */ cmap_size = 0; for ( i = 0; i < num_cmaps; i++ ) { /* Get the visual info for the indicated visual id. */ vis_templ.visualid = std_cmaps[i].visualid; visual = XGetVisualInfo( dpy, VisualIDMask, &vis_templ, &num_vis ); /* See if the visual's got the largest color table. */ switch ( visual->class ) { case TrueColor: case DirectColor: size = visual->red_mask | visual->green_mask | visual->blue_mask + 1; break; default: size = visual->colormap_size; } if ( size > cmap_size ) { *vis_info = *visual; *cmap_info = std_cmaps[i]; cmap_size = visual->colormap_size; } } XFree( (char *)std_cmaps ); XFree( (char *)visual ); return 1; } int ora_create_colormap( dpy, vis_info, cmap_info, capx_info ) Display *dpy; XVisualInfo *vis_info; XStandardColormap *cmap_info; PEXColorApproxEntry *capx_info; { int st = 0, n; switch ( vis_info->class ) { case DirectColor: /* Create the largest possible equal-length ramps. */ st = ora_create_direct_map( dpy, vis_info, cmap_info, capx_info ); break; case PseudoColor: /* Create the largest NxNxN color sampling. */ n = (int)pow( (double)vis_info->colormap_size - 1, 1.0/3.0 ); st = ora_create_pseudo_map( dpy, vis_info, n, n, n, cmap_info, capx_info ); break; case GrayScale: /* Create a GrayScale colormap with max number of grays. */ /* (but leave one empty spot for the background color.) */ st = ora_create_gray_map( dpy, vis_info, vis_info->colormap_size - 1, cmap_info, capx_info ); break; case TrueColor: case StaticColor: case StaticGray: st = ora_create_read_only_map( dpy, vis_info, cmap_info, capx_info ); break; } return st; } int ora_create_direct_map( dpy, vis_info, cmap_info, capx_info ) Display *dpy; XVisualInfo *vis_info; XStandardColormap *cmap_info; PEXColorApproxEntry *capx_info; { int st, red_planes, green_planes, blue_planes; unsigned long i; unsigned long num_reds, num_greens, num_blues, num_colors; unsigned long rshift, gshift, bshift; unsigned long rmask, gmask, bmask; XColor *colors, *color; /* Create the colormap. */ cmap_info->visualid = vis_info->visualid; cmap_info->colormap = XCreateColormap( dpy, RootWindow( dpy, DefaultScreen( dpy )), vis_info->visual, AllocNone ); /* Determine the number of red, green, and blue planes and the */ /* maximum possible number of color values for each. */ red_planes = 0; num_reds = 1; for( i = vis_info->red_mask; i; i = i >> 1 ) if ( i & 1 ) { ++red_planes; num_reds *= 2; } cmap_info->red_max = num_reds - 1; green_planes = 0; num_greens = 1; for( i = vis_info->green_mask; i; i = i >> 1 ) if ( i & 1 ) { ++green_planes; num_greens *= 2; } cmap_info->green_max = num_greens - 1; blue_planes = 0; num_blues = 1; for( i = vis_info->blue_mask; i; i = i >> 1 ) if ( i & 1 ) { ++blue_planes; num_blues *= 2; } cmap_info->blue_max = num_blues - 1; /* Allocate the planes. */ st = XAllocColorPlanes( dpy, cmap_info->colormap, True, &cmap_info->base_pixel, 1, red_planes, green_planes, blue_planes, &rmask, &gmask, &bmask ); if ( st == 0 ) return 0; /* Determine the red, green, and blue multipliers by finding */ /* the first bit set in each mask. */ for ( rshift = 0; !(rmask & (1 << rshift)); rshift++ ) ; cmap_info->red_mult = 1 << rshift; for ( gshift = 0; !(gmask & (1 << gshift)); gshift++ ) ; cmap_info->green_mult = 1 << gshift; for ( bshift = 0; !(bmask & (1 << bshift)); bshift++ ) ; cmap_info->blue_mult = 1 << bshift; /* Store the colors in the colormap. */ num_colors = vis_info->colormap_size; colors = (XColor *) malloc( num_colors * sizeof(XColor) ); for ( i = 0, color = colors; i < num_colors; i++, color++ ) { color->flags = 0; color->pixel = cmap_info->base_pixel; if ( i < cmap_info->red_max ) { color->flags |= DoRed ; color->pixel |= (i << rshift); color->red = i * 65535 / cmap_info->red_max; } if ( i < cmap_info->green_max ) { color->flags |= DoGreen ; color->pixel |= (i << gshift); color->green = i * 65535 / cmap_info->green_max; } if ( i < cmap_info->blue_max ) { color->flags |= DoBlue; color->pixel |= (i << bshift); color->blue = i * 65535 / cmap_info->blue_max; } } XStoreColors( dpy, cmap_info->colormap, colors, num_colors ); free( colors ); /* Fill in the color approximation information. */ capx_info->type = PEXColorSpace; capx_info->model = PEXColorApproxRGB; capx_info->dither = PEXOn; capx_info->base_pixel = cmap_info->base_pixel; capx_info->max1 = cmap_info->red_max; capx_info->max2 = cmap_info->green_max; capx_info->max3 = cmap_info->blue_max; capx_info->weight1 = 0.0; /* not used by PEXColorSpace */ capx_info->weight2 = 0.0; /* not used by PEXColorSpace */ capx_info->weight3 = 0.0; /* not used by PEXColorSpace */ capx_info->mult1 = cmap_info->red_mult; capx_info->mult2 = cmap_info->green_mult; capx_info->mult3 = cmap_info->blue_mult; return 1; } int ora_create_pseudo_map( dpy, vis_info, nr, ng, nb, cmap_info, capx_info ) Display *dpy; XVisualInfo *vis_info; int nr, ng, nb; XStandardColormap *cmap_info; PEXColorApproxEntry *capx_info; { int num_colors, st, i, j, k, p; unsigned long *pixels; XColor *colors, *color; /* Create the colormap and fill in the standard cmap info. */ cmap_info->colormap = XCreateColormap( dpy, RootWindow( dpy, DefaultScreen( dpy )), vis_info->visual, AllocNone ); cmap_info->visualid = vis_info->visualid; cmap_info->blue_max = nb - 1; cmap_info->blue_mult = 1; cmap_info->green_max = ng - 1; cmap_info->green_mult = nb; cmap_info->red_max = nr - 1; cmap_info->red_mult = nb * ng; num_colors = nr * ng * nb; pixels = (unsigned long*) malloc( num_colors * sizeof(*pixels) ); st = XAllocColorCells( dpy, cmap_info->colormap, True, (unsigned long *)NULL, 0, pixels, num_colors ); if ( st == 0 ) { free( pixels ); return 0; } cmap_info->base_pixel = pixels[0]; free( pixels ); colors = (XColor *) malloc( num_colors * sizeof(*colors) ); p = cmap_info->base_pixel; for ( i = 0, color = colors; i < nr; i++ ) { for ( j = 0; j < ng; j++ ) { for ( k = 0; k < nb; k++ ) { color->flags = DoRed | DoGreen | DoBlue; color->pixel = p++; color->red = i * 65535 / cmap_info->red_max; color->green = j * 65535 / cmap_info->green_max; color->blue = k * 65535 / cmap_info->blue_max; ++color; } } } XStoreColors( dpy, cmap_info->colormap, colors, num_colors ); free( colors ); /* Fill in the color approximation information. */ capx_info->type = PEXColorSpace; capx_info->model = PEXColorApproxRGB; capx_info->dither = PEXOn; capx_info->base_pixel = cmap_info->base_pixel; capx_info->max1 = cmap_info->red_max; capx_info->max2 = cmap_info->green_max; capx_info->max3 = cmap_info->blue_max; capx_info->weight1 = 0.0; /* not used by PEXColorSpace */ capx_info->weight2 = 0.0; /* not used by PEXColorSpace */ capx_info->weight3 = 0.0; /* not used by PEXColorSpace */ capx_info->mult1 = cmap_info->red_mult; capx_info->mult2 = cmap_info->green_mult; capx_info->mult3 = cmap_info->blue_mult; return 1; } int ora_create_gray_map( dpy, vis_info, num_grays, cmap_info, capx_info ) Display *dpy; XVisualInfo *vis_info; int num_grays; XStandardColormap *cmap_info; PEXColorApproxEntry *capx_info; { int st, i, p; unsigned long *pixels; XColor *colors, *color; cmap_info->visualid = vis_info->visualid; cmap_info->colormap = XCreateColormap( dpy, RootWindow( dpy, DefaultScreen( dpy )), vis_info->visual, AllocNone ); cmap_info->red_max = num_grays - 1; cmap_info->red_mult = 1; pixels = (unsigned long*) malloc( num_grays * sizeof(*pixels) ); st = XAllocColorCells( dpy, cmap_info->colormap, True, (unsigned long *)NULL, 0, pixels, num_grays ); if ( st == 0 ) { free( pixels ); return 0; } cmap_info->base_pixel = pixels[0]; free( pixels ); /* Fill in the RGB color values. */ colors = (XColor *) malloc( num_grays * sizeof(*colors) ); p = cmap_info->base_pixel; for ( i = 0, color = colors; i < num_grays; i++ ) { color->flags = DoRed | DoGreen | DoBlue; color->pixel = p++; /* R, G, and B are the same intensity within a cell. */ color->red = color->green = color->blue = i * 65535 / (num_grays - 1); ++color; } XStoreColors( dpy, cmap_info->colormap, colors, num_grays ); free( colors ); /* Fill in the color approximation information. */ capx_info->type = PEXColorRange; capx_info->model = PEXColorApproxRGB; capx_info->dither = PEXOn; capx_info->base_pixel = cmap_info->base_pixel; capx_info->max1 = num_grays - 1; capx_info->max2 = 0; /* not used by PEXColorRange */ capx_info->max3 = 0; /* not used by PEXColorRange */ /* Give the weights the NTSC intensity coefficients. */ capx_info->weight1 = 0.299; capx_info->weight2 = 0.587; capx_info->weight3 = 0.114; capx_info->mult1 = 1.0; capx_info->mult2 = 0.0; capx_info->mult3 = 0.0; return 1; } int ora_create_read_only_map( dpy, vis_info, cmap_info, capx_info ) Display *dpy; XVisualInfo *vis_info; XStandardColormap *cmap_info; PEXColorApproxEntry *capx_info; { /* Create the colormap. */ cmap_info->colormap = XCreateColormap( dpy, RootWindow( dpy, DefaultScreen( dpy )), vis_info->visual, AllocNone ); /* Set up the colormap and color approximation info. */ cmap_info->base_pixel = 0; cmap_info->visualid = vis_info->visualid; /* The rest depends on the visual class. */ switch ( vis_info->class ) { case TrueColor: case StaticColor: cmap_info->red_max = vis_info->red_mask; cmap_info->red_mult = 1; while ( !(cmap_info->red_max & 0x01) ) { cmap_info->red_max >>= 1; cmap_info->red_mult <<= 1; } cmap_info->green_max = vis_info->green_mask; cmap_info->green_mult = 1; while ( !(cmap_info->green_max & 0x01) ) { cmap_info->green_max >>= 1; cmap_info->green_mult <<= 1; } cmap_info->blue_max = vis_info->blue_mask; cmap_info->blue_mult = 1; while ( !(cmap_info->blue_max & 0x01) ) { cmap_info->blue_max >>= 1; cmap_info->blue_mult <<= 1; } capx_info->type = PEXColorSpace; capx_info->model = PEXColorApproxRGB; capx_info->dither = PEXOn; capx_info->base_pixel = cmap_info->base_pixel; capx_info->max1 = cmap_info->red_max; capx_info->max2 = cmap_info->green_max; capx_info->max3 = cmap_info->blue_max; capx_info->weight1 = 0.0; /* not used by PEXColorSpace */ capx_info->weight2 = 0.0; /* not used by PEXColorSpace */ capx_info->weight3 = 0.0; /* not used by PEXColorSpace */ capx_info->mult1 = cmap_info->red_mult; capx_info->mult2 = cmap_info->green_mult; capx_info->mult3 = cmap_info->blue_mult; break; case StaticGray: cmap_info->red_max = vis_info->colormap_size - 1; cmap_info->red_mult = 1; capx_info->type = PEXColorRange; capx_info->model = PEXColorApproxRGB; capx_info->dither = PEXOn; capx_info->base_pixel = cmap_info->base_pixel; capx_info->max1 = cmap_info->red_max; capx_info->max2 = 0; /* not used by PEXColorRange */ capx_info->max3 = 0; /* not used by PEXColorRange */ /* Give the weights the NTSC intensity coefficients. */ capx_info->weight1 = 0.299; capx_info->weight2 = 0.587; capx_info->weight3 = 0.114; capx_info->mult1 = cmap_info->red_mult; capx_info->mult2 = 0; capx_info->mult3 = 0; break; } return 1; } #define NUM_LAT_SEGS 20 #define NUM_LON_SEGS 30 void ora_build_sphere( radius, sphere ) double radius; PEXListOfCoord *sphere; { /* Build a "wire" sphere, using a single spiral polyline. */ double phi, delta_phi, theta, delta_theta; unsigned long i; sphere->count = NUM_LAT_SEGS * NUM_LON_SEGS + 1; sphere->points = (PEXCoord *) malloc( (unsigned) (sphere->count * sizeof(PEXCoord)) ); phi = 0; /* start at the North pole */ delta_phi = M_PI / (NUM_LAT_SEGS * NUM_LON_SEGS); theta = 0; delta_theta = (2 * M_PI) / NUM_LON_SEGS; for ( i = 0; i < sphere->count; i++ ) { sphere->points[i].x = radius * sin( phi ) * sin( theta ); sphere->points[i].y = radius * cos( phi ); sphere->points[i].z = radius * sin( phi ) * cos( theta ); theta += delta_theta; phi += delta_phi; } } PEXStructure ora_build_axes_struct( dpy, origin, length ) Display *dpy; PEXCoord *origin; double length; { PEXVertexRGB x_axis[2], y_axis[2], z_axis[2]; PEXListOfVertex axes[3]; PEXStructure struct_id; /* Set the vertex coordinates and colors. */ axes[0].count = 2; axes[0].vertices.rgb = x_axis; x_axis[0].point = *origin; x_axis[1].point.x = origin->x + length; x_axis[1].point.y = origin->y; x_axis[1].point.z = origin->z; SET_COLOR( 1, 0, 0, x_axis[0] ) SET_COLOR( 1, 0, 0, x_axis[1] ) axes[1].count = 2; axes[1].vertices.rgb = y_axis; y_axis[0].point = *origin; y_axis[1].point.x = origin->x; y_axis[1].point.y = origin->y + length; y_axis[1].point.z = origin->z; SET_COLOR( 0, 1, 0, y_axis[0] ) SET_COLOR( 0, 1, 0, y_axis[1] ) axes[2].count = 2; axes[2].vertices.rgb = z_axis; z_axis[0].point = *origin; z_axis[1].point.x = origin->x; z_axis[1].point.y = origin->y; z_axis[1].point.z = origin->z + length; SET_COLOR( 0, 0, 1, z_axis[0] ) SET_COLOR( 0, 0, 1, z_axis[1] ) struct_id = PEXCreateStructure( dpy ); PEXPolylineSetWithData( dpy, struct_id, PEXOCStore, PEXGAColor, PEXColorTypeRGB, 3, axes ); return struct_id; }