/* rotate.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" /* The triangle's coordinates. */ static PEXCoord2D points[] = {{.4,.5},{.6,.5},{.5,.9}}; void redraw( dpy, window, renderer, angle ) Display *dpy; Window window; PEXRenderer renderer; double angle; { PEXColor colr; PEXVector2D shift; PEXMatrix3x3 translation, rotation; /* Redraw the window, after first erasing (clearing) it. */ XClearWindow( dpy, window ); PEXBeginRendering( dpy, window, renderer ); { #ifdef PRECONCAT /* Translate back to center of screen. */ shift.x = shift.y = 0.5; PEXTranslate2D( &shift, translation ); PEXSetLocalTransform2D( dpy, renderer, PEXOCRender, PEXReplace, translation ); /* Apply the rotation. */ PEXRotate2D( angle, rotation ); PEXSetLocalTransform2D( dpy, renderer, PEXOCRender, PEXPreConcatenate, rotation ); #elif USE_BUILD_TRANSFORM { PEXVector2D shift, scale; PEXCoord2D center; center.x = center.y = 0.5; shift.x = shift.y = 0; scale.x = scale.y = 1; PEXBuildTransform2D( ¢er, &shift, angle, &scale, rotation ); PEXSetLocalTransform2D( dpy, renderer, PEXOCRender, PEXReplace, rotation ); } #else /* Translate center of bar to the origin. */ shift.x = shift.y = -0.5; PEXTranslate2D( &shift, translation ); PEXSetLocalTransform2D( dpy, renderer, PEXOCRender, PEXPreConcatenate, translation ); /* Translate center of bar to the origin. */ shift.x = shift.y = -0.5; PEXTranslate2D( &shift, translation ); PEXSetLocalTransform2D( dpy, renderer, PEXOCRender, PEXReplace, translation ); /* Apply the rotation. */ PEXRotate2D( angle, rotation ); PEXSetLocalTransform2D( dpy, renderer, PEXOCRender, PEXPostConcatenate, rotation ); /* Translate back to center of screen. */ shift.x = shift.y = 0.5; PEXTranslate2D( &shift, translation ); PEXSetLocalTransform2D( dpy, renderer, PEXOCRender, PEXPostConcatenate, translation ); #endif /* Create the primitive. */ PEXSetInteriorStyle( dpy, renderer, PEXOCRender, PEXInteriorStyleSolid ); SET_COLOR( 1, 0, 0, colr ); /* red */ PEXSetSurfaceColor( dpy, renderer, PEXOCRender, PEXColorTypeRGB, &colr ); PEXFillArea2D( dpy, renderer, PEXOCRender, PEXShapeConvex, True, 3, points ); } PEXEndRendering( dpy, renderer, True ); XFlush( dpy ); } #define WIN_GEOM "500x500+50+50" 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; XWindowAttributes wattrs; PEXRenderer renderer; PEXRendererAttributes rattrs; PEXExtensionInfo *pexinfo; int done = 0; double angle = 0, delta; /* 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 ); /* Set up the PEX renderer. */ if ( IMMED_MODE_SPT( pexinfo ) ) { renderer = ora_setup_renderer( dpy, window, &capx_info, &rattrs ); } else { fprintf( stderr, "No immediate mode.\n" ); exit(1); } /* 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, angle ); break; case ButtonPress: switch( event.xbutton.button ) { case Button1: /* Rotate. */ delta = M_PI/10; for ( angle = delta; angle < 2*M_PI; angle += delta ) { redraw( dpy, window, renderer, angle ); sleep( 1 ); } /* Reset to initial position. */ angle = 0; redraw( dpy, window, renderer, angle ); break; default: done = 1; break; } break; } } XCloseDisplay( dpy ); return 0; }