home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / misc / volume22 / popi / part06 < prev    next >
Text File  |  1991-08-22  |  43KB  |  1,751 lines

  1. Newsgroups: comp.sources.misc
  2. From: Rich Burridge <richb@Aus.Sun.COM>
  3. Subject:  v22i045:  popi - The Digital Darkroom, Part06/09
  4. Message-ID: <1991Aug22.153121.15839@sparky.IMD.Sterling.COM>
  5. X-Md4-Signature: a25b763670f84dfa349e2d1c6007b880
  6. Date: Thu, 22 Aug 1991 15:31:21 GMT
  7. Approved: kent@sparky.imd.sterling.com
  8.  
  9. Submitted-by: Rich Burridge <richb@Aus.Sun.COM>
  10. Posting-number: Volume 22, Issue 45
  11. Archive-name: popi/part06
  12. Environment: Xlib, Xview, SunView
  13. Supersedes: popi: Volume 9, Issue 47-55
  14.  
  15. #! /bin/sh
  16. # 1. Remove everything above the #! /bin/sh line
  17. # 2. Save the resulting text in a file.
  18. # 3. Execute the file with /bin/sh to create the files:
  19. #    ibmpc.c
  20. #    mgr.c
  21. #    news.c
  22. #    next.m
  23. # This archive created: Wed Aug 21 10:36:03 EST 1991
  24. #
  25. #
  26. export PATH; PATH=/bin:$PATH
  27. #
  28. if [ -f ibmpc.c ]
  29. then
  30. echo shar: will not over-write existing file ibmpc.c
  31. else
  32. echo shar: extracting 'ibmpc.c',    21588 characters
  33. cat > ibmpc.c <<'Funky_Stuff'
  34. /*LINTLIBRARY*/
  35. #ifndef    lint
  36. static char sccsid[] = "@(#)ibmpc.c 1.2 90/12/28" ;
  37. #endif
  38.  
  39. /*  Popi device driver for a PC using one of:
  40.  *    Borland Turbo C
  41.  *    Microsoft C
  42.  *    MIX Power C
  43.  *  Written by Stephen Frede, Softway Pty Ltd.
  44.  *
  45.  *  Popi was originally written by Gerard J. Holzmann - AT&T Bell Labs.
  46.  *  This version is based on the code in his Prentice Hall book,
  47.  *  "Beyond Photography - the digital darkroom," ISBN 0-13-074410-7,
  48.  *  which is copyright (c) 1988 by Bell Telephone Laboratories, Inc. 
  49.  *
  50.  *  Permission is given to distribute these extensions, as long as these
  51.  *  introductory messages are not removed, and no monies are exchanged.
  52.  *
  53.  *  No responsibility is taken for any errors or inaccuracies inherent
  54.  *  either to the comments or the code of this program, but if reported
  55.  *  (see README file) then an attempt will be made to fix them.
  56.  */
  57.  
  58. /*
  59.  *  There is still some work to be done here:
  60.  *    + vid_detect() needs to be written.
  61.  *    + HGC code needs to be fixed properly.
  62.  *    + other standard modes need to be added.
  63.  *    + Dithering or something needs to be added for EGA (sim to CGA).
  64.  *    + Handle image allocation properly with far pointers
  65.  *        where appropriate (ie unavoidable).
  66.  */
  67.  
  68. #if defined(__STDC__) && defined(__TURBOC__)
  69. /* The user has (with commendable intentions) used the Turbo C
  70.  * ANSI compatibility flag. Unfortunately, we need the nonstandard
  71.  * extensions to include <graphics.h> and use far pointers.
  72.  */
  73. #include "Unfortunately, can't use ANSI compatibility flag."
  74. #endif    /* __STDC__ && __TURBOC__ */
  75.  
  76. #include "popi.h"
  77.  
  78. /* I don't know what token Power C defines to distinguish itself.
  79.  * But it does define a max() macro in stdlib.h include file.
  80.  * Hopefully no other vendor is silly enough to do this, so we
  81.  * can use that to distinguish Power C.
  82.  */
  83. #if    defined(__STDC__) && defined(max)
  84. #define    __POWERC__    1
  85. #endif    /* __STDC__ && max */
  86.  
  87. /* We assume that the compiler has these files header files. */
  88. #include <dos.h>
  89. #include <conio.h>
  90.  
  91. /* We only use the __TURBOC__ token to test for graphics related
  92.  * features from here on, so if we have an old version with no
  93.  * graphics support, just pretend we are a generic compiler.
  94.  */
  95. #if defined(__TURBOC__)
  96. # if __TURBOC__ < 0x0200
  97. #  undef    __TURBOC__
  98. # endif    /* __TURBOC__ < 0x0200 */
  99. #endif    /* __TURBOC__ */
  100.  
  101. #if __TURBOC__ || __POWERC__
  102. # include <graphics.h>
  103. #endif /* __TURBOC__ || __POWERC__ */
  104.  
  105. #if    __MSC__
  106. #include <graph.h>
  107. #endif    /* __MSC__ */
  108.  
  109.  
  110. #if    defined(__TURBOC__)
  111. # ifndef    BGIPATH
  112. #  define    STRBGIPATH    ""
  113. # else
  114. #  define    STR(x)    #x
  115. #  define    STRBGIPATH    STR(BGIPATH)
  116. # endif    /* BGIPATH */
  117. #endif /* __TURBOC__ */
  118.  
  119. #ifndef MK_FP
  120. #define MK_FP(segment,offset)    ((void far *) \
  121.                (((unsigned long)(segment) << 16) | (unsigned)(offset)))
  122. #endif    /* MK_FP */
  123.  
  124. /*  These are the exportable routines used by the popi program.
  125.  *
  126.  *  disp_init(argc, argv)    - called from main at the start.
  127.  *  disp_finish()        - called from main prior to exit.
  128.  *  disp_imgstart()        - called prior to drawing an image.
  129.  *  disp_imgend()        - called after drawing an image.
  130.  *  disp_putline(lines, y)    - to draw an image scanline triple.
  131.  *  disp_getchar()        - to get the next character typed.
  132.  *  disp_prompt()        - display popi prompt and clear input buffer.
  133.  *  disp_error(errtype,pos)    - display error message.
  134.  *  disp_percentdone(n)        - display percentage value of conversion.
  135.  */
  136.  
  137. /*
  138.  *    Bios function call definitions
  139.  */
  140.  
  141. #define    BIOS_VIDFN        0x10    /* Video functions */
  142. #define VID_PALETTE        0x10    /* palette access function */
  143. #define PAL_SETPAL        0x00    /* update single palette register */
  144. #define PAL_SETPALBLOCK        0x02    /* update all palette registers */
  145. #define PAL_GETPALBLOCK        0x09    /* read all palette registers */
  146. #define PAL_GETDACBLOCK        0x17    /* read current VGA DAC values */
  147. #define PAL_SETDACBLOCK        0x12    /* set new VGA DAC values */
  148. #define VID_SETPIXEL        0x0C    /* store pixel value */
  149. #define VID_DISPLAY        0x1A    /* video display combination */
  150. #define VID_SUBSYSTEM        0x12    /* video subsystem configuration */
  151.  
  152. /*
  153.  *    Arguments to the vid_vgapalette and vid_setpalette functions
  154.  */
  155. #define    PAL_SAVE        0    /* Save existing values */
  156. #define    PAL_RESTORE        1    /* Restore saved values */
  157. #define    PAL_SETGREY        2    /* Set greyscale mapping */
  158. #define    PAL_SETLIN        3    /* Set 1:1 mapping (vid_setpalette) */
  159.  
  160. /* Bios Addresses */
  161. #define SEG_VIDBIOS        0x0040    /* Segment of video BIOS addresses */
  162. #define BIOSADDR_MODE        0x0049    /* Current BIOS video mode number */
  163. #define BIOSADDR_CRTCPORT    0x0063    /* Port Address of CRTC */
  164.  
  165. /* Fixed port addresses */
  166. #define    HGC_SWITCH    0x03BF
  167.  
  168.  
  169. /* Prototypes for local functions */
  170. void    vid_vgapalette P((int));
  171. void    vid_setpalette P((int));
  172. void    vid_setmode P((unsigned char));
  173. void    vid_sethgc P((void));
  174. void    vid_setpixel P((int, int, pixel_t));
  175. unsigned char    vid_detect P((void));
  176.  
  177.     /* Array containing threshold values for dithering. */
  178. pixel_t thresh[BITSPERPIXEL][BITSPERPIXEL] =
  179. {
  180.     {    0, 128,     32, 160,   8, 136,  40, 168, },
  181.     { 192,  64,    224,  96, 200,    72, 232, 104, },
  182.     {  48, 176,     16, 144,  56, 184,  24, 152, },
  183.     { 240, 112,    208,  80, 248, 120, 216,  88, },
  184.     {  12, 140,     44, 172,   4, 132,  36, 164, },
  185.     { 204,  76,    236, 108, 196,    68, 228, 100, },
  186.     {  60, 188,     28, 156,  52, 180,  20, 148, },
  187.     { 252, 124,    220,  92, 244, 116, 212,  84, },
  188. };
  189.  
  190. struct VidDriver
  191. {
  192.     unsigned char    bios_mode;    /* Bios mode no. */
  193.     unsigned int    xsize,        /* Pixels/scanline */
  194.                 ysize;        /* Scanlines/image */
  195.     /* Segment to which screen buffer is mapped */
  196.     unsigned int    ScreenMem;
  197.     unsigned int    interlace,    /* no. lines interlaced */
  198.                 interlace_offset; /* memory offset for interlace */
  199.     unsigned char    PixelsPerByte;
  200. };
  201.  
  202. static struct VidDriver    VidDrivers[] =
  203. {
  204. #define VID_VGA    0
  205.     {
  206.         0x13, 320, 200, 0xA000, 1, 0, 1,
  207.     },
  208. #define VID_EGA    1
  209.     {
  210.         0x10, 640, 350, 0xA000, 2, 0x2000, 8,
  211.     },
  212. #define VID_CGA    2
  213.     {
  214.         0x06, 640, 200, 0xB800, 2, 0x2000, 8,
  215.     },
  216. #define VID_MDA 3
  217.     {
  218.         0x06, 640, 200, 0xB800, 2, 0x2000, 8,
  219.     },
  220. #define VID_MCGA 4
  221.     {
  222.         0x06, 640, 200, 0xB800, 2, 0x2000, 8,
  223.     },
  224. #define VID_STD    4    /* Last standard adapter */
  225. /* From here on, adapters have no bios support. The bios
  226.  * number will be stored in the appropriate place in the video
  227.  * bios data area (this is useful eg if a mouse is being used,
  228.  * so it gets the graphics cursor correct).
  229.  */
  230. #define VID_HGC    5
  231.     {
  232.         0x06, 720, 348, 0xB000, 4, 0x2000, 8,
  233.     },
  234. };
  235. #define    VID_NONE    -1    /* Unknown video adapter */
  236. /* When VidAdapter is VID_LIB, use compile-time dependant
  237.  * library routines. For example, the Turbo C graphics library
  238.  * allows custom drivers to be added for nonstandard adapters.
  239.  */
  240. #define    VID_LIB        -2
  241.  
  242. static struct VidDriver
  243.     *VidDriver = 0;
  244.  
  245. static int
  246.     VidAdapter = VID_NONE,
  247.     vid_xbytes,
  248.     vid_xoff_bytes,
  249.     vid_yoff;
  250. #if __TURBOC__
  251. static int
  252.     tc_driver,
  253.     tc_mode,
  254.     tc_error;
  255. #endif    /* __TURBOC__ */
  256.  
  257. static unsigned char far
  258.     *ScreenMem;
  259. /* Pointer to current mode in Bios video display data area */
  260. static char far
  261.     *VidModeBiosAddr = MK_FP(SEG_VIDBIOS, BIOSADDR_MODE);
  262. /* Pointer to CRTC register port number in Bios dideo display area */
  263. static short far
  264.     *CrtcPortBiosAddr = MK_FP(SEG_VIDBIOS, BIOSADDR_CRTCPORT);
  265. static char
  266.     VidInitMode;
  267.  
  268. /*
  269.  *    Routine to map VGA palette registers (256 colour mode)
  270.  *    to and from a greyscale display.
  271.  */
  272. #define BITSPERBYTE        8
  273. #define BITSPERVGACOLOUR    6
  274.                 /* no. VGA DAC registers */
  275. #define SIZE_DACS        256
  276.                 /* no. distinct greyscale values */
  277. #define NUM_GREY        (1 << BITSPERVGACOLOUR)
  278.                 /* no. palette registers that map
  279.                  * to the same greyscale value */
  280. #define GREY_SAME        (SIZE_DACS / NUM_GREY)
  281.                 /* no. underlying colours on vga */
  282. #define PRIMARY_COLOURS        3
  283.  
  284. static void
  285. vid_vgapalette(action)
  286. int    action;
  287. {
  288.     union REGS            regs;
  289.     struct SREGS        sreg;
  290.     static unsigned char    SaveDacs[SIZE_DACS * PRIMARY_COLOURS],
  291.                     *GreyDacs = 0;
  292.  
  293.     switch(action)
  294.     {
  295.         case PAL_SAVE:
  296.         /* Save existing palette */
  297.         regs.h.ah = VID_PALETTE;
  298.         regs.h.al = PAL_GETPALBLOCK;
  299.         regs.x.bx = 0;        /* first palette register */
  300.         regs.x.cx = SIZE_DACS;    /* read all palette registers */
  301.         segread(&sreg);
  302.         sreg.es = FP_SEG(SaveDacs);
  303.         regs.x.dx = FP_OFF(SaveDacs);
  304.         int86x(BIOS_VIDFN, ®s, ®s, &sreg);
  305.         break;
  306.  
  307.     case PAL_RESTORE:
  308.         /* restore saved palette */
  309.         regs.h.ah = VID_PALETTE;
  310.         regs.h.al = PAL_SETDACBLOCK;
  311.         regs.x.bx = 0;        /* first palette register */
  312.         regs.x.cx = SIZE_DACS;    /* read all palette registers */
  313.         segread(&sreg);
  314.         sreg.es = FP_SEG(SaveDacs);
  315.         regs.x.dx = FP_OFF(SaveDacs);
  316.         int86x(BIOS_VIDFN, ®s, ®s, &sreg);
  317.         break;
  318.  
  319.     case PAL_SETGREY:
  320.         /* set palette to greyscale */
  321.         if (GreyDacs == 0)
  322.         {
  323.         unsigned char    *p,
  324.                 c;
  325.  
  326.             if ((GreyDacs = malloc(SIZE_DACS*PRIMARY_COLOURS))
  327.             == 0)
  328.         {
  329.             sprintf(ErrBuf, "Dacs allocation failed");
  330.             error(ERR_SYS);
  331.             return;
  332.         }
  333.         for (p = GreyDacs, c = 0; c < NUM_GREY; ++c)
  334.         {
  335.             int        i;
  336.  
  337.             for (i = 0; i < PRIMARY_COLOURS * GREY_SAME; ++i)
  338.             *p++ = c;
  339.         }
  340.         }
  341.         regs.h.ah = VID_PALETTE;
  342.         regs.h.al = PAL_SETDACBLOCK;
  343.         regs.x.bx = 0;        /* first palette register */
  344.         regs.x.cx = SIZE_DACS;    /* read all palette registers */
  345.         segread(&sreg);
  346.         sreg.es = FP_SEG(GreyDacs);
  347.         regs.x.dx = FP_OFF(GreyDacs);
  348.         int86x(BIOS_VIDFN, ®s, ®s, &sreg);
  349.         break;
  350.     }
  351. }
  352.  
  353. /*
  354.  *    Routine to map 16 palette registers.
  355.  */
  356.  
  357. #define SIZE_PALETTE        17    /* 16 + overscan */
  358.  
  359. static void
  360. vid_setpalette(action)
  361. int    action;
  362. {
  363.     union REGS            regs;
  364.     struct SREGS        sreg;
  365.     static unsigned char    SavePalette[SIZE_PALETTE],
  366.                     *GreyPalette = 0;
  367.     unsigned char        palette;
  368.  
  369.     switch (action)
  370.     {
  371.         case PAL_SAVE:
  372.         /* Save existing palette */
  373.         regs.h.ah = VID_PALETTE;
  374.         regs.h.al = PAL_GETPALBLOCK;
  375.         segread(&sreg);
  376.         sreg.es = FP_SEG(SavePalette);
  377.         regs.x.dx = FP_OFF(SavePalette);
  378.         int86x(BIOS_VIDFN, ®s, ®s, &sreg);
  379.         break;
  380.  
  381.     case PAL_RESTORE:
  382.         /* restore saved palette */
  383.         regs.h.ah = VID_PALETTE;
  384.         regs.h.al = PAL_SETPALBLOCK;
  385.         segread(&sreg);
  386.         sreg.es = FP_SEG(SavePalette);
  387.         regs.x.dx = FP_OFF(SavePalette);
  388.         int86x(BIOS_VIDFN, ®s, ®s, &sreg);
  389.         break;
  390.  
  391.     case PAL_SETGREY:
  392.         /* set palette to greyscale */
  393.         if (GreyPalette == 0)
  394.         {
  395.         if ((GreyPalette = (unsigned char *) malloc(SIZE_PALETTE)) == 0)
  396.         {
  397.             sprintf(ErrBuf, "Palette allocation failed");
  398.             error(ERR_SYS);
  399.             return;
  400.         }
  401.         GreyPalette[0] = 000;
  402.         GreyPalette[1] = 070;
  403.         GreyPalette[2] = 007;
  404.         GreyPalette[3] = 077;
  405.         GreyPalette[SIZE_PALETTE-1] = SavePalette[SIZE_PALETTE-1];
  406.         }
  407.         regs.h.ah = VID_PALETTE;
  408.         regs.h.al = PAL_SETPALBLOCK;
  409.         segread(&sreg);
  410.         sreg.es = FP_SEG(GreyPalette);
  411.         regs.x.dx = FP_OFF(GreyPalette);
  412.         int86x(BIOS_VIDFN, ®s, ®s, &sreg);
  413.         break;
  414.  
  415.     case PAL_SETLIN:
  416.         for (palette = 0; palette < SIZE_PALETTE; ++palette)
  417.         {
  418.         union REGS regs;
  419.  
  420.         regs.h.ah = VID_PALETTE;
  421.         regs.h.al = PAL_SETPAL;
  422.         regs.h.bh = palette;
  423.         regs.h.bl = palette;
  424.         int86(BIOS_VIDFN, ®s, ®s);
  425.         }
  426.         break;
  427.     }
  428. }
  429.  
  430. static void
  431. vid_setmode(mode)
  432. unsigned char    mode;
  433. {
  434.     union REGS    regs;
  435.  
  436.     regs.h.ah = 0;
  437.     regs.h.al = mode;
  438.     int86(BIOS_VIDFN, ®s, ®s);
  439. }
  440.  
  441. static void
  442. vid_setpixel(x, y, value)
  443. int x, y;
  444. pixel_t value;
  445. {
  446.     union REGS    regs;
  447.  
  448.     regs.h.al = value;
  449.     regs.h.ah = VID_SETPIXEL;
  450.     regs.h.bh = 0;            /* video page */
  451.     regs.x.cx = (unsigned) x;
  452.     regs.x.dx = (unsigned) y;
  453.     int86(BIOS_VIDFN, ®s, ®s);
  454. }
  455.  
  456. static unsigned char
  457. vid_chkherc()
  458. {
  459.     return VID_MDA;
  460. }
  461.  
  462. /*
  463.  *    Detect installed graphics hardware.
  464.  */
  465. static unsigned char
  466. vid_detect()
  467. {
  468.     union REGS    regs;
  469.  
  470.     regs.h.ah = VID_DISPLAY;
  471.     regs.h.al = 0;        /* get video display combination */
  472.     int86(BIOS_VIDFN, ®s, ®s);
  473.     if (regs.h.al == 0x1a)
  474.     {
  475.     /* VGA or MCGA present - what is the active display? */
  476.     switch(regs.h.bl)
  477.     {
  478.         case 1:
  479.         /* MDA or hercules */
  480.             return vid_chkherc();
  481.  
  482.         case 2:
  483.             return VID_CGA;
  484.  
  485.         case 4:
  486.         case 5:
  487.             return VID_EGA;
  488.  
  489.         case 7:
  490.         case 8:
  491.             return VID_VGA;
  492.  
  493.         case 10:
  494.         case 11:
  495.         case 12:
  496.             return VID_MCGA;
  497.  
  498.         default:
  499.             return VID_NONE;
  500.     }
  501.     }
  502.  
  503.     /* System doesn't have a VGA or MCGA - check for EGA */
  504.     regs.h.ah = VID_SUBSYSTEM;
  505.     regs.h.bl = 0x10;        /* get video configuration information */
  506.     int86(BIOS_VIDFN, ®s, ®s);
  507.     if (regs.h.bl != 0x10)
  508.     {
  509.         /* EGA BIOS present */
  510.     return VID_EGA;
  511.     }
  512.     return VID_NONE;
  513. }
  514.  
  515. /*ARGSUSED*/
  516. void
  517. disp_init(argc,argv)        /* called from main at the start. */
  518. int argc;
  519. char *argv[];
  520. {
  521.    /* Some compilers (eg Power C) don't get the initialisation right,
  522.     * so repeat it here.
  523.     */
  524.     VidModeBiosAddr = MK_FP(SEG_VIDBIOS, BIOSADDR_MODE);
  525.     CrtcPortBiosAddr = MK_FP(SEG_VIDBIOS, BIOSADDR_CRTCPORT);
  526.     VidInitMode = *VidModeBiosAddr;
  527.  
  528.     VidAdapter = vid_detect();
  529.  
  530. #if    __TURBOC__
  531.     tc_driver = DETECT;
  532.     detectgraph(&tc_driver, &tc_mode);
  533.  
  534.     switch (tc_driver)
  535.     {
  536.     case VGA:
  537.         VidAdapter = VID_VGA;
  538.         break;
  539.  
  540.     case EGA:
  541.     case EGA64:
  542.         VidAdapter = VID_EGA;
  543.         break;
  544.  
  545.     case CGA:
  546.         VidAdapter = VID_CGA;
  547.         break;
  548.  
  549.     default:
  550.         initgraph(&tc_driver, &tc_mode, STRBGIPATH);
  551.         tc_error = graphresult();
  552.         if (tc_error < 0)
  553.         {
  554.         sprintf(ErrBuf, "initgraph error (%s)",
  555.             grapherrormsg(tc_error));
  556.         error(ERR_WARN);
  557.         VidAdapter = VID_NONE;
  558.         return;
  559.         }
  560.         else
  561.         VidAdapter = VID_LIB;
  562.     }
  563. #endif    /* __TURBOC__ */
  564.  
  565. #if    __MSC__
  566.     if (_setvideomode(_VRES2COLOR))
  567.         VidAdapter = VID_VGA;
  568.     else if (_setvideomode(_ERESNOCOLOR))
  569.         VidAdapter = VID_EGA;
  570.     else if (_setvideomode(_HRESBW))
  571.         ;
  572.     else
  573.     VidAdapter = VID_NONE;
  574. #endif    /* __MSC__ */
  575.  
  576. #if    __POWERC__
  577.     if (setvmode(17) == 17)
  578.         VidAdapter = VID_VGA;
  579.     else if (setvmode(15) == 15)
  580.         VidAdapter = VID_EGA;
  581.     else if (setvmode(6) == 6)
  582.         VidAdapter = VID_CGA;
  583.     else if (setvmode(99) == 99)
  584.         VidAdapter = VID_HGC;
  585. #endif    /* __POWERC__ */
  586.  
  587.     /* This is also a last minute addition that needs to
  588.      * be cleaned up - again, next release.
  589.      */
  590.     for (++argv; *argv; ++argv)
  591.     {
  592.     char    *card;
  593.  
  594.     if (**argv == '-')
  595.         switch ((*argv)[1])
  596.         {
  597.         case 'c':    /* card */
  598.             card = *argv + 2;
  599.             if (strcmp(card, "vga") == 0)
  600.                 VidAdapter = VID_VGA;
  601.             else if (strcmp(card, "ega") == 0)
  602.                 VidAdapter = VID_EGA;
  603.             else if (strcmp(card, "cga") == 0)
  604.                 VidAdapter = VID_CGA;
  605.             else if (strcmp(card, "hgc") == 0)
  606.                 VidAdapter = VID_HGC;
  607.             else if (strcmp(card, "lib") == 0)
  608.                 VidAdapter = VID_LIB;
  609.         }
  610.     }
  611.  
  612.     if (VidAdapter == VID_NONE)
  613.     {
  614.     vid_setmode(VidInitMode);
  615.     sprintf(ErrBuf,    "No graphics hardware detected");
  616.     error(ERR_WARN);
  617.     return;
  618.     }
  619.  
  620.     switch (VidAdapter)
  621.     {
  622.     case VID_LIB:
  623.         return;
  624.  
  625.     case VID_VGA:
  626.         vid_setpalette(PAL_SAVE);
  627.         vid_setpalette(PAL_SETLIN);/**/
  628.         vid_vgapalette(PAL_SAVE);
  629.             break;
  630.  
  631.     case VID_EGA:
  632.         vid_setpalette(PAL_SAVE);
  633.         break;
  634.  
  635.     case VID_CGA:
  636.         break;
  637.     }
  638.  
  639.     vid_setmode(VidInitMode);
  640.  
  641.     VidDriver = &VidDrivers[VidAdapter];
  642.     if (Xsize > VidDriver->xsize)
  643.     Xsize = VidDriver->xsize;
  644.     if (Ysize > VidDriver->ysize)
  645.     Ysize = VidDriver->ysize;
  646.     vid_xbytes = VidDriver->xsize / VidDriver->PixelsPerByte;
  647.     vid_yoff = (VidDriver->ysize - Ysize) / 2;
  648.     vid_xoff_bytes =
  649.         ((VidDriver->xsize - Xsize) / 2) / VidDriver->PixelsPerByte;
  650.     ScreenMem = MK_FP(VidDriver->ScreenMem, 0);
  651. }
  652.  
  653. void
  654. disp_finish()            /* called from main prior to exit. */
  655. {
  656. #if    __TURBOC__
  657.     if (VidAdapter == VID_LIB)
  658.     closegraph();
  659. #endif    /* __TURBOC__ */
  660. }
  661.  
  662. /*
  663.  *    Set up Hercules Graphics Card 720 * 348 graphics mode
  664.  */
  665. static void
  666. vid_sethgc()
  667. {
  668.     unsigned short    ModeControl = 0x03b8;
  669.     unsigned short    CrtcAddress = 0x03b4;
  670.     unsigned short    CrtcData = CrtcAddress + 1;
  671.  
  672.     outportb(HGC_SWITCH, 0x01);        /* allow graphics mode */
  673.     outportb(ModeControl, 0x00);    /* Video disabled during setup */
  674.  
  675.     /* Horizontal total: 54 "characters" (at 16 pixels/char) */
  676.     outportb(CrtcAddress, 0x00);
  677.     outportb(CrtcData, 0x35);
  678.     /* Horizontal displayed: 45 "characters" */
  679.     outportb(CrtcAddress, 0x01);
  680.     outportb(CrtcData, 0x2d);
  681.     /* Horizontal sync position: at 45th character */
  682.     outportb(CrtcAddress, 0x02);
  683.     outportb(CrtcData, 0x2e);
  684.     /* Horizontal sync width: 7 character clocks */
  685.     outportb(CrtcAddress, 0x03);
  686.     outportb(CrtcData, 0x07);
  687.     /* Vertical total: 94 "characters" (at 4 scanlines/char) */
  688.     outportb(CrtcAddress, 0x04);
  689.     outportb(CrtcData, 0x5b);
  690.     /* Vertical adjust: 2 scanlines */
  691.     outportb(CrtcAddress, 0x05);
  692.     outportb(CrtcData, 0x02);
  693.     /* Vertical displayed: 87 "character" rows */
  694.     outportb(CrtcAddress, 0x06);
  695.     outportb(CrtcData, 0x57);
  696.     /* Vertical sync position: after 87th char row */
  697.     outportb(CrtcAddress, 0x07);
  698.     outportb(CrtcData, 0x57);
  699.     /* Max scan line: 4 lines/char */
  700.     outportb(CrtcAddress, 0x09);
  701.     outportb(CrtcData, 0x03);
  702.  
  703.     *VidModeBiosAddr = 6;    /* Microsoft mouse: HGC using CRT page 0 */
  704.  
  705.     outportb(ModeControl, 0x0a);    /* Video enabled, Graphics mode */
  706. }
  707.  
  708. void
  709. disp_imgstart()            /* called prior to drawing an image. */
  710. {
  711.     if (VidAdapter == VID_NONE)
  712.     return;
  713.  
  714.     if (VidAdapter == VID_LIB)
  715.     {
  716. #if __TURBOC__
  717.     setgraphmode(tc_mode);
  718. #endif    /* __TURBOC__ */
  719.     return;
  720.     }
  721.  
  722.     if (VidAdapter <= VID_STD)
  723.     vid_setmode(VidDriver->bios_mode);
  724.     else
  725.     *VidModeBiosAddr = VidDriver->bios_mode;    /* fake it */
  726.  
  727.     switch (VidAdapter)
  728.     {
  729.     case VID_VGA:
  730.         vid_vgapalette(PAL_SETGREY);
  731.         break;
  732.  
  733.     case VID_EGA:
  734.         vid_setpalette(PAL_SETGREY);
  735.         break;
  736.  
  737.     case VID_HGC:
  738.         vid_sethgc();
  739.         break;
  740.     }
  741. }
  742.  
  743. void
  744. disp_imgend()            /* called after drawing an image. */
  745. {
  746.     (void) getch();
  747.  
  748.     switch (VidAdapter)
  749.     {
  750.     case VID_VGA:
  751.         vid_vgapalette(PAL_RESTORE);
  752.         vid_setpalette(PAL_RESTORE);
  753.         break;
  754.  
  755.     case VID_EGA:
  756.         vid_setpalette(PAL_RESTORE);
  757.         break;
  758.     }
  759.  
  760.     vid_setmode(VidInitMode);
  761. }
  762.  
  763. void
  764. disp_putline(lines, y)        /* called to draw image scanline y. */
  765. pixel_t **lines;
  766. int y;
  767. {
  768.     register int        x;
  769.     register unsigned char far    *p;
  770.     pixel_t                     *line;
  771.  
  772.     if (VidAdapter == VID_NONE)
  773.     return;
  774.  
  775.     line = ntsc_luma(lines);
  776.     if (VidAdapter == VID_LIB)
  777.     {
  778.     for (x = 0; x < Xsize; ++x)
  779.     {
  780.         pixel_t    val;
  781.  
  782.         val = *line++ < thresh[y % BITSPERPIXEL][x % BITSPERPIXEL] ?
  783.             (pixel_t) 0 : (pixel_t) 1;
  784. #if __TURBOC__
  785.         putpixel(x, y, val);
  786. #endif    /* __TURBOC__ */
  787. #if __MSC__
  788.         _setcolor(val);
  789.         _setpixel(x, y);
  790. #endif    /* __MSC__ */
  791. #if __POWERC__
  792.         pen_color(val);
  793.         setpixel(x, y);
  794. #endif    /* __POWERC__ */
  795.     }
  796.     return;
  797.     }
  798.  
  799.     p = &ScreenMem[
  800.             (
  801.                 ((y + vid_yoff) % VidDriver->interlace)
  802.                 *
  803.                 VidDriver->interlace_offset
  804.             )
  805.             +
  806.             (y + vid_yoff) / VidDriver->interlace * vid_xbytes
  807.             /*
  808.             +
  809.             vid_xoff_bytes
  810.             */
  811.         ];
  812.  
  813.     switch (VidAdapter)
  814.     {
  815.     case VID_VGA:
  816.         for (x = 0; x < Xsize; ++x)
  817.         *p++ = *line++;
  818.         break;
  819.  
  820.     case VID_EGA:
  821.         /* 4 grey levels isn't enough - need to do dithering as well,
  822.          * or perhaps fake it with some colours.
  823.          */
  824.         for (x = 0; x < Xsize; ++x)
  825.         vid_setpixel(x, y, *line++ / 64);
  826.         break;
  827.  
  828.     case VID_CGA:
  829.         for (x = 0; x < Xsize;)
  830.         {
  831.         register unsigned char    t;
  832.         register unsigned char    val;
  833.         register unsigned char    byte;
  834.         register int        pixel;
  835.  
  836.         byte = 0;
  837.         for (pixel = 8; pixel > 0; ++x)
  838.         {
  839.             t = thresh[y % BITSPERPIXEL][x % BITSPERPIXEL];
  840.             val = *line++;
  841.             byte |= (val > t * 2 / 3 ? 1 : 0) << --pixel;
  842.             byte |= (val > (t * 2 + Zsize) / 3 ? 1 : 0) << --pixel;
  843.         }
  844.         *p++ = byte;
  845.         }
  846.         break;
  847.  
  848.     case VID_HGC:
  849.         for (x = 0; x < Xsize;)
  850.         {
  851.         register char    t;
  852.         register unsigned char    byte;
  853.         register int        pixel;
  854.  
  855.         byte = 0;
  856.         for (pixel = 8; pixel > 0; ++x)
  857.         {
  858.             t = *line++ < thresh[y % BITSPERPIXEL][x % BITSPERPIXEL] ?
  859.             (pixel_t) 0 : (pixel_t) 1;
  860.             byte |= t << --pixel;
  861.         }
  862.         *p++ = byte;
  863.         }
  864.         break;
  865.     }
  866. }
  867.  
  868. int
  869. disp_getchar()            /* get next user typed character. */
  870. {
  871.     static unsigned char line[255] = {254,0,'\r'};
  872.     static unsigned char *lp = 0;
  873.  
  874.     if (!lp){
  875.     union REGS    regs;
  876.         struct SREGS    sreg;
  877.  
  878.     regs.h.ah = 10;
  879.     segread(&sreg);
  880.     sreg.ds = FP_SEG(line);
  881.     regs.x.dx = FP_OFF(line);
  882.     int86x(0x21, ®s, ®s, &sreg);
  883.  
  884.     regs.h.ah = 2;
  885.     regs.h.dl = '\n';
  886.     int86(0x21, ®s, ®s);
  887.  
  888.         lp = &line[2];
  889.     }
  890.     if (*lp == '\r'){
  891.         lp = NULL;
  892.         return('\n');
  893.     }
  894.     return(*lp++);
  895. }
  896.  
  897.  
  898. int
  899. disp_prompt()            /* display popi prompt. */
  900. {
  901.     static char    prompt[] = "-> ";
  902.  
  903.     PRINTF(prompt);
  904.     return sizeof prompt - 1;
  905. }
  906.  
  907. void
  908. disp_error(errtype, pos)    /* display error message. */
  909. int    errtype,
  910.     pos;
  911. {
  912.     extern int    errno;
  913.     extern char    *sys_errlist[];
  914.  
  915.     if (errtype    & ERR_PARSE)
  916.     {
  917.     int    i;
  918.  
  919.     for (i=1; i < pos; ++i)
  920.         PUTC('-', stderr);
  921.     PUTC('^', stderr);
  922.     PUTC('\n', stderr);
  923.     }
  924.  
  925.     FPRINTF(stderr, "%s\n", ErrBuf);
  926.     /* we assume errno hasn't been reset by the    preceding output */
  927.     if (errtype    & ERR_SYS)
  928.     FPRINTF(stderr,    "\t(%s)\n", sys_errlist[errno]);
  929. }
  930.  
  931. void
  932. disp_percentdone(percent)
  933. int    percent;
  934. {
  935.     static int    lastpercent = 100;
  936.  
  937.     if (!Verbose)
  938.     return;
  939.     if (percent    == 100)
  940.     {
  941.     printf("\r    \n");
  942.     return;
  943.     }
  944.     if (percent    != lastpercent)
  945.     {
  946.     printf("\r%2d%%    ", percent);
  947.     fflush(stdout);
  948.     lastpercent = percent;
  949.     }
  950. }
  951. Funky_Stuff
  952. len=`wc -c < ibmpc.c`
  953. if [ $len !=    21588 ] ; then
  954. echo error: ibmpc.c was $len bytes long, should have been    21588
  955. fi
  956. fi # end of overwriting check
  957. if [ -f mgr.c ]
  958. then
  959. echo shar: will not over-write existing file mgr.c
  960. else
  961. echo shar: extracting 'mgr.c',     7730 characters
  962. cat > mgr.c <<'Funky_Stuff'
  963. /*LINTLIBRARY*/
  964.  
  965. /*  @(#)mgr.c 1.2 90/12/28
  966.  *
  967.  *  MGR dependent graphics routines used by popi.
  968.  *  written by Rich Burridge - Sun Microsystems.
  969.  *
  970.  *  Popi was originally written by Gerard J. Holzmann - AT&T Bell Labs.
  971.  *  This version is based on the code in his Prentice Hall book,
  972.  *  "Beyond Photography - the digital darkroom," ISBN 0-13-074410-7,
  973.  *  which is copyright (c) 1988 by Bell Telephone Laboratories, Inc. 
  974.  *
  975.  *  Permission is given to distribute these extensions, as long as these
  976.  *  introductory messages are not removed, and no monies are exchanged.
  977.  *
  978.  *  No responsibility is taken for any errors or inaccuracies inherent
  979.  *  either to the comments or the code of this program, but if reported
  980.  *  (see README file) then an attempt will be made to fix them.
  981.  */
  982.  
  983. #include "dump.h"
  984. #include "term.h"
  985. #include "popi.h"
  986. #include "graphics.h"
  987. #include <signal.h>
  988. #include <sys/types.h>
  989. #include <sys/time.h>
  990.  
  991. #define  B_FONT       1    /* Font descriptors. */
  992. #define  N_FONT       2
  993.  
  994. #define  ICONIC       0    /* States that the popi display can be in. */
  995. #define  OPEN         1
  996.  
  997. #define  PR_ICON      1    /* Descriptor for closed icon image. */
  998. #define  PR_SCAN      2    /* Descriptor for current popi scan line. */
  999.  
  1000. #define  BOLD_FONT    "cour7x14b"
  1001. #define  NORMAL_FONT  "cour7x14r"
  1002.  
  1003. #define  ICONHEIGHT   64   /* Height of the popi icon. */
  1004. #define  ICONWIDTH    64   /* Width of the popi icon. */
  1005.  
  1006. char fontname[MAXLINE] ;   /* Full pathname of each font. */
  1007.  
  1008. int local_mode;            /* Used by load_icon for correct line mode. */
  1009. int mgr_infd ;             /* MGR input connection file descriptor. */
  1010. int mgr_outfd ;            /* MGR output connection file descriptor. */
  1011.  
  1012. short icon_image[] = {
  1013. #include "popi.icon"
  1014. } ;
  1015.  
  1016. #ifdef NO_43SELECT
  1017. int fullmask ;             /* Full mask of file descriptors to check on. */
  1018. int readmask ;             /* Readmask used in select call. */
  1019. #else
  1020. fd_set fullmask ;          /* Full mask of file descriptors to check on. */
  1021. fd_set readmask ;          /* Readmask used in select call. */
  1022. #endif /* NO_43SELECT */
  1023.  
  1024.  
  1025. SIGRET
  1026. clean(code)
  1027. int code ;
  1028. {
  1029.   m_bitdestroy(1) ;
  1030.   m_pop() ;
  1031.   m_ttyreset() ;
  1032.   m_clear() ;
  1033.   exit(code) ;
  1034. }
  1035.  
  1036.  
  1037. cleanup()                   /* Cleanup before exiting. */
  1038. {
  1039.   clean(0) ;
  1040. }
  1041.  
  1042.  
  1043. close_frame()
  1044. {
  1045.   reshape(ICONIC) ;
  1046.   m_clearmode(M_ACTIVATE) ;
  1047.   iconic = 1 ;
  1048. }
  1049.  
  1050.  
  1051. draw_scanline(lines, y)       /* Display image scanline on the screen. */
  1052. unsigned char **lines ;
  1053. int y ;
  1054. {
  1055.   int fd, size ;
  1056.   unsigned char *line ;
  1057.  
  1058.   line = ntsc_luma(lines);
  1059.   halftone(line, y) ;
  1060.  
  1061.   IOCTL(mgr_outfd, TIOCLGET, &local_mode) ;
  1062.   local_mode |= LLITOUT ;
  1063.   IOCTL(mgr_outfd, TIOCLSET, &local_mode) ;
  1064.  
  1065.   size = (Xsize / 8) + 1 ;
  1066.   m_bitldto(Xsize, 1, 0, 0, PR_SCAN, size) ;
  1067.   m_flush() ;
  1068.   WRITE(mgr_outfd, mptr, size) ;
  1069.  
  1070.   local_mode &= ~LLITOUT ;
  1071.   IOCTL(mgr_outfd, TIOCLSET, &local_mode) ;
  1072.  
  1073.   m_bitcopyto(0, y+100, Xsize, 1, 0, 0, 0, PR_SCAN) ;
  1074. }
  1075.  
  1076.  
  1077. drawarea(x, y, width, height, op)
  1078. int x, y, width, height ;
  1079. enum op_type op ;
  1080. {
  1081.   m_func(ops[(int) op]) ;
  1082.   m_bitwrite(x, y, width, height) ;
  1083. }
  1084.  
  1085.  
  1086. drawline(x1, y1, x2, y2)
  1087. int x1, y1, x2, y2 ;
  1088. {
  1089.   m_func(B_COPY) ;
  1090.   m_line(x1, y1, x2, y2) ;
  1091. }
  1092.  
  1093.  
  1094. drawtext(x, y, fontno, str)
  1095. enum font_type fontno ;
  1096. int x, y ;
  1097. char *str ;
  1098. {
  1099.        if (fontno == NFONT) m_font(N_FONT) ;
  1100.   else if (fontno == BFONT) m_font(B_FONT) ;
  1101.   m_func(B_XOR) ;
  1102.   if (str[strlen(str)-1] == '\n') str[strlen(str)-1] = '\0' ;
  1103.   m_stringto(0, x, y+4, str) ;
  1104.   m_movecursor(2500, 2500) ;
  1105. }
  1106.  
  1107.  
  1108. get_next_char(c)      /* Process events, and return when character typed. */
  1109. char *c ;
  1110. {
  1111.   int chr ;
  1112.   static struct timeval tval = { 0, 0 } ;
  1113.  
  1114.   m_flush() ;
  1115.   for (;;)
  1116.     {
  1117.       readmask = fullmask ;
  1118. #ifdef NO_43SELECT
  1119.       SELECT(32, &readmask, 0, 0, &tval) ;
  1120.       if (readmask && (1 << mgr_infd))
  1121. #else
  1122.       SELECT(FD_SETSIZE, &readmask, (fd_set *) 0, (fd_set *) 0, &tval) ;
  1123.       if (FD_ISSET(mgr_infd, &readmask))
  1124. #endif /* NO_4.3SELECT */
  1125.         {
  1126.           if ((chr = m_getchar()) == EOF)
  1127.             {
  1128.               clearerr(m_termin) ;
  1129.               continue ;
  1130.             }
  1131.           switch (chr)
  1132.             {
  1133.               case '\032' :
  1134.               case '\033' : close_frame() ;    /* Turn window iconic. */
  1135.                             break ;
  1136.               case '\034' : clean(1) ;         /* Window destroyed. */
  1137.               case '\035' : if (iconic) iconic = 0 ;
  1138.               case '\036' : reshape(OPEN) ;
  1139.               case '\037' : paint_canvas() ;   /* Repaint popi canvas. */
  1140.                             break ;
  1141.               default     : *c = chr ;
  1142.                             return ;
  1143.             }
  1144.         }
  1145.     }
  1146. }
  1147.  
  1148.  
  1149. init_fonts()
  1150. {
  1151.   char path[MAXLINE] ;     /* Directory path for font files. */
  1152.  
  1153. #ifdef MGRHOME
  1154.   STRCPY(path, MGRHOME) ;
  1155. #else
  1156.   STRCPY(path, "/usr/mgr") ;
  1157. #endif
  1158.  
  1159.   SPRINTF(fontname, "%s/font/%s", path, NORMAL_FONT) ;
  1160.   m_loadfont(NFONT, fontname) ;
  1161.   nfont_width = 7 ;
  1162.  
  1163.   SPRINTF(fontname, "%s/font/%s", path, BOLD_FONT) ;
  1164.   m_loadfont(BFONT, fontname) ;
  1165. }
  1166.  
  1167.  
  1168. init_ws_type()
  1169. {
  1170.   m_setup(M_FLUSH) ;     /* Setup I/O; turn on flushing. */
  1171.   m_push(P_BITMAP | P_MENU | P_EVENT | P_FONT | P_FLAGS | P_POSITION) ;
  1172.   mgr_infd = fileno(m_termin) ;
  1173.   mgr_outfd = fileno(m_termout) ;
  1174.  
  1175.   SIGNAL(SIGHUP, clean) ;
  1176.   SIGNAL(SIGINT, clean) ;
  1177.   SIGNAL(SIGTERM, clean) ;
  1178.   m_ttyset() ;
  1179.   m_setraw() ;
  1180.   m_setmode(M_NOWRAP) ;
  1181.   m_setmode(M_ABS) ;
  1182.   m_setmode(ACTIVATE) ;
  1183.   m_clearmode(M_NOINPUT) ;
  1184.   m_func(B_COPY) ;
  1185.  
  1186.   mptr = (unsigned char *) malloc((unsigned) Xsize) ;
  1187.   ops[(int) GCLR] = B_CLEAR ;
  1188.   ops[(int) GSET] = B_SET ;
  1189.   return 0 ;
  1190. }
  1191.  
  1192.  
  1193. load_colors()                /* Hardwired to a monochrome version. */
  1194. {
  1195.   iscolor = 0 ;
  1196. }
  1197.  
  1198.  
  1199. load_icon(pixrect, ibuf)
  1200. int pixrect ;
  1201. short ibuf[256] ;
  1202. {
  1203.   int size ;
  1204.  
  1205.   IOCTL(mgr_outfd, TIOCLGET, &local_mode) ;
  1206.   local_mode |= LLITOUT ;
  1207.   IOCTL(mgr_outfd, TIOCLSET, &local_mode) ;
  1208.  
  1209.   size = ICONHEIGHT * (((64 + 15) &~ 15) >> 3) ;
  1210.   m_bitldto(ICONWIDTH, ICONHEIGHT, 0, 0, pixrect, size) ;
  1211.   m_flush() ;
  1212.   WRITE(mgr_outfd, (char *) ibuf, size) ;
  1213.  
  1214.   local_mode &= ~LLITOUT ;
  1215.   IOCTL(mgr_outfd, TIOCLSET, &local_mode) ;
  1216. }
  1217.  
  1218.  
  1219. make_items(argc, argv)       /* Create icon, frame, canvas etc.. */
  1220. int argc ;
  1221. char *argv[] ;
  1222. {
  1223.  
  1224. #ifdef NO_43SELECT
  1225.   fullmask = 1 << mgr_infd ;
  1226. #else
  1227.   FD_ZERO(&fullmask) ;
  1228.   FD_SET(mgr_infd, &fullmask) ;
  1229. #endif /* NO_4.3SELECT */
  1230.  
  1231.   m_setevent(BUTTON_2U, "\032") ;   /* Middle mouse button released. */
  1232.   m_setevent(BUTTON_1U, "\033") ;   /* Right mouse button released. */
  1233.   m_setevent(DESTROY, "\034") ;     /* Window has been destroyed. */
  1234.   m_setevent(ACTIVATE, "\035") ;    /* Window has been activated. */
  1235.   m_setevent(RESHAPE, "\036") ;     /* Check for window being reshaped. */
  1236.   m_setevent(REDRAW, "\037") ;      /* Check for window being redrawn. */
  1237.  
  1238.   m_movecursor(2500, 2500) ;        /* Move character cursor offscreen. */
  1239.   m_font(N_FONT) ;                  /* Default is the normal font. */
  1240.   load_icon(PR_ICON, icon_image) ;
  1241.   reshape(OPEN) ;
  1242.   m_clear() ;                       /* Clear popi window. */
  1243.   load_colors() ;                   /* Hardwired to monochrome. */
  1244. }
  1245.  
  1246.  
  1247. reshape(type)
  1248. int type ;
  1249. {
  1250.   int x, y, w, h ;      /* Position and size of popi window. */
  1251.  
  1252.   get_size(&x, &y, &w, &h) ;
  1253.   switch (type)
  1254.     {
  1255.       case ICONIC : m_shapewindow(x, y, ICONWIDTH+10, ICONHEIGHT+10) ;
  1256.                     m_clear() ;
  1257.                     m_bitcopyto(0, 0, ICONWIDTH, ICONHEIGHT,
  1258.                                 0, 0, 0, PR_ICON) ;
  1259.                     break ;
  1260.       case OPEN   : m_shapewindow(x, y, TXsize+10, TYsize+10) ;
  1261.     }
  1262.   m_movecursor(2500, 2500) ;
  1263. }
  1264.  
  1265.  
  1266. /*ARGUSED*/
  1267. set_cursor(type)      /* Doesn't appear to be any way to set the cursor. */
  1268. enum cur_type type ;
  1269. {
  1270. }
  1271.  
  1272.  
  1273. start_tool()          /* Null routine. */
  1274. {
  1275. }
  1276. Funky_Stuff
  1277. len=`wc -c < mgr.c`
  1278. if [ $len !=     7730 ] ; then
  1279. echo error: mgr.c was $len bytes long, should have been     7730
  1280. fi
  1281. fi # end of overwriting check
  1282. if [ -f news.c ]
  1283. then
  1284. echo shar: will not over-write existing file news.c
  1285. else
  1286. echo shar: extracting 'news.c',     5319 characters
  1287. cat > news.c <<'Funky_Stuff'
  1288. /*LINTLIBRARY*/
  1289.  
  1290. /*  @(#)news.c 1.2 90/12/28
  1291.  *
  1292.  *  C wrappers for News dependent graphics routines used by popi.
  1293.  *  written by Rich Burridge - Sun Microsystems Australia.
  1294.  *
  1295.  *  Popi was originally written by Gerard J. Holzmann - AT&T Bell Labs.
  1296.  *  This version is based on the code in his Prentice Hall book,
  1297.  *  "Beyond Photography - the digital darkroom," ISBN 0-13-074410-7,
  1298.  *  which is copyright (c) 1988 by Bell Telephone Laboratories, Inc. 
  1299.  *
  1300.  *  Permission is given to distribute these extensions, as long as these
  1301.  *  introductory messages are not removed, and no monies are exchanged.
  1302.  *
  1303.  *  No responsibility is taken for any errors or inaccuracies inherent
  1304.  *  either to the comments or the code of this program, but if reported
  1305.  *  (see README file) then an attempt will be made to fix them.
  1306.  */
  1307.  
  1308. #include "popi.h"
  1309. #include "graphics.h"
  1310. #include <sys/types.h>
  1311.  
  1312. /* Various pseudo events generated by the popi program. */
  1313. #define  KEYBOARD  100          /* Keyboard character was pressed. */
  1314. #define  REPAINT   101          /* Popi canvas needs repainting. */
  1315.  
  1316. extern FILE *PostScript ;
  1317. extern FILE *PostScriptInput ;
  1318.  
  1319. unsigned short icon_image[] = {
  1320. #include "popi.icon"
  1321. } ;
  1322.  
  1323.  
  1324. cleanup()            /* Null routine for the NeWS version. */
  1325. {
  1326.   FPRINTF(PostScript, "/destroy Frame send\n") ;
  1327.   FFLUSH(PostScript) ;
  1328. }
  1329.  
  1330.  
  1331. draw_scanline(lines, y)      /* Display image scanline on the screen. */
  1332. unsigned char **lines ;
  1333. int y ;
  1334. {
  1335.   int depth, i ;
  1336.   unsigned char *line;
  1337.  
  1338.   line = ntsc_luma(lines);
  1339.   depth = (iscolor) ? 8 : 1 ;
  1340.   FPRINTF(PostScript, "/ScanLine %1d 1 %1d { } { < \n", Xsize, depth) ;
  1341.   if (iscolor)
  1342.     {
  1343.       for (i = 0; i < Xsize; i++)
  1344.         FPRINTF(PostScript, "%.2X ", line[i]) ;
  1345.     }
  1346.   else
  1347.     {
  1348.       mptr = (unsigned char *) Emalloc((Xsize / 8) + 1) ;
  1349.       halftone(line, y) ;
  1350.       for (i = 0; i < (Xsize / 8) + 1; i++)
  1351.         FPRINTF(PostScript, "%.2X ", 255 - mptr[i]) ;
  1352.     }
  1353.   FPRINTF(PostScript, "> } buildimage def\n") ;
  1354.   FPRINTF(PostScript, "%1d PSDrawScanLine\n", y) ;
  1355.   FFLUSH(PostScript) ;
  1356. }
  1357.  
  1358.  
  1359. drawarea(x, y, width, height, op)
  1360. int x, y, width, height ;
  1361. enum op_type op ;
  1362. {
  1363.   FPRINTF(PostScript, "%d %d %d %d %d PSDrawArea\n",
  1364.           x, y, width, height, (int) op) ;
  1365.   FFLUSH(PostScript) ;
  1366. }
  1367.  
  1368.  
  1369. drawline(x1, y1, x2, y2)
  1370. int x1, y1, x2, y2 ;
  1371. {
  1372.   FPRINTF(PostScript, "%d %d %d %d PSDrawLine\n", x1, y1, x2, y2) ;
  1373. }
  1374.  
  1375.  
  1376. drawtext(x, y, fontno, str)
  1377. enum font_type fontno ;
  1378. int x, y ;
  1379. char *str ;
  1380. {
  1381.   int i ;
  1382.   char font, fonttype[6], line[MAXLINE] ;
  1383.  
  1384.        if (fontno == NFONT) STRCPY(fonttype, "NFont") ;
  1385.   else if (fontno == BFONT) STRCPY(fonttype, "BFont") ;
  1386.   line[0] = '\0' ;
  1387.   for (i = 0; i < strlen(str); i++)
  1388.     switch (str[i])
  1389.       {
  1390.         case '\\' : STRCAT(line,"\\\\") ;
  1391.                     break ;
  1392.         case '('  : STRCAT(line,"\\(") ;
  1393.                     break ;
  1394.         case ')'  : STRCAT(line,"\\)") ;
  1395.                     break ;
  1396.         default   : STRNCAT(line, &str[i], 1) ;
  1397.       }
  1398.   FPRINTF(PostScript, "%s %d %d (%s) PSDrawText\n", fonttype, x, y, line) ;
  1399. }
  1400.  
  1401.  
  1402. get_next_char(c)    /* Process events, and return when character is typed. */
  1403. char *c ;
  1404. {
  1405.   int ch, type ;
  1406.  
  1407.   for (;;)
  1408.     {
  1409.       FFLUSH(PostScript) ;
  1410.       if (pscanf(PostScriptInput, "%d", &type) == EOF) exit(0) ;
  1411.       switch (type)
  1412.         {
  1413.           case KEYBOARD : pscanf(PostScriptInput, "%d", &ch) ;
  1414.                           *c = ch ;
  1415.                           return ;
  1416.           case REPAINT  : paint_canvas() ;
  1417.         }
  1418.     }
  1419. /*NOTREACHED*/
  1420. }
  1421.  
  1422.  
  1423. init_fonts()
  1424. {
  1425.   FPRINTF(PostScript, "PSInitFonts\n") ;
  1426.   nfont_width = 9 ;
  1427. }
  1428.  
  1429.  
  1430. init_ws_type()
  1431. {
  1432.   if (ps_open_PostScript() < 0) return -1 ;
  1433.   if (send_ps_file(NEWSFILE) == -1)
  1434.     {
  1435.       FCLOSE(PostScript) ;
  1436.       return(-1) ;
  1437.     }
  1438.   FFLUSH(PostScript) ;
  1439.   if (ferror(PostScript))
  1440.     {
  1441.       FCLOSE(PostScript) ;
  1442.       return(-1) ;
  1443.     }
  1444.   FPRINTF(PostScript, "PSIsColor\n") ;
  1445.   pscanf(PostScriptInput, "%d", &iscolor) ;
  1446.   FPRINTF(PostScript, "PSInitialise\n") ;
  1447.   return(0) ;
  1448. }
  1449.  
  1450.  
  1451. load_colors()    /* Create and load popi color map. */
  1452. {
  1453.   int i ;
  1454.   u_char red[CMAPLEN], green[CMAPLEN], blue[CMAPLEN] ;
  1455.  
  1456.   for (i = 0; i < CMAPLEN; i++)
  1457.     red[i] = green[i] = blue[i] = 255 - i ;
  1458.  
  1459.   FPRINTF(PostScript, "%d PSMakeColorTable\n", 256) ;
  1460.   for (i = 0; i < 256; i++)
  1461.     FPRINTF(PostScript, "%d %d %d %d PSLoadColor\n",
  1462.                        red[i], green[i], blue[i], i) ;
  1463. }
  1464.  
  1465.  
  1466. make_icon()
  1467. {
  1468.   int i, j ;
  1469.  
  1470.   FPRINTF(PostScript,"/PopiIcon 64 64 1 { } { <\n") ;
  1471.   for (i = 0; i < 32; i++)
  1472.     {
  1473.       for (j = 0; j < 8; j++) FPRINTF(PostScript,"%.4X ", icon_image[i*8+j]) ;
  1474.       FPRINTF(PostScript,"\n") ;
  1475.     }
  1476.   FPRINTF(PostScript,"> } buildimage def\n") ;
  1477. }
  1478.  
  1479.  
  1480. make_items(argc, argv)       /* Create icon, frame, canvas etc.. */
  1481. int argc ;
  1482. char *argv[] ;
  1483. {
  1484.   make_icon() ;
  1485.   FPRINTF(PostScript, "%d %d %d %d %d %d %d PSMakeItems\n",
  1486.                      wx, wy, TXsize, TYsize,
  1487.                      ix, iy, iconic) ;
  1488.   load_colors() ;
  1489. }
  1490.  
  1491.  
  1492. send_ps_file(fname)
  1493. char *fname ;
  1494. {
  1495.   FILE *stream ;
  1496.   int c ;
  1497.  
  1498.   if ((stream = fopen(fname,"r")) == NULL) return -1 ;
  1499.   while ((c = getc(stream)) != EOF) PUTC(c, PostScript) ;
  1500.   FCLOSE(stream) ;
  1501.   return 0 ;
  1502. }
  1503.  
  1504.  
  1505. set_cursor(type)
  1506. enum cur_type type ;
  1507. {
  1508.   FPRINTF(PostScript, "%d PSSetCursor\n", (int) type) ;
  1509. }
  1510.  
  1511.  
  1512. start_tool()          /* Null routine in the NeWS version. */
  1513. {
  1514. }
  1515. Funky_Stuff
  1516. len=`wc -c < news.c`
  1517. if [ $len !=     5319 ] ; then
  1518. echo error: news.c was $len bytes long, should have been     5319
  1519. fi
  1520. fi # end of overwriting check
  1521. if [ -f next.m ]
  1522. then
  1523. echo shar: will not over-write existing file next.m
  1524. else
  1525. echo shar: extracting 'next.m',     5771 characters
  1526. cat > next.m <<'Funky_Stuff'
  1527. /*LINTLIBRARY*/
  1528.  
  1529. /*  @(#)next.m 1.1 90/12/12
  1530.  *
  1531.  *  Popi device driver for a NeXT machine
  1532.  *  Written by Joe Freeman.
  1533.  *
  1534.  *  Popi was originally written by Gerard J. Holzmann - AT&T Bell Labs.
  1535.  *  This version is based on the code in his Prentice Hall book,
  1536.  *  "Beyond Photography - the digital darkroom," ISBN 0-13-074410-7,
  1537.  *  which is copyright (c) 1988 by Bell Telephone Laboratories, Inc. 
  1538.  *
  1539.  *  Permission is given to distribute these extensions, as long as these
  1540.  *  introductory messages are not removed, and no monies are exchanged.
  1541.  *
  1542.  *  No responsibility is taken for any errors or inaccuracies inherent
  1543.  *  either to the comments or the code of this program, but if reported
  1544.  *  (see README file) then an attempt will be made to fix them.
  1545.  */
  1546.  
  1547. #include "popi.h"
  1548. #import "appkit/appkit.h"    /* lazy tsk tsk */
  1549.  
  1550. /*  These are the exportable routines used by the popi program.
  1551.  *
  1552.  *  These are:
  1553.  *
  1554.  *  disp_init(argc, argv)    - called from main at the start.
  1555.  *  disp_finish()            - called from main prior to exit.
  1556.  *  disp_imgstart()          - called prior to drawing an image.
  1557.  *  disp_imgend()            - called after drawing an image.
  1558.  *  disp_putline(line, y)    - to draw an image scanline.
  1559.  *  disp_getchar()           - to get the next character typed.
  1560.  *  disp_prompt()            - display popi prompt and clear input buffer.
  1561.  *  disp_error(errtype)      - display error message.
  1562.  *  disp_percentdone(n)      - display percentage value of conversion.
  1563.  */
  1564.  
  1565. #define  RES  8
  1566. int dither[RES][RES] = {        /* dither matrix */
  1567.   {   0, 128,  32, 160,   8, 136,  40, 168, },
  1568.   { 192,  64, 224,  96, 200,  72, 232, 104, },
  1569.   {  48, 176,  16, 144,  56, 184,  24, 152, },
  1570.   { 240, 112, 208,  80, 248, 120, 216,  88, },
  1571.   {  12, 140,  44, 172,   4, 132,  36, 164, },
  1572.   { 204,  76, 236, 108, 196,  68, 228, 100, },
  1573.   {  60, 188,  28, 156,  52, 180,  20, 148, },
  1574.   { 252, 124, 220,  92, 244, 116, 212,  84, },
  1575. } ;
  1576.  
  1577. id    NXApp;
  1578. id    drawWindow,percentWindow;
  1579.  
  1580. #define    PERCENTHEIGHT    50
  1581. #define    PERCENTWIDTH    120
  1582. #define    LOGHEIGHT    250
  1583. #define    LOGWIDTH    200
  1584. #define    DRAWBASEX        250
  1585. #define    DRAWBASEY     250
  1586.  
  1587. /*ARGSUSED*/
  1588. void
  1589. disp_init(argc,argv)           /* called from main at the atart. */
  1590. int argc;
  1591. char *argv[];
  1592. {
  1593.     NXRect    bound;
  1594.     NXApp = [Application new];
  1595.     [NXApp setAppName:"popi"];
  1596.     bound.origin.x = DRAWBASEX;
  1597.     bound.origin.y = DRAWBASEY;
  1598.     bound.size.width = Xsize;  bound.size.height = Ysize;
  1599.     drawWindow = [Window newContent:&bound
  1600.                         style:NX_TITLEDSTYLE
  1601.                         backing: NX_RETAINED
  1602.                         buttonMask: NX_MINIATURIZEBUTTONMASK
  1603.                         defer : NO];
  1604.     [[drawWindow contentView] setFlip:YES];    /* start at top */
  1605.     [drawWindow orderFront:nil];
  1606.     [drawWindow setTitle:"popi image window"];
  1607.     [drawWindow display];
  1608.     bound.origin.x = DRAWBASEX - PERCENTWIDTH;
  1609.     bound.origin.y = DRAWBASEY + Ysize - PERCENTHEIGHT;
  1610.     bound.size.width = PERCENTWIDTH; bound.size.height = PERCENTHEIGHT;
  1611.     percentWindow = [Panel newContent:&bound
  1612.                         style:NX_TITLEDSTYLE
  1613.                         backing: NX_RETAINED
  1614.                         buttonMask: 0
  1615.                         defer: NO];
  1616.     [percentWindow setTitle:"percent done"];
  1617.     bound.origin.x = 40.0; bound.origin.y = 350;
  1618.     bound.size.width = LOGWIDTH; bound.size.height = LOGHEIGHT;
  1619.     [percentWindow display];
  1620.     bound.origin.x = 0.0; bound.origin.y = DRAWBASEY;
  1621.     bound.size.width = DRAWBASEX ;  bound.size.height = Ysize - PERCENTHEIGHT;
  1622.     NXPing();
  1623. }
  1624.  
  1625.  
  1626. void
  1627. disp_finish()                  /* called from main prior to exit. */
  1628. {
  1629.     [drawWindow free];
  1630.     [percentWindow free];
  1631.     [NXApp free];
  1632. }
  1633.  
  1634.  
  1635. void
  1636. disp_imgstart()                /* called prior to drawing an image. */
  1637. {
  1638. }
  1639.  
  1640.  
  1641. void
  1642. disp_imgend()                  /* called after drawing an image. */
  1643. {
  1644.     [drawWindow flushWindow];
  1645.     NXPing();
  1646. }
  1647.  
  1648.  
  1649. void
  1650. disp_putline(line, y)        /* called to draw image scanline y. */
  1651. pixel_t *line;
  1652. int y;
  1653. {
  1654.     NXRect    theRect;
  1655.     [[drawWindow contentView] lockFocus];
  1656.     PSgsave();
  1657.     theRect.origin.x = 0.0;
  1658.     theRect.origin.y = (float)y;
  1659.     theRect.size.width = (float)Xsize;
  1660.     theRect.size.height = (float)1.0;
  1661.     NXImageBitmap(&theRect, Xsize, 1.0, 
  1662.                     8, 1, NX_PLANAR, NX_MONOTONICMASK, 
  1663.                     line, NULL,NULL, NULL, NULL);
  1664.      PSgrestore();
  1665.     [[drawWindow contentView] unlockFocus];
  1666. }
  1667.  
  1668.  
  1669. disp_getchar()                 /* get next user typed character. */
  1670. {
  1671.     return(getchar());
  1672. }
  1673.  
  1674.  
  1675. disp_prompt()                  /* display popi prompt. */
  1676. {
  1677.     char    *prompt = "-> ";
  1678.  
  1679.     PRINTF(prompt);
  1680.     return sizeof prompt - 1;
  1681. }
  1682.  
  1683.  
  1684. void
  1685. disp_error(errtype, pos)            /* display error message. */
  1686. int    errtype,
  1687.     pos;
  1688. {
  1689.     extern int  errno;
  1690.     extern char *sys_errlist[];
  1691.  
  1692.     if (errtype & ERR_PARSE)
  1693.     {
  1694.         int     i;
  1695.  
  1696.         for (i=1; i < pos; ++i)
  1697.             PUTC('-', stderr);
  1698.         PUTC('^', stderr);
  1699.         PUTC('\n', stderr);
  1700.     }
  1701.  
  1702.     FPRINTF(stderr, "%s\n", ErrBuf);
  1703.     /* we assume errno hasn't been reset by the preceding output */
  1704.     if (errtype & ERR_SYS)
  1705.         FPRINTF(stderr, "\t(%s)\n", sys_errlist[errno]);
  1706. }
  1707.  
  1708. void
  1709. disp_percentdone(percent)
  1710. int    percent;
  1711. {
  1712.     static    int    lastpercent = 100;
  1713.     static    NXRect    bound;
  1714.  
  1715.     if (!Verbose)
  1716.     return;
  1717.     if (percent == 100)
  1718.     {
  1719.         [percentWindow orderOut:nil];
  1720.     return;
  1721.     }
  1722.     if ((percent == 0) && (lastpercent != 0))
  1723.     {
  1724.         [[percentWindow  contentView] lockFocus];
  1725.         [[percentWindow  contentView] getBounds:&bound];
  1726.     NXDrawGrayBezel( &bound, &bound);
  1727.         [[percentWindow contentView] unlockFocus];
  1728.         [percentWindow orderFront:nil];
  1729.     NXPing();
  1730.     bound.origin.x = bound.origin.y = 10.0;
  1731.     bound.size.height = PERCENTHEIGHT - (2.0 * 10.0);
  1732.     lastpercent = percent;
  1733.     }
  1734.     if (percent != lastpercent && percent % 5 == 0)
  1735.     {
  1736.     [[percentWindow contentView] lockFocus];
  1737.     bound.size.width = (float)percent;
  1738.     NXDrawButton(&bound,&bound);
  1739.     [[percentWindow contentView] unlockFocus];
  1740.     NXPing();
  1741.     lastpercent = percent;
  1742.     }
  1743. }
  1744. Funky_Stuff
  1745. len=`wc -c < next.m`
  1746. if [ $len !=     5771 ] ; then
  1747. echo error: next.m was $len bytes long, should have been     5771
  1748. fi
  1749. fi # end of overwriting check
  1750. exit 0 # Just in case...
  1751.