Path: utzoo!attcan!uunet!bbn.com!rsalz From: rsalz@uunet.uu.net (Rich Salz) Newsgroups: comp.sources.unix Subject: v18i063: GL Graphics Library for AT-clone Unix, Part05/07 Message-ID: <1617@fig.bbn.com> Date: 24 Mar 89 17:58:08 GMT Lines: 1261 Approved: rsalz@uunet.UU.NET 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 < g_init.c < X#include "config.h" X#if MIX_C X#else X#include X#include X#if TCC X#else X#include X#endif /* TCC */ X#endif /* MIX_C */ X#if MS_DOS X#include X/* Mode to return to before exiting */ Xint g_text = -1; X#else X#include X#endif /* MS_DOS */ X#if XENIX_286 X#include X#include X#include X#endif /* XENIX_286 */ X#if HAS_SIG X#include 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 < gl.man < n_line.c <