home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1994 March / Source_Code_CD-ROM_Walnut_Creek_March_1994.iso / compsrcs / 3b1 / volume02 / mgrabscr / part01 < prev    next >
Encoding:
Internet Message Format  |  1993-02-01  |  47.4 KB

  1. Path: comp-sources-3b1
  2. From: John R MacMillan <john@chance.gts.org>
  3. Subject:  v02i032:  Capture MGR screen images & View MGR bitmaps, Part01/01
  4. Newsgroups: comp.sources.3b1
  5. Approved: dave@galaxia.network23.com
  6. X-Checksum-Snefru: b4566e6a 27c69f5b 8d6a4d30 0003f6f2
  7.  
  8. Submitted-by: John R MacMillan <john@chance.gts.org>
  9. Posting-number: Volume 2, Issue 32
  10. Archive-name: mgrabscr/part01
  11.  
  12. These are sufficiently UNIXpc-specific that I did not feel they
  13. belonged in comp.sources.misc.  Granted, they are of little or no use
  14. to non-MGR 3b1-ers (except for the MIME plug), but some folks may find
  15. them useful.
  16.  
  17. They perform similar functions to the MGR "snap" and "show" programs,
  18. but I found them unsuitable for what I wanted.
  19.  
  20. #!/bin/sh
  21. #  This is a shar file.  To extract, sh this file
  22. #
  23. #  Contents:
  24. #    ReadMe
  25. #    Makefile
  26. #    mgrabscr.man
  27. #    mview.man
  28. #    mgrabscr.c
  29. #    mview.c
  30. #    abspath.c
  31. #    mime.overview
  32. #    mhn-mgr
  33. #    mailcap
  34. #
  35. #  Wrapped by john@chance.UUCP ; Mon Jan 25 11:14:47 EST 1993
  36. #
  37. if [ -f "ReadMe" ] ; then
  38.     echo "shar: Will not overwrite existing file ReadMe"
  39. else
  40.     echo "shar: extracting ReadMe (4881 characters)"
  41.     sed 's/^X//' <<'BOP_BOP_A_LOO_WOP_BO_LOP_BAM_BOOM' > ReadMe
  42. XMview and mgrabscr                                     93/01/25
  43. X==================
  44. X
  45. XMview and mgrabscr are programs for viewing and creating (from the
  46. Xdisplay, not editing) MGR bitmaps.  The programs are at present
  47. Xspecific to the UNIXpc version of MGR, as I no longer have any others
  48. Xto play with.  If you wish to port them to another MGR system, see
  49. X"Porting Notes" below.
  50. X
  51. XThese programs evolved (mutated, really) out of my desire to have
  52. Xdecent bitmap display and composition tools while I was involved with
  53. Xthe RFC1341 (MIME) mailing list.  This has influenced the way they
  54. Xwork, and mview especially changed a lot as I played with more MIME
  55. Xmail messages.  Unfortunately, this means mview could probably use a
  56. Xrewrite, but I'm simply too lazy, I mean, uh, busy.  Both could
  57. Xprobably use a better user interface, but they are more in line with
  58. Xwhat I wanted than any of the demo programs that came with MGR.
  59. X
  60. XThis code is in the Public Domain, though I would appreciate receiving
  61. Xfixes and enhancements, and would prefer not to be represented as the
  62. Xauthor of changes I did not make.  No guarantee of suitability for any
  63. Xpurpose whatsoever, except possibly test cases for rm(1), is made
  64. Xunless your needs, wants and desires are the same as mine, in which
  65. Xcase, I feel these programs are tolerably suitable.
  66. X
  67. XBuild Procedure
  68. X===============
  69. X
  70. XEdit the Makefile to customize the things marked CUSTOMIZE, and
  71. Xanything else you feel comfortable changing.  Both mview and mgrabscr
  72. Xneed libmgr.a and the term.h and dump.h include files that usually get
  73. Xinstalled somewhere when you install MGR.  Mgrabscr also requires
  74. Xblitlib.a and bitmap.h, which I do not think are usually installed
  75. Xbut are in the MGR source directory "lib".
  76. X
  77. XWhen you're happy with the Makefile, just "make" to make the binaries,
  78. Xor "make man" to format the manual pages.
  79. X
  80. XSo What is MIME?
  81. X================
  82. X
  83. XMIME, or Multipurpose Internet Mail Extensions, is a "mechanism for
  84. Xspecifying and describing the format of Internet message bodies"
  85. Xdescribed in RFC 1341.  What it includes is a method for including
  86. Ximages, audio, different character sets, etc. in a mail message.  The
  87. Xlatest version of many popular UNIX mail user agents are MIME capable;
  88. Xsome directly (like MH6.8), others by using Nathaniel Borenstein's
  89. XMetamail package (Nathaniel is co-author of RFC 1341, from Bellcore,
  90. Xhome of MGR, coincidentally).
  91. X
  92. XThis may sound like an ad for MIME, and it is a bit.  I think MIME
  93. Xwill become more and more common in the near future, both in mail and
  94. Xnews, and I would encourage people to look into making themselves and
  95. Xtheir mailers "MIME capable".
  96. X
  97. XFor MH users, I've included my $MHN file for use with mgr, called
  98. Xmhn-mgr.  The "richtext" program mentioned in it is from the Metamail
  99. Xdistribution, available via anonymous FTP from thumper.bellcore.com.
  100. XFor Metamail users, I've included a sample mailcap that uses mview for
  101. Xdisplay (untested; I do not yet use Metamail, though I intend to when
  102. XI can get around to building trn with the Metamail patches).  Note
  103. Xthat the "X-*" image types are not sanctioned by the RFC (early drafts
  104. Xhad the p?m types, but they were removed), but they may be useful for
  105. Xexchanging images with "known" recipients.
  106. X
  107. XIf you're interested in MIME, you can get RFC 1341, or poke around in
  108. Xcomp.mail.mime and see what's up.  Mark Grand (mdg@netcom.netcom.com)
  109. Xhas prepared an overview and technical summary, available via
  110. Xanonymous FTP from adad.premenos.sf.ca.us in the /pub directory,
  111. Xcalled mime.ps (PostScript) or mime.txt (ASCII text).  I've included
  112. Xthe overview portion of mime.txt as mime.overview.
  113. X
  114. XPorting Notes
  115. X=============
  116. X
  117. XBoth programs are basically System V-ish; they use uname() to get the
  118. Xnode name instead of gethostname(), include <string.h>, and that sort
  119. Xof thing.
  120. X
  121. XIn mview, the bitmap file reading may not be correct for colour MGRs
  122. X(ie. with a bit depth greater than 1).
  123. X
  124. XIn mgrabscr, the bitmap file writing flips the bits around because the
  125. XUNIXpc screen stores them "backwards", and the screen device is
  126. Xessentially ignored.
  127. X
  128. XMiscellaneous
  129. X=============
  130. X
  131. XMview was never intended as something to manipulate (rotate, stretch,
  132. Xetc.) bitmaps.  You can always use the PBM utilities to do this, but
  133. Xsuch a tool would be neat if somebody else would write it...
  134. X
  135. XThe only image types that are blessed by the RFC are image/gif and
  136. Ximage/jpeg.  Going from a GIF to an MGR bitmap with the PBM utilities
  137. Xis pretty slow, and JPEG to MGR is likewise not fast.  I may try and
  138. Xdo GIF to MGR and JPEG to MGR programs based on the PBM and JPEG
  139. Xwork.  If anybody else does this, please let me know.
  140. X
  141. XI don't use the normal UNIXpc window system much, but I would like an
  142. X"s4grabscr"-like program to go with pbmto3b1 for those rare
  143. Xoccasions.  Anyone know of one?
  144. X
  145. XI'd like bug reports, enhancements, etc.  Mail them to me:
  146. X
  147. Xjohn@chance.gts.org
  148. X
  149. XEnjoy!
  150. X
  151. XJohn R. MacMillan
  152. BOP_BOP_A_LOO_WOP_BO_LOP_BAM_BOOM
  153.     set -- `wc -c ReadMe`
  154.     if [ "$1" != "4881" ] ; then
  155.         echo "shar: ReadMe unpacked with wrong size!"
  156.     fi
  157.     chmod u=r,g=r,o=r ReadMe
  158. fi
  159. if [ -f "Makefile" ] ; then
  160.     echo "shar: Will not overwrite existing file Makefile"
  161. else
  162.     echo "shar: extracting Makefile (1207 characters)"
  163.     sed 's/^X//' <<'BOP_BOP_A_LOO_WOP_BO_LOP_BAM_BOOM' > Makefile
  164. X# @(#)Makefile    2.1    93/01/25
  165. X
  166. X# CUSTOMIZE the next two for your site to point to the area where
  167. X# MGR include files are kept, and the MGR library, and anything
  168. X# else you might want.
  169. X
  170. XINCLUDES= -I/usr/local/lib/mgr/include
  171. XLIBS=/usr/local/lib/mgr/lib/libmgr.a
  172. X
  173. X# CUSTOMIZE these two.  They are in the lib directory in the MGR source
  174. X# area, but you may have them elsewhere (I have them in the same area
  175. X# as above, for instance).
  176. X
  177. XBITINCLUDES=
  178. XBITLIBS=/usr/local/lib/mgr/lib/blitlib.a
  179. X
  180. X# CUSTOMIZE as appropriate.  Remember to include relevant flags to
  181. X# pick up libraries in LIBS if you didn't include full paths.
  182. X
  183. XCC= cc
  184. XOPTIM= -O
  185. XLDFLAGS= -s
  186. X#CC= gcc
  187. X#OPTIM= -O
  188. X#LDFLAGS= -s -shlib
  189. X
  190. XCFLAGS= $(OPTIM) $(INCLUDES)
  191. X
  192. XTARGETS= mview mgrabscr
  193. X
  194. Xall:    $(TARGETS)
  195. X
  196. Xmview: mview.o abspath.o
  197. X    $(CC) $(LDFLAGS) -o $@ mview.o abspath.o $(LIBS)
  198. X
  199. Xmgrabscr: mgrabscr.o abspath.o
  200. X    $(CC) $(LDFLAGS) -o $@ mgrabscr.o abspath.o $(BITLIBS) $(LIBS)
  201. X
  202. Xmgrabscr.o: mgrabscr.c
  203. X    $(CC) $(CFLAGS) $(BITINCLUDES) -c mgrabscr.c
  204. X
  205. Xman: mview.1 mgrabscr.1
  206. X
  207. Xmview.1: mview.man
  208. X    nroff -man mview.man > mview.1
  209. X
  210. Xmgrabscr.1: mgrabscr.man
  211. X    nroff -man mgrabscr.man > mgrabscr.1
  212. X
  213. Xclean:
  214. X    rm -f *.o *.out core
  215. X
  216. Xclobber: clean
  217. X    rm -f $(TARGETS) *.1
  218. BOP_BOP_A_LOO_WOP_BO_LOP_BAM_BOOM
  219.     set -- `wc -c Makefile`
  220.     if [ "$1" != "1207" ] ; then
  221.         echo "shar: Makefile unpacked with wrong size!"
  222.     fi
  223.     chmod u=rw,g=r,o=r Makefile
  224. fi
  225. if [ -f "mgrabscr.man" ] ; then
  226.     echo "shar: Will not overwrite existing file mgrabscr.man"
  227. else
  228.     echo "shar: extracting mgrabscr.man (3338 characters)"
  229.     sed 's/^X//' <<'BOP_BOP_A_LOO_WOP_BO_LOP_BAM_BOOM' > mgrabscr.man
  230. X.TH MVIEW 1 "93/01/25" "MGR"
  231. X.SH NAME
  232. Xmgrabscr \- grab portion of MGR display
  233. X.SH SYNOPSIS
  234. X.B mview
  235. X[\fB\-r\fP|\fB\-w\fP|\fB\-s\fP]
  236. X[\fB\-d\fP \fIdelay\fP|\fB\-D\fP \fIdelay\fP]
  237. X[\fB\-v\fP]
  238. X.I [file]
  239. X.SH DESCRIPTION
  240. X.I Mgrabscr
  241. Xgrabs a portion of an MGR display and writes it out as a bitmap to
  242. X.I file
  243. Xor to standard out if no file is given.  The portion can either be the
  244. Xentire screen, a particular window, or a rectangle swept out by the
  245. Xuser.
  246. X.LP
  247. XThe portion grabbed is dictated by the arguments, as described below.
  248. XIf no arguments are given which indicate what should be grabbed, the
  249. Xoperation of \fImgrabscr\fP is controlled by a menu available on
  250. Xeither mouse button.  The menu allows the user to select what should
  251. Xbe grabbed, and to initiate the grab when the desired mode is
  252. Xselected.  The current grab mode is indicated in the menu with an
  253. Xasterisk (\fB*\fP).  When the \fBDo Grab\fP menu item is selected, the
  254. Xgrab will proceed as if the selected mode had been given on the
  255. Xcommand line, as described below.
  256. X.LP
  257. XOccasionally it may be desirable to rearrange the screen prior to the
  258. Xgrab taking place but after the area has been selected (to hide the
  259. Xwindow \fImgrabscr\fP is running in, for instance).  To allow this
  260. Xdelay may be specified on the command line or selected from the menu.
  261. XThe default delay, if not given on the command line but selected from
  262. Xthe menu, is 10 seconds.
  263. X.LP
  264. X\fIMgrabscr\fP works only on the same host that MGR is running on.
  265. X.IP "\fB\-r\fP"
  266. XSweep out a rectangle.  Pressing either mouse button will fix one
  267. Xcorner of a rectangle which may be swept out in the normal manner of
  268. XMGR.  \fIMgrabscr\fP will then write the contents of this rectangle as
  269. Xthe bitmap, in new bitmap format.  If possible, the mouse cursor will
  270. Xbe moved out of the rectangle so as not to appear in the bitmap.  Not
  271. Xsweeping an area (ie. clicking either mouse button) will abort the
  272. Xgrab.
  273. X.LP
  274. X.IP "\fB\-w\fP"
  275. XPressing either mouse button over a window (which may be partially
  276. Xobscured) will cause the contents of that window to be written out in
  277. Xthe bitmap format in use by MGR (see the \fB\-n\fP option of the
  278. X\fImgr\fP(1) command).  Pressing either mouse button over a non-window
  279. Xwill abort the grab.
  280. X.LP
  281. X.IP "\fB\-s\fP"
  282. XClicking either mouse button will cause the entire screen contents to
  283. Xbe written out in the new bitmap format.  The mouse cursor will appear
  284. Xin the bitmap, so you may wish to move it somewhere unobtrusive before
  285. Xclicking.
  286. X.LP
  287. X.IP "\fB\-d\fP \fIdelay\fP"
  288. XSet the delay time to \fIdelay\fP seconds.  If none of
  289. X\fB\-r\fP, \fB\-w\fP, or \fB\-s\fP is given, the menu option for
  290. Xdelaying will be selected initially.  \fIMgrabscr\fP will flash the
  291. Xscreen and beep immediately before the image is actually grabbed.
  292. X.LP
  293. X.IP "\fB\-D\fP \fIdelay\fP"
  294. XLike \fB\-d\fP except that the menu option for delaying will not be
  295. Xselected initially.  This allows the user to change the default delay
  296. Xfor the menu mode without actually causing a delay.
  297. X.LP
  298. X.IP "\fB\-v\fP"
  299. XSends some instructions and status information to standard error.
  300. X.SH SEE ALSO
  301. Xmgr(1), bitmap(5)
  302. X.SH AUTHOR
  303. XJohn R. MacMillan
  304. X.sp
  305. XE\-mail: john@chance.gts.org or ...!{scocan.sco.com,sq.com}!chance!john
  306. X.SH BUGS
  307. X.LP
  308. XThere should be some way to do remote grabs.
  309. X.LP
  310. XWindow grabs will be written out in a bitmap format dependent upon how
  311. XMGR was invoked.
  312. BOP_BOP_A_LOO_WOP_BO_LOP_BAM_BOOM
  313.     set -- `wc -c mgrabscr.man`
  314.     if [ "$1" != "3338" ] ; then
  315.         echo "shar: mgrabscr.man unpacked with wrong size!"
  316.     fi
  317.     chmod u=r,g=r,o=r mgrabscr.man
  318. fi
  319. if [ -f "mview.man" ] ; then
  320.     echo "shar: Will not overwrite existing file mview.man"
  321. else
  322.     echo "shar: extracting mview.man (4732 characters)"
  323.     sed 's/^X//' <<'BOP_BOP_A_LOO_WOP_BO_LOP_BAM_BOOM' > mview.man
  324. X.TH MVIEW 1 "93/01/25" "MGR"
  325. X.SH NAME
  326. Xmview \- MGR bitmap viewer
  327. X.SH SYNOPSIS
  328. X.B mview
  329. X[\fB\-x\fP \fIxpos\fP]
  330. X[\fB\-y\fP \fIypos\fP]
  331. X[\fB\-w\fP \fIwidth\fP]
  332. X[\fB\-h\fP \fIheight\fP]
  333. X[\fB\-s\fP \fIseconds\fP]
  334. X[\fB\-f\fP]
  335. X[\fB\-r\fP]
  336. X[\fB\-v\fP]
  337. X[\fB\-c\fP]
  338. X.I [file ...]
  339. X.SH DESCRIPTION
  340. X.I Mview
  341. Xdisplays MGR bitmap files on an MGR display.  Bitmaps are displayed in
  342. Xsuccession in an alternate window; if no \fIfile\fPs are given, the
  343. Xbitmap is read from standard input.  Entering
  344. X\fBN<RETURN>\fP or \fB<RETURN>\fP will advance to the next bitmap,
  345. X\fBP<RETURN>\fP will move to the previous bitmap, and pressing the
  346. Xinterrupt character or entering \fBQ<RETURN>\fP will terminate the
  347. Xprogram.  These actions are also available from a menu on both user
  348. Xmouse buttons.
  349. X.LP
  350. XBy default, \fImview\fP places the alternate window randomly to
  351. Xallow as much of the bitmap as possible to be displayed.  If a
  352. Xsubsequent bitmap is larger, the window will normally be moved to
  353. Xaccommodate the larger image.  This behaviour can be changed with
  354. Xthe options below.
  355. X.LP
  356. XIf the image does not fit in the window, \fImview\fP can scroll the
  357. Xwindow over image.  The direction names for scrolling are for moving
  358. Xthe window over the image; the window starts displaying the top left
  359. Xcorner of the image.  Pressing \fBF<RETURN>\fP or \fBD<RETURN>\fP will
  360. Xmove the window down the image by a full or half window, respectively.
  361. XPressing \fBB<RETURN>\fP or \fBU<RETURN>\fP return will move the
  362. Xwindow up a full or half window.  \fBR<RETURN>\fP or \fB><RETURN>\fP
  363. Xwill move the window right by a half window, \fBL<RETURN>\fP or
  364. X\fB<<RETURN>\fP will move the window right a half window.  The menu
  365. Xcan also be used to perform these functions.
  366. X.LP
  367. XIf the \fImview\fP window is reshaped or moved, \fImview\fP will use
  368. Xthe new shape and position.  Note that the image is not scaled; it is
  369. Xsimply cropped.  This is the only way to reposition a window if it has
  370. Xbeen forced to a particular position with \fB\-f\fP (see below).
  371. X.LP
  372. X.IP "\fB\-x\fP \fIxpos\fP"
  373. XSet the \fIx\fP position of the alternate window in display
  374. Xco-ordinates.  The window may be moved to accommodate larger images
  375. Xunless \fB\-f\fP is set (see below).
  376. X.LP
  377. X.IP "\fB\-y\fP \fIypos\fP"
  378. XSet the \fIy\fP position of the alternate window in display
  379. Xco-ordinates.  The window may be moved to accommodate larger images
  380. Xunless \fB\-f\fP is set (see below).
  381. X.LP
  382. X.IP "\fB\-w\fP \fIwidth\fP"
  383. XSet the maximum width of the alternate window to \fIwidth\fP
  384. Xpixels.  Images larger than this will be cropped.
  385. X.LP
  386. X.IP "\fB\-h\fP \fIheight\fP"
  387. XSet the maximum height of the alternate window to \fIheight\fP
  388. Xpixels.  Images larger than this will be cropped.
  389. X.LP
  390. X.IP "\fB\-s\fP \fIseconds\fP"
  391. XUse slideshow mode.  After \fIseconds\fP seconds, move automatically
  392. Xto the next image.  This option is ignored if the bitmap is being read
  393. Xfrom standard input.
  394. X.LP
  395. X.IP "\fB\-f\fP"
  396. XForce the position of the alternate window, even if this means the
  397. Ximage will be cropped.  If \fB\-x\fP or \fB\-y\fP are not specified
  398. Xthe random position chosen for the first bitmap will be used.
  399. X.LP
  400. X.IP "\fB\-r\fP"
  401. XReverse the sense of black/white pixels when displaying each bitmap.
  402. XAn item on the menu may be used to toggle this once mview is running.
  403. X.LP
  404. X.IP "\fB\-v\fP"
  405. XBe verbose.  Information about the size and position of the bitmap
  406. X(and size of the image if it was cropped) is displayed in the main
  407. Xwindow.
  408. X.LP
  409. X.IP "\fB\-c\fP"
  410. XCycle through images.  The ``next'' image after the last one on the
  411. Xcommand line is the first one, and the ``previous'' from the first is
  412. Xthe last.  This option is ignored if the bitmap is being read from
  413. Xstandard input.
  414. X.LP
  415. XIf \fImview\fP is run on a different host than MGR, there must be an
  416. X8 bit clean path between the two.
  417. X.SH SEE ALSO
  418. Xmgr(1), bitmap(5)
  419. X.SH AUTHOR
  420. XJohn R. MacMillan
  421. X.sp
  422. XE\-mail: john@chance.gts.org or ...!{scocan.sco.com,sq.com}!chance!john
  423. X.SH BUGS
  424. X.LP
  425. XSince \fImview\fP uses an alternate window to display the bitmap, you
  426. Xcan't run it in the background, or run several simultaneously from the
  427. Xsame window, without it fighting for the keyboard.
  428. X.LP
  429. XThere is no way to use standard input as one of several bitmaps to be
  430. Xdisplayed.  If this is required, save standard input in a temporary
  431. Xfile before invoking \fImview\fP.
  432. X.LP
  433. XIf \fImview\fP and MGR are on the same host, the filenames are
  434. Xinterpreted by MGR (though \fImview\fP will provide MGR with absolute
  435. Xpathnames) so files such as \fB/dev/stdin\fP will not work as expected.
  436. X.LP
  437. XIn slideshow mode, if the user is selecting from a menu when the
  438. Xslideshow timer expires, the menu item may not take effect.
  439. X.LP
  440. XIt would be nice to enhance the keyboard commands to allow single
  441. Xkeypress commands, with vi-like and emacs-like bindings.
  442. BOP_BOP_A_LOO_WOP_BO_LOP_BAM_BOOM
  443.     set -- `wc -c mview.man`
  444.     if [ "$1" != "4732" ] ; then
  445.         echo "shar: mview.man unpacked with wrong size!"
  446.     fi
  447.     chmod u=r,g=r,o=r mview.man
  448. fi
  449. if [ -f "mgrabscr.c" ] ; then
  450.     echo "shar: Will not overwrite existing file mgrabscr.c"
  451. else
  452.     echo "shar: extracting mgrabscr.c (8716 characters)"
  453.     sed 's/^X//' <<'BOP_BOP_A_LOO_WOP_BO_LOP_BAM_BOOM' > mgrabscr.c
  454. X/*
  455. X * Grab an MGR bitmap from the screen
  456. X *
  457. X * @(#)mgrabscr.c    2.1    93/01/25
  458. X */
  459. X
  460. X#include <stdio.h>
  461. X#include <signal.h>
  462. X#include <string.h>
  463. X#include <sys/utsname.h>
  464. X#include "term.h"
  465. X#include "dump.h"
  466. X#include "bitmap.h"
  467. X
  468. X#ifndef lint
  469. Xstatic char *SCCS = "@(#)mgrabscr.c    2.1 93/01/25";
  470. X#endif
  471. X
  472. X#ifndef SCREEN
  473. X#define SCREEN "/dev/null"    /* UNIXpc MGR doesn't use screen dev */
  474. X#endif
  475. X
  476. X#define OPTIONS    "wrsd:D:v"
  477. X#define USAGE    "[-r|-w|-s] [-d delay|-D delay] [-v] [file]"
  478. X
  479. Xint rect = 0;                /* Sweep a rectangle */
  480. Xint window = 0;                /* Grab window contents */
  481. Xint screen = 0;                /* Grab whole screen */
  482. Xint verbose = 0;            /* Be verbose */
  483. Xint delay = 0;                /* Seconds to delay */
  484. X
  485. Xint quit = 0;
  486. Xint dodelay = 0;
  487. X
  488. Xchar menufmt[] = "|%c Rectangle|%c Window|%c Screen|-----------|%c Delay|%c No Delay|-----------|  Do Grab|  Quit|R\n|W\n|S\n||D\n|N\n||G\n|Q\n|";
  489. X
  490. Xchar *prog;
  491. X
  492. X#define abs(a)        (((a) < 0) ? -(a) : (a))
  493. X#define min(a,b)    (((a) < (b)) ? (a) : (b))
  494. X#define DEF_DELAY    10
  495. X#define MARK(n)        ((n) ? '*' : ' ')
  496. X
  497. Xextern int ckmgrterm(), m_setup(), m_ttyset(), m_ttyreset();
  498. X
  499. Xmain(argc, argv)
  500. Xint argc;
  501. Xchar  **argv;
  502. X{
  503. X    int ret;
  504. X    char *file;
  505. X    int w, h;
  506. X    int c;
  507. X    char buf[80];
  508. X    char node[9];
  509. X    struct utsname uts;
  510. X    extern int optind, opterr;
  511. X    extern char *optarg;
  512. X    extern int getopt(), atoi();
  513. X    extern int uname(), unlink();
  514. X    extern void exit();
  515. X    extern char *abspath();
  516. X    static int catch(), grabrect(), grabwindow(), grabarea(), cat();
  517. X    static void usage(), getmode();
  518. X
  519. X    prog = strrchr(argv[0], '/');
  520. X    if (prog)
  521. X        prog++;
  522. X    else
  523. X        prog = argv[0];
  524. X
  525. X    opterr = 0;
  526. X    while ((c = getopt(argc, argv, OPTIONS)) != EOF) {
  527. X        switch (c) {
  528. X        case 'r':
  529. X            rect = 1;
  530. X            break;
  531. X        case 'w':
  532. X            window = 1;
  533. X            break;
  534. X        case 's':
  535. X            screen = 1;
  536. X            break;
  537. X        case 'd':
  538. X            dodelay = 1;
  539. X            /* FALLTHROUGH */
  540. X        case 'D':
  541. X            delay = atoi(optarg);
  542. X            break;
  543. X        case 'v':
  544. X            verbose = 1;
  545. X            break;
  546. X        default:
  547. X            usage();
  548. X            break;
  549. X        }
  550. X    }
  551. X
  552. X    if (rect + window + screen > 1 || argc - optind > 1)
  553. X        usage();
  554. X
  555. X    (void) signal(SIGHUP, catch);
  556. X    (void) signal(SIGINT, catch);
  557. X    (void) signal(SIGQUIT, catch);
  558. X    (void) signal(SIGTERM, catch);
  559. X
  560. X    /* MGR setup */
  561. X
  562. X    ckmgrterm();
  563. X
  564. X    (void) m_setup(M_FLUSH);
  565. X    (void) m_ttyset();
  566. X    m_flags |= M_MODEOK;
  567. X    m_push(P_MENU|P_EVENT|P_FLAGS);
  568. X    m_setmode(M_ABS);
  569. X
  570. X    m_getinfo(G_SYSTEM);
  571. X    m_gets(buf);
  572. X    (void) sscanf(buf, "%s %d %d", node, &w, &h);
  573. X    if (uname(&uts) != -1 && strcmp(node, uts.nodename) != 0) {
  574. X        m_popall();
  575. X        (void) m_ttyreset();
  576. X        fprintf(stderr, "%s: can only grab on host %s\n", prog,
  577. X            node);
  578. X        exit(1);
  579. X    }
  580. X
  581. X    if (optind == argc) {
  582. X        /* Use stdout */
  583. X        file = tempnam(NULL, "mgs");
  584. X        if (file == NULL) {
  585. X            m_popall();
  586. X            (void) m_ttyreset();
  587. X            fprintf(stderr, "%s: unable to get temporary file name\n",
  588. X                prog);
  589. X            exit(1);
  590. X        }
  591. X    } else {
  592. X        file = abspath(argv[optind]);
  593. X        if (file == NULL) {
  594. X            m_popall();
  595. X            (void) m_ttyreset();
  596. X            fprintf(stderr, "%s: unable to convert %s to absolute path\n",
  597. X                prog, argv[optind]);
  598. X            exit(1);
  599. X        }
  600. X    }
  601. X
  602. X    /* Set mode if not specified */
  603. X
  604. X    if (rect + window + screen == 0) {
  605. X        if (verbose) {
  606. X            (void) m_ttyreset();
  607. X            fprintf(stderr, "Select grab mode with menu, and then \"Do Grab\" to grab\n");
  608. X            (void) m_ttyset();
  609. X        }
  610. X        getmode();
  611. X        if (dodelay && delay == 0)
  612. X            delay = DEF_DELAY;
  613. X    } else {
  614. X        /* Let -D or -d work if one of -r, -w, -s given */
  615. X        if (delay != 0)
  616. X            dodelay++;
  617. X    }
  618. X
  619. X    if (rect) {
  620. X        if (verbose) {
  621. X            (void) m_ttyreset();
  622. X            fprintf(stderr, "Sweep out rectangle to grab with the mouse\n");
  623. X            (void) m_ttyset();
  624. X        }
  625. X        ret = grabrect(file, w, h);
  626. X    } else if (window) {
  627. X        if (verbose) {
  628. X            (void) m_ttyreset();
  629. X            fprintf(stderr, "Click on the window to grab\n");
  630. X            (void) m_ttyset();
  631. X        }
  632. X        ret = grabwindow(file);
  633. X    } else if (screen) {
  634. X        if (verbose) {
  635. X            (void) m_ttyreset();
  636. X            fprintf(stderr, "Click to grab screen\n");
  637. X            (void) m_ttyset();
  638. X        }
  639. X        m_setevent(BUTTON_1, "\n");
  640. X        m_setevent(BUTTON_2, "\n");
  641. X        m_gets(buf);
  642. X        ret = grabarea(file, 0, 0, w, h);
  643. X    } else {
  644. X        ret = 1;
  645. X    }
  646. X
  647. X    if (verbose) {
  648. X        (void) m_ttyreset();
  649. X        fprintf(stderr, "Grab %s\n", (ret || quit) ? "aborted" : "complete");
  650. X        (void) m_ttyset();
  651. X    }
  652. X
  653. X    m_popall();
  654. X    (void) m_ttyreset();
  655. X
  656. X    if (optind == argc) {
  657. X        if (ret == 0 && quit == 0)
  658. X            ret = cat(file);
  659. X        unlink(file);
  660. X    }
  661. X
  662. X    exit(ret || quit);
  663. X}
  664. X
  665. Xstatic int
  666. Xcatch(n)
  667. Xint n;
  668. X{
  669. X    (void) signal(n, catch);
  670. X    quit++;
  671. X    return 0;
  672. X}
  673. X
  674. Xstatic void
  675. Xusage()
  676. X{
  677. X    extern void exit();
  678. X
  679. X    (void) fprintf(stderr, "Usage: %s %s\n", prog, USAGE);
  680. X    exit(1);
  681. X}
  682. X
  683. Xstatic void
  684. Xgetmode()
  685. X{
  686. X    char menubuf[sizeof(menufmt)];
  687. X    char buf[80];
  688. X
  689. X    m_push(P_MENU);
  690. X    do {
  691. X        sprintf(menubuf, menufmt, MARK(rect), MARK(window),
  692. X            MARK(screen), MARK(dodelay), MARK(!dodelay));
  693. X        m_loadmenu(1, menubuf);
  694. X        m_selectmenu(1);
  695. X        m_selectmenu2(1);
  696. X        buf[0] = '\0';
  697. X        m_gets(buf);
  698. X        switch(buf[0]) {
  699. X        case 'R':
  700. X            rect = 1;
  701. X            screen = window = 0;
  702. X            break;
  703. X        case 'W':
  704. X            window = 1;
  705. X            rect = screen = 0;
  706. X            break;
  707. X        case 'S':
  708. X            screen = 1;
  709. X            rect = window = 0;
  710. X            break;
  711. X        case 'D':
  712. X            dodelay = 1;
  713. X            break;
  714. X        case 'N':
  715. X            dodelay = 0;
  716. X            break;
  717. X        case 'Q':
  718. X            rect = screen = window = 0;
  719. X            quit = 1;
  720. X            break;
  721. X        case 'G':
  722. X            if (rect + screen + window == 0) {
  723. X                buf[0] = '\0';
  724. X                if (verbose) {
  725. X                    (void) m_ttyreset();
  726. X                    fprintf(stderr, "No grab mode; select one from the menu before grabbing\n");
  727. X                    (void) m_ttyset();
  728. X                }
  729. X            }
  730. X            break;
  731. X        default:
  732. X            break;
  733. X        }
  734. X    } while (!quit && buf[0] != 'G');
  735. X    m_pop();
  736. X}
  737. X
  738. Xstatic int
  739. Xgrabrect(file, xmax, ymax)
  740. Xchar *file;
  741. Xint xmax;
  742. Xint ymax;
  743. X{
  744. X    char buf[80];
  745. X    int sx, sy, ex, ey;
  746. X    int w, h;
  747. X    static int grabarea();
  748. X
  749. X    m_setevent(BUTTON_1, "%R\n");
  750. X    m_setevent(BUTTON_2, "%R\n");
  751. X    m_gets(buf);
  752. X    if (sscanf(buf, "%d %d %d %d", &sx, &sy, &ex, &ey) != 4)
  753. X        return 1;
  754. X
  755. X    w = abs(sx - ex);
  756. X    h = abs(sy - ey);
  757. X
  758. X    if (w == 16 && h == 16)
  759. X        return 1;
  760. X
  761. X    sx = min(sx, ex);
  762. X    sy = min(sy, ey);
  763. X
  764. X    m_push(P_MOUSE);
  765. X    if (sx > 16 || sy > 16)
  766. X        m_movemouse(0, 0);
  767. X    else 
  768. X        m_movemouse(xmax-17, ymax-17);
  769. X
  770. X    return grabarea(file, sx, sy, w, h);
  771. X}
  772. X
  773. Xstatic int
  774. Xgrabwindow(file)
  775. Xchar *file;
  776. X{
  777. X    char buf[80];
  778. X    int x, y, id, sub;
  779. X
  780. X    m_setevent(BUTTON_1, "\n");
  781. X    m_setevent(BUTTON_2, "\n");
  782. X    m_gets(buf);
  783. X    if (!quit) {
  784. X        m_getinfo(G_MOUSE);
  785. X        m_gets(buf);
  786. X        if (sscanf(buf, "%d %d", &x, &y) != 2) {
  787. X            return 1;
  788. X        }
  789. X        m_whatsat(x, y);
  790. X        m_gets(buf);
  791. X        if (sscanf(buf, "%*s %*s %d %d", &sub, &id) != 2) {
  792. X            return 1;
  793. X        }
  794. X        m_othersave(id, sub, file);
  795. X
  796. X        /* Delay until MGR has written file */
  797. X
  798. X        m_sendme("delay\n");
  799. X        m_gets(buf);
  800. X    }
  801. X    return 0;
  802. X}
  803. X
  804. Xstatic int
  805. Xgrabarea(file, x, y, wide, high)
  806. Xchar *file;
  807. Xint x;
  808. Xint y;
  809. Xint wide;
  810. Xint high;
  811. X{
  812. X    BITMAP *screen, *scratch;
  813. X    FILE *fp;
  814. X    struct b_header hdr;
  815. X    int filerow, memrow, n;
  816. X    char *bp;
  817. X    unsigned short s, *sp;
  818. X    extern int sleep();
  819. X    extern void free();
  820. X
  821. X    /* Get everything ready */
  822. X
  823. X    if ((screen = bit_open(SCREEN)) == NULL) {
  824. X        (void) m_ttyreset();
  825. X        fprintf(stderr, "%s: unable to open screen\n", prog);
  826. X        return 1;
  827. X    }
  828. X
  829. X    if ((scratch = bit_alloc(wide, high, BIT_NULL, DEPTH)) == NULL) {
  830. X        (void) m_ttyreset();
  831. X        fprintf(stderr, "%s: unable to allocate memory for bitmap\n",
  832. X            prog);
  833. X        return 1;
  834. X    }
  835. X    wide = BIT_WIDE(scratch);
  836. X    high = BIT_HIGH(scratch);
  837. X
  838. X    if ((fp = fopen(file, "w")) == NULL) {
  839. X        (void) m_ttyreset();
  840. X        fprintf(stderr, "%s: unable to open bitmap file %s\n",
  841. X            prog, file);
  842. X        return 1;
  843. X    }
  844. X
  845. X    /* Delay if requested */
  846. X
  847. X    if (dodelay) {
  848. X        if (verbose) {
  849. X            (void) m_ttyreset();
  850. X            fprintf(stderr, "Waiting %d seconds...", delay);
  851. X            fflush(stderr);
  852. X            (void) m_ttyset();
  853. X        }
  854. X        while (delay = sleep(delay))
  855. X            ;
  856. X        m_bell();
  857. X    }
  858. X
  859. X    /* Get the bitmap */
  860. X
  861. X    bit_blit(scratch, 0, 0, wide, high, BIT_SRC, screen, x, y);
  862. X
  863. X    /* Write it out */
  864. X
  865. X    B_PUTHDR8(&hdr, wide, high, DEPTH);
  866. X    filerow = B_SIZE8(wide, 1, DEPTH);
  867. X    memrow = BIT_Size(wide, 1, DEPTH);
  868. X    bp = (char *)BIT_DATA(scratch);
  869. X
  870. X    if (fwrite(&hdr, B_HSIZE, 1, fp) != 1) {
  871. X        (void) m_ttyreset();
  872. X        fprintf(stderr, "%s: unable to write bitmap header to %s\n",
  873. X            prog, file);
  874. X        return 1;
  875. X    }
  876. X
  877. X    while (high--) {
  878. X        /* On the UNIXpc we have to flip stuff around */
  879. X        for (n = memrow / 2, sp = (unsigned short *)bp; n--; sp++) {
  880. X            s = ((*sp >> 8) & 0x00ff) | ((*sp << 8) & 0xff00);
  881. X            s = ((s >> 4) & 0x0f0f) | ((s << 4) & 0xf0f0);
  882. X            s = ((s >> 2) & 0x3333) | ((s << 2) & 0xcccc);
  883. X            *sp = ((s >> 1) & 0x5555) | ((s << 1) & 0xaaaa);
  884. X        }
  885. X        if (fwrite(bp, 1, filerow, fp) != filerow) {
  886. X            (void) m_ttyreset();
  887. X            fprintf(stderr, "%s: error writing bitmap file %s\n",
  888. X                prog, file);
  889. X            return 1;
  890. X        }
  891. X        bp += memrow;
  892. X    }
  893. X
  894. X    fclose(fp);
  895. X    free(scratch);
  896. X
  897. X    return 0;
  898. X}
  899. X
  900. Xstatic int
  901. Xcat(file)
  902. Xchar *file;
  903. X{
  904. X    FILE *fp;
  905. X    char buf[BUFSIZ];
  906. X    int n;
  907. X
  908. X    if ((fp = fopen(file, "r")) != NULL) {
  909. X        do {
  910. X            n = fread(buf, 1, BUFSIZ, fp);
  911. X            fwrite(buf, 1, n, stdout);
  912. X        } while (!feof(fp) && !ferror(fp));
  913. X        fclose(fp);
  914. X    }
  915. X
  916. X    return !fp || ferror(fp);
  917. X}
  918. BOP_BOP_A_LOO_WOP_BO_LOP_BAM_BOOM
  919.     set -- `wc -c mgrabscr.c`
  920.     if [ "$1" != "8716" ] ; then
  921.         echo "shar: mgrabscr.c unpacked with wrong size!"
  922.     fi
  923.     chmod u=r,g=r,o=r mgrabscr.c
  924. fi
  925. if [ -f "mview.c" ] ; then
  926.     echo "shar: Will not overwrite existing file mview.c"
  927. else
  928.     echo "shar: extracting mview.c (12808 characters)"
  929.     sed 's/^X//' <<'BOP_BOP_A_LOO_WOP_BO_LOP_BAM_BOOM' > mview.c
  930. X/*
  931. X * Bitmap viewer for MGR
  932. X *
  933. X * @(#)mview.c    2.1    93/01/25
  934. X */
  935. X
  936. X#include <stdio.h>
  937. X#include <signal.h>
  938. X#include <string.h>
  939. X#include <sys/utsname.h>
  940. X#include "term.h"
  941. X#include "dump.h"
  942. X
  943. X#ifndef lint
  944. Xstatic char *SCCS = "@(#)mview.c    2.1 93/01/25";
  945. X#endif
  946. X
  947. X#define SCRATCH    1
  948. X#define    MAINWIN    0
  949. X
  950. X#define OPTIONS    "x:y:h:w:frvs:-c"
  951. X#define USAGE    "[-x n] [-y n] [-h n] [-w n] [-s secs] [-frvc] [file] ..."
  952. X
  953. Xchar *prog;
  954. X
  955. Xint xpos = -1, ypos = -1;        /* User set (x,y) position */
  956. Xint maxh = -1, maxw = -1;        /* Max height and width */
  957. Xint slideshow = -1;            /* Seconds to sleep in slideshow */
  958. Xint force = 0;            /* Force holding (x,y) pos */
  959. Xint reverse = 0;            /* Reverse bitmaps */
  960. Xint verbose = 0;            /* Be verbose about bitmaps */
  961. Xint cycle = 0;            /* Cycle around file list */
  962. X
  963. Xint quit = 0;            /* Exit indicator */
  964. Xint win;                /* Alternate window id */
  965. Xint direction;            /* Direction indicator */
  966. Xint remote = 0;            /* MGR is on remote host */
  967. X
  968. X#define MENU_STAT    0
  969. X#define MENU_FWD    1
  970. X#define MENU_BACK    2
  971. X
  972. Xstruct menu_item {
  973. X    int show;            /* Show menu item */
  974. X    int dir;            /* "Direction" of item */
  975. X    char *item;            /* Menu item */
  976. X    char *action;        /* Menu item action */
  977. X} menu[] = {
  978. X    { 0,    MENU_FWD,    "down half",    "D\r" },
  979. X    { 0,    MENU_FWD,    "     full",    "F\r" },
  980. X    { 0,    MENU_FWD,    "right",    "R\r" },
  981. X    { 0,    MENU_FWD,    "next",        "N\r" },
  982. X    { 0,    MENU_BACK,    "up half",    "U\r" },
  983. X    { 0,    MENU_BACK,    "   full",    "B\r" },
  984. X    { 0,    MENU_BACK,    "left",        "L\r" },
  985. X    { 0,    MENU_BACK,    "prev",        "P\r" },
  986. X    { 1,    MENU_STAT,    "reverse",    "I\r" },
  987. X    { 1,    MENU_STAT,    "quit",        "Q\r" },
  988. X};
  989. X
  990. X#define MENU_HALFD    0
  991. X#define MENU_FULLD    1
  992. X#define MENU_RIGHT    2
  993. X#define MENU_NEXT    3
  994. X#define MENU_HALFU    4
  995. X#define MENU_FULLU    5
  996. X#define MENU_LEFT    6
  997. X#define MENU_PREV    7
  998. X#define MENU_REVERSE    8
  999. X#define MENU_QUIT    9
  1000. X
  1001. Xextern int ckmgrterm(), m_setup(), m_ttyset(), m_ttyreset();
  1002. X
  1003. Xmain(argc, argv)
  1004. Xint argc;
  1005. Xchar  **argv;
  1006. X{
  1007. X    int n, c;
  1008. X    char *file, *p;
  1009. X    int x, y, w, h, bw;
  1010. X    int ret;
  1011. X    char buf[80];
  1012. X    char node[9];
  1013. X    struct utsname uts;
  1014. X    extern char *optarg;
  1015. X    extern int optind, opterr;
  1016. X    extern int getopt(), atoi(), uname();
  1017. X    extern long strtol(), time();
  1018. X    extern void srand48(), exit();
  1019. X    extern char *abspath();
  1020. X    static int catch(), timer(), display();
  1021. X    static void usage();
  1022. X
  1023. X    prog = strrchr(argv[0], '/');
  1024. X    if (prog)
  1025. X        prog++;
  1026. X    else
  1027. X        prog = argv[0];
  1028. X
  1029. X    opterr = 0;
  1030. X    while ((c = getopt(argc, argv, OPTIONS)) != EOF) {
  1031. X        switch (c) {
  1032. X        case 'x':
  1033. X            xpos = (int) strtol(optarg, &p, 10);
  1034. X            if (p == optarg || *p || xpos < 0)
  1035. X                usage();
  1036. X            break;
  1037. X        case 'y':
  1038. X            ypos = (int) strtol(optarg, &p, 10);
  1039. X            if (p == optarg || *p || ypos < 0)
  1040. X                usage();
  1041. X            break;
  1042. X        case 'h':
  1043. X            maxh = (int) strtol(optarg, &p, 10);
  1044. X            if (p == optarg || *p || maxh < 0)
  1045. X                usage();
  1046. X            break;
  1047. X        case 'w':
  1048. X            maxw = (int) strtol(optarg, &p, 10);
  1049. X            if (p == optarg || *p || maxw < 0)
  1050. X                usage();
  1051. X            break;
  1052. X        case 's':
  1053. X            slideshow = (int) strtol(optarg, &p, 10);
  1054. X            if (p == optarg || *p  || slideshow < 0)
  1055. X                usage();
  1056. X            break;
  1057. X        case 'f':
  1058. X            force++;
  1059. X            break;
  1060. X        case 'r':
  1061. X            reverse++;
  1062. X            break;
  1063. X        case 'v':
  1064. X            verbose++;
  1065. X            break;
  1066. X        case 'c':
  1067. X            cycle++;
  1068. X            break;
  1069. X        default:
  1070. X            usage();
  1071. X            break;
  1072. X        }
  1073. X    }
  1074. X
  1075. X    (void) signal(SIGHUP, catch);
  1076. X    (void) signal(SIGINT, catch);
  1077. X    (void) signal(SIGQUIT, catch);
  1078. X    (void) signal(SIGTERM, catch);
  1079. X    (void) signal(SIGALRM, timer);
  1080. X
  1081. X    srand48(time((long *)0));
  1082. X
  1083. X    /* MGR setup */
  1084. X
  1085. X    ckmgrterm();
  1086. X
  1087. X    (void) m_setup(M_FLUSH);
  1088. X    (void) m_ttyset();
  1089. X    m_flags |= M_MODEOK;
  1090. X    m_push(P_MENU|P_EVENT|P_FLAGS);
  1091. X    m_setmode(M_ABS);
  1092. X
  1093. X    /*
  1094. X     * Set up the alternate window, overlapping current window.
  1095. X     */
  1096. X
  1097. X    m_getinfo(G_COORDS);
  1098. X    m_gets(buf);
  1099. X    (void) sscanf(buf, "%d %d %d %d", &x, &y, &w, &h);
  1100. X    m_getinfo(G_SYSTEM);
  1101. X    m_gets(buf);
  1102. X    (void) sscanf(buf, "%s %*d %*d %d", node, &bw);
  1103. X    if (uname(&uts) != -1 && strcmp(node, uts.nodename) != 0)
  1104. X        remote++;
  1105. X    h += 2 * bw;
  1106. X    w += 2 * bw;
  1107. X    m_newwin(x, y, w, h);
  1108. X    m_gets(buf);
  1109. X    if (buf[0] == '\n') {
  1110. X        /* Couldn't create window; complain */
  1111. X        (void) m_ttyreset();
  1112. X        (void) fprintf(stderr, "unable to create new window\n");
  1113. X        m_popall();
  1114. X        exit(1);
  1115. X    }
  1116. X    win = atoi(buf);
  1117. X    m_selectwin(win);
  1118. X    m_setmode(M_ABS);
  1119. X    m_setcursor(CS_INVIS);
  1120. X    m_setevent(RESHAPE, "S\r");
  1121. X    m_setevent(MOVE, "M\r");
  1122. X    m_setevent(REDRAW, "W\r");
  1123. X    m_setevent(DESTROY, "Q\r");
  1124. X
  1125. X    /* Display each bitmap */
  1126. X
  1127. X    n = optind;
  1128. X    if (n == argc) {
  1129. X        /* Use stdin */
  1130. X        cycle = 0;
  1131. X        slideshow = 0;
  1132. X        display("<stdin>", NULL);
  1133. X    } else {
  1134. X        while (n < argc && !quit) {
  1135. X
  1136. X            if (argc - optind <= 1) {
  1137. X                menu[MENU_NEXT].show = 0;
  1138. X                menu[MENU_PREV].show = 0;
  1139. X            } else if (!cycle) {
  1140. X                menu[MENU_PREV].show = (n != optind);
  1141. X                menu[MENU_NEXT].show = (n < argc - 1);
  1142. X            } else {
  1143. X                menu[MENU_NEXT].show = 1;
  1144. X                menu[MENU_PREV].show = 1;
  1145. X            }
  1146. X
  1147. X            /* Make file name absolute if it's not */
  1148. X
  1149. X            if (!remote)
  1150. X                file = abspath(argv[n]);
  1151. X            else
  1152. X                file = argv[n];
  1153. X            if (file) {
  1154. X                ret = display(argv[n], file);
  1155. X            } else {
  1156. X                (void) m_ttyreset();
  1157. X                m_selectwin(MAINWIN);
  1158. X                (void) fprintf(stderr, "unable to get cwd for \"%s\"\n",
  1159. X                    argv[n]);
  1160. X                m_selectwin(win);
  1161. X                (void) m_ttyset();
  1162. X                ret = 1;
  1163. X            }
  1164. X            if (ret) {
  1165. X                n += ret;
  1166. X                if (n < optind)
  1167. X                    n = cycle ? argc - 1 : optind;
  1168. X                else if (cycle && n >= argc)
  1169. X                    n = optind;
  1170. X            } else {
  1171. X                quit = 1;
  1172. X            }
  1173. X        }
  1174. X    }
  1175. X
  1176. X    m_clearevent(DESTROY);
  1177. X    m_selectwin(MAINWIN);
  1178. X    m_destroywin(win);
  1179. X    m_popall();
  1180. X    (void) m_ttyreset();
  1181. X
  1182. X    exit(0);
  1183. X}
  1184. X
  1185. Xstatic int
  1186. Xcatch(n)
  1187. Xint n;
  1188. X{
  1189. X    (void) signal(n, catch);
  1190. X    quit++;
  1191. X    return 0;
  1192. X}
  1193. X
  1194. Xstatic int
  1195. Xtimer(n)
  1196. Xint n;
  1197. X{
  1198. X    (void) signal(n, timer);
  1199. X    return 0;
  1200. X}
  1201. X
  1202. Xstatic void
  1203. Xusage()
  1204. X{
  1205. X    extern void exit();
  1206. X
  1207. X    (void) fprintf(stderr, "Usage: %s %s\n", prog, USAGE);
  1208. X    exit(1);
  1209. X}
  1210. X
  1211. X/*
  1212. X * Display a bitmap, waiting for input.  If input requests local motion,
  1213. X * redisplay.
  1214. X */
  1215. X
  1216. Xstatic int
  1217. Xdisplay(arg, file)
  1218. Xchar  *arg;
  1219. Xchar  *file;
  1220. X{
  1221. X    char buf[80];
  1222. X    int ch;
  1223. X    int bm_x, bm_y, bm_w, bm_h, w, h;
  1224. X    int redisplay;
  1225. X    int ret = 0;
  1226. X    static int adjust();
  1227. X    static void loadmap(), makemenu(), placewindow();
  1228. X    extern int alarm(), toupper();
  1229. X
  1230. X    if (remote || !file) {
  1231. X        loadmap(SCRATCH, file, buf);
  1232. X    } else {
  1233. X        m_bitfromfile(SCRATCH, file);
  1234. X        m_gets(buf);
  1235. X    }
  1236. X    if (sscanf(buf, "%d %d", &w, &h) != 2) {
  1237. X        /* Couldn't read bitmap */
  1238. X        (void) m_ttyreset();
  1239. X        m_selectwin(MAINWIN);
  1240. X        (void) fprintf(stderr, "unable to load bitmap %s\n", file ? file : "<stdin>");
  1241. X        m_selectwin(win);
  1242. X        (void) m_ttyset();
  1243. X        ret = 1;
  1244. X    } else {
  1245. X        /* Set up to display bitmap*/
  1246. X
  1247. X        m_clear();
  1248. X        bm_w = w;
  1249. X        bm_h = h;
  1250. X        bm_x = bm_y = 0;
  1251. X        redisplay = 1;
  1252. X        placewindow(arg, &w, &h);
  1253. X        m_func(reverse ? B_COPYINVERTED : B_COPY);
  1254. X
  1255. X        /* Display bitmap, and handle local motion */
  1256. X
  1257. X        while (redisplay && !quit) {
  1258. X            m_bitcopyto(0, 0, w, h, bm_x, bm_y, MAINWIN, SCRATCH);
  1259. X
  1260. X            /* Set up menu */
  1261. X
  1262. X            menu[MENU_LEFT].show = bm_x;
  1263. X            menu[MENU_HALFU].show = menu[MENU_FULLU].show = bm_y;
  1264. X            menu[MENU_RIGHT].show = (bm_x + w < bm_w);
  1265. X            menu[MENU_HALFD].show =
  1266. X                menu[MENU_FULLD].show = (bm_y + h < bm_h); 
  1267. X            makemenu();
  1268. X
  1269. X            /* Get input */
  1270. X
  1271. X            buf[0] = '\0';
  1272. X            if (slideshow)
  1273. X                (void) alarm(slideshow);
  1274. X            m_gets(buf);
  1275. X            if (slideshow)
  1276. X                (void) alarm(0);
  1277. X
  1278. X            /* Act on local motion, or next/prev */
  1279. X
  1280. X            ch = toupper((int)buf[0]);
  1281. X            switch(ch) {
  1282. X            case 'W':
  1283. X                /* REDRAW event */
  1284. X                break;
  1285. X            case 'S':
  1286. X            case 'M':
  1287. X                /* RESHAPE or MOVE (minor cheat) event */
  1288. X                m_getinfo(G_COORDS);
  1289. X                m_gets(buf);
  1290. X                (void) sscanf(buf, "%d %d %d %d", &xpos,
  1291. X                          &ypos, &w, &h);
  1292. X                if (w > bm_w || h > bm_h) {
  1293. X                    if (w > bm_w)
  1294. X                        w = bm_w;
  1295. X                    if (h > bm_h)
  1296. X                        h = bm_h;
  1297. X                    m_shapewindow(xpos, ypos, w, h);
  1298. X                }
  1299. X                break;
  1300. X            case 'F':
  1301. X            case '\006':    /* ^F */
  1302. X            case '\026':    /* ^V */
  1303. X                /* Down full */
  1304. X                direction = MENU_FWD;
  1305. X                bm_y = adjust(bm_y, h, h, bm_h);
  1306. X                break;
  1307. X            case 'D':
  1308. X            case '\004':    /* ^D */
  1309. X                /* Down half */
  1310. X                direction = MENU_FWD;
  1311. X                bm_y = adjust(bm_y, h / 2, h, bm_h);
  1312. X                break;
  1313. X            case 'B':
  1314. X            case '\002':    /* ^B */
  1315. X                /* Up full */
  1316. X                direction = MENU_BACK;
  1317. X                bm_y = adjust(bm_y, -h , h, 0);
  1318. X                break;
  1319. X            case 'U':
  1320. X            case '\025':    /* ^U */
  1321. X                direction = MENU_BACK;
  1322. X                bm_y = adjust(bm_y, -h / 2, h, 0);
  1323. X                break;
  1324. X            case 'R':
  1325. X            case '>':
  1326. X                direction = MENU_FWD;
  1327. X                bm_x = adjust(bm_x, w / 2, w, bm_w);
  1328. X                break;
  1329. X            case 'L':
  1330. X            case '<':
  1331. X                direction = MENU_BACK;
  1332. X                bm_x = adjust(bm_x, -w / 2, w, 0);
  1333. X                break;
  1334. X            case 'I':
  1335. X                reverse = !reverse;
  1336. X                m_func(reverse ? B_COPYINVERTED : B_COPY);
  1337. X                break;
  1338. X            case 'P':
  1339. X                direction = MENU_BACK;
  1340. X                redisplay = 0;
  1341. X                ret = -1;
  1342. X                break;
  1343. X            case 'Q':
  1344. X                redisplay = 0;
  1345. X                ret = 0;
  1346. X                break;
  1347. X            default:
  1348. X                direction = MENU_FWD;
  1349. X                redisplay = 0;
  1350. X                ret = 1;
  1351. X                break;
  1352. X            }
  1353. X        }
  1354. X    }
  1355. X    m_bitdestroy(SCRATCH);
  1356. X
  1357. X    return ret;
  1358. X}
  1359. X
  1360. X/*
  1361. X * Load a bitmap from a file, complete with all the ugliness inherent in
  1362. X * the multiple formats.
  1363. X */
  1364. X
  1365. Xstatic void
  1366. Xloadmap(to, file, buf)
  1367. Xint  to;
  1368. Xchar   *file;
  1369. Xchar   *buf;
  1370. X{
  1371. X    int wide, high, depth, size, bw, pad, n, ch;
  1372. X    FILE *fp;
  1373. X    union {
  1374. X        struct b_header hdr;
  1375. X        struct old_b_header oldhdr;
  1376. X    } h;
  1377. X
  1378. X    *buf = '\0';
  1379. X    if (file)
  1380. X        fp = fopen(file, "r");
  1381. X    else
  1382. X        fp = stdin;
  1383. X
  1384. X    if (!fp)
  1385. X        return;
  1386. X
  1387. X    /* Get the header */
  1388. X
  1389. X    if (fread(h.hdr.magic, sizeof(h.hdr.magic), 1, fp) != 1)
  1390. X        return;
  1391. X    if (B_ISHDR8(&h.hdr)) {
  1392. X        if (fread(&h.hdr.h_wide, B_HSIZE - sizeof(h.hdr.magic), 1, fp) != 1)
  1393. X            return;
  1394. X        B_GETHDR8(&h.hdr, wide, high, depth);
  1395. X        size = B_SIZE8(wide, high, depth);
  1396. X        bw = wide / 8 + ((wide % 8) ? 1 : 0);
  1397. X        pad = (bw % 2) ? 1 : 0;
  1398. X    } else if (B_ISHDR(&h.oldhdr)) {
  1399. X        if (fread(&h.hdr.h_wide, B_OHSIZE - sizeof(h.oldhdr.magic), 1, fp) != 1)
  1400. X            return;
  1401. X        B_GETOLDHDR(&h.oldhdr, wide, high);
  1402. X        size = B_SIZE16(wide, high, 1);
  1403. X        bw = wide / 8 + ((wide % 8) ? 1 : 0);
  1404. X        bw += (bw % 2) ? 1 : 0;
  1405. X        pad = 0;
  1406. X    } else {
  1407. X        return;
  1408. X    }
  1409. X
  1410. X    /*
  1411. X     * Loop through and read; we'll do it byte at a time to simplify
  1412. X     * our work converting old style bitmaps to new.
  1413. X     */
  1414. X
  1415. X    sprintf(buf, "%d %d", wide, high);
  1416. X    m_bitldto(wide, high, 0, 0, to, size + (high * pad));
  1417. X    while (high--) {
  1418. X        for (n = 0; n < bw; n++) {
  1419. X            ch = getc(fp);
  1420. X            putc(ch, m_termout);
  1421. X        }
  1422. X        if (pad)
  1423. X            putc('\0', m_termout);
  1424. X        m_flush();
  1425. X    }
  1426. X}
  1427. X
  1428. X/*
  1429. X * Place the window on the screen, possibly adjusting for the size of the
  1430. X * bitmap.
  1431. X */
  1432. X
  1433. Xstatic void
  1434. Xplacewindow(arg, wp, hp)
  1435. Xchar *arg;
  1436. Xint *wp, *hp;
  1437. X{
  1438. X    int x, y, maxx, maxy, w, h;
  1439. X    char buf[80];
  1440. X    static int dispw, disph, border;
  1441. X    extern double drand48();
  1442. X
  1443. X    /* Get display information */
  1444. X
  1445. X    if (!dispw) {
  1446. X        m_getinfo(G_SYSTEM);
  1447. X        m_gets(buf);
  1448. X        (void) sscanf(buf, "%*s %d %d %d", &dispw, &disph, &border);
  1449. X        border *= 2;
  1450. X    }
  1451. X
  1452. X    /*
  1453. X     * Place the window.  First find the maximum (x,y) pos that will
  1454. X     * fit the bitmap.
  1455. X     */
  1456. X
  1457. X    w = (maxw >= 0 && *wp > maxw) ? maxw : *wp;
  1458. X    maxx = dispw - w - border;
  1459. X    if (maxx < 0)
  1460. X        maxx = 0;
  1461. X    h = (maxh >= 0 && *hp > maxh) ? maxh : *hp;
  1462. X    maxy = disph - h - border;
  1463. X    if (maxy < 0)
  1464. X        maxy = 0;
  1465. X
  1466. X    /*
  1467. X     * If we haven't been given a positon, pick one.  If we've got
  1468. X     * one, but the bitmap won't fit, adjust unless the user has set
  1469. X     * -f.
  1470. X     */
  1471. X
  1472. X    if (xpos < 0) {
  1473. X        xpos = drand48() * (maxx + 1);
  1474. X    } else if (xpos > maxx && !force) {
  1475. X        xpos = maxx;
  1476. X    }
  1477. X    if (ypos < 0) {
  1478. X        ypos = drand48() * (maxy + 1);
  1479. X    } else if (ypos > maxy && !force) {
  1480. X        ypos = maxy;
  1481. X    }
  1482. X
  1483. X    /* Adjust window size */
  1484. X
  1485. X    m_shapewindow(xpos, ypos, w + border, h + border);
  1486. X    m_getinfo(G_COORDS);
  1487. X    m_gets(buf);
  1488. X    (void) sscanf(buf, "%d %d %d %d", &x, &y, &w, &h);
  1489. X
  1490. X    if (verbose) {
  1491. X        (void) m_ttyreset();
  1492. X        m_selectwin(MAINWIN);
  1493. X        (void) printf("%s: %dx%d at (%d, %d)", arg, *wp, *hp, xpos, ypos);
  1494. X        if (w != *wp || h != *hp)
  1495. X            (void) printf(", cropped to %dx%d", w, h);
  1496. X        putchar('\n');
  1497. X        m_selectwin(win);
  1498. X        (void) m_ttyset();
  1499. X    }
  1500. X
  1501. X    *wp = w;
  1502. X    *hp = h;
  1503. X}
  1504. X
  1505. X/*
  1506. X * Calculate new position for local motions, starting at "from",
  1507. X * adjusting by "by", with a window width or height of "use", not to
  1508. X * exceed "limit". (Whew!)
  1509. X */
  1510. X
  1511. Xstatic int
  1512. Xadjust(from, by, use, limit)
  1513. Xint from;
  1514. Xint by;
  1515. Xint use;
  1516. Xint limit;
  1517. X{
  1518. X    if (by > 0) {
  1519. X        if (from + by + use > limit)
  1520. X            from = limit - use;
  1521. X        else
  1522. X            from += by;
  1523. X    } else {
  1524. X        if (from + by < limit)
  1525. X            from = limit;
  1526. X        else
  1527. X            from += by;
  1528. X    }
  1529. X    return from;
  1530. X}
  1531. X
  1532. X/*
  1533. X * Construct a menu string based on what in the menu[] array says it
  1534. X * should be shown.
  1535. X */
  1536. X
  1537. Xstatic void
  1538. Xmakemenu()
  1539. X{
  1540. X    char mbuf[512], *p;
  1541. X    int order[3];
  1542. X    int i, n;
  1543. X
  1544. X    if (direction == MENU_FWD) {
  1545. X        order[0] = MENU_FWD;
  1546. X        order[1] = MENU_BACK;
  1547. X    } else {
  1548. X        order[0] = MENU_BACK;
  1549. X        order[1] = MENU_FWD;
  1550. X    }
  1551. X    order[2] = MENU_STAT;
  1552. X
  1553. X    p = mbuf;
  1554. X    for (i = 0; i < sizeof(order) / sizeof(int); i++) {
  1555. X        for (n = 0; n <= MENU_QUIT; n++) {
  1556. X            if (menu[n].show && menu[n].dir == order[i])
  1557. X                p += sprintf(p, "%c%s", M_DELIM, menu[n].item);
  1558. X        }
  1559. X    }
  1560. X    for (i = 0; i < sizeof(order) / sizeof(int); i++) {
  1561. X        for (n = 0; n <= MENU_QUIT; n++) {
  1562. X            if (menu[n].show && menu[n].dir == order[i])
  1563. X                p += sprintf(p, "%c%s", M_DELIM,
  1564. X                         menu[n].action);
  1565. X        }
  1566. X    }
  1567. X    *p++ = M_DELIM;
  1568. X    *p++ = '\0';
  1569. X
  1570. X    m_loadmenu(1, mbuf);
  1571. X    m_selectmenu(1);
  1572. X    m_selectmenu2(1);
  1573. X}
  1574. BOP_BOP_A_LOO_WOP_BO_LOP_BAM_BOOM
  1575.     set -- `wc -c mview.c`
  1576.     if [ "$1" != "12808" ] ; then
  1577.         echo "shar: mview.c unpacked with wrong size!"
  1578.     fi
  1579.     chmod u=r,g=r,o=r mview.c
  1580. fi
  1581. if [ -f "abspath.c" ] ; then
  1582.     echo "shar: Will not overwrite existing file abspath.c"
  1583. else
  1584.     echo "shar: extracting abspath.c (511 characters)"
  1585.     sed 's/^X//' <<'BOP_BOP_A_LOO_WOP_BO_LOP_BAM_BOOM' > abspath.c
  1586. X/*
  1587. X * Convert to absolute pathname; may return pointer to static buffer
  1588. X *
  1589. X * @(#)abspath.c    2.1    93/01/25
  1590. X */
  1591. X
  1592. X#ifndef lint
  1593. Xstatic char *SCCS = "@(#)abspath.c    2.1 93/01/25";
  1594. X#endif
  1595. X
  1596. X#include <stdio.h>
  1597. X
  1598. Xchar *
  1599. Xabspath(file)
  1600. Xchar  *file;
  1601. X{
  1602. X    static char absfile[1024];
  1603. X    static char cwd[512];
  1604. X    extern char *getcwd();
  1605. X
  1606. X    if (*file != '/') {
  1607. X        if (cwd[0] == '\0') {
  1608. X            if (getcwd(cwd, sizeof(cwd)) == NULL) {
  1609. X                return NULL;
  1610. X            }
  1611. X        }
  1612. X        (void) sprintf(absfile, "%s/%s", cwd, file);
  1613. X        file = absfile;
  1614. X    }
  1615. X    return file;
  1616. X}
  1617. BOP_BOP_A_LOO_WOP_BO_LOP_BAM_BOOM
  1618.     set -- `wc -c abspath.c`
  1619.     if [ "$1" != "511" ] ; then
  1620.         echo "shar: abspath.c unpacked with wrong size!"
  1621.     fi
  1622.     chmod u=r,g=r,o=r abspath.c
  1623. fi
  1624. if [ -f "mime.overview" ] ; then
  1625.     echo "shar: Will not overwrite existing file mime.overview"
  1626. else
  1627.     echo "shar: extracting mime.overview (4136 characters)"
  1628.     sed 's/^X//' <<'BOP_BOP_A_LOO_WOP_BO_LOP_BAM_BOOM' > mime.overview
  1629. X
  1630. X
  1631. X                            MIME Overview
  1632. X
  1633. X                by Mark Grand <mark@premenos.sf.ca.us>
  1634. X
  1635. XInternet e-mail allows mail messages to be exchanged between users of
  1636. Xcomputers around the world and occasionally beyond... to space
  1637. Xshuttles.  One of the main reasons that Internet e-mail has achieved
  1638. Xsuch wide use is because it provides a standard mechanism for messages
  1639. Xto be exchanged between over 1,000,000 computers connected to the
  1640. XInternet.
  1641. X
  1642. XThe standards that are the basis for Internet e-mail were established
  1643. Xin 1982.  Though they were state of the art in 1982, in the
  1644. Xintervening years they have begun to show their age.  The 1982
  1645. Xstandards allow for mail messages that contain a single human readable
  1646. Xmessage with the restrictions that:
  1647. X
  1648. X    * the message contains only ASCII characters.
  1649. X
  1650. X    * the message contains no lines longer than 1000 characters.
  1651. X
  1652. X    * the message does not exceed a certain length
  1653. X
  1654. XThe 1982 standards do not allow EDI to be transmitted through Internet
  1655. Xmail, since EDI messages can violate all of these restrictions.  There
  1656. Xare a number of other types of messages and services that have are
  1657. Xsupported by other mail standards that have been designed more
  1658. Xrecently.  In June of 1992 a new Internet mail standard was approved.
  1659. XThis new standard is called MIME.
  1660. X
  1661. XMIME is an acronym for Multipurpose Internet Mail Extensions.  It
  1662. Xbuilds on the older standard by standardizing additional fields for
  1663. Xmail message headers that describe new types of content and
  1664. Xorganization for messages.
  1665. X
  1666. XMIME allows mail messages to contain:
  1667. X
  1668. X    * Multiple objects in a single message.
  1669. X
  1670. X    * Text having unlimited line length or overall length.
  1671. X
  1672. X    * Character sets other than ASCII.
  1673. X
  1674. X    * Multi-font messages.
  1675. X
  1676. X    * Binary or application specific files.
  1677. X
  1678. X    * Images, Audio, Video and multi-media messages.
  1679. X
  1680. XMIME defines the following new header fields:
  1681. X
  1682. X1.  A MIME-Version header field, which uses a version number to
  1683. X    declare that a message conforms to the MIME standard.
  1684. X
  1685. X2.  A Content-Type header field, which can be used to specify the type
  1686. X    and subtype of data in the body of a message and to fully specify
  1687. X    the encoding of such data.
  1688. X
  1689. X    2.a.  A Text Content-Type value, which can be used to represent
  1690. X          textual information in a number of character sets and
  1691. X          formatted text description languages in a standardized
  1692. X          manner.
  1693. X
  1694. X    2.b.  A Multipart Content-Type value, which can be used to combine
  1695. X          several body parts, possibly of differing types of data,
  1696. X          into a single message.
  1697. X
  1698. X    2.c.  An Application Content-Type value, which can be used to
  1699. X          transmit application data or binary data.
  1700. X
  1701. X    2.d.  A Message Content-Type value, for encapsulating a mail
  1702. X          message.
  1703. X
  1704. X    2.e.  An Image Content-Type value, for transmitting still image
  1705. X          (picture) data.
  1706. X
  1707. X    2.f.  An Audio Content-Type value, for transmitting audio or voice
  1708. X          data.
  1709. X
  1710. X    2.g.  A Video Content-Type value, for transmitting video or moving
  1711. X          image data, possibly with audio as part of the composite
  1712. X          video data format.
  1713. X
  1714. X3.  A Content-Transfer-Encoding header field, that specifies how the
  1715. X    data is encoded to allow it to pass through mail transports having
  1716. X    data or character set limitations.
  1717. X
  1718. X4.  Two optional header fields that can be used to further describe
  1719. X    the data in a message body, the Content-ID and Content-Description
  1720. X    header fields.
  1721. X
  1722. XMIME is an extensible mechanism.  It is expected that the set of
  1723. Xcontent-type/subtype pairs and their associated parameters will grow
  1724. Xwith time.  Several other MIME fields, such as character set names,
  1725. Xare likely to have new values defined over time.  To ensure that the
  1726. Xset of such values develops in an orderly, and public manner, MIME
  1727. Xdefines a registration process which uses the Internet Assigned
  1728. XNumbers Authority (IANA) as a central registry for such values.
  1729. X
  1730. XTo promote interoperability between implementations, the MIME standard
  1731. Xdocument specifies a minimal subset of the above mechanisms that are
  1732. Xrequired for an implementation to claim to conform to the MIME
  1733. Xstandard.
  1734. BOP_BOP_A_LOO_WOP_BO_LOP_BAM_BOOM
  1735.     set -- `wc -c mime.overview`
  1736.     if [ "$1" != "4136" ] ; then
  1737.         echo "shar: mime.overview unpacked with wrong size!"
  1738.     fi
  1739.     chmod u=rw,g=rw,o=rw mime.overview
  1740. fi
  1741. if [ -f "mhn-mgr" ] ; then
  1742.     echo "shar: Will not overwrite existing file mhn-mgr"
  1743. else
  1744.     echo "shar: extracting mhn-mgr (566 characters)"
  1745.     sed 's/^X//' <<'BOP_BOP_A_LOO_WOP_BO_LOP_BAM_BOOM' > mhn-mgr
  1746. Xmhn-compose-image/X-mgr:    mgrabscr
  1747. Xmhn-compose-image/X-pbm:    mgrabscr | mgrtopbm
  1748. Xmhn-compose-image/gif:        mgrabscr | mgrtopbm | ppmtogif
  1749. Xmhn-show-image/X-mgr:    mview -v %F
  1750. Xmhn-show-image/X-pbm:    pbmtomgr %F | mview -v
  1751. Xmhn-show-image/X-pgm:    pgmtopbm %F | pbmtomgr | mview -v
  1752. Xmhn-show-image/X-ppm:    ppmtopgm %F | pgmtopbm | pbmtomgr | mview -v
  1753. Xmhn-show-image/gif:    giftoppm %F | ppmtopgm | pgmtopbm | pbmtomgr | mview -v
  1754. Xmhn-show-image/jpeg:    djpeg -pnm -grayscale %F | pgmtopbm | pbmtomgr | mview -v
  1755. Xmhn-show-text/plain:    less %F
  1756. Xmhn-show-text/richtext:    richtext -o %F | less
  1757. BOP_BOP_A_LOO_WOP_BO_LOP_BAM_BOOM
  1758.     set -- `wc -c mhn-mgr`
  1759.     if [ "$1" != "566" ] ; then
  1760.         echo "shar: mhn-mgr unpacked with wrong size!"
  1761.     fi
  1762.     chmod u=rw,g=r,o=r mhn-mgr
  1763. fi
  1764. if [ -f "mailcap" ] ; then
  1765.     echo "shar: Will not overwrite existing file mailcap"
  1766. else
  1767.     echo "shar: extracting mailcap (995 characters)"
  1768.     sed 's/^X//' <<'BOP_BOP_A_LOO_WOP_BO_LOP_BAM_BOOM' > mailcap
  1769. X# Untested mailcaps for images on MGR using mview and mgrabscr, in
  1770. X# conjuction with the PBM and djpeg tools.
  1771. X# There's no composition rules for JPEG, since you probably would want
  1772. X# to do that manually, and no composition rules for PGM or PPM, since
  1773. X# anything that could understand them should work with PBM as well.
  1774. Ximage/gif; giftoppm %s | ppmtopgm | pgmtopbm | pbmtomgr | mview -v; \
  1775. X    needsterminal; compose="mgrabscr -v | mgrtopbm | ppmtogif > %s"; \
  1776. X    description="An MGR screen image in GIF format";
  1777. Ximage/jpeg; djpeg -pnm -grayscale %s | pgmtopbm | pbmtomgr | mview -v; \
  1778. X    needsterminal;
  1779. Ximage/x-mgr; mview %s; needsterminal; compose="mgrabscr -v %s"; \
  1780. X    description="An MGR screen image in MGR format";
  1781. Ximage/X-pbm; pbmtomgr %s | mview -v; needsterminal; \
  1782. X    compose="mgrabscr -v | mgrtopbm > %s"; \
  1783. X    description="An MGR screen image in PBM format";
  1784. Ximage/X-pgm; pgmtopbm %s | pbmtomgr | mview -v; needsterminal;
  1785. Ximage/X-ppm; ppmtopgm %s | pgmtopbm | pbmtomgr | mview -v; needsterminal;
  1786. BOP_BOP_A_LOO_WOP_BO_LOP_BAM_BOOM
  1787.     set -- `wc -c mailcap`
  1788.     if [ "$1" != "995" ] ; then
  1789.         echo "shar: mailcap unpacked with wrong size!"
  1790.     fi
  1791.     chmod u=rw,g=r,o=r mailcap
  1792. fi
  1793. exit
  1794.  
  1795. -- 
  1796. David H. Brierley
  1797. Home: dave@galaxia.network23.com; Work: dhb@quahog.ssd.ray.com
  1798. Send comp.sources.3b1 submissions to comp-sources-3b1@galaxia.network23.com
  1799. %% Pardon me Professor, can I be excused, my brain is full. **
  1800.