v09i048: popi, The Digital Darkroom, Part02/09
Rich Burridge
richb at sunaus.sun.oz.AU
Wed Dec 13 10:45:02 AEST 1989
Posting-number: Volume 9, Issue 48
Submitted-by: Rich Burridge <richb at sunaus.sun.oz.AU>
Archive-name: popi/part02
---- Cut Here and unpack ----
#!/bin/sh
# this is part 2 of a multipart archive
# do not concatenate these parts, unpack them in order with /bin/sh
# file expr.c continued
#
CurArch=2
if test ! -r s2_seq_.tmp
then echo "Please unpack part 1 first!"
exit 1; fi
( read Scheck
if test "$Scheck" != $CurArch
then echo "Please unpack part $Scheck next!"
exit 1;
else exit 0; fi
) < s2_seq_.tmp || exit 1
echo "x - Continuing file expr.c"
sed 's/^X//' << 'Funky_Stuff' >> expr.c
Xstatic
X#endif /* __MSC__ */
Xvoid
Xexpr()
X{
X extern int prs;
X int remem1,
X remem2;
X
X DEBUG((Debug, "expr() lat='%c'\n", lat));
X DEBUG((Debug, "levels of precedence: %d\n", PREC_LEVELS));
X
X level(PREC_LEVELS - 1);
X
X if (lat == '?')
X {
X lex();
X emit('?');
X remem1 = prs;
X emit(0);
X expr();
X expect(':');
X emit(':');
X remem2 = prs;
X emit(0);
X parsed[remem1] = prs-1;
X expr();
X parsed[remem2] = prs-1;
X }
X}
X
X
Xvoid
Xexpect(t)
Xint t;
X{
X DEBUG((Debug, "expect('%c')\n", t));
X
X if (lat == t)
X lex();
X else
X {
X if (t < 127)
X SPRINTF(ErrBuf, "expected token '%c' (%d)", t, t);
X else
X SPRINTF(ErrBuf, "expected token (%d)", t);
X error(ERR_PARSE);
X }
X}
X
X/*
X * Transform = NEW '[' index ']' '=' expr
X * | NEW '=' expr
X * | expr
X */
Xvoid
Xtransform()
X{
X extern int prs;
X
X DEBUG((Debug, "transform() lat='%c'\n", lat));
X
X prs = 0 ; /* initial length of parse string */
X if (lat != NEW)
X {
X expr();
X emit('@');
X }
X else
X {
X lex();
X if (lat == '[')
X {
X fileref(CURNEW, CLVAL);
X expect('=');
X expr();
X emit('=');
X }
X else
X {
X expect('=');
X expr();
X emit('@');
X }
X }
X if (lat != '\n')
X {
X SPRINTF(ErrBuf,
X "syntax error - expected operator or end of expression");
X error(ERR_PARSE);
X }
X assert(lat == '\n');
X}
Funky_Stuff
echo "File expr.c is complete"
chmod 0444 expr.c || echo "restore of expr.c fails"
set `wc -c expr.c`;Sum=$1
if test "$Sum" != "8806"
then echo original size 8806, current size $Sum;fi
echo "x - extracting ibmpc.c (Text)"
sed 's/^X//' << 'Funky_Stuff' > ibmpc.c &&
X/*LINTLIBRARY*/
X#ifndef lint
Xstatic char sccsid[] = "@(#)ibmpc.c 1.4 89/12/12" ;
X#endif
X
X/* Popi device driver for a PC using one of:
X * Borland Turbo C
X * Microsoft C
X * MIX Power C
X * Written by Stephen Frede, Softway Pty Ltd.
X *
X * Popi was originally written by Gerard J. Holzmann - AT&T Bell Labs.
X * This version is based on the code in his Prentice Hall book,
X * "Beyond Photography - the digital darkroom," ISBN 0-13-074410-7,
X * which is copyright (c) 1988 by Bell Telephone Laboratories, Inc.
X *
X * Permission is given to distribute these extensions, as long as these
X * introductory messages are not removed, and no monies are exchanged.
X *
X * No responsibility is taken for any errors or inaccuracies inherent
X * either to the comments or the code of this program, but if reported
X * (see README file) then an attempt will be made to fix them.
X */
X
X/*
X * There is still some work to be done here:
X * + vid_detect() needs to be written.
X * + HGC code needs to be fixed properly.
X * + other standard modes need to be added.
X * + Dithering or something needs to be added for EGA (sim to CGA).
X * + Handle image allocation properly with far pointers
X * where appropriate (ie unavoidable).
X */
X
X#if defined(__STDC__) && defined(__TURBOC__)
X/* The user has (with commendable intentions) used the Turbo C
X * ANSI compatibility flag. Unfortunately, we need the nonstandard
X * extensions to include <graphics.h> and use far pointers.
X */
X#include "Unfortunately, can't use ANSI compatibility flag."
X#endif /* __STDC__ && __TURBOC__ */
X
X#include "popi.h"
X
X/* I don't know what token Power C defines to distinguish itself.
X * But it does define a max() macro in stdlib.h include file.
X * Hopefully no other vendor is silly enough to do this, so we
X * can use that to distinguish Power C.
X */
X#if defined(__STDC__) && defined(max)
X#define __POWERC__ 1
X#endif /* __STDC__ && max */
X
X/* We assume that the compiler has these files header files. */
X#include <dos.h>
X#include <conio.h>
X
X/* We only use the __TURBOC__ token to test for graphics related
X * features from here on, so if we have an old version with no
X * graphics support, just pretend we are a generic compiler.
X */
X#if defined(__TURBOC__)
X# if __TURBOC__ < 0x0200
X# undef __TURBOC__
X# endif /* __TURBOC__ < 0x0200 */
X#endif /* __TURBOC__ */
X
X#if __TURBOC__ || __POWERC__
X# include <graphics.h>
X#endif /* __TURBOC__ || __POWERC__ */
X
X#if __MSC__
X#include <graph.h>
X#endif /* __MSC__ */
X
X
X#if defined(__TURBOC__)
X# ifndef BGIPATH
X# define STRBGIPATH ""
X# else
X# define STR(x) #x
X# define STRBGIPATH STR(BGIPATH)
X# endif /* BGIPATH */
X#endif /* __TURBOC__ */
X
X#ifndef MK_FP
X#define MK_FP(segment,offset) ((void far *) \
X (((unsigned long)(segment) << 16) | (unsigned)(offset)))
X#endif /* MK_FP */
X
X/* There are ten exportable routines used by the popi program.
X *
X * These are:
X *
X * disp_init(argc, argv) - called from main at the start.
X * disp_finish() - called from main prior to exit.
X * disp_imgstart() - called prior to drawing an image.
X * disp_imgend() - called after drawing an image.
X * disp_putline(line, y) - to draw an image scanline.
X * disp_getchar() - to get the next character typed.
X * disp_ungetc(c) - put back the last character typed.
X * disp_prompt() - display popi prompt and clear input buffer.
X * disp_error(errtype,pos) - display error message.
X * disp_percentdone(n) - display percentage value of conversion.
X */
X
X/*
X * Bios function call definitions
X */
X
X#define BIOS_VIDFN 0x10 /* Video functions */
X#define VID_PALETTE 0x10 /* palette access function */
X#define PAL_SETPAL 0x00 /* update single palette register */
X#define PAL_SETPALBLOCK 0x02 /* update all palette registers */
X#define PAL_GETPALBLOCK 0x09 /* read all palette registers */
X#define PAL_GETDACBLOCK 0x17 /* read current VGA DAC values */
X#define PAL_SETDACBLOCK 0x12 /* set new VGA DAC values */
X
X/*
X * Arguments to the vid_vgapalette and vid_setpalette functions
X */
X#define PAL_SAVE 0 /* Save existing values */
X#define PAL_RESTORE 1 /* Restore saved values */
X#define PAL_SETGREY 2 /* Set greyscale mapping */
X#define PAL_SETLIN 3 /* Set 1:1 mapping (vid_setpalette) */
X
X/* Bios Addresses */
X#define SEG_VIDBIOS 0x0040 /* Segment of video BIOS addresses */
X#define BIOSADDR_MODE 0x0049 /* Current BIOS video mode number */
X#define BIOSADDR_CRTCPORT 0x0063 /* Port Address of CRTC */
X
X/* Fixed port addresses */
X#define HGC_SWITCH 0x03BF
X
X
X/* Prototypes for local functions */
Xvoid vid_vgapalette P((int));
Xvoid vid_setpalette P((int));
Xvoid vid_setmode P((unsigned char));
Xvoid vid_sethgc P((void));
Xvoid vid_setpixel P((int, int, pixel_t));
Xunsigned char vid_detect P((void));
X
X /* Array containing threshold values for dithering. */
Xpixel_t thresh[BITSPERPIXEL][BITSPERPIXEL] =
X{
X { 0, 128, 32, 160, 8, 136, 40, 168, },
X { 192, 64, 224, 96, 200, 72, 232, 104, },
X { 48, 176, 16, 144, 56, 184, 24, 152, },
X { 240, 112, 208, 80, 248, 120, 216, 88, },
X { 12, 140, 44, 172, 4, 132, 36, 164, },
X { 204, 76, 236, 108, 196, 68, 228, 100, },
X { 60, 188, 28, 156, 52, 180, 20, 148, },
X { 252, 124, 220, 92, 244, 116, 212, 84, },
X};
X
Xstruct VidDriver
X{
X unsigned char bios_mode; /* Bios mode no. */
X unsigned int xsize, /* Pixels/scanline */
X ysize; /* Scanlines/image */
X /* Segment to which screen buffer is mapped */
X unsigned int ScreenMem;
X unsigned int interlace, /* no. lines interlaced */
X interlace_offset; /* memory offset for interlace */
X unsigned char PixelsPerByte;
X};
X
Xstatic struct VidDriver VidDrivers[] =
X{
X#define VID_VGA 0
X {
X 0x13, 320, 200, 0xA000, 1, 0, 1,
X },
X#define VID_EGA 1
X {
X 0x10, 640, 350, 0xA000, 2, 0x2000, 8,
X },
X#define VID_CGA 2
X {
X 0x06, 640, 200, 0xB800, 2, 0x2000, 8,
X },
X#define VID_STD 2 /* Last standard adapter */
X/* From here on, adapters have no bios support. The bios
X * number will be stored in the appropriate place in the video
X * bios data area (this is useful eg if a mouse is being used,
X * so it gets the graphics cursor correct).
X */
X#define VID_HGC 3
X {
X 0x06, 720, 348, 0xB000, 4, 0x2000, 8,
X },
X};
X#define VID_NONE -1 /* Unknown video adapter */
X/* When VidAdapter is VID_LIB, use compile-time dependant
X * library routines. For example, the Turbo C graphics library
X * allows custom drivers to be added for nonstandard adapters.
X */
X#define VID_LIB -2
X
Xstatic struct VidDriver
X *VidDriver = 0;
X
Xstatic int
X VidAdapter = VID_NONE,
X vid_xbytes,
X vid_xoff_bytes,
X vid_yoff;
X#if __TURBOC__
Xstatic int
X tc_driver,
X tc_mode,
X tc_error;
X#endif /* __TURBOC__ */
X
Xstatic unsigned char far
X *ScreenMem;
X/* Pointer to current mode in Bios video display data area */
Xstatic char far
X *VidModeBiosAddr = MK_FP(SEG_VIDBIOS, BIOSADDR_MODE);
X/* Pointer to CRTC register port number in Bios dideo display area */
Xstatic short far
X *CrtcPortBiosAddr = MK_FP(SEG_VIDBIOS, BIOSADDR_CRTCPORT);
Xstatic char
X VidInitMode;
X
X/*
X * Routine to map VGA palette registers (256 colour mode)
X * to and from a greyscale display.
X */
X#define BITSPERBYTE 8
X#define BITSPERVGACOLOUR 6
X /* no. VGA DAC registers */
X#define SIZE_DACS 256
X /* no. distinct greyscale values */
X#define NUM_GREY (1 << BITSPERVGACOLOUR)
X /* no. palette registers that map
X * to the same greyscale value */
X#define GREY_SAME (SIZE_DACS / NUM_GREY)
X /* no. underlying colours on vga */
X#define PRIMARY_COLOURS 3
X
Xstatic void
Xvid_vgapalette(action)
Xint action;
X{
X union REGS regs;
X struct SREGS sreg;
X static unsigned char SaveDacs[SIZE_DACS * PRIMARY_COLOURS],
X *GreyDacs = 0;
X
X switch(action)
X {
X case PAL_SAVE:
X /* Save existing palette */
X regs.h.ah = VID_PALETTE;
X regs.h.al = PAL_GETPALBLOCK;
X regs.x.bx = 0; /* first palette register */
X regs.x.cx = SIZE_DACS; /* read all palette registers */
X segread(&sreg);
X sreg.es = sreg.ds;
X regs.x.dx = (unsigned int) SaveDacs;
X int86x(BIOS_VIDFN, ®s, ®s, &sreg);
X break;
X
X case PAL_RESTORE:
X /* restore saved palette */
X regs.h.ah = VID_PALETTE;
X regs.h.al = PAL_SETDACBLOCK;
X regs.x.bx = 0; /* first palette register */
X regs.x.cx = SIZE_DACS; /* read all palette registers */
X segread(&sreg);
X sreg.es = sreg.ds;
X regs.x.dx = (unsigned int) SaveDacs;
X int86x(BIOS_VIDFN, ®s, ®s, &sreg);
X break;
X
X case PAL_SETGREY:
X /* set palette to greyscale */
X if (GreyDacs == 0)
X {
X unsigned char *p,
X c;
X
X if ((GreyDacs = malloc(SIZE_DACS*PRIMARY_COLOURS))
X == 0)
X {
X sprintf(ErrBuf, "Dacs allocation failed");
X error(ERR_SYS);
X return;
X }
X for (p = GreyDacs, c = 0; c < NUM_GREY; ++c)
X {
X int i;
X
X for (i = 0; i < PRIMARY_COLOURS * GREY_SAME; ++i)
X *p++ = c;
X }
X }
X regs.h.ah = VID_PALETTE;
X regs.h.al = PAL_SETDACBLOCK;
X regs.x.bx = 0; /* first palette register */
X regs.x.cx = SIZE_DACS; /* read all palette registers */
X segread(&sreg);
X sreg.es = sreg.ds;
X regs.x.dx = (unsigned int) GreyDacs;
X int86x(BIOS_VIDFN, ®s, ®s, &sreg);
X break;
X }
X}
X
X/*
X * Routine to map 16 palette registers.
X */
X
X#define SIZE_PALETTE 17 /* 16 + overscan */
X
Xstatic void
Xvid_setpalette(action)
Xint action;
X{
X union REGS regs;
X struct SREGS sreg;
X static unsigned char SavePalette[SIZE_PALETTE],
X *GreyPalette = 0;
X unsigned char palette;
X
X switch (action)
X {
X case PAL_SAVE:
X /* Save existing palette */
X regs.h.ah = VID_PALETTE;
X regs.h.al = PAL_GETPALBLOCK;
X segread(&sreg);
X sreg.es = sreg.ds;
X regs.x.dx = (unsigned int) SavePalette;
X int86x(BIOS_VIDFN, ®s, ®s, &sreg);
X break;
X
X case PAL_RESTORE:
X /* restore saved palette */
X regs.h.ah = VID_PALETTE;
X regs.h.al = PAL_SETPALBLOCK;
X segread(&sreg);
X sreg.es = sreg.ds;
X regs.x.dx = (unsigned int) SavePalette;
X int86x(BIOS_VIDFN, ®s, ®s, &sreg);
X break;
X
X case PAL_SETGREY:
X /* set palette to greyscale */
X if (GreyPalette == 0)
X {
X if ((GreyPalette = (unsigned char *) malloc(SIZE_PALETTE)) == 0)
X {
X sprintf(ErrBuf, "Palette allocation failed");
X error(ERR_SYS);
X return;
X }
X GreyPalette[0] = 000;
X GreyPalette[1] = 070;
X GreyPalette[2] = 007;
X GreyPalette[3] = 077;
X GreyPalette[SIZE_PALETTE-1] = SavePalette[SIZE_PALETTE-1];
X }
X regs.h.ah = VID_PALETTE;
X regs.h.al = PAL_SETPALBLOCK;
X segread(&sreg);
X sreg.es = sreg.ds;
X regs.x.dx = (unsigned int) GreyPalette;
X int86x(BIOS_VIDFN, ®s, ®s, &sreg);
X break;
X
X case PAL_SETLIN:
X for (palette = 0; palette < SIZE_PALETTE; ++palette)
X {
X union REGS regs;
X
X regs.h.ah = VID_PALETTE;
X regs.h.al = PAL_SETPAL;
X regs.h.bh = palette;
X regs.h.bl = palette;
X int86(BIOS_VIDFN, ®s, ®s);
X }
X break;
X }
X}
X
Xstatic void
Xvid_setmode(mode)
Xunsigned char mode;
X{
X union REGS regs;
X
X regs.h.ah = 0;
X regs.h.al = mode;
X int86(0x10, ®s, ®s);
X}
X
Xstatic void
Xvid_setpixel(x, y, value)
Xint x, y;
Xpixel_t value;
X{
X union REGS regs;
X
X regs.h.al = value;
X regs.h.ah = 0x0C;
X regs.h.bh = 0;
X regs.x.cx = (unsigned) x;
X regs.x.dx = (unsigned) y;
X int86(0x10, ®s, ®s);
X}
X
X/*
X * Detect installed graphics hardware.
X */
Xstatic unsigned char
Xvid_detect()
X{
X /* Yes, well, when I get a chance I'll do this.
X * Wait for the next release.
X */
X return VID_NONE;
X}
X
X/*ARGSUSED*/
Xvoid
Xdisp_init(argc,argv) /* called from main at the start. */
Xint argc;
Xchar *argv[];
X{
X /* Some compilers (eg Power C) don't get the initialisation right,
X * so repeat it here.
X */
X VidModeBiosAddr = MK_FP(SEG_VIDBIOS, BIOSADDR_MODE);
X CrtcPortBiosAddr = MK_FP(SEG_VIDBIOS, BIOSADDR_CRTCPORT);
X VidInitMode = *VidModeBiosAddr;
X
X VidAdapter = vid_detect();
X
X#if __TURBOC__
X tc_driver = DETECT;
X detectgraph(&tc_driver, &tc_mode);
X
X switch (tc_driver)
X {
X case VGA:
X VidAdapter = VID_VGA;
X break;
X
X case EGA:
X case EGA64:
X VidAdapter = VID_EGA;
X break;
X
X case CGA:
X VidAdapter = VID_CGA;
X break;
X
X default:
X initgraph(&tc_driver, &tc_mode, STRBGIPATH);
X tc_error = graphresult();
X if (tc_error < 0)
X {
X sprintf(ErrBuf, "initgraph error (%s)",
X grapherrormsg(tc_error));
X error(ERR_WARN);
X VidAdapter = VID_NONE;
X return;
X }
X else
X VidAdapter = VID_LIB;
X }
X#endif /* __TURBOC__ */
X
X#if __MSC__
X if (_setvideomode(_VRES2COLOR))
X VidAdapter = VID_VGA;
X else if (_setvideomode(_ERESNOCOLOR))
X VidAdapter = VID_EGA;
X else if (_setvideomode(_HRESBW))
X ;
X else
X VidAdapter = VID_NONE;
X#endif /* __MSC__ */
X
X#if __POWERC__
X if (setvmode(17) == 17)
X VidAdapter = VID_VGA;
X else if (setvmode(15) == 15)
X VidAdapter = VID_EGA;
X else if (setvmode(6) == 6)
X VidAdapter = VID_CGA;
X else if (setvmode(99) == 99)
X VidAdapter = VID_HGC;
X#endif /* __POWERC__ */
X
X /* This is also a last minute addition that needs to
X * be cleaned up - again, next release.
X */
X for (++argv; *argv; ++argv)
X {
X char *card;
X
X if (**argv == '-')
X switch ((*argv)[1])
X {
X case 'c': /* card */
X card = *argv + 2;
X if (strcmp(card, "vga") == 0)
X VidAdapter = VID_VGA;
X else if (strcmp(card, "ega") == 0)
X VidAdapter = VID_EGA;
X else if (strcmp(card, "cga") == 0)
X VidAdapter = VID_CGA;
X else if (strcmp(card, "hgc") == 0)
X VidAdapter = VID_HGC;
X else if (strcmp(card, "lib") == 0)
X VidAdapter = VID_LIB;
X }
X }
X
X if (VidAdapter == VID_NONE)
X {
X vid_setmode(VidInitMode);
X sprintf(ErrBuf, "No graphics hardware detected");
X error(ERR_WARN);
X return;
X }
X
X switch (VidAdapter)
X {
X case VID_LIB:
X return;
X
X case VID_VGA:
X vid_setpalette(PAL_SAVE);
X vid_setpalette(PAL_SETLIN);/**/
X vid_vgapalette(PAL_SAVE);
X break;
X
X case VID_EGA:
X vid_setpalette(PAL_SAVE);
X break;
X
X case VID_CGA:
X break;
X }
X
X vid_setmode(VidInitMode);
X
X VidDriver = &VidDrivers[VidAdapter];
X if (Xsize > VidDriver->xsize)
X Xsize = VidDriver->xsize;
X if (Ysize > VidDriver->ysize)
X Ysize = VidDriver->ysize;
X vid_xbytes = VidDriver->xsize / VidDriver->PixelsPerByte;
X vid_yoff = (VidDriver->ysize - Ysize) / 2;
X vid_xoff_bytes =
X ((VidDriver->xsize - Xsize) / 2) / VidDriver->PixelsPerByte;
X ScreenMem = MK_FP(VidDriver->ScreenMem, 0);
X}
X
Xvoid
Xdisp_finish() /* called from main prior to exit. */
X{
X#if __TURBOC__
X if (VidAdapter == VID_LIB)
X closegraph();
X#endif /* __TURBOC__ */
X}
X
X/*
X * Set up Hercules Graphics Card 720 * 348 graphics mode
X */
Xstatic void
Xvid_sethgc()
X{
X unsigned short ModeControl = 0x03b8;
X unsigned short CrtcAddress = 0x03b4;
X unsigned short CrtcData = CrtcAddress + 1;
X
X outportb(HGC_SWITCH, 0x01); /* allow graphics mode */
X outportb(ModeControl, 0x00); /* Video disabled during setup */
X
X /* Horizontal total: 54 "characters" (at 16 pixels/char) */
X outportb(CrtcAddress, 0x00);
X outportb(CrtcData, 0x35);
X /* Horizontal displayed: 45 "characters" */
X outportb(CrtcAddress, 0x01);
X outportb(CrtcData, 0x2d);
X /* Horizontal sync position: at 45th character */
X outportb(CrtcAddress, 0x02);
X outportb(CrtcData, 0x2e);
X /* Horizontal sync width: 7 character clocks */
X outportb(CrtcAddress, 0x03);
X outportb(CrtcData, 0x07);
X /* Vertical total: 94 "characters" (at 4 scanlines/char) */
X outportb(CrtcAddress, 0x04);
X outportb(CrtcData, 0x5b);
X /* Vertical adjust: 2 scanlines */
X outportb(CrtcAddress, 0x05);
X outportb(CrtcData, 0x02);
X /* Vertical displayed: 87 "character" rows */
X outportb(CrtcAddress, 0x06);
X outportb(CrtcData, 0x57);
X /* Vertical sync position: after 87th char row */
X outportb(CrtcAddress, 0x07);
X outportb(CrtcData, 0x57);
X /* Max scan line: 4 lines/char */
X outportb(CrtcAddress, 0x09);
X outportb(CrtcData, 0x03);
X
X *VidModeBiosAddr = 6; /* Microsoft mouse: HGC using CRT page 0 */
X
X outportb(ModeControl, 0x0a); /* Video enabled, Graphics mode */
X}
X
Xvoid
Xdisp_imgstart() /* called prior to drawing an image. */
X{
X if (VidAdapter == VID_NONE)
X return;
X
X if (VidAdapter == VID_LIB)
X {
X#if __TURBOC__
X setgraphmode(tc_mode);
X#endif /* __TURBOC__ */
X return;
X }
X
X if (VidAdapter <= VID_STD)
X vid_setmode(VidDriver->bios_mode);
X else
X *VidModeBiosAddr = VidDriver->bios_mode; /* fake it */
X
X switch (VidAdapter)
X {
X case VID_VGA:
X vid_vgapalette(PAL_SETGREY);
X break;
X
X case VID_EGA:
X vid_setpalette(PAL_SETGREY);
X break;
X
X case VID_HGC:
X vid_sethgc();
X break;
X }
X}
X
Xvoid
Xdisp_imgend() /* called after drawing an image. */
X{
X (void) getch();
X
X switch (VidAdapter)
X {
X case VID_VGA:
X vid_vgapalette(PAL_RESTORE);
X vid_setpalette(PAL_RESTORE);
X break;
X
X case VID_EGA:
X vid_setpalette(PAL_RESTORE);
X break;
X }
X
X vid_setmode(VidInitMode);
X}
X
Xvoid
Xdisp_putline(line, y) /* called to draw image scanline y. */
Xpixel_t *line;
Xint y;
X{
X register int x;
X register unsigned char far *p;
X
X if (VidAdapter == VID_NONE)
X return;
X
X if (VidAdapter == VID_LIB)
X {
X for (x = 0; x < Xsize; ++x)
X {
X pixel_t val;
X
X val = *line++ < thresh[y % BITSPERPIXEL][x % BITSPERPIXEL] ?
X (pixel_t) 0 : (pixel_t) 1;
X#if __TURBOC__
X putpixel(x, y, val);
X#endif /* __TURBOC__ */
X#if __MSC__
X _setcolor(val);
X _setpixel(x, y);
X#endif /* __MSC__ */
X#if __POWERC__
X pen_color(val);
X setpixel(x, y);
X#endif /* __POWERC__ */
X }
X return;
X }
X
X p = &ScreenMem[
X (
X ((y + vid_yoff) % VidDriver->interlace)
X *
X VidDriver->interlace_offset
X )
X +
X (y + vid_yoff) / VidDriver->interlace * vid_xbytes
X /*
X +
X vid_xoff_bytes
X */
X ];
X
X switch (VidAdapter)
X {
X case VID_VGA:
X for (x = 0; x < Xsize; ++x)
X *p++ = *line++;
X break;
X
X case VID_EGA:
X /* 4 grey levels isn't enough - need to do dithering as well,
X * or perhaps fake it with some colours.
X */
X for (x = 0; x < Xsize; ++x)
X vid_setpixel(x, y, *line++ / 64);
X break;
X
X case VID_CGA:
X for (x = 0; x < Xsize;)
X {
X register unsigned char t;
X register unsigned char val;
X register unsigned char byte;
X register int pixel;
X
X byte = 0;
X for (pixel = 8; pixel > 0; ++x)
X {
X t = thresh[y % BITSPERPIXEL][x % BITSPERPIXEL];
X val = *line++;
X byte |= (val > t * 2 / 3 ? 1 : 0) << --pixel;
X byte |= (val > (t * 2 + Zsize) / 3 ? 1 : 0) << --pixel;
X }
X *p++ = byte;
X }
X break;
X
X case VID_HGC:
X for (x = 0; x < Xsize;)
X {
X register char t;
X register unsigned char byte;
X register int pixel;
X
X byte = 0;
X for (pixel = 8; pixel > 0; ++x)
X {
X t = *line++ < thresh[y % BITSPERPIXEL][x % BITSPERPIXEL] ?
X (pixel_t) 0 : (pixel_t) 1;
X byte |= t << --pixel;
X }
X *p++ = byte;
X }
X break;
X }
X}
X
Xint
Xdisp_getchar() /* get next user typed character. */
X{
X return(getchar());
X}
X
X
X/*ARGSUSED*/
Xvoid
Xdisp_ungetc(c) /* put back the last character typed. */
Xint c;
X{
X UNGETC(c, stdin);
X}
X
Xint
Xdisp_prompt() /* display popi prompt. */
X{
X char *prompt = "-> ";
X
X PRINTF(prompt);
X return sizeof prompt - 1;
X}
X
Xvoid
Xdisp_error(errtype, pos) /* display error message. */
Xint errtype,
X pos;
X{
X extern int errno;
X extern char *sys_errlist[];
X
X if (errtype & ERR_PARSE)
X {
X int i;
X
X for (i=1; i < pos; ++i)
X PUTC('-', stderr);
X PUTC('^', stderr);
X PUTC('\n', stderr);
X }
X
X FPRINTF(stderr, "%s\n", ErrBuf);
X /* we assume errno hasn't been reset by the preceding output */
X if (errtype & ERR_SYS)
X FPRINTF(stderr, "\t(%s)\n", sys_errlist[errno]);
X}
X
Xvoid
Xdisp_percentdone(percent)
Xint percent;
X{
X static int lastpercent = 100;
X
X if (!Verbose)
X return;
X if (percent == 100)
X {
X printf("\r \n");
X return;
X }
X if (percent != lastpercent)
X {
X printf("\r%2d%% ", percent);
X fflush(stdout);
X lastpercent = percent;
X }
X}
Funky_Stuff
chmod 0444 ibmpc.c || echo "restore of ibmpc.c fails"
set `wc -c ibmpc.c`;Sum=$1
if test "$Sum" != "20056"
then echo original size 20056, current size $Sum;fi
echo "x - extracting io.c (Text)"
sed 's/^X//' << 'Funky_Stuff' > io.c &&
X/* @(#)io.c 1.8 89/12/11
X *
X * File handling routines used by the popi program.
X *
X * Popi was originally written by Gerard J. Holzmann - AT&T Bell Labs.
X * This version is based on the code in his Prentice Hall book,
X * "Beyond Photography - the digital darkroom," ISBN 0-13-074410-7,
X * which is copyright (c) 1988 by Bell Telephone Laboratories, Inc.
X *
X * Permission is given to distribute these extensions, as long as these
X * introductory messages are not removed, and no monies are exchanged.
X *
X * No responsibility is taken for any errors or inaccuracies inherent
X * either to the comments or the code of this program, but if reported
X * (see README file) then an attempt will be made to fix them.
X */
X
X
X#include <stdio.h>
X#include <errno.h>
X#include <ctype.h>
X#include "popi.h"
X
X#if unix || AMIGA
X#define RMODE "r"
X#define WMODE "w"
X#else /* ! (unix || AMIGA) */
X#define RMODE "rb"
X#define WMODE "wb"
X#endif /* unix || AMIGA */
X
Xint nsrc = 2;
Xstatic int IsPopen = 0;
X
Xpixel_t **
XImgAlloc()
X{
X int y;
X pixel_t **p;
X
X noerr = 1;
X if ((p = (pixel_t **) LINT_CAST(Emalloc((unsigned)Xsize * sizeof(pixel_t *)))) == 0)
X return (pixel_t **) 0;
X
X for (y = 0; y < Ysize; ++y)
X p[y] = (pixel_t *) Emalloc((unsigned)Xsize * sizeof (pixel_t));
X
X if (noerr == 0)
X {
X /* Run out of memory; free what we have allocated */
X for (y = 0; y < Ysize; ++y)
X {
X if (p[y])
X free((char *) p[y]);
X }
X return (pixel_t **) 0;
X }
X
X return p;
X}
X
Xvoid
XImgFree(img)
Xstruct SRC *img;
X{
X int y;
X pixel_t **p;
X
X free(img->str);
X img->str = (char *) 0;
X
X p = img->pix;
X
X for (y = 0; y < Ysize; ++y)
X free((char *) (*p++));
X
X free((char *) img->pix);
X img->pix = (pixel_t **) 0;
X}
X
Xvoid
XEfclose(stream)
XFILE *stream;
X{
X#if unix
X if (IsPopen)
X PCLOSE(stream);
X else
X#endif /* unix */
X FCLOSE(stream);
X}
X
XFILE *
XEfopenR(filename)
Xchar *filename;
X{
X FILE *istr;
X#if unix
X FILE *popen();
X#endif /* unix */
X
X DEBUG((Debug, "EfopenR(%s)\n", filename));
X IsPopen = 0;
X if ((istr = fopen(filename, RMODE)) != NULL)
X return istr;
X
X#if unix
X if (errno == ENOENT)
X {
X char buf[512];
X
X /* first see if the compressed file exists and is readable */
X SPRINTF(buf, "%s.Z", filename);
X if ((istr = fopen(buf, "r")) != NULL)
X {
X /* OK - it's there */
X FCLOSE(istr);
X SPRINTF(buf, "zcat %s", filename);
X DEBUG((Debug, "popen(%s)\n", buf));
X if ((istr = popen(buf, "r")) != NULL)
X {
X IsPopen = 1;
X return istr;
X }
X }
X }
X#endif /* unix */
X
X SPRINTF(ErrBuf, "Can't read file '%s'", filename);
X error(ERR_SYS);
X return NULL;
X}
X
XFILE *
XEfopenW(filename)
Xchar *filename;
X{
X FILE *ostr;
X FILE *popen();
X
X DEBUG((Debug, "EfopenW(%s)\n", filename));
X IsPopen = 0;
X
X#if unix
X if (*filename == '|')
X {
X ++filename;
X
X if ((ostr = popen(filename, "w")) == NULL)
X {
X SPRINTF(ErrBuf, "Can't run command '%s'", filename);
X error(ERR_SYS);
X }
X return ostr;
X }
X#endif /* unix */
X
X if ((ostr = fopen(filename, WMODE)) == NULL)
X {
X SPRINTF(ErrBuf, "Can't write file '%s'", filename);
X error(ERR_SYS);
X }
X return ostr;
X}
X
X
Xvoid
Xgetpix(filename, imgname)
Xchar *filename; /* file name */
Xchar *imgname; /* image name */
X{
X FILE *fd;
X int y,
X c;
X struct SRC *img = (struct SRC *) 0; /* work buffer */
X char *p,
X *rem;
X
X if ((fd = EfopenR(filename)) == NULL)
X return;
X
X if (imgname == 0 || *imgname == '\0')
X {
X imgname = filename;
X
X /*
X * Use the basename of the filename for the image name.
X * If this results in a non-valid image name, they'll
X * just have to use the $n equivalent. It's not our
X * business to go transforming names.
X */
X
X /* find last '/' in string */
X for (p = rem = imgname; *p; ++p)
X if (*p == '/' && p[1] != '\0')
X rem = p + 1;
X
X imgname = rem;
X }
X
X /* See if the named image already exists */
X for (c = 0; c < nsrc; c++)
X if (src[c].str && strcmp(src[c].str, imgname) == 0)
X {
X img = &src[c];
X break;
X }
X
X if (img == (struct SRC *) 0)
X {
X /* Allocate a new image */
X img = &src[nsrc++];
X
X if
X (
X (img->pix = ImgAlloc()) == 0
X ||
X (img->str = (char *) Emalloc((unsigned int) (strlen(imgname)+1))) == 0
X )
X return;
X
X STRCPY(img->str, imgname);
X }
X
X /* Read in the image */
X for (y = 0; y < Ysize; y++)
X {
X long total = 0;
X int count;
X
X if ((count = fread((char *) img->pix[y], 1, Xsize, fd)) <= 0)
X {
X if (ferror(fd))
X {
X SPRINTF(ErrBuf,
X "File '%s' read error (read %ld of %ld bytes)",
X filename, total, (long)Xsize * Ysize);
X error(ERR_SYS);
X FCLOSE(fd);
X return;
X }
X
X SPRINTF(ErrBuf,
X "File '%s' insufficient data (read %ld of %ld bytes)",
X filename, total, Xsize * Ysize);
X error(0);
X return;
X }
X
X total += count;
X }
X
X
X Efclose(fd);
X}
X
Xvoid
Xputpix(into, str)
Xstruct SRC *into ; /* work buffer */
Xchar *str ; /* file name */
X{
X FILE *fd;
X int i;
X
X if ((fd = EfopenW(str)) == NULL)
X return;
X
X for (i = 0; i < Ysize; i++)
X FWRITE((char *) into->pix[i], 1, Xsize, fd);
X
X Efclose(fd);
X}
X
X
Xvoid
Xshowfiles()
X{
X int n;
X
X for (n = 2; n < nsrc; n++)
X if(src[n].str)
X {
X PRINTF("$%d = %s\n", n - 1, src[n].str);
X if (LogStr)
X FPRINTF(LogStr, "$%d = %s\n", n - 1, src[n].str);
X }
X}
Funky_Stuff
chmod 0444 io.c || echo "restore of io.c fails"
set `wc -c io.c`;Sum=$1
if test "$Sum" != "5312"
then echo original size 5312, current size $Sum;fi
echo "x - extracting kerterm.c (Text)"
sed 's/^X//' << 'Funky_Stuff' > kerterm.c &&
X/*LINTLIBRARY*/
X
X/* @(#)kerterm.c 1.2 89/12/11
X *
X * Popi graphics driver for kermit TERM windows.
X * written by Frank Crawford - Q.H.Tours.
X *
X * Popi was originally written by Gerard J. Holzmann - AT&T Bell Labs.
X * This version is based on the code in his Prentice Hall book,
X * "Beyond Photography - the digital darkroom," ISBN 0-13-074410-7,
X * which is copyright (c) 1988 by Bell Telephone Laboratories, Inc.
X *
X * Permission is given to distribute these extensions, as long as these
X * introductory messages are not removed, and no monies are exchanged.
X *
X * No responsibility is taken for any errors or inaccuracies inherent
X * either to the comments or the code of this program, but if reported
X * (see README file) then an attempt will be made to fix them.
X */
X
X
X#include <stdio.h>
X#include <signal.h>
X#include <sys/types.h>
X#include "popi.h"
X
X#define KER_MAX_X 1023 /* Maximum Kermit X value */
X#define KER_MAX_Y 779 /* Maximum Kermit Y value */
X#define PC_MAX_X 640 /* Number of PC X value (EGA Card) */
X#define PC_MAX_Y 350 /* Number of PC Y value (EGA Card) */
X#define MAX_GREY 2 /* Max. Greyscale value (Black, Low-int, Hi-int) */
X
Xint thresh[MAX_GREY][BITSPERPIXEL][BITSPERPIXEL] =
X{
X { /* Array containing threshold values for low value. */
X { 0, 64, 16, 80, 4, 68, 20, 84, },
X { 96, 32, 112, 48, 100, 36, 116, 52, },
X { 24, 88, 8, 72, 28, 92, 12, 76, },
X { 120, 56, 104, 40, 124, 60, 108, 44, },
X { 6, 70, 22, 86, 2, 66, 18, 82, },
X { 102, 38, 118, 54, 98, 34, 114, 50, },
X { 30, 94, 14, 78, 26, 90, 10, 74, },
X { 126, 62, 110, 46, 122, 58, 106, 42, },
X },
X { /* Array containing threshold values for high value. */
X { 128, 192, 144, 208, 132, 196, 148, 212, },
X { 224, 160, 240, 176, 228, 164, 244, 180, },
X { 152, 216, 136, 200, 156, 220, 140, 204, },
X { 248, 184, 232, 168, 252, 188, 236, 172, },
X { 134, 198, 150, 214, 130, 194, 146, 210, },
X { 230, 166, 246, 182, 226, 162, 242, 178, },
X { 158, 222, 142, 206, 154, 218, 138, 202, },
X { 254, 190, 238, 174, 250, 186, 234, 170, },
X },
X};
X
X/* There are ten exportable routines used by the popi program.
X *
X * These are:
X *
X * disp_init(argc, argv) - called from main at the start.
X * disp_finish() - called from main prior to exit.
X * disp_imgstart() - called prior to drawing an image.
X * disp_imgend() - called after drawing an image.
X * disp_putline(line, y) - to draw an image scanline.
X * disp_getchar() - to get the next character typed.
X * disp_ungetc(c) - put back the last character typed.
X * disp_prompt() - display popi prompt and clear input buffer.
X * disp_error(errtype) - display error message.
X * disp_percentdone(n) - display percentage value of conversion.
X */
X
X/*ARGSUSED*/
Xvoid
Xdisp_init(argc,argv)
Xint argc;
Xchar *argv[];
X{
X}
X
Xvoid
Xdisp_finish()
X{
X}
X
Xvoid
Xdisp_intr(signal)
Xint signal;
X{
X disp_imgend();
X exit(signal);
X}
X
Xvoid
Xdisp_imgstart()
X{
X (void) signal(SIGINT, disp_intr);
X putchar('\033');
X putchar('\f');
X}
X
Xvoid
Xdisp_imgend()
X{
X char ch;
X
X putchar('\033');
X putchar('[');
X putchar('0');
X putchar('m');
X PRINTF("\037\n\n\007Hit return when ready:");
X fflush(stdout);
X while (read(1, &ch, 1) == 1 && ch != '\n') /* Because of inconsistent use */
X ;
X putchar('\033');
X putchar('[');
X putchar('?');
X putchar('3');
X putchar('8');
X putchar('l');
X fflush(stdout);
X (void) signal(SIGINT, SIG_DFL);
X}
X
Xstatic void
Xcoord(x, y, repeat)
Xint x, y;
Xint repeat;
X{
X /*
X * This function goes to a lot of effort to optimes the number of
X * characters sent down the line.
X */
X int hi_x, lo_x, hi_y, lo_y;
X static int sav_x = -1, sav_y = -1;
X
X y = KER_MAX_Y - y; /* To invert picture */
X hi_x = (x / 32);
X lo_x = (x % 32);
X hi_y = (y / 32);
X lo_y = (y % 32);
X if (!repeat || y != sav_y)
X {
X putchar(hi_y + 0x20);
X putchar(lo_y + 0x60);
X putchar(hi_x + 0x20);
X }
X else if (hi_x != (sav_x / 32))
X {
X putchar(lo_y + 0x60);
X putchar(hi_x + 0x20);
X }
X putchar(lo_x + 0x40);
X sav_x = x;
X sav_y = y;
X}
X
Xvoid
Xdisp_putline(line,y) /* Output scanline y. */
Xpixel_t *line;
Xint y;
X{
X int x;
X int real_x, real_y;
X int repeat, level;
X static old_level = 0;
X
X repeat = 0;
X /*
X * Calculate the real pixel location to handle the grey-scale threshold
X * values.
X */
X real_y = (y * PC_MAX_Y) / (KER_MAX_Y + 1);
X putchar('\034');
X for (x = 0; x < Xsize; x++, line++)
X {
X /* See above */
X real_x = (x * PC_MAX_X) / (KER_MAX_X + 1);
X for (level = 0; level < MAX_GREY; level++)
X if (*line < thresh[level][real_y % BITSPERPIXEL][real_x % BITSPERPIXEL])
X break;
X if (level != old_level)
X {
X if (level != 0)
X {
X putchar('\033');
X putchar('[');
X putchar((level == 1) ? '0' : '1');
X putchar('m');
X }
X old_level = level;
X }
X if (level != 0)
X coord(x, y, repeat++);
X }
X putchar('\n');
X}
X
X
Xdisp_getchar() /* Get next user typed character. */
X{
X return(getchar());
X}
X
X
Xvoid
Xdisp_ungetc(c) /* Put back the last character typed. */
Xchar c ;
X{
X UNGETC(c, stdin);
X}
X
X
X
Xdisp_prompt() /* Display popi prompt and clear input line. */
X{
X PRINTF("-> ");
X return 3;
X}
X
X
Xvoid
Xdisp_error(errtype, pos) /* Display error message. */
Xint errtype, pos ;
X{
X extern int errno;
X extern char *sys_errlist[];
X
X if (errtype & ERR_PARSE)
X {
X int i;
X
X for (i=1; i < pos; ++i)
X PUTC('-', stderr);
X PUTC('^', stderr);
X PUTC('\n', stderr);
X }
X
X FPRINTF(stderr, "%s\n", ErrBuf);
X /* we assume errno hasn't been reset by the preceding output */
X if (errtype & ERR_SYS)
X FPRINTF(stderr, "\t(%s)\n", sys_errlist[errno]);
X}
X
Xvoid
Xdisp_percentdone(percent)
Xint percent;
X{
X static int lastpercent = 100;
X
X if (!Verbose)
X return;
X if (percent == 100)
X {
X printf("\r \n");
X return;
X }
X if (percent != lastpercent && percent % 5 == 0)
X {
X printf("\r%2d%% ", percent);
X fflush(stdout);
X lastpercent = percent;
X }
X}
Funky_Stuff
chmod 0444 kerterm.c || echo "restore of kerterm.c fails"
set `wc -c kerterm.c`;Sum=$1
if test "$Sum" != "6329"
then echo original size 6329, current size $Sum;fi
echo "x - extracting main.c (Text)"
sed 's/^X//' << 'Funky_Stuff' > main.c &&
X/* @(#)main.c 1.11 89/12/12
X *
X * Main routine and declarations used by the popi program.
X *
X * Popi was originally written by Gerard J. Holzmann - AT&T Bell Labs.
X * This version is based on the code in his Prentice Hall book,
X * "Beyond Photography - the digital darkroom," ISBN 0-13-074410-7,
X * which is copyright (c) 1988 by Bell Telephone Laboratories, Inc.
X *
X * Permission is given to distribute these extensions, as long as these
X * introductory messages are not removed, and no monies are exchanged.
X *
X * No responsibility is taken for any errors or inaccuracies inherent
X * either to the comments or the code of this program, but if reported
X * (see README file) then an attempt will be made to fix them.
X */
X
X
X#include <stdio.h>
X#include <ctype.h>
X#include "popi.h"
X#include "patchlevel.h"
X
X/* prototypes for local functions */
X
Xbool do_parse P((void));
Xvoid get_options P((char **));
Xvoid Usage P((int));
Xint main P((int, char **));
X
Xstruct SRC
X src[MAXIMG]; /* array of images */
Xshort CUROLD = 0; /* index of "old" image */
Xshort CURNEW = 1; /* index of "new" image */
Xint noerr = 1;
Xint lexval; /* value of numerical token */
Xint Xsize = DEF_X, /* image width */
X Ysize = DEF_Y, /* image height */
X Zsize = DEF_ZSIZE; /* no. brightness levels */
Xpixel_t Zmax = DEF_ZSIZE - 1; /* max brightness level */
Xchar text[512]; /* value of string token */
Xchar *ProgName, /* program name (for err messages) */
X *LogFile = "popi.log"; /* Name of log file */
XFILE *Debug = NULL, /* debugging output stream */
X *LogStr = NULL; /* logging output stream */
Xint disp_active = 1, /* so we can turn off the display */
X Truncate = 0, /* Truncate assignments instead of wrapping. */
X Verbose = 0; /* be chatty */
Xchar geometry[MAXLINE]; /* X11 geometry information. */
Xchar x11_display[MAXLINE]; /* X11 display information. */
Xint iconic = 0; /* Set if the window is in an iconic state. */
X
X#if SEQPAR
Xint ncpus = 1; /* default is single-tasking */
X#endif /* SEQPAR */
X
Xstatic char *UsageMsg[] =
X{
X "valid options:",
X "\t-xWidth\t\tspecify image width (number pixels)",
X "\t-yHeight\tspecify image height (number scanlines)",
X "\t-a[+-]\t\tturn auto-display on or off",
X "\t-r[+-]\t\tturn range checking on or off",
X (char *) 0
X};
X
Xvoid
XPrStrs(msg)
Xchar *msg[];
X{
X char **p;
X
X p = msg;
X for (p = msg; *p; ++p)
X FPRINTF(stderr, "%s\n", *p);
X}
X
Xstatic void
XUsage(status)
Xint status;
X{
X FPRINTF(stderr, "Usage: %s [options] [image-files]\n", ProgName);
X PrStrs(UsageMsg);
X /* Also need a driver-specific usage message appended */
X exit(status);
X}
X
Xvoid
Xversion()
X{
X FPRINTF(stderr, "%s: version 2.1.%1d\n", ProgName, PATCHLEVEL);
X}
X
Xstatic void
Xget_options(argv) /* read command line options. */
Xchar *argv[];
X{
X for (ProgName = *argv++; *argv && **argv == '-'; ++argv)
X {
X switch (*++*argv)
X {
X case 'x':
X Xsize = atoi(++*argv);
X break;
X
X case 'y':
X Ysize = atoi(++*argv);
X break;
X
X case 'z':
X Zsize = atoi(++*argv);
X Zmax = (pixel_t) (Zsize - 1);
X break;
X
X case 'D':
X if (*++*argv)
X {
X if ((Debug = fopen(*argv, "w")) == NULL)
X {
X SPRINTF(ErrBuf,
X "Can't open debug file '%s' - using stderr",
X *argv);
X error(ERR_SYS);
X Debug = stderr;
X }
X }
X else
X Debug = stderr;
X setbuf(Debug, NULL); /**/
X break;
X
X case 'l': /* log all commands */
X if (*++*argv)
X LogFile = *argv;
X OpenLog();
X break;
X
X case 'p': /* No. cpus to use in parallel */
X /* Still recognise the option on other machines,
X * so scripts can use this option portably.
X */
X
X#if SEQPAR
X if (*++*argv)
X {
X ncpus = atoi(*argv);
X if (ncpus >= cpus_online())
X ncpus = cpus_online() - 1;
X if (ncpus < 0)
X ncpus = 0;
X }
X else
X ncpus = cpus_online() - 1;
X#endif /* SEQPAR */
X
X break;
X
X case 'd': /* x11 display information. */
X ++argv;
X STRCPY(x11_display,*argv);
X break;
X
X case 'g': /* x11 geometry information. */
X ++argv;
X STRCPY(geometry,*argv);
X break;
X
X case 'i': /* start window iconically. */
X iconic = 1;
X break;
X
X case 'r': /* range checking */
X if (*++*argv == '-')
X RangeCheck = 0;
X else
X RangeCheck = 1;
X break;
X
X case 'a': /* auto-display */
X if (*++*argv == '+')
X disp_active = 1;
X else
X disp_active = 0;
X break;
X
X case 'v': /* verbose */
X if (*++*argv == '-')
X Verbose = 0;
X else
X ++Verbose;
X break;
X
X case 'V': /* print version number. */
X version();
X exit(0);
X break;
X
X case '?': /* Print usage message */
X Usage(0);
X /* NOTREACHED */
X
X /* Note: no error on default because drivers may
X * interpret other options.
X */
X default:
X --*argv; /* reset for disp_init() */
X }
X }
X
X src[CUROLD].pix = ImgAlloc();
X src[CUROLD].str = "old";
X src[CURNEW].pix = ImgAlloc();
X src[CURNEW].str = "new";
X
X for (; *argv; ++argv)
X getpix(*argv, (char *) 0);
X}
X
X
X/*
X * Parse = # special
X * | '?' help
X * | 'q' quit
X */
Xstatic bool
Xdo_parse()
X{
X extern int lat ; /* look ahead token */
X
X /* display popi prompt and clear input line. Returns length of popi prompt. */
X CharPos = disp_prompt();
X
X if (LogStr)
X {
X FPRINTF(LogStr, "-> ");
X FFLUSH(LogStr);
X }
X
X lex();
X
X switch (lat)
X {
X case '#':
X special();
X break;
X
X case '?':
X help();
X Skip();
X break;
X
X case 'q':
X return FALSE;
X
X case '\n':
X break;
X
X default:
X transform();
X if (noerr)
X run();
X break;
X }
X assert(lat == '\n');
X return TRUE;
X}
X
X
X/*
X * We deliberately don't exit on error here.
X * The user may have some picture that has taken ages to develop.
X * If we run out of memory, they have a chance to save the
X * image and exit themselves, which they should do as soon
X * as possible.
X */
X
Xchar *
XEmalloc(n)
Xunsigned int n;
X{
X char *try;
X static unsigned long
X TotalAllocated = 0L;
X
X if ((try = malloc(n)) == NULL)
X {
X SPRINTF(ErrBuf,
X "Allocate %u bytes failed (total malloc=%lx)",
X n, TotalAllocated);
X error(ERR_SYS);
X }
X TotalAllocated += n;
X return try;
X}
X
Xmain(argc,argv)
Xint argc;
Xchar **argv;
X{
X get_options(argv) ; /* read the command line options. */
X disp_init(argc, argv);
X
X#if SEQPAR
X m_set_procs(ncpus);
X#endif /* SEQPAR */
X
X do
X noerr = TRUE;
X while (do_parse());
X
X disp_finish();
X
X /* Some compilers don't get the exit status right when
X * you return from main()
X */
X exit(0);
X return 0; /* shut up warning messages from some compilers */
X}
Funky_Stuff
chmod 0444 main.c || echo "restore of main.c fails"
set `wc -c main.c`;Sum=$1
if test "$Sum" != "7419"
then echo original size 7419, current size $Sum;fi
echo "x - extracting mgr.c (Text)"
sed 's/^X//' << 'Funky_Stuff' > mgr.c &&
X/*LINTLIBRARY*/
X
X/* @(#)mgr.c 1.8 89/12/11
X *
X * MGR dependent graphics routines used by popi.
X * written by Rich Burridge - Sun Microsystems.
X *
X * Popi was originally written by Gerard J. Holzmann - AT&T Bell Labs.
X * This version is based on the code in his Prentice Hall book,
X * "Beyond Photography - the digital darkroom," ISBN 0-13-074410-7,
X * which is copyright (c) 1988 by Bell Telephone Laboratories, Inc.
X *
X * Permission is given to distribute these extensions, as long as these
X * introductory messages are not removed, and no monies are exchanged.
X *
X * No responsibility is taken for any errors or inaccuracies inherent
X * either to the comments or the code of this program, but if reported
X * (see README file) then an attempt will be made to fix them.
X */
X
X#include "dump.h"
X#include "term.h"
X#include "popi.h"
X#include "graphics.h"
X#include <signal.h>
X#include <sys/types.h>
X#include <sys/time.h>
X
X#define B_FONT 1 /* Font descriptors. */
X#define N_FONT 2
X
X#define ICONIC 0 /* States that the popi display can be in. */
X#define OPEN 1
X
X#define PR_ICON 1 /* Descriptor for closed icon image. */
X#define PR_SCAN 2 /* Descriptor for current popi scan line. */
X
X#define BOLD_FONT "cour7x14b"
X#define NORMAL_FONT "cour7x14r"
X
X#define ICONHEIGHT 64 /* Height of the popi icon. */
X#define ICONWIDTH 64 /* Width of the popi icon. */
X
Xchar fontname[MAXLINE] ; /* Full pathname of each font. */
X
Xint local_mode; /* Used by load_icon for correct line mode. */
Xint mgr_infd ; /* MGR input connection file descriptor. */
Xint mgr_outfd ; /* MGR output connection file descriptor. */
X
Xshort icon_image[] = {
X#include "popi.icon"
X} ;
X
X#ifdef NO_43SELECT
Xint fullmask ; /* Full mask of file descriptors to check on. */
Xint readmask ; /* Readmask used in select call. */
X#else
Xfd_set fullmask ; /* Full mask of file descriptors to check on. */
Xfd_set readmask ; /* Readmask used in select call. */
X#endif /* NO_43SELECT */
X
X
XSIGRET
Xclean(code)
Xint code ;
X{
X m_bitdestroy(1) ;
X m_pop() ;
X m_ttyreset() ;
X m_clear() ;
X exit(code) ;
X}
X
X
Xcleanup() /* Cleanup before exiting. */
X{
X clean(0) ;
X}
X
X
Xclose_frame()
X{
X reshape(ICONIC) ;
X m_clearmode(M_ACTIVATE) ;
X iconic = 1 ;
X}
X
X
Xdraw_scanline(line, y) /* Display image scanline on the screen. */
Xunsigned char *line ;
Xint y ;
X{
X int fd, size ;
X
X halftone(line, y) ;
X
X IOCTL(mgr_outfd, TIOCLGET, &local_mode) ;
X local_mode |= LLITOUT ;
X IOCTL(mgr_outfd, TIOCLSET, &local_mode) ;
X
X size = (Xsize / 8) + 1 ;
X m_bitldto(Xsize, 1, 0, 0, PR_SCAN, size) ;
X m_flush() ;
X WRITE(mgr_outfd, mptr, size) ;
X
X local_mode &= ~LLITOUT ;
X IOCTL(mgr_outfd, TIOCLSET, &local_mode) ;
X
X m_bitcopyto(0, y+100, Xsize, 1, 0, 0, 0, PR_SCAN) ;
X}
X
X
Xdrawarea(x, y, width, height, op)
Xint x, y, width, height ;
Xenum op_type op ;
X{
X m_func(ops[(int) op]) ;
Funky_Stuff
echo "End of part 2"
echo "File mgr.c is continued in part 3"
echo "3" > s2_seq_.tmp
exit 0
More information about the Comp.sources.misc
mailing list