/* highlight.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 #include #include #include #include #include #include #include #include #include #include #include "book_utils.h" #include "western-europe.h" /* Internal global variables */ static Display *dpy; static Window window; static PEXRenderer renderer; static PEXRendererAttributes rattrs; static Widget top, form, canvas, incl, excl; static Atom delete_window_atom; /* The structure ids. */ static PEXStructure w_europe, structs[NUM_COUNTRIES]; void create_model() { PEXColor color; PEXName names[2]; int i; /* Create the structures for the individual countries. */ for ( i = 0; i < NUM_COUNTRIES; i++ ) { structs[i] = PEXCreateStructure( dpy ); /* Add the country and group name to the name set. */ names[0] = (PEXName) countries[i].name; names[1] = (PEXName) countries[i].group; PEXAddToNameSet( dpy, structs[i], PEXOCStore, 2, names ); /* Create the primitive representing the country. */ PEXFillAreaSet2D( dpy, structs[i], PEXOCStore, PEXShapeUnknown, False, PEXContourUnknown, countries[i].num_lists, countries[i].lists ); } /* Create the top-level structure. */ w_europe = PEXCreateStructure( dpy ); PEXSetViewIndex( dpy, w_europe, PEXOCStore, 1 ); /* Set the edge attributes. */ PEXSetSurfaceEdgeFlag( dpy, w_europe, PEXOCStore, PEXOn ); SET_COLOR( 1, 1, 1, color ); /* white */ PEXSetSurfaceEdgeColor( dpy, w_europe, PEXOCStore, PEXColorTypeRGB, &color ); /* Set the interior attributes. */ PEXSetInteriorStyle( dpy, w_europe, PEXOCStore, PEXInteriorStyleSolid ); SET_COLOR( 1, 0, 0, color ); /* red */ PEXSetSurfaceColor( dpy, w_europe, PEXOCStore, PEXColorTypeRGB, &color ); /* Put all countries in the WESTERN_EUROPE Group. */ names[0] = (PEXName) WESTERN_EUROPE; PEXAddToNameSet( dpy, w_europe, PEXOCStore, 1, names ); /* Invoke all the countries. */ for ( i = 0; i < NUM_COUNTRIES; i++ ) PEXExecuteStructure( dpy, w_europe, PEXOCStore, structs[i] ); } static void redraw() { XClearWindow( dpy, window ); PEXRenderNetwork( dpy, window, renderer, w_europe ); XFlush( dpy ); } /* Callback to change the highlight filter. */ static void change_filter( w, name, call_data ) Widget w; int name; XmToggleButtonCallbackStruct *call_data; { PEXNameSet name_set; PEXName names[1]; int action; /* Determine which name set to change. */ if ( XtParent(w) == incl ) name_set = rattrs.highlight_incl; else if ( XtParent(w) == excl ) name_set = rattrs.highlight_excl; /* Should we add or remove the name from the set? */ action = (call_data->set ? PEXNSAdd : PEXNSRemove); names[0] = name; PEXChangeNameSet( dpy, name_set, action, 1, names ); /* Make the change appear. */ redraw(); } static void set_view( view_table ) PEXLookupTable view_table; { PEXViewEntry view; PEXCoord2D window[2]; double view_plane, front_plane, back_plane; PEXCoord prp; PEXNPCSubVolume viewport; /* The view orientation parameters. */ static PEXCoord view_ref_pt = {0,0,0}; static PEXVector view_plane_normal = {0,0,1}; static PEXVector view_up_vec = {0,1,0}; /* Compute the view orientation transform. */ (void)PEXViewOrientationMatrix( &view_ref_pt, &view_plane_normal, &view_up_vec, view.orientation ); /* The view mapping parameters. */ prp.x = 0.5; prp.y = 0.5; prp.z = 1; window[0].x = -0.1; window[1].x = 1.7; window[0].y = -0.1; window[1].y = 1.7; front_plane = 1; view_plane = 0; back_plane = 0; viewport.min.x = 0; viewport.max.x = 1; viewport.min.y = 0; viewport.max.y = 1; viewport.min.z = 0; viewport.max.z = 1; /* Compute the view mapping transform. */ (void)PEXViewMappingMatrix( window, &viewport, True, &prp, view_plane, back_plane, front_plane, view.mapping ); /* The view clipping parameters. */ view.clip_flags = PEXClippingAll; view.clip_limits = viewport; /* Set view 1. */ PEXSetTableEntries( dpy, view_table, 1, 1, PEXLUTView, (PEXPointer) &view ); } /* Callback for Expose events. */ static void expose( w, client_data, event ) Widget w; caddr_t client_data; XEvent *event; { /* Redraw when last Expose event received. */ if ( event->xexpose.count == 0 ) redraw(); } /* Callback function to quit the program. */ static void quit( w, client_data, call_data ) Widget w; caddr_t client_data; XmAnyCallbackStruct *call_data; { XClientMessageEvent *cm = &call_data->event->xclient; if ( cm->data.l[0] == delete_window_atom ) { XtDestroyWidget( top ); exit( 0 ); } } static void create_toggle_list( label, parent ) char *label; Widget parent; { Widget w; int i; /* Create the label. */ w = XtVaCreateManagedWidget( label, xmLabelGadgetClass, parent, NULL ); w = XtVaCreateManagedWidget( "_sep", xmSeparatorGadgetClass, parent, NULL ); /* Create the EFTA and EX items. */ w = XtVaCreateManagedWidget( "EFTA", xmToggleButtonGadgetClass, parent, NULL ); XtAddCallback( w, XmNvalueChangedCallback, change_filter, EFTA ); w = XtVaCreateManagedWidget( "EC", xmToggleButtonGadgetClass, parent, NULL ); XtAddCallback( w, XmNvalueChangedCallback, change_filter, EC ); /* Create an item for each country. */ for ( i = 0; i < NUM_COUNTRIES; i++ ) { w = XtVaCreateManagedWidget( countries[i].string, xmToggleButtonGadgetClass, parent, NULL ); XtAddCallback( w, XmNvalueChangedCallback, change_filter, countries[i].name ); } } main( argc, argv ) int argc; char *argv[]; { XtAppContext app; XVisualInfo vis_info; XStandardColormap cmap_info; PEXColorApproxEntry capx_info; XSetWindowAttributes wattrs; PEXExtensionInfo *pexinfo; char err[80]; /* Initialize the toolkit. */ argv[0] = "Western European Countries and Trade Groups"; top = XtVaAppInitialize( &app, "PEXlib", NULL, 0, &argc, argv, NULL, NULL ); /* See what display is being used. */ dpy = XtDisplay( top ); /* See if a PEX extension exists and initialize PEXlib. */ if ( PEXInitialize( dpy, &pexinfo, 80, err ) != 0 ) { fprintf ( stderr, "No PEX extension.\n" ); fprintf( stderr, "%s\n", err ); 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 ); /* Set the visual, depth, and colormap for the shell. */ XtVaSetValues( top, XtNvisual, vis_info.visual, XtNdepth, vis_info.depth, XtNcolormap, cmap_info.colormap, NULL ); /* Create the program's containing form. */ form = XtVaCreateManagedWidget( NULL, xmFormWidgetClass, top, NULL ); /* Create the widget we'll use as a drawing window. */ canvas = XtVaCreateManagedWidget( "canvas", xmDrawingAreaWidgetClass, form, XtVaTypedArg, XmNbackground, XmRString, "black", 6, XtNwidth, 450, XtNheight, 450, XmNtopAttachment, XmATTACH_FORM, XmNleftAttachment, XmATTACH_FORM, XmNbottomAttachment, XmATTACH_FORM, NULL ); /* Register an event handler for Expose events. */ XtAddEventHandler( canvas, ExposureMask, False, expose, 0 ); /* Create the Inclusion list. */ incl = XtVaCreateManagedWidget( "rowcolumn", xmRowColumnWidgetClass, form, XmNtopAttachment, XmATTACH_FORM, XmNleftAttachment, XmATTACH_WIDGET, XmNleftWidget, canvas, XmNbottomAttachment, XmATTACH_FORM, NULL ); create_toggle_list( "Inclusion", incl ); /* Create the Exclusion list. */ excl = XtVaCreateManagedWidget( "rowcolumn", xmRowColumnWidgetClass, form, XmNtopAttachment, XmATTACH_FORM, XmNleftAttachment, XmATTACH_WIDGET, XmNleftWidget, incl, XmNbottomAttachment, XmATTACH_FORM, NULL ); create_toggle_list( "Exclusion", excl ); /* Realize the widgets. */ XtRealizeWidget( top ); /* Set up to use window manager DELETE_WINDOW protocol. */ delete_window_atom = XInternAtom( dpy, "WM_DELETE_WINDOW", TRUE ); XmAddWMProtocols( top, &delete_window_atom, 1 ); XmSetWMProtocolHooks( top, delete_window_atom, NULL, NULL, quit, NULL ); /* Set the backing store attribute. */ window = XtWindow( canvas ); wattrs.backing_store = NotUseful; XChangeWindowAttributes( dpy, window, CWBackingStore, &wattrs ); /* Create the renderer and the structure. */ if ( STRUCTURE_SPT( pexinfo ) ) { renderer = ora_setup_renderer( dpy, window, &capx_info, &rattrs ); create_model( dpy ); } else { fprintf( stderr, "Structures not supported.\n" ); exit(1); } set_view( rattrs.view_table ); XtAppMainLoop( app ); return 0; }