[comp.sources.unix] v18i063: GL Graphics Library for AT-clone Unix, Part05/07

rsalz@uunet.uu.net (Rich Salz) (03/25/89)

Submitted-by: umix!m-net!dtlewis!lewis
Posting-number: Volume 18, Issue 63
Archive-name: gl_plot/part05

# To recover, type "sh archive"
echo restoring Things_to_do
sed 's/^X//' > Things_to_do <<XxX--EOF--XxX
XThings that need to be added to enhance the graphics routines:
X
X
XVolunteers needed:
X------------------
X
X-Port to 386 UNIX and XENIX.  Some 16 bit integer dependencies have
Xalready been removed (using the INT16 macro in config.h), but this
Xhas not been tested on an actual 386 system.  Also, I have no idea
Xhow to change video modes and get pointers to video memory for any
Xof the flavors of 386 UNIX/XENIX.
X
X-Complete port to Xenix 286.  So far, only an EGA system had been
Xtested, so other device types need verification.  No testing of the
Xprint queue output has been done.  The FAR macro (in graphics.h) has
Xbeen defined for support of mixed memory models, but only the large
Xmemory model is currently working.
X
X-Add additional device support (VGA, Laserjet, enhanced EGA boards).
X
X
XThings I'll probably get around to doing myself:
X------------------------------------------------
X
X-Add XOR and color support to EGA.
X
X-Add line thickness and line style support to pixel and/or line drawing
Xroutines.
X
X-Add polygon fill routines.
X
X-Add windows, viewports, 3-D transforms, etc.
X
X
X			Tue Dec 27 16:01:22 EST 1988 dtl
XxX--EOF--XxX
echo restoring g_init.c
sed 's/^X//' > g_init.c <<XxX--EOF--XxX
X#ifndef lint
Xstatic char sccsid[] = "@(#) g_init.c 5.1 89/02/20";
X#endif
X
X/*
X *	Copyright (c) David T. Lewis 1987, 1988, 1989
X *	All rights reserved.
X *
X *	Permission is granted to use this for any personal noncommercial use.
X *	You may not distribute source or executable code for profit, nor
X *	may you distribute it with a commercial product without the written
X *	consent of the author.  Please send modifications to the author for
X *	inclusion in updates to the program.  Thanks.
X */
X
X/* Sat Nov 28 17:10:53 EST 1987 */
X/* Initialize shared or video memory for use in graphics I/O.  For 	*/
X/* Microport System V/AT we presume that shared memory segments have	*/
X/* been defined (usually at system boot time) such that the shared	*/
X/* memory keys are "B8000L" for CGA adapter, and so on (or change	*/
X/* the definitions in config.h).  For Xenix, we can directly address	*/
X/* video memory via the appropriate segment selector.			*/
X
X#define MODULE "g_init()"
X
X#include <stdio.h>
X#include "config.h"
X#if MIX_C
X#else
X#include <sys/types.h>
X#include <math.h>
X#if TCC
X#else
X#include <malloc.h>
X#endif /* TCC */
X#endif /* MIX_C */
X#if MS_DOS
X#include <stdlib.h>
X/* Mode to return to before exiting	*/
Xint g_text = -1;
X#else
X#include <sys/ipc.h>
X#endif /* MS_DOS */
X#if XENIX_286
X#include <sys/fcntl.h>
X#include <sys/machdep.h>
X#include <sys/sysmacros.h>
X#endif /* XENIX_286 */
X#if HAS_SIG
X#include <signal.h>
X#endif /* HAS_SIG */
X#include "bitmaps.h"
X#include "gf_types.h"
X#include "graphics.h"
X#include "modes.h"
X
X#ifndef HUGE
X#define HUGE (3.4e+38)
X#endif /* HUGE */
X
Xstruct GL_graphics graphics;
Xextern int (*p_do_pix)();
Xextern int g_clear();
Xextern int g_finish();
Xextern int p_wr_pix();
Xextern char *getenv();
X
X#if TCC
X#else
Xextern char *calloc();
X#endif /* TCC */
X
X#if HAS_SIG
X/* Global variable to save previous interrupt signal handler (usually	*/
X/* SIG_DFL, but someone may have their own handler for closing files	*/
X/* or other cleanup).  This value is restored when g_finish() is	*/
X/* called.								*/
XSIG_TYPE (*gl_last_int_handler)();
X
X/* This is the default interrupt signal handler, which is in effect	*/
X/* starting with the call to g_init(), until the call to g_finish().	*/
XSIG_TYPE gl_sig_catch() {
X	/* Don't take any more signals while we work.			*/
X	signal (SIGINT, SIG_IGN);
X
X	/* Clean up and exit.  Don't bother cleaning up for printers,	*/
X	/* since we are only interested in clearing the screen and	*/
X	/* detaching from shared memory segments.			*/
X	if (graphics.grafmode <= MAXVIDEO)  {
X		g_finish();
X	}
X	exit(1);
X}
X#endif /* HAS_SIG */
X
X/* Warning for System V/AT problems.					*/
Xstatic void bad_key_warning(key)  
Xlong key;
X{
X	system(MODEPROG);
X	fprintf (stderr,"Cannot attach to shared memory key %lx for mode ",key);
X	fprintf (stderr,"%d in routine %s.\n", graphics.grafmode, MODULE);
X	fprintf (stderr,"The problem is most likely caused by ",0);
X	fprintf (stderr,"lack of a shared memory key.\n",0);
X	fprintf (stderr,"You must use a kernel with shared memory ",0);
X	fprintf (stderr,"enabled, and define the keys\n",0);
X	fprintf (stderr,"using the shmcreate(1) utility.\n",0);
X}
X
X/* Warning for Xenix 286 problems.					*/
Xstatic void bad_sel_warning(device_name)  
Xchar device_name[];
X{
X	system(MODEPROG);
X	fprintf (stderr,"Cannot locate selector for the ",0);
X	fprintf (stderr,"requested video adapter %s.\n", device_name);
X	fprintf (stderr,"Graphics mode %d was requested in routine %s.\n",
X		graphics.grafmode, MODULE);
X	fprintf (stderr,"The most likely problem is that your ",0);
X	fprintf (stderr,"physical board does not match the\n",0);
X	fprintf (stderr,"type you tried to attach to (see ",0);
X	fprintf (stderr,"the \"config.h\" file for the gl library).\n",0);
X}
X
Xint not_enuf_mem()  {
X	fprintf(stderr,
X		"%s: Insufficient memory for in-core print buffer.\n",
X		MODULE);
X	return(1);
X}
X
X/* For printers, the following four functions send data required to	*/
X/* start the print, end the print, start each line, and end each line.	*/
X/* These function pointers will point to routines in g_print.c.		*/
X
Xextern int (*pr_head)(), (*pr_tail)(), (*pr_lnst)(), (*pr_lnend)();
X
X/* There will be one set of these functions for each printer type.	*/
X
Xextern int IBM_head(), IBM_tail(), IBM_lnst(), IBM_lnend();
Xextern int LJ_head(), LJ_tail(), LJ_lnst(), LJ_lnend();
X
Xint g_init(mode)
Xint mode;
X/* Mode is the video mode that will be used when in graphics mode.	*/
X/* By implication, this gives us the memory location we want to attach	*/
X/* to, as well as the dimensions of the screen.				*/
X
X{
X	char *env_mode;
X	extern int errno;
X	int istat;
X	char command[40], modebuf[10];
X
X#if SVAT
X	long key;
X	char *shmat();
X	int shmid;
X#endif /* SVAT */
X
X#if XENIX_286
X	int fd, selector;
X	char device_name[20];
X	int map_request;
X
X#if GL_EGA
X	map_request = MAPEGA;
X	strcpy(device_name,"/dev/ega");
X#else
X#if GL_HERC
X	map_request = MAPMONO;
X	strcpy(device_name,"/dev/monochrome");
X#else
X#if GL_PGA
X	map_request = MAPPGA;
X	strcpy(device_name,"/dev/pga");
X#else
X#if GL_VGA
X	/* No support for this.  Wait for later Xenix release, I guess.	*/
X	map_request = MAPCONS;
X	strcpy(device_name,"/dev/console");
X#else
X#if GL_CGA
X	map_request = MAPCGA;
X	strcpy(device_name,"/dev/color");
X#else
X	/* May as well default to CGA.	*/
X	map_request = MAPCGA;
X	strcpy(device_name,"/dev/console");
X#endif /* GL_CGA */
X#endif /* GL_VGA */
X#endif /* GL_PGA */
X#endif /* GL_HERC */
X#endif /* GL_EGA */
X
X#endif /* XENIX_286 */
X
X#if MS_DOS
X	/* Save the mode we started in so we can exit in text mode.	*/
X	if (g_text == -1) g_text = g_getmod();
X#endif /* MS_DOS */
X
X	/* If we have already initialized, then call g_finish() before	*/
X	/* proceeding.							*/
X
X	if (graphics.initialized == TRUE)  {
X		if ((istat=g_finish()) != 0) return(istat);
X	}
X	else graphics.initialized = FALSE;
X
X	/* Remember what mode we are in.				*/
X
X	graphics.grafmode = mode;
X
X	/* If mode is ENV_MODE, then get mode from the 		*/
X	/* environment.  Get the default video mode if 		*/
X	/* specified in an  environment variable; otherwise,	*/
X	/* use the compiled-in default value.			*/
X
X	if (graphics.grafmode==ENV_MODE)  
X#if HAS_ENV
X	{
X		if ((env_mode = getenv(GL_ENV_MODE)) == NULL)  {
X			/* No environment variable; use the default.	*/
X			/* Put warning message to standard error, then	*/
X			/* continue.					*/
X			fprintf(stderr,
X			"Use environment variable %s to control mode.\n",
X				GL_ENV_MODE);
X			fprintf(stderr,"Continuing with default mode %d.\n",
X				DEFAULT_MODE);
X			graphics.grafmode = DEFAULT_MODE;
X			sleep(2);
X		}
X		else if(sscanf(env_mode,"%d",&(graphics.grafmode)) != 1)  {
X			fprintf (stderr,
X				"WARNING:  Routine %s checking environment ",
X				MODULE);
X			fprintf (stderr,
X				"variable %s.\n",
X				GL_ENV_MODE);
X			fprintf (stderr,
X				"Cannot understand mode \"%s\".  Integer ",
X				env_mode);
X			fprintf (stderr,
X				"value is required.\n",0);
X			return(1);
X		}
X	}
X#else
X	{
X		/* Some systems do not understand getenv()	*/
X		graphics.grafmode = DEFAULT_MODE;
X	}
X#endif /* HAS_ENV */
X
X	/* Tell the hardware to go into the appropriate mode, using	*/
X	/* the MODEPROG program.					*/
X
X	if (graphics.grafmode <= MAXVIDEO)  {
X#if MS_DOS
X		g_setmod(graphics.grafmode);
X#else
X		strcpy(command, MODEPROG);
X		strcat(command," ");
X		sprintf(modebuf,"%d\0", graphics.grafmode);
X		strcat(command, modebuf);
X		system(command);
X#endif /* MS_DOS */
X	}
X
X	/* Attach to the appropriate shared memory segment, and set the	*/
X	/* values of graphics.x_extent and graphics.y_extent, according	*/
X	/* to the video mode requested.					*/
X
X	switch (graphics.grafmode)  {
X	case CGA_COLOR_MODE:
X		graphics.x_extent = 319;
X		graphics.y_extent = 199;
X		graphics.x_window_ll = 0;
X		graphics.y_window_ll = 0;
X		graphics.x_window_ur = 319;
X		graphics.y_window_ur = 199;
X		graphics.aspect_ratio = CGA_ASPECT_RATIO;
X		graphics.cellfont.chars_per_line = 40;
X		graphics.cellfont.lines_per_screen = 25;
X#if SVAT
X		key = CGA_KEY;
X		if ((shmid = shmget(key, 32768, IPC_CREAT)) < 0)  {
X			bad_key_warning(key);
X			return(shmid);
X		}
X		graphics.cgamem = (CGA_BUF_TYPE *)shmat(shmid, 0L, 0);
X#else
X#if XENIX_286
X		fd = open(device_name, O_WRONLY);
X		selector = ioctl(fd,map_request,0);
X		if (selector < 0)  {
X			bad_sel_warning(device_name);
X			return(selector);
X		}
X		graphics.cgamem = (CGA_BUF_TYPE *)sotofar(selector,0);
X#else
X#if MS_DOS
X		graphics.cgamem = (CGA_BUF_TYPE *)DOS_CGA;
X#endif /* MS_DOS */
X#endif /* XENIX_286 */
X#endif /* SVAT */
X		break;
X	case CGA_HI_RES_MODE:
X		graphics.x_extent = 639;
X		graphics.y_extent = 199;
X		graphics.x_window_ll = 0;
X		graphics.y_window_ll = 0;
X		graphics.x_window_ur = 639;
X		graphics.y_window_ur = 199;
X		graphics.aspect_ratio = CGA_ASPECT_RATIO;
X		graphics.cellfont.chars_per_line = 80;
X		graphics.cellfont.lines_per_screen = 25;
X#if SVAT
X		key = CGA_KEY;
X		if ((shmid = shmget(key, 32768, IPC_CREAT)) < 0)  {
X			bad_key_warning(key);
X			return(shmid);
X		}
X		graphics.cgamem = (CGA_BUF_TYPE *)shmat(shmid, 0L, 0);
X#else
X#if XENIX_286
X		fd = open(device_name, O_WRONLY);
X		selector = ioctl(fd,map_request,0);
X		if (selector < 0)  {
X			bad_sel_warning(device_name);
X			return(selector);
X		}
X		graphics.cgamem = (CGA_BUF_TYPE *)sotofar(selector,0);
X#else
X#if MS_DOS
X		graphics.cgamem = (CGA_BUF_TYPE *)DOS_CGA;
X#endif /* MS_DOS */
X#endif /* XENIX_286 */
X#endif /* SVAT */
X		break;
X	case HERC_P0_MODE:
X	case HERC_P1_MODE:
X		graphics.x_extent = 719;
X		graphics.y_extent = 347;
X		graphics.x_window_ll = 0;
X		graphics.y_window_ll = 0;
X		graphics.x_window_ur = 719;
X		graphics.y_window_ur = 347;
X		graphics.aspect_ratio = HERC_ASPECT_RATIO;
X		graphics.cellfont.chars_per_line = 90;
X		graphics.cellfont.lines_per_screen = 43;
X#if SVAT
X		if (mode == HERC_P0_MODE) key = HERC_P0KEY;	/* Page 0 */
X		else key = HERC_P1KEY;				/* Page 1 */
X		if ((shmid = shmget(key, 32768, IPC_CREAT)) < 0)  {
X			bad_key_warning(key);
X			return(shmid);
X		}
X		graphics.hercmem = (HERC_BUF_TYPE *)shmat(shmid, 0L, 0);
X#else
X#if XENIX_286
X		/* Note: I don't know how page 0 and 1 will be selected	*/
X		/* under Xenix.  Microport can use two different shared	*/
X		/* memory keys. dtl 1-8-89				*/
X		fd = open(device_name, O_WRONLY);
X		selector = ioctl(fd,map_request,0);
X		if (selector < 0)  {
X			bad_sel_warning(device_name);
X			return(selector);
X		}
X		graphics.hercmem = (HERC_BUF_TYPE *)sotofar(selector,0);
X#else
X#if MS_DOS
X		graphics.hercmem = (HERC_BUF_TYPE *)DOS_H_P0;
X#endif /* MS_DOS */
X#endif /* XENIX_286 */
X#endif /* SVAT */
X		break;
X	case EGA_COLOR_MODE:
X		graphics.x_extent = 639;
X		graphics.y_extent = 349;
X		graphics.x_window_ll = 0;
X		graphics.y_window_ll = 0;
X		graphics.x_window_ur = 639;
X		graphics.y_window_ur = 349;
X		graphics.aspect_ratio = EGA_ASPECT_RATIO;
X		graphics.cellfont.chars_per_line = 80;
X		graphics.cellfont.lines_per_screen = 43;
X#if SVAT
X		key = EGA_KEY;
X		if ((shmid = shmget(key, 32768, IPC_CREAT)) < 0)  {
X			bad_key_warning(key);
X			return(shmid);
X		}
X		graphics.egamem = (EGA_BUF_TYPE *)shmat(shmid, 0L, 0);
X#else
X#if XENIX_286
X		fd = open(device_name, O_WRONLY);
X		selector = ioctl(fd,map_request,0);
X		if (selector < 0)  {
X			bad_sel_warning(device_name);
X			return(selector);
X		}
X		graphics.egamem = (EGA_BUF_TYPE *)sotofar(selector,0);
X#else
X#if MS_DOS
X		graphics.egamem = (EGA_BUF_TYPE *)DOS_EGA;
X#endif /* MS_DOS */
X#endif /* XENIX_286 */
X#endif /* SVAT */
X		break;
X	case IBM_PRINTER:
X		/* Initialize the function pointers for this printer.	*/
X		pr_head = IBM_head;
X		pr_tail = IBM_tail;
X		pr_lnst = IBM_lnst;
X		pr_lnend = IBM_lnend;
X		graphics.x_extent = 719;
X		graphics.y_extent = 959;
X		graphics.x_window_ll = 0;
X		graphics.y_window_ll = 0;
X		graphics.x_window_ur = 719;
X		graphics.y_window_ur = 959;
X		graphics.aspect_ratio = IBM_PR_ASPECT_RATIO;
X		graphics.cellfont.chars_per_line = 90;
X		graphics.cellfont.lines_per_screen = 120;
X		/* Memory will be g_cleared by calloc(), no need	*/
X		/* to call g_clear() later.			*/
X		if ((graphics.printbuf1 = (PR_BUF_TYPE *) calloc
X			(1,sizeof(PR_BUF_TYPE)))==NULL) return(not_enuf_mem());
X		if ((graphics.printbuf2 = (PR_BUF_TYPE *) calloc
X			(1,sizeof(PR_BUF_TYPE)))==NULL) return(not_enuf_mem());
X		if ((graphics.printbuf3 = (PR_BUF_TYPE *) calloc
X			(1,sizeof(PR_BUF_TYPE)))==NULL) return(not_enuf_mem());
X		break;
X	case LJ_PRINTER:
X		/* Initialize the function pointers for this printer.	*/
X		pr_head = LJ_head;
X		pr_tail = LJ_tail;
X		pr_lnst = LJ_lnst;
X		pr_lnend = LJ_lnend;
X		graphics.x_extent = 1379;
X		graphics.y_extent = 1119;
X		graphics.x_window_ll = 0;
X		graphics.y_window_ll = 0;
X		graphics.x_window_ur = 1379;
X		graphics.y_window_ur = 1119;
X		graphics.aspect_ratio = LJ_PR_ASPECT_RATIO;
X		graphics.cellfont.chars_per_line = 138;
X		graphics.cellfont.lines_per_screen = 94;
X		/* Memory will be g_cleared by calloc(), no need	*/
X		/* to call g_clear() later.			*/
X		if ((graphics.lj_buf1 = (LJ_BUF_TYPE *) calloc
X			(1, LJ_BUF_SIZE))==NULL) return(not_enuf_mem());
X		if ((graphics.lj_buf2 = (LJ_BUF_TYPE *) calloc
X			(1, LJ_BUF_SIZE))==NULL) return(not_enuf_mem());
X		if ((graphics.lj_buf3 = (LJ_BUF_TYPE *) calloc
X			(1, LJ_BUF_SIZE))==NULL) return(not_enuf_mem());
X		break;
X	default:
X		/* The programmer is probably confused at this point.	*/
X		/* Print a warning and return.				*/
X		system(MODEPROG);
X		fprintf (stderr,"Unable to initialize in routine %s.  Mode %d requested.\n",MODULE,graphics.grafmode);
X		return(1);
X	}
X
X	/* Set other variables to reasonable values.			*/
X
X	graphics.color = 2;
X	graphics.lineweight = LIGHT;
X	graphics.linestyle = SOLID;
X	graphics.wrt_mode = OR;
X
X	graphics.xlate_x = 0;
X	graphics.xlate_y = 0;
X	graphics.xlate_z = 0;
X	graphics.offset_x = 0;
X	graphics.offset_y = 0;
X	graphics.offset_z = 0;
X	graphics.theta_x = 0;
X	graphics.theta_y = 0;
X	graphics.theta_z = 0;
X	graphics.c_tz_c_ty = 1.0;
X	graphics.s_tz = 0.0;
X	graphics.s_ty = 0.0;
X	graphics.c_tz_c_tx = 1.0;
X	graphics.s_tx = 0.0;
X	graphics.scale_factor = 1.0;
X	graphics.perspect_dist = HUGE;
X	graphics.x_vport_ll = NRM_X_MIN;
X	graphics.y_vport_ll = NRM_Y_MAX;
X	graphics.x_vport_ur = NRM_X_MIN;
X	graphics.y_vport_ur = NRM_Y_MAX;
X
X	/* Character cell spacing in normalized coordinates.  This is	*/
X	/* the distance in normalized coordinates.			*/
X
X	/* The horizontal size of a line of cell text is the width of	*/
X	/* a pixel (NRM_Y_RANGE divided by the number of pixels across	*/
X	/* the screen) times the number of pixels in a line of text.	*/
X	/* Rearrange this for computational accuracy.			*/
X
X	graphics.cellfont.xtic = 
X		NRM_X_RANGE * X_CELL_BITS / graphics.x_extent;
X
X	/* The vertical size of a line of cell text is the size of	*/
X	/* a scan line (NRM_Y_RANGE divided by the number of lines	*/
X	/* we need) times the number of scan lines for a line of text.	*/
X	/* Rearrange this for computational accuracy.			*/
X
X	graphics.cellfont.ytic =
X		NRM_Y_RANGE * Y_CELL_BITS / graphics.y_extent;
X
X	graphics.cellfont.xmult = 1;	/* Cell size multipliers	*/
X	graphics.cellfont.ymult = 1;
X
X	graphics.default_strokefont.xtic
X		 = graphics.strokefont.xtic = graphics.cellfont.xtic;
X	graphics.default_strokefont.ytic
X		= graphics.strokefont.ytic = graphics.cellfont.ytic;
X	graphics.default_strokefont.xsize
X		= graphics.strokefont.xsize = graphics.strokefont.xtic / 8;
X	graphics.default_strokefont.ysize
X		= graphics.strokefont.ysize = graphics.strokefont.ytic /10;
X	graphics.default_strokefont.angle
X		= graphics.strokefont.angle = 0;
X	graphics.default_strokefont.slant
X		= graphics.strokefont.slant = 0;
X	graphics.default_strokefont.angle_flag
X		= graphics.strokefont.angle_flag = FALSE;
X	graphics.default_strokefont.slant_flag
X		= graphics.strokefont.slant_flag = FALSE;
X
X	/* Erase graphics memory and set video mode.  Anything beyond	*/
X	/* MAXVIDEO is not a video board.  Assume it is a printer; no	*/
X	/* need to clear memory.					*/
X
X	if (graphics.grafmode <= MAXVIDEO)  {
X		if (g_clear() != 0)  {
X			system(MODEPROG);
X			return(1);
X		}
X	}
X
X	/* Initialize the p_do_pix function pointer to point to the	*/
X	/* p_wr_pix routine (see the p_do_pix routine in		*/
X	/* g_pixctl.c).  This corresponds to the current linestyle	*/
X	/* value of SOLID.						*/
X
X	p_do_pix = p_wr_pix;
X
X	graphics.initialized = TRUE;
X
X#if HAS_SIG
X#if DO_CLEANUP
X	/* Catch interrupt signals, and clean up before exiting.	 */
X	gl_last_int_handler = signal(SIGINT, gl_sig_catch);
X#endif /* DO_CLEANUP */
X#endif /* HAS_SIG */
X
X	return(0);
X}
X
XxX--EOF--XxX
echo restoring gl.3L
sed 's/^X//' > gl.3L <<XxX--EOF--XxX
X.\" dummy line
X.TH GL 3L "01 Oct 1988"
X.UC 4
X.SH NAME
Xg_init, g_finish, g_clear, p_wr_pix,
Xn_movepen, n_point, n_draw, n_line,
Xn_box, n_ellipse, n_arc,
Xn_grafchar, n_grafstr, g_fontctl,
Xc_cellchar, c_cellstr, c_cursor,
Xg_pix_mode, g_pix_color, g_weight, g_style,
Xplot(3)
X\- graphics primitives for PC UNIX and DOS systems.
X.SH SYNOPSIS
X.nf
X.B
X#include "gl.h"
X.PP
X.B int g_init(mode)
Xint mode;
X.PP
X.B int g_finish()
X.PP
X.B int g_clear()
X.PP
X.B int p_wr_pix(x,y)
Xint x, y;
X.PP
X.B int n_movepen(x,y)
Xint x, y;
X.PP
X.B int n_point(x,y)
Xint x, y;
X.PP
X.B int n_draw(x,y)
Xint x, y;
X.PP
X.B int n_line(x1,y1,x2,y2)
Xint x1, y1, x2, y2;
X.PP
X.B int n_box(x1, y1, x2, y2)
Xint x1, y1, x2, y2;
X.PP
X.B int n_ellipse(x,y,a,b)
Xint x, y, a, b;
X.PP
X.B int n_arc(x,y,a,b,angle1,angle2)
Xint x, y, a, b;
Xfloat angle1, angle2;
X.PP
X.B int n_grafchar(asc_char)
Xunsigned char asc_char;
X.PP
X.B int n_grafstr(strng)  
Xchar strng[];
X.PP
X.B int g_fontctl(size, aspect_ratio, spacing, angle, slant)
Xfloat size, aspect_ratio, spacing, angle, slant;
X.PP
X.B int c_cellchar(asc_char)
Xunsigned char asc_char;
X.PP
X.B int c_cellstr(strng)
Xchar strng[];
X.PP
X.B int c_cursor(row,col)
Xint row, col;
X.PP
X.B int g_pix_mode(mode_val)
Xint mode_val;
X.PP
X.B int g_pix_color(color)
Xint color;
X.PP
X.B int g_weight(lineweight)
Xint lineweight;
X.PP
X.B long g_style(linestyle)
Xlong linestyle;
X.br
X.SH DESCRIPTION
XThe
X.I gl 
Xcollection of routines is designed to provide graphic output
Xto a number of video adapters and printers for PC clone computers
Xrunning UNIX or MS-DOS operating systems.  
X.PP
XVarious output devices are supported, including CGA, EGA, Hercules,
Xand dot matrix and laser printers.  For each type of device, one or more 
Xgraphics "modes" is defined in graphics.h, and the corresponding 
Xbitmaps are defined in bitmaps.h.  These modes roughly correspond 
Xto the BIOS video modes defined for MS-DOS, with additional modes 
Xdefined for Hercules and for printer output.
X.PP
XAlso included is an emulation of the BSD 
X.I plot(3) 
Xgraphics interface library.  See 
X.I plot(3) 
Xfor details.
X.PP
XThe
X.I g_init
Xroutine initializes device (sets video mode), buffers, and variables, 
Xand obtains pointers to video memory, video shared memory segment or 
Xtemporary printer buffers.
X.PP
XThe
X.I g_finish
Xroutine releases resources and detaches memory segments.
X.PP
XThe
X.I g_clear
Xroutine clears the screen (or printer buffer area). 
X.PP
XThe
X.I p_wr_pix
Xroutine activates a pixel.  If the current writing mode is OR, 
Xthe pixel is turned on (set to the currently active color).  If 
Xthe current writing mode is XOR, the pixel value (color) is XORed 
Xwith its current value.
X.PP
XThe
X.I n_movepen
Xroutine moves the logical cursor in normalized 32768 x 32768 
Xaddress space, where (0,0) is the upper left corner of the screen
Xor printed page.
X.PP
XThe
X.I n_point
Xroutine draws a dot on the screen at (x,y) in normalized address space.
X.PP
XThe
X.I n_draw
Xroutine draws a vector from the current address to (x,y) in 
Xnormalized address space.
X.PP
XThe
X.I n_line
Xroutine draws a line from (x1,y1) to (x2,y2) in normalized address 
Xspace.
X.PP
XThe
X.I n_box
Xroutine draws a box with corners at (x1, y1) and (x2, y2) in 
Xnormalized address space.
X.PP
XThe
X.I n_ellipse
Xroutine draws an ellipse in normalized address space with center at (x, y)
Xand semi-axes a and b parallel to the x and y axes, respectively.
X.PP
XThe
X.I n_arc
Xroutine draws an elliptical arc in normalized address space.  The ellipse
Xis centered at (x, y) with semi-axes a and b parallel to the x and
Xy axes, respectively.  The arc begins at angle1 and continues to
Xangle2.  The direction of travel is clockwise as viewed on the screen 
X(counterclockwise in the "inverted" normalized coordinate system).
X.PP
XThe
X.I n_grafchar
Xroutine displays a vectorized (stroke font) text character 
Xasc_char located at the current location.  The cursor is advanced 
Xto the next character position.
X.PP
XThe
X.I n_grafstr
Xroutine displays a character string using a stroke font.
X.PP
XThe
X.I g_fontctl
Xroutine controls size, aspect ratio, spacing, angle and slant of stroke
Xfont.  The size, aspect ratio and spacing control height, relative width
Xand relative spacing of characters, with 1.0 selecting default values.
XChanging size will change the width and spacing appropriately.
XChanging width will change the spacing.
XAngle is the angle of a text string in radians, with positive
Xvalues rotating the text clockwise.  Slant is the character slant
Xin radians (typically a number on the order of 0.2), with positive
Xvalues slanting the text to the "right," as in italics.
X.PP
XThe
X.I c_cellchar
Xroutine displays a bit mapped character at the current location.
XThe cursor is advanced to the next character position.
X.PP
XThe
X.I c_cellstr
Xroutine displays a string at the current location, using bit mapped 
Xcharacters.
X.PP
XThe
X.I c_cursor
Xroutine moves the graphics cursor to a position corresponding to
Xa character row and column.  This is used for easy positioning of text
Xdrawn with the 
X.I c_cellstr 
Xroutine.
X.PP
XThe
X.I g_pix_mode
Xroutine establishes the active OR mode or XOR mode pixel 
Xsetting mode, and returns the previous mode value.
X.PP
XThe
X.I g_pix_color
Xroutine sets the active pixel color, and returns previous color 
Xvalue.
X.PP
XThe
X.I g_weight
Xroutine sets the active line thickness, and returns the previous line
Xthickness value.
X.PP
XThe
X.I g_style
Xroutine sets the active line style (e.g. dot-dash), and returns the 
Xprevious line style value.
X.SH ENVIRONMENT
XThe GLMODE shell variable may be used to specify the default graphics mode
X(such as "16" to specify EGA 640x350 color graphics).  The PLOTDEV shell 
Xvariable may be used to specify the printer device to use (such as "lpt" 
Xto use /dev/lpt).
X.SH SEE ALSO
Xplot(3), lpset(1), shmcreate(1)
X.SH AUTHOR
XDavid T Lewis, Ann Arbor, MI, USA
X.br
X(...!m-net!dtlewis!lewis)
X.SH BUGS
XThe 
X.I g_pix_mode
Xroutine does not set XOR mode for EGA high res graphics.  
X.PP
XThe
X.I g_pix_color 
Xroutine does not do anything for EGA high res graphics.
X.PP
XThe
X.I g_weight
Xroutine does not do anything (not yet implemented).
X.PP
XThe
X.I arc
Xroutine in plot(3) calculates the arc endpoint differently from the BSD 
Xversions.  The BSD version is simpler and less precise, but will give
Xdifferent display output in some cases.
X.PP
XWriting in XOR mode is done at the p_wr_pix routine level.  In XOR
Xmode, therefore, routines such as n_box and n_grafchar will "lose 
Xpixels" at line intersections in XOR mode, due to writing the same
Xpixel twice (that is, turning in on, then off again).
X.PP
XThe
X.I g_init
Xroutine sets a signal handler to clean up the screen before exiting, and
X.I g_finish
Xrestores the handler to its previous value.  This may interfere
Xwith an application's intended signal handling (the DO_CLEANUP macro in
Xconfig.h can eliminate this behavior).
X.PP
XFor MS-DOS versions, graphics printer output must be done with BIOS calls.  
XTherefore, the default system printer device must be used, and the 
XPLOTDEV environment variable has no meaning.
X.SH CAVEATS
XNo checking is done to control ownership of the console output.  The
Xuser of the program is assumed to be at the console.  Any checks for
Xthis must be done by the application program.
X.PP
XThe EGA and VGA adapters control color and writing modes (OR or XOR)
Xwith output to port addresses on the EGA/VGA card.  On System V/AT,
Xthis requires use of the outb() routine with write access to /dev/mem.
XSince this would require the application program to be suid to root,
Xsupport for color and writing modes has not yet been implemented.
X.SH SEE ALSO
Xplot(3), plot(1), plot(5).
X
XxX--EOF--XxX
echo restoring gl.man
sed 's/^X//' > gl.man <<XxX--EOF--XxX
X
X
X
X     GGGGLLLL((((3333LLLL))))               UUUUNNNNIIIIXXXX 5555....0000 ((((00001111 OOOOcccctttt 1111999988888888))))                GGGGLLLL((((3333LLLL))))
X
X
X
X     NNNNAAAAMMMMEEEE
X          g_init, g_finish, g_clear, p_wr_pix, n_movepen, n_point,
X          n_draw, n_line, n_box, n_ellipse, n_arc, n_grafchar,
X          n_grafstr, g_fontctl, c_cellchar, c_cellstr, c_cursor,
X          g_pix_mode, g_pix_color, g_weight, g_style, plot(3) -
X          graphics primitives for PC UNIX and DOS systems.
X
X     SSSSYYYYNNNNOOOOPPPPSSSSIIIISSSS
X          ####iiiinnnncccclllluuuuddddeeee """"ggggllll....hhhh""""
X
X          iiiinnnntttt gggg____iiiinnnniiiitttt((((mmmmooooddddeeee))))
X          int mode;
X
X          iiiinnnntttt gggg____ffffiiiinnnniiiisssshhhh(((())))
X
X          iiiinnnntttt gggg____cccclllleeeeaaaarrrr(((())))
X
X          iiiinnnntttt pppp____wwwwrrrr____ppppiiiixxxx((((xxxx,,,,yyyy))))
X          int x, y;
X
X          iiiinnnntttt nnnn____mmmmoooovvvveeeeppppeeeennnn((((xxxx,,,,yyyy))))
X          int x, y;
X
X          iiiinnnntttt nnnn____ppppooooiiiinnnntttt((((xxxx,,,,yyyy))))
X          int x, y;
X
X          iiiinnnntttt nnnn____ddddrrrraaaawwww((((xxxx,,,,yyyy))))
X          int x, y;
X
X          iiiinnnntttt nnnn____lllliiiinnnneeee((((xxxx1111,,,,yyyy1111,,,,xxxx2222,,,,yyyy2222))))
X          int x1, y1, x2, y2;
X
X          iiiinnnntttt nnnn____bbbbooooxxxx((((xxxx1111,,,, yyyy1111,,,, xxxx2222,,,, yyyy2222))))
X          int x1, y1, x2, y2;
X
X          iiiinnnntttt nnnn____eeeelllllllliiiippppsssseeee((((xxxx,,,,yyyy,,,,aaaa,,,,bbbb))))
X          int x, y, a, b;
X
X          iiiinnnntttt nnnn____aaaarrrrcccc((((xxxx,,,,yyyy,,,,aaaa,,,,bbbb,,,,aaaannnngggglllleeee1111,,,,aaaannnngggglllleeee2222))))
X          int x, y, a, b;
X          float angle1, angle2;
X
X          iiiinnnntttt nnnn____ggggrrrraaaaffffcccchhhhaaaarrrr((((aaaasssscccc____cccchhhhaaaarrrr))))
X          unsigned char asc_char;
X
X          iiiinnnntttt nnnn____ggggrrrraaaaffffssssttttrrrr((((ssssttttrrrrnnnngggg))))
X          char strng[];
X
X          iiiinnnntttt gggg____ffffoooonnnnttttccccttttllll((((ssssiiiizzzzeeee,,,, aaaassssppppeeeecccctttt____rrrraaaattttiiiioooo,,,, ssssppppaaaacc
cciiiinnnngggg,,,, aaaannnngggglllleeee,,,, ssssllllaaaannnntttt))))
X          float size, aspect_ratio, spacing, angle, slant;
X
X          iiiinnnntttt cccc____cccceeeellllllllcccchhhhaaaarrrr((((aaaasssscccc____cccchhhhaaaarrrr))))
X
X
X
X     Page 1                                          (printed 2/21/89)
X
X
X
X
X
X
X     GGGGLLLL((((3333LLLL))))               UUUUNNNNIIIIXXXX 5555....0000 ((((00001111 OOOOcccctttt 1111999988888888))))                GGGGLLLL((((3333LLLL))))
X
X
X
X          unsigned char asc_char;
X
X          iiiinnnntttt cccc____cccceeeellllllllssssttttrrrr((((ssssttttrrrrnnnngggg))))
X          char strng[];
X
X          iiiinnnntttt cccc____ccccuuuurrrrssssoooorrrr((((rrrroooowwww,,,,ccccoooollll))))
X          int row, col;
X
X          iiiinnnntttt gggg____ppppiiiixxxx____mmmmooooddddeeee((((mmmmooooddddeeee____vvvvaaaallll))))
X          int mode_val;
X
X          iiiinnnntttt gggg____ppppiiiixxxx____ccccoooolllloooorrrr((((ccccoooolllloooorrrr))))
X          int color;
X
X          iiiinnnntttt gggg____wwwweeeeiiiigggghhhhtttt((((lllliiiinnnneeeewwwweeeeiiiigggghhhhtttt))))
X          int lineweight;
X
X          lllloooonnnngggg gggg____ssssttttyyyylllleeee((((lllliiiinnnneeeessssttttyyyylllleeee))))
X          long linestyle;
X
X     DDDDEEEESSSSCCCCRRRRIIIIPPPPTTTTIIIIOOOONNNN
X          The _g_l collection of routines is designed to provide graphic
X          output to a number of video adapters and printers for PC
X          clone computers running UNIX or MS-DOS operating systems.
X
X          Various output devices are supported, including CGA, EGA,
X          Hercules, and dot matrix and laser printers.  For each type
X          of device, one or more graphics "modes" is defined in
X          graphics.h, and the corresponding bitmaps are defined in
X          bitmaps.h.  These modes roughly correspond to the BIOS video
X          modes defined for MS-DOS, with additional modes defined for
X          Hercules and for printer output.
X
X          Also included is an emulation of the BSD _p_l_o_t(_3) graphics
X          interface library.  See _p_l_o_t(_3) for details.
X
X          The _g__i_n_i_t routine initializes device (sets video mode),
X          buffers, and variables, and obtains pointers to video
X          memory, video shared memory segment or temporary printer
X          buffers.
X
X          The _g__f_i_n_i_s_h routine releases resources and detaches memory
X          segments.
X
X          The _g__c_l_e_a_r routine clears the screen (or printer buffer
X          area).
X
X          The _p__w_r__p_i_x routine activates a pixel.  If the current
X          writing mode is OR, the pixel is turned on (set to the
X          currently active color).  If the current writing mode is
X          XOR, the pixel value (color) is XORed with its current
X          value.
X
X
X
X     Page 2                                          (printed 2/21/89)
X
X
X
X
X
X
X     GGGGLLLL((((3333LLLL))))               UUUUNNNNIIIIXXXX 5555....0000 ((((00001111 OOOOcccctttt 1111999988888888))))                GGGGLLLL((((3333LLLL))))
X
X
X
X          The _n__m_o_v_e_p_e_n routine moves the logical cursor in normalized
X          32768 x 32768 address space, where (0,0) is the upper left
X          corner of the screen or printed page.
X
X          The _n__p_o_i_n_t routine draws a dot on the screen at (x,y) in
X          normalized address space.
X
X          The _n__d_r_a_w routine draws a vector from the current address
X          to (x,y) in normalized address space.
X
X          The _n__l_i_n_e routine draws a line from (x1,y1) to (x2,y2) in
X          normalized address space.
X
X          The _n__b_o_x routine draws a box with corners at (x1, y1) and
X          (x2, y2) in normalized address space.
X
X          The _n__e_l_l_i_p_s_e routine draws an ellipse in normalized address
X          space with center at (x, y) and semi-axes a and b parallel
X          to the x and y axes, respectively.
X
X          The _n__a_r_c routine draws an elliptical arc in normalized
X          address space.  The ellipse is centered at (x, y) with
X          semi-axes a and b parallel to the x and y axes,
X          respectively.  The arc begins at angle1 and continues to
X          angle2.  The direction of travel is clockwise as viewed on
X          the screen (counterclockwise in the "inverted" normalized
X          coordinate system).
X
X          The _n__g_r_a_f_c_h_a_r routine displays a vectorized (stroke font)
X          text character asc_char located at the current location.
X          The cursor is advanced to the next character position.
X
X          The _n__g_r_a_f_s_t_r routine displays a character string using a
X          stroke font.
X
X          The _g__f_o_n_t_c_t_l routine controls size, aspect ratio, spacing,
X          angle and slant of stroke font.  The size, aspect ratio and
X          spacing control height, relative width and relative spacing
X          of characters, with 1.0 selecting default values.  Changing
X          size will change the width and spacing appropriately.
X          Changing width will change the spacing.  Angle is the angle
X          of a text string in radians, with positive values rotating
X          the text clockwise.  Slant is the character slant in radians
X          (typically a number on the order of 0.2), with positive
X          values slanting the text to the "right," as in italics.
X
X          The _c__c_e_l_l_c_h_a_r routine displays a bit mapped character at
X          the current location.  The cursor is advanced to the next
X          character position.
X
X          The _c__c_e_l_l_s_t_r routine displays a string at the current
X          location, using bit mapped characters.
X
X
X
X     Page 3                                          (printed 2/21/89)
X
X
X
X
X
X
X     GGGGLLLL((((3333LLLL))))               UUUUNNNNIIIIXXXX 5555....0000 ((((00001111 OOOOcccctttt 1111999988888888))))                GGGGLLLL((((3333LLLL))))
X
X
X
X          The _c__c_u_r_s_o_r routine moves the graphics cursor to a position
X          corresponding to a character row and column.  This is used
X          for easy positioning of text drawn with the _c__c_e_l_l_s_t_r
X          routine.
X
X          The _g__p_i_x__m_o_d_e routine establishes the active OR mode or XOR
X          mode pixel setting mode, and returns the previous mode
X          value.
X
X          The _g__p_i_x__c_o_l_o_r routine sets the active pixel color, and
X          returns previous color value.
X
X          The _g__w_e_i_g_h_t routine sets the active line thickness, and
X          returns the previous line thickness value.
X
X          The _g__s_t_y_l_e routine sets the active line style (e.g. dot-
X          dash), and returns the previous line style value.
X
X     EEEENNNNVVVVIIIIRRRROOOONNNNMMMMEEEENNNNTTTT
X          The GLMODE shell variable may be used to specify the default
X          graphics mode (such as "16" to specify EGA 640x350 color
X          graphics).  The PLOTDEV shell variable may be used to
X          specify the printer device to use (such as "lpt" to use
X          /dev/lpt).
X
X     SSSSEEEEEEEE AAAALLLLSSSSOOOO
X          plot(3), lpset(1), shmcreate(1)
X
X     AAAAUUUUTTTTHHHHOOOORRRR
X          David T Lewis, Ann Arbor, MI, USA
X          (...!m-net!dtlewis!lewis)
X
X     BBBBUUUUGGGGSSSS
X          The _g__p_i_x__m_o_d_e routine does not set XOR mode for EGA high
X          res graphics.
X
X          The _g__p_i_x__c_o_l_o_r routine does not do anything for EGA high
X          res graphics.
X
X          The _g__w_e_i_g_h_t routine does not do anything (not yet
X          implemented).
X
X          The _a_r_c routine in plot(3) calculates the arc endpoint
X          differently from the BSD versions.  The BSD version is
X          simpler and less precise, but will give different display
X          output in some cases.
X
X          Writing in XOR mode is done at the p_wr_pix routine level.
X          In XOR mode, therefore, routines such as n_box and
X          n_grafchar will "lose pixels" at line intersections in XOR
X          mode, due to writing the same pixel twice (that is, turning
X          in on, then off again).
X
X
X
X     Page 4                                          (printed 2/21/89)
X
X
X
X
X
X
X     GGGGLLLL((((3333LLLL))))               UUUUNNNNIIIIXXXX 5555....0000 ((((00001111 OOOOcccctttt 1111999988888888))))                GGGGLLLL((((3333LLLL))))
X
X
X
X          The _g__i_n_i_t routine sets a signal handler to clean up the
X          screen before exiting, and _g__f_i_n_i_s_h restores the handler to
X          its previous value.  This may interfere with an
X          application's intended signal handling (the DO_CLEANUP macro
X          in config.h can eliminate this behavior).
X
X          For MS-DOS versions, graphics printer output must be done
X          with BIOS calls. Therefore, the default system printer
X          device must be used, and the PLOTDEV environment variable
X          has no meaning.
X
X     CCCCAAAAVVVVEEEEAAAATTTTSSSS
X          No checking is done to control ownership of the console
X          output.  The user of the program is assumed to be at the
X          console.  Any checks for this must be done by the
X          application program.
X
X          The EGA and VGA adapters control color and writing modes (OR
X          or XOR) with output to port addresses on the EGA/VGA card.
X          On System V/AT, this requires use of the outb() routine with
X          write access to /dev/mem.  Since this would require the
X          application program to be suid to root, support for color
X          and writing modes has not yet been implemented.
X
X     SSSSEEEEEEEE AAAALLLLSSSSOOOO
X          plot(3), plot(1), plot(5).
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X     Page 5                                          (printed 2/21/89)
X
X
X
XxX--EOF--XxX
echo restoring n_line.c
sed 's/^X//' > n_line.c <<XxX--EOF--XxX
X#ifndef lint
Xstatic char sccsid[] = "@(#) n_line.c 5.1 89/02/20";
X#endif
X
X/*
X *	Copyright (c) David T. Lewis 1987, 1988
X *	All rights reserved.
X *
X *	Permission is granted to use this for any personal noncommercial use.
X *	You may not distribute source or executable code for profit, nor
X *	may you distribute it with a commercial product without the written
X *	consent of the author.  Please send modifications to the author for
X *	inclusion in updates to the program.  Thanks.
X */
X
X/* Fri Jul  3 23:43:36 EDT 1987
X** dtlewis
X** Routine to draw a line.
X*/
X
Xextern int n_movepen(), n_draw();
X
Xint n_line(x1,y1,x2,y2)  
X	int x1, y1, x2, y2;
X{
X	if (n_movepen(x1,y1)) return(1);
X	if (n_draw(x2,y2)) return(1);
X	return(0);
X}
XxX--EOF--XxX


-- 
Please send comp.sources.unix-related mail to rsalz@uunet.uu.net.