v10i097: hpgl -- HPGL for X11, Part01/02

Andrew Gerber gerber at sushi.Solbourne.COM
Wed Dec 19 13:42:21 AEST 1990


Submitted-by: gerber at sushi.Solbourne.COM (Andrew Gerber)
Posting-number: Volume 10, Issue 97
Archive-name: xhpgl/part01

This is the X11 version of xhpgl originally written for X10.
xhpgl is a quick and dirty 7470a hpgl display program.

---- Cut Here and unpack ----
#!/bin/sh
# shar:	Shell Archiver  (v1.22)
#
#	Run the following text with /bin/sh to create:
#	  Imakefile
#	  Makefile.nonImake
#	  README
#	  RubberWin.c
#	  hpgl.l
#	  config.h
#	  hpgl.y
#	  xhpgl.c
#
if test -f Imakefile; then echo "File Imakefile exists"; else
echo "x - extracting Imakefile (Text)"
sed 's/^X//' << 'SHAR_EOF' > Imakefile &&
XCDEBUGFLAGS = -O
XYACCFLAGS = -dv
XINCLUDES = -I$(TOP) -I$(TOP)/X11
XDEPLIBS = $(DEPXLIB)
XLOCAL_LIBRARIES = $(XLIB)
X
XSRCS = y.tab.c y.tab.h xhpgl.c parse.c RubberWin.c lex.yy.c 
X
XOBJS = lex.yy.o xhpgl.o parse.o  RubberWin.o 
X
X
Xall::	xhpgl
X
Xy.tab.c: hpgl.y 
X	  yacc $(YACCFLAGS) hpgl.y
X
Xy.tab.h: hpgl.y 
X	  yacc $(YACCFLAGS) hpgl.y
X
Xlex.yy.c: hpgl.l y.tab.h $(FILES)
X	  lex $(LEXFLAGS) hpgl.l
X
X
XComplexProgramTarget(xhpgl)
X
X
SHAR_EOF
chmod 0644 Imakefile || echo "restore of Imakefile fails"
set `wc -c Imakefile`;Sum=$1
if test "$Sum" != "421"
then echo original size 421, current size $Sum;fi
fi
if test -f Makefile.nonImake; then echo "File Makefile.nonImake exists"; else
echo "x - extracting Makefile.nonImake (Text)"
sed 's/^X//' << 'SHAR_EOF' > Makefile.nonImake &&
XOBJS  = xhpgl.o \
X	lex.yy.o \
X	parse.o \
X	RubberWin.o 
X
XPARSER = hpgl.l \
X	 hpgl.y
X
XCOMPPARS = lex.yy.c \
X	   y.tab.c \
X	   y.tab.h \
X	   y.output
X
XFILES = Makefile
XHEADERS = 
X
XLINTFLAGS =
XCFLGS = -O
X#CFLGS = -O -DULTRIX
XLLIB = -lX11 -lm
XLEXFLAGS = 
XYACCFLAGS = -dv
X
X#BINDIR = /eng/eng4/ryach/local/uvax
XBINDIR = /eng/eng4/ryach/local/ui38
XMANDIR = /eng/eng4/ryach/local/man
XCHAPTER = 1
X
Xxhpgl:   $(OBJS) xhpgl.$(CHAPTER)
X	  /bin/cc $(CFLGS) $(OBJS) -o xhpgl $(LLIB)
X
Xy.tab.h: hpgl.y $(FILES)
X	  yacc $(YACCFLAGS) hpgl.y
X
Xlex.yy.o: lex.yy.c y.tab.c
X	  /bin/cc $(CFLGS) -c lex.yy.c
X
Xlex.yy.c: hpgl.l y.tab.h $(FILES)
X	  lex $(LEXFLAGS) hpgl.l
X
Xxhpgl.o:  xhpgl.c $(FILES) $(HEADERS) 
X	  /bin/cc $(CFLGS) -c xhpgl.c
X
XRubberWin.o:  xhpgl.c $(FILES) $(HEADERS) 
X	  /bin/cc $(CFLGS) -c RubberWin.c
X
XMakefile: 
X	cp Makefile.nonImake Makefile
X
X
SHAR_EOF
chmod 0644 Makefile.nonImake || echo "restore of Makefile.nonImake fails"
set `wc -c Makefile.nonImake`;Sum=$1
if test "$Sum" != "837"
then echo original size 837, current size $Sum;fi
fi
if test -f README; then echo "File README exists"; else
echo "x - extracting README (Text)"
sed 's/^X//' << 'SHAR_EOF' > README &&
XThis is a port of the X10 xhpgl to X11.  To compile, either use the
XImakefile and xmkmf to make your own Makefile, or edit
XMakefile.nonImake, move it to Makefile, and use it. You can edit the
Xfile config.h to define your window size, coordinate origin, and
Xmultipler.  This is only needed if the hpgl files does not define its
Xown coordinates via an "SC" call.
X
XThis version of xhpgl is improved with a speedup in plotting, using a
Xhand written parser.  Dashed lines are supported.
X
Xusage: xhpgl -fn [font] -cf [color_file] -geometry [geometry] plot_file
Xin window: [z] zoom [o] original [u] unzoom [r] redisplay [q] quit
X
XXhpgl now takes geometry on the command line, supports unzooming, and
Xis ICCCM compliant. Please send me copies of hpgl files which don't
Xwork with this parser.  There are some advanced plotting commands
Xwhich are not supported (text at angles, user defined fonts, etc).
X
XThe files pc.xw and shuttle.uuencoded are provided as example xhpgl
Xplots.  You must uudecode and uncompress the shuttle plot.
X
XThanks,
X
XAndrew Gerber
Xgerber at solbourne.com
X
XOriginal README File:  (from the X10 xhpgl)
X=-------------------------------------------------------------=
X
Xxhpgl is a quick and dirty 7470a hpgl display program.  It was written on 
Xa Sun 382i and tested on Sunos 4.0 and ultrix 3.2.  All it takes to compile
Xthe code is to modify the BINDIR pointer and MANDIR pointer and CHAPTER in the
XMakefile and type make and make install.  It should have no problems.  Sorry,
XI still do not have X11 so it is written for X10 and was tested for X10.3 and
XX10.4.
X
XIf xhpgl is being compiled on ultrix change -DUI38 in the Makefile to
X-DULTRIX.  -DUI38 is for the sun 386i.
X
XThe file pc.xw is a sample hpgl format file to use to test the software once
Xit has been compiled.  Other files are up to the user to generate.
X
XThe file hpcolors is a default color file to be placed in the users home
Xdirectory as .hpcolors.
X
XRandy Yach
SHAR_EOF
chmod 0644 README || echo "restore of README fails"
set `wc -c README`;Sum=$1
if test "$Sum" != "1935"
then echo original size 1935, current size $Sum;fi
fi
if test -f RubberWin.c; then echo "File RubberWin.c exists"; else
echo "x - extracting RubberWin.c (Text)"
sed 's/^X//' << 'SHAR_EOF' > RubberWin.c &&
X/*
X RubberWin.c; from olwm as distributed in X11R4
X *	Written for Sun Microsystems by Crucible, Santa Cruz, CA.
X
X        (c) Copyright 1989 Sun Microsystems, Inc. Sun design patents
X        pending in the U.S. and foreign countries. OPEN LOOK is a
X        trademark of AT&T. Used by written permission of the owners.
X
X
X        (c) Copyright Bigelow & Holmes 1986, 1985. Lucida is a registered
X        trademark of Bigelow & Holmes. Permission to use the Lucida
X        trademark is hereby granted only in association with the images
X        and fonts described in this file.
X
X        SUN MICROSYSTEMS, INC., AT&T, AND BIGELOW & HOLMES
X        MAKE NO REPRESENTATIONS ABOUT THE SUITABILITY OF
X        THIS SOURCE CODE FOR ANY PURPOSE. IT IS PROVIDED "AS IS"
X        WITHOUT EXPRESS OR IMPLIED WARRANTY OF ANY KIND.
X        SUN  MICROSYSTEMS, INC., AT&T AND BIGELOW  & HOLMES,
X        SEVERALLY AND INDIVIDUALLY, DISCLAIM ALL WARRANTIES
X        WITH REGARD TO THIS SOURCE CODE, INCLUDING ALL IMPLIED
X        WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
X        PARTICULAR PURPOSE. IN NO EVENT SHALL SUN MICROSYSTEMS,
X        INC., AT&T OR BIGELOW & HOLMES BE LIABLE FOR ANY
X        SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL DAMAGES,
X        OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA
X        OR PROFITS, WHETHER IN AN ACTION OF  CONTRACT, NEGLIGENCE
X        OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
X        WITH THE USE OR PERFORMANCE OF THIS SOURCE CODE.
X*/
X
X#include <errno.h>
X#include <stdio.h>
X#include <X11/Xos.h>
X#include <X11/Xlib.h>
X#include <X11/Xutil.h>
X#include <X11/cursorfont.h>
X
Xint	DefScreen;
XGC	RootGC;
XCursor	MoveWinCursor;
Xint	lastButton;
X
X
X/*
X * TraceBoundingBox -- trace an XOR box with the initial point specified
X *	by pEvent.  Return the dimensions of the box in boxX, boxY, boxW,
X *	and boxH.
X */
XTraceBoundingBox(dpy, win, pEvent, pboxX, pboxY, pboxW, pboxH)
XDisplay	*dpy;
XXEvent	*pEvent;
XWindow win;
Xshort	*pboxX, *pboxY, *pboxW, *pboxH;
X{
X	int	initX, initY;
X	int	mouseX, mouseY;
X	XEvent	event;
X	Bool	boxFinished;
X	XPoint	points[5];
X	int	anchorX, anchorY;
X	XGCValues       values;
X
X	/*
X	 * Change the cursor.
X	 */
X	MoveWinCursor = XCreateFontCursor(dpy, XC_top_left_arrow);
X
X	/* Create a GC for drawing in the root window. */
X        values.function = GXxor;
X	values.plane_mask = AllPlanes;
X 	values.foreground = 1;
X        values.subwindow_mode = IncludeInferiors;
X        RootGC = XCreateGC( dpy, RootWindow(dpy,DefaultScreen(dpy)), 
X                        ( GCPlaneMask | GCFunction | GCForeground |
X                          GCBackground | GCSubwindowMode ),
X                        &values );
X
X	XGrabPointer(dpy, win,
X		     True, 
X		     (ButtonReleaseMask | ButtonPressMask | PointerMotionMask),
X		     GrabModeAsync, GrabModeAsync,
X		     win,
X		     MoveWinCursor,
X		     CurrentTime);
X	DefScreen = DefaultScreen( dpy );
X	/*
X	 * Grab the server, so that the outline(s) don't
X	 * corrupt or get corrupted.
X	 */
X	XGrabServer(dpy);
X
X	/* Due to a bug (in the X11R3 server?) we have to set the
X	 * lastButton, used in rootEvent of RootWin.c, to a
X	 * button that is not checked for.  There are problems
X	 * with MotionNotify events getting through to the rootEvent
X	 * loop when they shouldn't.  They cause TraceBoundingBox
X	 * to be called again, without a button down.
X	 */
X	lastButton = Button5;
X
X	/* these values are fixed */
X	points[0].x = pEvent->xbutton.x;
X	points[0].y = pEvent->xbutton.y;
X	points[1].x = pEvent->xbutton.x;
X	points[3].y = pEvent->xbutton.y;
X	points[4].x = pEvent->xbutton.x;
X	points[4].y = pEvent->xbutton.y;
X
X	/* these are the values that vary */
X	points[1].y = pEvent->xbutton.y;
X	points[2].x = pEvent->xbutton.x;
X	points[2].y = pEvent->xbutton.y;
X	points[3].x = pEvent->xbutton.x;
X
X	/*
X	 * Draw initial outline
X	 */
X	XDrawLines(dpy, win,
X		       RootGC, points, 5, CoordModeOrigin);
X
X	for (boxFinished = False; boxFinished != True; )
X	{
X		XMaskEvent(dpy, ButtonReleaseMask|PointerMotionMask, &event);
X		switch (event.type)
X		{
X		case ButtonRelease:
X			boxFinished = True;
X			break;
X		
X		case MotionNotify:
X			/* erase old box */
X			XDrawLines(dpy, win,
X				       RootGC, points, 5, CoordModeOrigin);
X
X			/*
X			 * there may be multiple motion events queued up,
X			 * consume them and just use the last one.
X			 */
X			while (XCheckTypedEvent(dpy, MotionNotify, &event))
X				;
X
X			/* set new position */
X			points[1].y = event.xmotion.y;
X			points[2].x = event.xmotion.x;
X			points[2].y = event.xmotion.y;
X			points[3].x = event.xmotion.x;
X
X			/* draw new box */
X			XDrawLines(dpy, win,
X				       RootGC, points, 5, CoordModeOrigin);
X			break;
X		
X		default:
X			/*if (PrintOrphans)
X				DebugEvent(&event, "TraceBounding");*/
X			break;
X		}
X	}
X
X	/*
X	 * erase outline
X	 */
X	XDrawLines(dpy, win,
X		       RootGC, points, 5, CoordModeOrigin);
X
X	/*
X	 * let go of the server
X	 */
X	XUngrabServer(dpy);
X	XUngrabPointer(dpy, CurrentTime);
X
X	if (points[0].x < points[2].x)
X	{
X		*pboxX = points[0].x;
X		*pboxW = points[2].x - points[0].x;
X	}
X	else
X	{
X		*pboxX = points[2].x;
X		*pboxW = points[0].x - points[2].x;
X	}
X
X	if (points[0].y < points[2].y)
X	{
X		*pboxY = points[0].y;
X		*pboxH = points[2].y - points[0].y;
X	}
X	else
X	{
X		*pboxY = points[2].y;
X		*pboxH = points[0].y - points[2].y;
X	}
X	XFlush(dpy);
X}
X
XWindow Select_Window(dpy, win, pboxX, pboxY, pboxW, pboxH)
X     Display *dpy;
X	Window win;
X	short *pboxX, *pboxY, *pboxW, *pboxH;
X{
X  int status;
X  Cursor cursor;
X  XEvent event;
X  Window target_win = None;
X  int buttons = 0;
X
X  /* Make the target cursor */
X  cursor = XCreateFontCursor(dpy, XC_crosshair);
X
X  /* Grab the pointer using target cursor, letting it room all over */
X  status = XGrabPointer(dpy, win, False,
X			ButtonPressMask|ButtonReleaseMask, GrabModeSync,
X			GrabModeAsync, win, cursor, CurrentTime);
X  if (status != GrabSuccess) 
X    {
X      fprintf(stderr, "Fatal Error - Can't grab the mouse.");
X      exit(1);
X    }
X
X  /* Let the user select a window... */
X  while ((target_win == None)/* || (buttons != 0)*/) {
X    /* allow one more event */
X    XAllowEvents(dpy, SyncPointer, CurrentTime);
X    XWindowEvent(dpy, win,
X		 ButtonPressMask|ButtonReleaseMask, &event);
X    switch (event.type) {
X    case ButtonPress:
X      if (target_win == None) {
X	target_win = win; /* window selected */
X	if (target_win == None)
X	  target_win = win;
X      }
X      buttons++;
X      break;
X    case ButtonRelease:
X      if (buttons > 0) /* there may have been some down before we started */
X	buttons--;
X       break;
X    }
X  } 
X
X  XUngrabPointer(dpy, CurrentTime);      /* Done with pointer */
X  TraceBoundingBox(dpy, target_win, &event, pboxX, pboxY, pboxW, pboxH);
X  return(target_win);
X}
SHAR_EOF
chmod 0644 RubberWin.c || echo "restore of RubberWin.c fails"
set `wc -c RubberWin.c`;Sum=$1
if test "$Sum" != "6686"
then echo original size 6686, current size $Sum;fi
fi
if test -f hpgl.l; then echo "File hpgl.l exists"; else
echo "x - extracting hpgl.l (Text)"
sed 's/^X//' << 'SHAR_EOF' > hpgl.l &&
X%{
X/*****************************************************************\
X * FILE: hpgl.l   part of hpgl to X windows                      *
X *                                                               *
X * Written by Randy L. Yach aid by Jackie Harrison               *
X * Some additional rules added by Andrew Gerber                  *
X * (gerber at solbourne.com) during port to X11                     *
X *  Decription:                                                  *
X *    this is the lexical analizer of HPGL syntax.  All action   *
X *    tokens are covered first.                                  *
X\*****************************************************************/
X
X#include <stdio.h>
X#include <floatingpoint.h>
X#include "y.tab.h"
X
X#ifdef ULTRIX
X#    include <math.h>
X#endif
X
X/* need this because the sun 386i has a funny location of the atof
X   definition */
X
X#ifdef UI38
X#    include <floatingpoint.h>
X#endif
X
X/* need this to keep count of the input lines for error messages */
Xint hline = 1;
X%}
XD	[0-9]
XR       [0-9\.]
XRR      [0-9\.\-]
XA	[A-Z]
XLBL     [a-z\-\, \.A-Z0-9\:\;\(\)\&\^\%\$\#\@\!\"\'\~\`|?\/\<\>\_\+\-]
XDOT     [\.]
XCOMMA   [\,]
XALT     [A-Z\(\)\@]
XG       [A-Z0-9\;]
X%%
XLT	                        {
X                                return(LT);
X                                }
XLB{LBL}*\n?                      {
X                                /* strip off the LB and the ending ^C
X                                   from the input line and return it */
X			        strcpy(yylval.sb,&yytext[2]);
X				yylval.sb[strlen(yylval.sb)-1] = '\0';
X				return(LB);
X				}
XSC                              {
X				return(SC);
X				}
XSP{D}?                          {
X                                /* return the pen number */
X				yylval.i = yytext[2] - '0';
X				return(SP);
X				}
XPA              		{
X				return(PA);
X				}
XPR              		{
X				return(PR);
X				}
XPU              		{
X				return(PU);
X				}
XPD              		{
X				return(PD);
X				}
XEA              		{
X				return(EA);
X				}
XRA              		{
X				return(RA);
X				}
XUC                              {
X                                return(EAT_TO_SEMI);
X                                }
X\-?{D}+                         {
X                                /* integer digit routine */
X				yylval.i = atoi(yytext);
X				return(DIGIT);
X				}
X\-?{R}+                         {
X                                /* real digit routine */
X				yylval.f = atof(yytext);
X				return(NUMBER);
X				}
X\;				{
X				return(SEMICOLON);
X                                }
X\,                              {
X				return(COMMA);
X                                }
XIN\;                            return(RESET);
XDF\;                            return(RESET);
X[ \t]*			        ;
X[\n]                            {
X                                hline++;
X				}
X{DOT}{ALT}({G}+\:)?             ;
XC{A}{R}*({COMMA}{D}*)?\;        ;
XDI{RR}*({COMMA}{RR}*)?\;        ;
XDR{D}*({COMMA}{D}*)?\;          ;
XDT{A}\;                         ;
XDC\;                            ;
XDP\;                            ;
XO{A}\;                          ;
XIM{D}*({COMMA}{D}*)*\;          ;
XIP{D}*({COMMA}{D}*)*\;          ;
XIW{D}*({COMMA}{D}*)*\;          ;
XSA\;                            ;
XSI{R}*{COMMA}{R}*\;             ;
XSL{D}*\;                        ;
XSM{A}\;                         ;
XSR{R}*{COMMA}{R}*\;             ;
XSS\;                            ;
XSA\;                            ;
XTL{R}*({COMMA}{R}+)?\;          ;
XVS{D}*\;                        ;
XXT\;                            ;
XYT\;                            ;
XRO{D}\;                         ;
XPS{R}\;                         ;
X.                               ;
X%%
SHAR_EOF
chmod 0644 hpgl.l || echo "restore of hpgl.l fails"
set `wc -c hpgl.l`;Sum=$1
if test "$Sum" != "3657"
then echo original size 3657, current size $Sum;fi
fi
if test -f config.h; then echo "File config.h exists"; else
echo "x - extracting config.h (Text)"
sed 's/^X//' << 'SHAR_EOF' > config.h &&
X/* Set the default window size in pixels*/
X#define SIZEX 1000
X#define SIZEY 650
X
X/* Set the HP coordinate origin of the window */
X#define XMIN 0             
X#define YMIN 0             
X
X/* Set the muliplier for plotter units/xpixels */
X/* i.e. max X coord = XMIN + MULT * SIZEX */
X#define MULT 33  
X
X
SHAR_EOF
chmod 0666 config.h || echo "restore of config.h fails"
set `wc -c config.h`;Sum=$1
if test "$Sum" != "302"
then echo original size 302, current size $Sum;fi
fi
if test -f hpgl.y; then echo "File hpgl.y exists"; else
echo "x - extracting hpgl.y (Text)"
sed 's/^X//' << 'SHAR_EOF' > hpgl.y &&
X%{
X/*****************************************************************\
X * FILE: hpgl.y   part of hpgl to X windows                      *
X *                                                               *
X * Written by Randy L. Yach aid by Jackie Harrison               *
X * Ported to X11R4 by Andrew Gerber gerber at solbourne.com         *
X *                  Lex & Yacc info from Warner Losh             *
X *                                                               *
X * Description:                                                  *
X *    this is the yacc parser of HPGL syntax.  All plotting      *
X *    line drawing and labeling are done in this procedure       *
X\*****************************************************************/
X
X#include <stdio.h>
X#include <X11/X.h>
X#include <X11/Xlib.h>
X#include <math.h>
X
X/* need all these external global variables to interface with the many
X   X windows variables. */
Xextern int hline;
Xextern char yytext[];
Xextern double xMin,xMax,yMin,yMax;
Xextern int last_x, last_y;
Xextern int x,y;
Xextern int cur_pen,no_pen;
Xextern int pen_down;
Xextern int absolute;
Xextern XColor pen[];
Xextern Window main_window;
Xextern Font text_font;
Xextern short font_offset;
Xextern int minWidth,minHeight;
Xextern line;
Xextern GC gc;
Xextern Display *dpy;
XXTextItem text;
Xextern int span_count;
Xextern int is_color;
Xextern initialize_plotter();
Xextern int offscreen, last_offscreen;
X
X/* binary pattern definitions for drawing dashed lines */
X/* default |________|  */
X/* line 0  |        |  */
X/* line 1  |_       |  */
X/* line 2  |____    |  */
X/* line 3  |______  |  */
X/* line 4  |______ _|  */
X/* line 5  |_____ __|  */
X/* line 6  |____ _ _|  */
Xunsigned short line_pattern[7] = {
X    0x00, 0x80, 0xf0, 0xfc, 0xfd, 0xfb, 0xf5
X    };
X
X/* these variables are needed to calculate the default length
X   of the patterns used in the dashed lines */
Xint pat_len;
Xdouble pat_perc,tot_dist;
X
X%}
X
X%token LT LB PA PR PU PD SP SC DIGIT SEMICOLON COMMA NUMBER RESET EA EAT_TO_SEMI RA
X
X%start xhpgl_start
X
X%union {
Xint i;
Xchar sb[BUFSIZ];
Xfloat f;
X}
X
X%type <i> DIGIT SP
X%type <sb> LB
X%type <f> NUMBER
X
X%%
X
Xxhpgl_start    : /* empty statement */
X	       | xhpgl_start xhpgl_commands
X	       ;
X
Xopt_semicolon  : SEMICOLON
X               | ;
X  
Xxhpgl_commands : plot_coordinates cordinate_list opt_semicolon
X	       | SP opt_semicolon
X		 { /* begin select pen */
X		 /* set pen color from the SP command */
X		 if (is_color)
X		   {
X		     cur_pen = pen[$1].pixel; 
X		     XSetForeground(dpy, gc, cur_pen); 
X		   }
X		 } /* end select pen */
X	       | SC scale_coordinates SEMICOLON
X	       | text_labels
X	       | LT line_type_change SEMICOLON
X	       | RESET
X		 { /* begin reset */
X		 initialize_plotter();
X		 } /* end reset */
X	       ;
X
Xline_type_change : /* empty statement */ 
X                   { /* begin solid line */
X		   /* set up solid line type */
X/*		   line_type = XMakePattern(0xff,8,1); */
X		   } /* end solid line */
X		 | DIGIT COMMA NUMBER
X                   { /* begin dashed line */
X		   /* set up line pattern */
X/*		   pat_perc=($3/100.0);
X		   tot_dist=sqrt(pow((float)minWidth,(float)2)
X				+pow((float)minHeight,(float)2));
X		   pat_len=(int)((pat_perc*tot_dist)/8.0);
X		   if (pat_len < 1) pat_len = 1;
X		   line_type = XMakePattern(line_pattern[$1],8,pat_len);
X*/		   } /* end dashed line */
X		 | DIGIT COMMA DIGIT
X                   { /* begin dashed line */
X		   /* set up line pattern */
X/*		   pat_perc=($3/100.0);
X		   tot_dist=sqrt(pow((float)minWidth,(float)2)
X				+pow((float)minHeight,(float)2));
X		   pat_len=(int)((pat_perc*tot_dist)/8.0);
X		   if (pat_len < 1) pat_len = 1;
X		   line_type = XMakePattern(line_pattern[$1],8,pat_len);
X*/		   } /* end dashed line */
X		 ;
X
Xtext_labels    : LB
X                 { /* begin plot label */
X		 /* plot the text given at the current X,Y locations */
X		   text.chars = $1;
X		   text.nchars = strlen($1);
X		   text.delta = 0;
X		   text.font = text_font;
X		   
X		 XDrawText(dpy, main_window, gc, x,y-font_offset, &text, 1);
X		 } /* end plot label */
X	       ;	
X
Xplot_coordinates : PA
X	           { /* begin pen absolute coordinates */
X		   absolute = 1;
X		   } /* end pen absolute coordinates */
X		 | PD
X		   { /* begin pen relitave coordinates */
X		   pen_down = 1;
X		   } /* end pen relitave coordinates */
X		 | PU
X		   { /* begin pen up coordinates */
X		   pen_down = 0;
X		   } /* end pen up coordinates */
X		 | PR
X		   { /* begin pen down coordinates */
X		   absolute = 0;
X		   } /* end pen down coordinates */
X		 ;
X
Xscale_coordinates : DIGIT COMMA DIGIT COMMA DIGIT COMMA DIGIT
X                    { /* begin user scale */
X		    /* set up the user coodinate boundaries */
X		    xMin = $1;
X		    xMax = $3;
X		    yMin = $5;
X		    yMax = $7;
X                    } /* end user scale */
X                  ;
X
Xcordinate_list : /* empty statement */
X	       | cordinate_list cordinate_def comma_opt
X	       ;
X
Xcomma_opt      : /* empty statement */
X	       | COMMA
X	       ;
X
Xcordinate_def  : DIGIT COMMA DIGIT
X                 { /* begin cordinate change */
X		 /* get the new x,y points and convert then to absolute
X                    X window coodinates based on the user coordinates and 
X		    plot scale. */
X		 last_x = x;
X		 last_y = y;
X		 last_offscreen = offscreen;
X		 offscreen = 0;
X
X		 if (absolute)
X		     { /* begin abs coordinate */
X		     x=(double)(($1 - xMin)*(minWidth/(xMax - xMin)));
X		     y=(double)(($3 - yMin)*(minHeight/(yMax - yMin)));
X		     } /* end abs coordinate */
X		 else
X		     { /* begin relative coordinate */
X		     x=last_x+(double)(($1 - xMin)*(minWidth/(xMax - xMin)));
X		     y=last_y+(double)(($3 - yMin)*(minHeight/(yMax - yMin)));
X		     } /* end relitave coordinate */
X
X		 /* See if the point is on the screen; if it is not and the last point 
X		    was not on the screen, don't paint anything */
X		 y = minHeight - y;
X
X		 if ($1 < xMin || $1 > xMax || $3 < yMin && $3 > yMax)
X		   offscreen = 1;
X		 if (offscreen == 1 && last_offscreen == 1)
X		   break;
X
X                 /* if the pen is down, draw a line of the appropriate line
X		    type between the last x,y and the current x,y
X		    coordinates */
X                 if (pen_down)
X		     { /* begin draw line */
X		     XDrawLine(dpy, main_window, gc, last_x, last_y, x, y);
X		     ++span_count;
X		     } /* end draw line */
X		 } /* end cordinate change */
X	       ;
X
X%%
Xvoid yyerror(mess)
Xchar *mess;
X{ 
X/* begin parsing error */
X    fprintf(stderr,"Syntax error line %d token %s.\n",hline,yytext); 
X/* end parsing error */
X/*     exit();  */
X} 
X
Xint yywrap()
X{ /* begin */
X	return(1);
X} /* end */
X
SHAR_EOF
chmod 0644 hpgl.y || echo "restore of hpgl.y fails"
set `wc -c hpgl.y`;Sum=$1
if test "$Sum" != "6582"
then echo original size 6582, current size $Sum;fi
fi
if test -f xhpgl.c; then echo "File xhpgl.c exists"; else
echo "x - extracting xhpgl.c (Text)"
sed 's/^X//' << 'SHAR_EOF' > xhpgl.c &&
X /******************************************************************\
X  *                                                                *
X  *  File Name:  xhpgl.c    part of hpgl to Xwindows program       *
X  *                                                                *
X  *                                                                *
X  *  Original Author:  Randy L. Yach                               *
X  *                                                                *
X  *  Port to X11R4 and Enhancements: Andrew Gerber                 *
X  *                                  gerber at solbourne.COM          *
X  *  Functional description:                                       *
X  *                                                                *
X  *     This program will read a 7470a syntax HPGL file and        *
X  *     display it on an Xwindow display.                          *
X  *                                                                *
X  \******************************************************************/
X
X
X#include <X11/X.h>
X#include <X11/Xlib.h>
X#include <X11/Xutil.h>
X#include <X11/cursorfont.h>
X#include <stdio.h>
X#include "config.h"
X
Xextern Window Select_Window();
Xdouble xMin,xMax,yMin,yMax; /* user min/max coordinate boundaries */
Xdouble oxMin,oxMax,oyMin,oyMax; /* original user min/max coordinate boundaries */
Xint last_x, last_y; /* last x and y coordinates for line drawing */
Xint x,y;           /* current x and y coordinates for line drawing */
Xint cur_pen,no_pen,line; /* current pen color */
Xint pen_down;            /* pen status */
Xint absolute;            /* ploter status */
Xint span_count;          /* number of spans drawn */
Xint rectangle;           /* flag for rectangle drawing */
XFont text_font;          /* font info */
XXFontStruct *font_info;
Xshort font_offset;       /* distance from lower left to upper left of font */
XWindow main_window;      /* main window for plotting */
XXColor pen[10];          /* all pen colors for plotting */
Xint minWidth,minHeight;  /* size of X window for plotting */
Xint x_org, y_org;        /* x and y origins */
Xextern FILE *yyin;       /* File pointer for hpgl input file */
Xchar file_name[32];      /* file name of hpgl input file */
Xchar font_name[32];      /* font name of user supplied font */
Xint dont_scale;      /* should we scale coordinates? Not done if zooming */
XDisplay *dpy;
XGC gc;                   /* default GC */
Xint is_color;
Xint offscreen, last_offscreen;
XCursor wait_cursor, norm_cursor;
X/**/
X/******************************************************************\
X * prodedure usage()                                              *  
X ******************************************************************
X *    will pick a font based on the window size                   *
X \******************************************************************/
Xvoid usage()
X{
X  fprintf(stderr,"\nusage: xhpgl -fn [font] -cf [color_file] -geometry [geometry] plot_file\n");
X  fprintf(stderr,"in window: [z] zoom [o] original [u] unzoom [r] redisplay [q] quit\n");
X  exit(-1);
X}
X
X/**/
X/******************************************************************\
X * prodedure select_font(x,y)                                     *
X ******************************************************************
X *    will pick a font based on the window size                   *
X \******************************************************************/
X
Xvoid get_text_font(user_font)
X     int user_font;
X{
X  if (!user_font)
X    {
X      if ((minWidth < 350) || (minHeight < 350)) 
X	strcpy(font_name,"nil2");
X      else if ((minWidth < 700) || (minHeight < 700)) 
X	strcpy(font_name,"6x10");
X      else if ((minWidth < 800) || (minHeight < 800)) 
X	strcpy(font_name,"8x13");
X      else 
X	strcpy(font_name,"9x15");
X    }
X  
X  /* get the font and check if it is valid */
X  text_font = XLoadFont(dpy, font_name);
X  font_info = XQueryFont(dpy, text_font);
X}
X
X/**/
X/******************************************************************\
X * procedure reverse                                              *
X ******************************************************************
X *    used to revers a string s                                   *
X \******************************************************************/
Xvoid reverse(s)
X     /* reverse string s in place */
X     char s[];
X{ /* begin reverse */
X  int c,i,j;
X  
X  for (i = 0, j = strlen(s)-1; i < j; i++, j--) 
X    { /* begin for string */
X      c = s[i];
X      s[i] = s[j];
X      s[j] = c;
X    } /* end for string */
X} /* end reverse */
X
X/**/
X/******************************************************************\
X * procedure itoa                                                 *
X ******************************************************************
X *    converts an integer to a string.                            *
X \******************************************************************/
Xvoid itoa(s,n) 
X     /* convert n to characters in s */
X     int n;
X     char s[];
X{ /* begin itoa */
X  int i, sign;
X  
X  if ((sign = n) < 0)  /* record sign */
X    n = -n;
X  i = 0;
X  do {  /* generate digits in reverse order */
X    s[i++] = n % 10 + '0';  /* get next digit */
X  } while ((n /= 10) > 0);  /* delete it */
X  if (sign < 0)
X    s[i++] = '-';
X  s[i] = '\0';
X  reverse(s);
X} /* end itoa */
X
X/**/
X/******************************************************************\
X * procedure initialize_plotter                                   *
X ******************************************************************
X *    used to set up the default plotter conditions.              *
X \******************************************************************/
Xvoid initialize_plotter()
X{ /* begin initialize_plotter */
X  x=0;                  /* set current x plotter coordinate */
X  y=0;                  /* set current y plotter coordinate */
X  last_x=0;             /* set last x plotter coordinate */
X  last_y=0;             /* set last y plotter coordinate */
X  
X  pen_down=0;           /* put the pen in up position */
X  
X  cur_pen=pen[0].pixel; /* select no pen or no color */
X  no_pen=pen[0].pixel;  /* need a reference background color for text */
X  absolute = 1;
X  offscreen = 0;
X  /*    line_type = XMakePattern(0xff,8,1); /* set up solid line pattern */
X} /* end initialize_plotter */
X/**/
X/******************************************************************\
X * procedure draw_plot                                         *
X ******************************************************************
X *    used to plot the current picture                         *
X \******************************************************************/
Xdraw_plot()
X{
X  XEvent event;
X  
X  /* set the wait cursor */
X  XDefineCursor(dpy, main_window, wait_cursor);
X  
X  /* if a redraw occures, open the file again
X     and call the yacc parser.  then flush and
X     discard all other events.  this keeps multiple
X     events from clogging the queue while a long
X     plot is painting. */
X  if((yyin=fopen(file_name,"r"))==NULL)
X    { /* beign file error */
X      fprintf(stderr, "Could not open file %s for read access.\n" ,file_name);
X      exit(-1);
X    } /* end file error */
X  
X  /* clear the display to get rid of any opbjects
X     that are not drawn to proper scale if the window
X     was resized */
X  XClearWindow(dpy, main_window);
X  initialize_plotter();
X  span_count = 0;
X  yyparse();
X  fclose(yyin);
X  
X  /* Clear any pending expose events or keyboard events */
X  while(XCheckTypedEvent(dpy, Expose, &event)); 
X  while(XCheckTypedEvent(dpy, KeyPress, &event)); 
X  
X  /* turn off the wait cursor */
X  XUndefineCursor(dpy, main_window);
X}
X
X/**/
X/******************************************************************\
X * procedure assign_color                                         *
X ******************************************************************
X *    used to assign a color to each plotter pen.                 *
X \******************************************************************/
Xvoid assign_color(pen_num,color)
X     int pen_num;
X     char color[];
X{ /* begin assign_color */
X  if ((pen_num <=0) || (pen_num >= 9))
X    { /* begin invalid pen */
X      fprintf(stderr,"pen numbers must be 1 to 8.\n");
X      exit(-1);
X    } /* end invalid pen */
X  else
X    { /* begin valid pen */
X      if (strcmp(color,"black")==0) 
X	{ /* begin black */
X	  pen[pen_num].red=0; 
X	  pen[pen_num].green=0; pen[pen_num].blue=0;
X	} /* end black */
X      else if (strcmp(color,"red")==0) 
X	{ /* begin red */
X	  pen[pen_num].red=65535; 
X	  pen[pen_num].green=0; pen[pen_num].blue=0;
X	} /* end red */
X      else if (strcmp(color,"gold")==0) 
X	{ /* begin gold */
X	  pen[pen_num].red=61500;pen[pen_num].green=36750; 
X	  pen[pen_num].blue=25000;
X	} /* end gold */
X      else if (strcmp(color,"firebrick")==0) 
X	{ /* begin firebrick */
X	  pen[pen_num].red=42600;pen[pen_num].green=10500; 
X	  pen[pen_num].blue=10500;
X	} /* end firebrick */
X      else if (strcmp(color,"maroon")==0) 
X	{ /* begin maroon */
X	  pen[pen_num].red=42600; pen[pen_num].green=10500; 
X	  pen[pen_num].blue=32100;
X	} /* end maroon */
X      else if (strcmp(color,"orange")==0) 
X	{ /* begin orange */
X	  pen[pen_num].red=61200; pen[pen_num].green=15000; 
X	  pen[pen_num].blue=15000;
X	} /* end orange */
X      else if (strcmp(color,"pink")==0) 
X	{ /* begin pink */
X	  pen[pen_num].red=56400; pen[pen_num].green=42900; 
X	  pen[pen_num].blue=42900;
X	} /* end pink */
X      else if (strcmp(color,"turquoise")==0) 
X	{ /* begin turquoise */
X	  pen[pen_num].red=51900; pen[pen_num].green=65535; 
X	  pen[pen_num].blue=65535;
X	} /* end turquoise */
X      else if (strcmp(color,"violet")==0) 
X	{ /* begin violet */
X	  pen[pen_num].red=23700; pen[pen_num].green=14100; 
X	  pen[pen_num].blue=23700;
X	} /* end violet */
X      else if (strcmp(color,"green")==0) 
X	{ /* begin green */
X	  pen[pen_num].red=0; 
X	  pen[pen_num].green=65535; pen[pen_num].blue=0;
X	} /* end green */
X      else if (strcmp(color,"blue")==0) 
X	{ /* begin blue */
X	  pen[pen_num].red=0; 
X	  pen[pen_num].green=0; pen[pen_num].blue=65535;
X	} /* end blue */
X      else if (strcmp(color,"yellow")==0) 
X	{ /* begin yellow */
X	  pen[pen_num].red=65535; 
X	  pen[pen_num].green=65535; pen[pen_num].blue=0;
X	} /* end yellow */
X      else if (strcmp(color,"cyan")==0) 
X	{ /* begin cyan */
X	  pen[pen_num].red=0; 
X	  pen[pen_num].green=65535; pen[pen_num].blue=65535;
X	} /* end cyan */
X      else if (strcmp(color,"magenta")==0) 
X	{ /* begin magenta */
X	  pen[pen_num].red=65535; 
X	  pen[pen_num].green=0; pen[pen_num].blue=65535;
X	} /* end magenta */
X      else if (strcmp(color,"white")==0) 
X	{ /* begin white */
X	  pen[pen_num].red=65535; 
X	  pen[pen_num].green=65535; pen[pen_num].blue=65535;
X	} /* end white */
X      else 
X	{ /* begin default white */
X	  fprintf(stderr,"Color %s not supported, using white.\n",color);
X	  pen[pen_num].red=65535; 
X	  pen[pen_num].green=65535; pen[pen_num].blue=65535;
X	} /* begin default white */
X    } /* end valid pen */
X} /* end assign_color */
X
X/**/
Xmain(argc, argv)
X     int argc;
X     char *argv[];
X{ /* begin main */
X  
X  /* variable declerations */
X  Pixmap pixmap,bpix; /* Used for frame and background of main window */
X  XEvent event;       /* used for watching for keys in main window */
X  XFontStruct *text_font_info; /* font information structure */
X  
X  
X  char size_def[22];  /* is the default size used for creating the window */
X  char temp[22];      /* temporary string holder */
X  int user_font = 0;  /* need to know if the user entered a font */
X  
X  int i; /* counter */
X  char user_color[10]; /* string for user color name */
X  char *color_file_path; /* path to user color file */
X  char color_file[65]; /* color file name */
X  FILE *color_file_pointer; /* color file pointer */
X  Colormap default_colormap; /* default colormap */
X  int default_screen; /* default screen */
X  XCharStruct big_char;   
X  XSetWindowAttributes attr;
X  XSizeHints size_hints;
X  int user_position;     /* has user specified window size and location */
X  int sync; /* has user specified synchronous mode */
X  extern double xScale;
X  extern double yScale;
X
X
X
X  /* should we scale coordinates? Not done if zooming */
X  /* set default value for dont_scale */
X  dont_scale = 0;
X
X  /* set default value for rectangle */
X  rectangle = 0;
X
X  /* set up default font_name and file_name */
X  *font_name='\0';
X  *file_name='\0';
X  
X  /* set up the default color file path and name */
X  color_file_path = (char *) getenv("HOME");
X  if (color_file_path != NULL)
X    {
X      strcpy(color_file,color_file_path);
X      strcat(color_file,"/.hpcolors");
X    }
X  else
X      strcat(color_file,".hpcolors");
X    
X  
X  /* set up the default pixel size of the display window.  all plot
X     coordinates will be scaled to these coordinates */
X  minWidth=SIZEX;
X  minHeight=SIZEY;
X  strcpy(size_def,"=");
X  itoa(temp,SIZEX);
X  strcat(size_def,temp);
X  strcat(size_def,"x");
X  itoa(temp,SIZEY);
X  strcat(size_def,temp);
X  strcat(size_def,"+0+0");
X  
X  /* set up default window origins */
X  x_org = 0;
X  y_org = 0;
X
X  /* initialize all the pen colors to default value */
X  pen[1].red=65535; pen[1].green=0; pen[1].blue=0;
X  pen[2].red=0; pen[2].green=65535; pen[2].blue=0;
X  pen[3].red=0; pen[3].green=0; pen[3].blue=65535;
X  pen[4].red=0; pen[4].green=65535; pen[4].blue=65535;
X  pen[5].red=65535; pen[5].green=0; pen[5].blue=65535;
X  pen[6].red=65535; pen[6].green=65535; pen[6].blue=0;
X  pen[7].red=65535; pen[7].green=65535; pen[7].blue=65535;
X  pen[8].red=65535; pen[8].green=65535; pen[8].blue=65535;
X  
X  /* define the window black and white colors.  let the user
X     defint all the rest.  pen 0 is background black and pen 9
X     is frame white.  pens 1-8 are user definable */
X  pen[0].red=0; pen[0].green=0; pen[0].blue=0; /* background black */
X  pen[9].red=65535; pen[9].green=65535; pen[9].blue=65535; /* white */
X  
X  /* check to see if the user did not enter a file name and print
X     and error message */
X  if(argc == 1) usage();
X
X  /* by default user does not specify position */
X  user_position = 0;
X
X  /* parse the input arguments and get the file name and font name.
X     also get the geometry.
X     This program will use the last arg sent as the file to plot. */
X  
X  for(i = argc - 1; i; i--)
X    { /* begin input arg parseing */
X      if (!strcmp(argv[argc - i],"-fn"))
X	{ /* begin arg fn */
X	  i--;
X	  strcpy(font_name,argv[argc - i]);
X	  user_font = 1;
X	} /* end arg fn */
X      if (!strcmp(argv[argc - i],"-cf"))
X	{ /* begin color file */
X	  i--;
X	  strcpy(color_file,argv[argc - i]);
X	} /* end color file */
X      if (!strncmp(argv[argc - i], "-g", 2))
X	{ /* begin geometry */
X	  i--;
X	  strcpy(size_def, argv[argc - i]);
X	  XParseGeometry(size_def, &x_org, &y_org, &minWidth, &minHeight);
X	  user_position = 1;
X	}
X      if (!strncmp(argv[argc - i], "-h", 2)) usage();
X      else
X	strcpy(file_name, argv[argc - i]);
X    } /* end input arg parseing */
X  
X  /* open the hpgl file and print error if not able to */
X  if((yyin=fopen(file_name,"r"))==NULL)
X    { /* begin open file error */
X      fprintf(stderr,"Could not open hpgl file -%s- for read.\n",
X	      file_name);
X      exit(-1);
X    } /* end open file error */
X  
X  
X  /* open the color definition file and print message of not found */
X  /* assign colors if file is found */
X  if((color_file_pointer=fopen(color_file,"r"))==NULL)
X    { /* begin no color file */
X      fprintf(stderr,"Could not open color file -%s- for read.\n",
X	      color_file);
X      fprintf(stderr,"Using default internal values...\n");
X    } /* end no color file */
X  else
X    { /* begin assign colors */
X      while(fscanf(color_file_pointer,"%d %s",&i,user_color) != EOF)
X	assign_color(i,user_color);
X      fclose(color_file_pointer);
X    } /* begin assign colors */
X  
X  
X  /* Set the origin and bounds of the coordinate system */
X  xMin = XMIN;             
X  yMin = YMIN;             
X  xMax = XMIN + (SIZEX * MULT);
X  yMax = YMIN + (SIZEY * MULT);
X  
X  {
X    extern double xScale;
X    extern double yScale;
X
X    xScale = minWidth / (xMax - xMin);
X    yScale = minHeight / (yMax - yMin);
X  }
X  /* connect to the Display as a client */
X  dpy = XOpenDisplay(NULL);
X  
X  if (dpy == NULL)
X    {
X      fprintf(stderr,"Could not open Display\n");
X      exit(-1);
X    }
X  
X  /* Get the default screen */
X  default_screen = XDefaultScreen(dpy);
X  
X  /* Test to see if we're on a color display */
X  if (DisplayCells(dpy, default_screen) < 3)
X    is_color = 0;
X  else
X    is_color = 1;
X  
X  
X  /* Get the default colormap */
X  /* allocate and create a hardware color for each of the pens */
X  
X  if (is_color)
X    {
X      default_colormap = XDefaultColormap(dpy, default_screen);
X      for (i=0;i<10;i++)
X	if (!(XAllocColor(dpy, default_colormap, &pen[i])))
X	  {
X	    fprintf(stderr,"Ran out of colormap entries!");
X	    exit(-1);
X	  }
X    }
X  
X  /* Create the wait cursor */
X  wait_cursor = XCreateFontCursor(dpy, XC_watch);
X  
X  gc = XDefaultGC(dpy, default_screen);
X  XSetForeground(dpy, gc, WhitePixel(dpy,default_screen));
X  XSetBackground(dpy, gc, BlackPixel(dpy,default_screen));
X  
X  /* create the main window */
X  main_window = XCreateSimpleWindow(dpy, DefaultRootWindow(dpy), x_org, y_org, minWidth,minHeight, 1, 0, BlackPixel(dpy, default_screen));
X  
X  /* create the XSizeHints structure */
X  if (user_position)
X    {
X      size_hints.flags = USPosition | USSize;
X      size_hints.x = x_org;
X      size_hints.y = y_org;
X      size_hints.width = minWidth;
X      size_hints.height = minHeight;
X    }
X  else
X    {
X      size_hints.flags = NULL;
X    }
X
X  /* Set the window manager info for the window */
X  XSetStandardProperties(dpy, main_window, argv[0], argv[0], NULL, argv, argc, size_hints);
X
X  /* select the proper font for the window size.  minWidth and minHeight
X     must be assigned to the current window size before this call is made,
X     or the font will be the wrong size */
X  get_text_font(user_font);
X  
X  /* check to make sure that the font selected exists on the 
X     hardware */
X  if (text_font == 0)
X    {/* begin get font error */
X      fprintf(stderr,"Could not read font %s\n",font_name);
X      exit(-1);
X    }/* end get font error */
X  
X  /* get size of the font */
X  text_font_info = XQueryFont(dpy, text_font);
X  big_char = text_font_info->max_bounds;
X  
X  font_offset = big_char.ascent + big_char.descent;
X  
X  /* map the window */
X  XMapWindow(dpy, main_window);
X  
X  /* set up the window to watch key events */
X  XSelectInput(dpy,main_window,KeyPressMask | ExposureMask | StructureNotifyMask);
X  
X  /* Synchornize  - debug only */
X  /*   XSynchronize(dpy, 1); */
X
X  while(1) 
X    { /* begin event handeling */
X      /* get the next pending event in the queue */
X      XNextEvent(dpy, &event);
X      
X      /* switch on the event type */
X      switch (event.type)
X	{ /* begin event switch */
X	case KeyPress:
X	  { /* begin key pressed */
X	    char key_char[1];
X	    XKeyEvent *key_event = (XKeyEvent *) &event;
X	    
X	    XLookupString(key_event, key_char, 1, NULL, NULL);
X	    switch(key_char[0])
X	      { /* begin key matching */
X	      case 'Q':
X	      case 'q': 
X		{ /* begin keys q and Q */
X		  XCloseDisplay(dpy);
X		  exit(0);
X		  break;
X		}/* end keys q and Q */
X	      case 'o':
X	      case 'O':
X		{ /* begin keys r and R */
X		  /* Reset the origin and bounds of the coordinate system */
X		  xMin = XMIN;             
X		  yMin = YMIN;             
X		  xMax = XMIN + (SIZEX * MULT);
X		  yMax = YMIN + (SIZEY * MULT);
X		  dont_scale = 0;
X		  draw_plot();
X		  break;
X		} /* end keys r and R */
X	      case 'r':
X	      case 'R':
X		{ /* begin keys r and R */
X		  draw_plot();
X		  break;
X		} /* end keys r and R */
X	      case 'z':
X	      case 'Z':
X		{ /* begin keys z and Z */
X		  short pboxX, pboxY, pboxW, pboxH;
X		  double xsiz, ysiz;
X		  double mult, multx, multy;
X		  if (Select_Window(dpy, main_window, &pboxX, &pboxY, &pboxW, &pboxH))
X		    {
X		      if (pboxX < 0) pboxX = 0;
X		      if (pboxY < 0) pboxY = 0;
X		      xsiz = xMax-xMin;
X		      ysiz = yMax-yMin;
X		      
X		      /* Figure out which multiplier is larger and use that one */
X		      /* This prevents the zoomed image from getting out of proportion */
X		      
X		      multx = (double)(xsiz/pboxW);
X		      multy = (double)(ysiz/pboxH);
X		      mult = (double)(xsiz/minWidth);
X		      
X		      if (multx < multy)
X			pboxH = pboxH * (multy/multx); 
X		      else
X			pboxW = pboxW * (multx/multy); 
X		      
X		      xMin = (double)(((xsiz/minWidth)*(pboxX)) + xMin);
X		      yMin = (double)(((ysiz/minHeight)*(minHeight - (pboxY + pboxH))) + yMin);
X		      xMax = (double)(xMin + pboxW * mult);
X		      yMax = (double)(yMin + pboxH * mult);
X		      xScale = minWidth / (xMax - xMin);
X		      yScale = minHeight / (yMax - yMin);
X		      dont_scale = 1;
X		    }
X		  draw_plot();
X		  break;
X		} /* end keys z and Z */
X	      case 'u':
X	      case 'U':
X		{
X		  /* unzoom */
X		  double xsiz, ysiz;
X		  xsiz = xMax-xMin;
X		  ysiz = yMax-yMin;
X
X		  xMax = xMax + .5 * xsiz;
X		  xMin = xMin - .5 * xsiz;
X
X		  yMax = yMax + .5 * ysiz;
X		  yMin = yMin - .5 * ysiz;
X	  
X
X		  xScale = minWidth / (xMax - xMin);
X		  yScale = minHeight / (yMax - yMin);
X
X		  dont_scale = 1;
X		  draw_plot();
X		  break;
X		}
X		break;
X	      } /* end key matching */
X	    break;
X	  } /* end key pressed */
X	case Expose:
X	  {
X	    /* If a configureNotify event is on the queue, we don't want to process
X	       this expose event.  Put the Configure Notify back on the queue; the extra
X	       Expose events will be flushed by the draw_plot routine */
X	    
X	    while(XCheckTypedEvent(dpy, ConfigureNotify, &event))
X	      {
X		XPutBackEvent(dpy, &event);
X		goto get_out;
X	      }
X	    draw_plot();
X	  get_out:
X	    break;
X	  }
X	case ConfigureNotify:
X	  {
X	    /* Window resize detected.  Rather than scale the drawing inside the window, we'll
X	       adjust the coordinate system to display more or less of the drawing */
X	    
X	    double xsiz, ysiz;
X	    int newWidth, newHeight;
X	    xsiz = xMax-xMin;
X	    ysiz = yMax-yMin;
X	    
X	    newWidth = event.xconfigure.width;
X	    newHeight = event.xconfigure.height;
X	    
X	    /* Nothing has changed.  So we do nothing! */
X	    if (newWidth == minWidth && newHeight == minHeight)
X	      break;
X	    
X	    xMax = (double)((xsiz/minWidth)*(newWidth - minWidth) + xMax);
X	    yMax = (double)((ysiz/minHeight)*(newHeight - minHeight) + yMax);
X	    
X	    minWidth = newWidth;
X	    minHeight = newHeight;
X	    draw_plot();
X	    break;
X	  }
X	default:
X	  break;
X	} /* end event switch */
X    } /* end event handeling */
X} /* end main */
SHAR_EOF
chmod 0644 xhpgl.c || echo "restore of xhpgl.c fails"
set `wc -c xhpgl.c`;Sum=$1
if test "$Sum" != "22504"
then echo original size 22504, current size $Sum;fi
fi
exit 0

--
dan
----------------------------------------------------
O'Reilly && Associates   argv at sun.com / argv at ora.com
Opinions expressed reflect those of the author only.



More information about the Comp.sources.x mailing list