/* indirect.c 1.1 */ /* 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" #define WIN_GEOM "500x500+50+50" extern void redraw(), set_colors(); main( argc, argv ) int argc; char *argv[]; { Display *dpy; Window window; XEvent event; XVisualInfo vis_info; XColor bkgd_color; XStandardColormap cmap_info; PEXColorApproxEntry capx_info; PEXRenderer renderer; PEXRendererAttributes rattrs; PEXExtensionInfo *pexinfo; int done = 0; /* Open a display and initialize PEX. */ dpy = ora_init_pex( argv, &pexinfo ); if ( !dpy ) exit(1); /* Determine the best visual to use. */ ora_find_best_visual( dpy, &vis_info ); /* Get a standard colormap for the visual. */ if ( !ora_get_standard_colormap( dpy, &vis_info, &cmap_info ) ) { fprintf ( stderr, "Cannot find a standard colormap\n" ); exit(1); } ora_set_stdcmap_approx( &vis_info, &cmap_info, &capx_info ); /* Create the window, giving it a gray background. */ bkgd_color.red = bkgd_color.green = bkgd_color.blue = 0x5555; bkgd_color.flags = DoRed | DoGreen | DoBlue; window = ora_create_window( dpy, &vis_info, &cmap_info, WIN_GEOM, &bkgd_color ); if ( IMMED_MODE_SPT( pexinfo ) ) { renderer = ora_setup_renderer( dpy, window, &capx_info, &rattrs ); } else { fprintf( stderr, "No immediate mode.\n" ); exit(1); } set_colors( dpy, rattrs.color_table ); /* Read and respond to X events. */ XSelectInput( dpy, window, ExposureMask | ButtonPressMask ); while ( !done ) { XNextEvent( dpy, &event ); switch ( event.type ) { case Expose: /* Flush remaining Expose events, then redraw. */ while ( XCheckTypedWindowEvent( dpy, window, Expose, &event ) ) ; /* empty statement */ redraw( dpy, window, renderer ); break; case ButtonPress: done = 1; break; } } XCloseDisplay( dpy ); return 0; } #define RED 1 #define YELLOW 2 #define WHITE 3 #define BLUE 4 static void set_colors( dpy, color_table ) Display *dpy; PEXLookupTable color_table; { PEXColorSpecifier colors[4]; /* Red */ colors[0].type = PEXColorTypeRGB; colors[0].value.rgb.red = 1.0; colors[0].value.rgb.green = 0.0; colors[0].value.rgb.blue = 0.0; /* Yellow */ colors[1].type = PEXColorTypeRGB; colors[1].value.rgb.red = 1.0; colors[1].value.rgb.green = 1.0; colors[1].value.rgb.blue = 0.0; /* White */ colors[2].type = PEXColorTypeRGB; colors[2].value.rgb.red = 1.0; colors[2].value.rgb.green = 1.0; colors[2].value.rgb.blue = 1.0; /* Blue */ colors[3].type = PEXColorTypeRGB; colors[3].value.rgb.red = 0.0; colors[3].value.rgb.green = 0.0; colors[3].value.rgb.blue = 1.0; /* Set the entries in the color table: four entries, starting */ /* with index 1 (entries 1, 2, 3, and 4 are set). */ PEXSetTableEntries( dpy, color_table, 1, 4, PEXLUTColor, (PEXPointer) colors ); } static PEXCoord2D border[2][4] = { /* outer contour */ {{0,0},{1,0},{1,1},{0,1}}, /* inner contour */ {{.05,.05},{.95,.05},{.95,.95},{.05,.95}} }; static char *title = "World Population"; static PEXCoord2D title_spot = {.5, .82}; static char *subtitle = "in billions"; static PEXCoord2D subtitle_spot = {.5, .75}; static char *label_1900 = "1900"; static PEXCoord2D label_1900_spot = {.20, .15}; static char *amount_1900 = "1.6"; static PEXCoord2D amount_1900_spot = {.33, .24}; static PEXCoord2D bar_1900[] = {{.28,.05},{.38,.05},{.38,.19},{.28,.19}}; static char *label_2000 = "2000"; static PEXCoord2D label_2000_spot = {.53, .15}; static char *amount_2000 = "6.1 (projected)"; static PEXCoord2D amount_2000_spot = {.66, .65}; static PEXCoord2D bar_2000[] = {{.61,.05},{.71,.05},{.71,.6},{.61,.6}}; void redraw( dpy, window, renderer ) Display *dpy; Window window; PEXRenderer renderer; { PEXListOfCoord2D contours[2]; /* Redraw the window, after first erasing (clearing) it. */ XClearWindow( dpy, window ); PEXBeginRendering( dpy, window, renderer ); { /* Set the text alignment for the title and all labels. */ PEXSetTextAlignment( dpy, renderer, PEXOCRender, PEXHAlignCenter, PEXVAlignBase ); /* The border. */ PEXSetSurfaceEdgeFlag( dpy, renderer, PEXOCRender, PEXOn ); PEXSetSurfaceEdgeColorIndex( dpy, renderer, PEXOCRender, WHITE ); PEXSetSurfaceColorIndex( dpy, renderer, PEXOCRender, BLUE ); PEXSetInteriorStyle( dpy, renderer, PEXOCRender, PEXInteriorStyleSolid ); contours[0].points = border[0]; contours[0].count = 4; contours[1].points = border[1]; contours[1].count = 4; PEXFillAreaSet2D( dpy, renderer, PEXOCRender, PEXShapeConvex, False, PEXContourNested, 2, contours ); /* The title. */ PEXSetTextColorIndex( dpy, renderer, PEXOCRender, WHITE ); PEXSetCharHeight( dpy, renderer, PEXOCRender, 0.04 ); PEXText2D( dpy, renderer, PEXOCRender, &title_spot, strlen(title), title ); PEXSetCharHeight( dpy, renderer, PEXOCRender, 0.02 ); PEXText2D( dpy, renderer, PEXOCRender, &subtitle_spot, strlen(subtitle), subtitle ); /* The 1900 bar. */ PEXSetSurfaceColorIndex( dpy, renderer, PEXOCRender, RED ); PEXFillArea2D( dpy, renderer, PEXOCRender, PEXShapeConvex, True, 4, bar_1900 ); /* The 1900 bar label. */ PEXSetTextColorIndex( dpy, renderer, PEXOCRender, YELLOW ); PEXSetCharHeight( dpy, renderer, PEXOCRender, 0.015 ); PEXText2D( dpy, renderer, PEXOCRender, &label_1900_spot, strlen(label_1900), label_1900 ); PEXText2D( dpy, renderer, PEXOCRender, &amount_1900_spot, strlen(amount_1900), amount_1900 ); /* The 2000 bar. */ PEXSetSurfaceEdgeType( dpy, renderer, PEXOCRender, PEXSurfaceEdgeDashed ); PEXFillArea2D( dpy, renderer, PEXOCRender, PEXShapeConvex, False, 4, bar_2000 ); /* The 2000 bar label. */ PEXText2D( dpy, renderer, PEXOCRender, &label_2000_spot, strlen(label_2000), label_2000 ); PEXText2D( dpy, renderer, PEXOCRender, &amount_2000_spot, strlen(amount_2000) , amount_2000 ); } PEXEndRendering( dpy, renderer, True ); XFlush( dpy ); }