home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1994 March / Source_Code_CD-ROM_Walnut_Creek_March_1994.iso / compsrcs / x / volume20 / xclipbrd / part01 < prev    next >
Encoding:
Text File  |  1993-05-31  |  30.8 KB  |  1,186 lines

  1. Newsgroups: comp.sources.x
  2. From: vafaeia@pasticcio.network.com (Amir Vafaei)
  3. Subject: v20i008:  xclipboard - Load, save and print the X clipboard, Part01/01
  4. Message-ID: <1993Jun1.225208.8519@sparky.imd.sterling.com>
  5. X-Md4-Signature: 2a2cd466cbda73dec760e6f4dc46c7a9
  6. Sender: chris@sparky.imd.sterling.com (Chris Olson)
  7. Organization: Network Systems Corporation
  8. Date: Tue, 1 Jun 1993 22:52:08 GMT
  9. Approved: chris@sparky.imd.sterling.com
  10.  
  11. Submitted-by: vafaeia@pasticcio.network.com (Amir Vafaei)
  12. Posting-number: Volume 20, Issue 8
  13. Archive-name: xclipboard/part01
  14. Environment: X11
  15.  
  16.  
  17. Looking thru my misc directories, I noitced a copy of XClipboard which I had
  18. modified a few years back.  I have added a Load, Save and Print feature to
  19. the xclipboard.  It was enjoyed quite alot by co-workers at Apertus
  20. Technologies, so I decided to send it out.  Hope it can be of use.
  21.  
  22. -Amir
  23.  
  24.  
  25. ------------------------------------------------------------------------------
  26. #!/bin/sh
  27. # This is a shell archive.  Remove anything before this line,
  28. # then unpack it by saving it in a file and typing "sh file"
  29. # Created Tue May 25 14:19:13 1993
  30. #
  31. # This archive contains:
  32. #        xclipboard
  33. #        xclipboard/CHANGES
  34. #        xclipboard/Imakefile
  35. #        xclipboard/Makefile
  36. #        xclipboard/XClipboard.ad
  37. #        xclipboard/xclipboard.c
  38. #        xclipboard/xclipboard.man
  39. echo "Creating xclipboard"
  40. mkdir xclipboard
  41. echo "Creating xclipboard/CHANGES"
  42. cat > xclipboard/CHANGES <<"***EOF xclipboard/CHANGES***"
  43. The following changes have been made to this directory since R3:
  44.  
  45.      o    removed Save to Tempfile.
  46.      o    added paging and sensitivity.
  47.      o    use CLIPBOARD_MANAGER to assert control.
  48.      o    make work with new text widget.
  49.  
  50.      o Added load, save and print capability.        Amir Vafaei
  51. ***EOF xclipboard/CHANGES***
  52. echo "Creating xclipboard/Imakefile"
  53. cat > xclipboard/Imakefile <<"***EOF xclipboard/Imakefile***"
  54. #ifdef BandAidCompiler
  55. #include BandAidCompiler
  56. #endif
  57.  
  58.           SRCS1 = xclipboard.c
  59.           OBJS1 = xclipboard.o
  60.           SRCS2 = xcutsel.c
  61.           OBJS2 = xcutsel.o
  62.        PROGRAMS = xclipboard xcutsel
  63.         DEPLIBS = XawClientDepLibs
  64. LOCAL_LIBRARIES = XawClientLibs
  65.  
  66. ComplexProgramTarget_1(xclipboard,$(LOCAL_LIBRARIES), /**/)
  67. ComplexProgramTarget_2(xcutsel,$(LOCAL_LIBRARIES), /**/)
  68.  
  69. InstallAppDefaults(XClipboard)
  70. ***EOF xclipboard/Imakefile***
  71. echo "Creating xclipboard/Makefile"
  72. cat > xclipboard/Makefile <<"***EOF xclipboard/Makefile***"
  73. # Makefile generated by imake - do not edit!
  74. # $XConsortium: imake.c,v 1.51 89/12/12 12:37:30 jim Exp $
  75. #
  76. # The cpp used on this machine replaces all newlines and multiple tabs and
  77. # spaces in a macro expansion with a single space.  Imake tries to compensate
  78. # for this, but is not always successful.
  79. #
  80.  
  81. ###########################################################################
  82. # Makefile generated from "Imake.tmpl" and <Imakefile>
  83. # $XConsortium: Imake.tmpl,v 1.77 89/12/18 17:01:37 jim Exp $
  84. #
  85. # Platform-specific parameters may be set in the appropriate .cf
  86. # configuration files.  Site-wide parameters may be set in the file
  87. # site.def.  Full rebuilds are recommended if any parameters are changed.
  88. #
  89. # If your C preprocessor doesn't define any unique symbols, you'll need
  90. # to set BOOTSTRAPCFLAGS when rebuilding imake (usually when doing
  91. # "make Makefile", "make Makefiles", or "make World").
  92. #
  93. # If you absolutely can't get imake to work, you'll need to set the
  94. # variables at the top of each Makefile as well as the dependencies at the
  95. # bottom (makedepend will do this automatically).
  96. #
  97.  
  98. ###########################################################################
  99. # platform-specific configuration parameters - edit sun.cf to change
  100.  
  101. # platform:  $XConsortium: sun.cf,v 1.38 89/12/23 16:10:10 jim Exp $
  102. # operating system:  SunOS 4.0.3
  103.  
  104. ###########################################################################
  105. # site-specific configuration parameters - edit site.def to change
  106.  
  107. # site:  $XConsortium: site.def,v 1.21 89/12/06 11:46:50 jim Exp $
  108.  
  109.             SHELL = /bin/sh
  110.  
  111.               TOP = ../../.
  112.       CURRENT_DIR = ./clients/xclipboard
  113.  
  114.                AR = ar cq
  115.   BOOTSTRAPCFLAGS =
  116.                CC = cc
  117.  
  118.          COMPRESS = compress
  119.               CPP = /lib/cpp $(STD_CPP_DEFINES)
  120.     PREPROCESSCMD = cc -E $(STD_CPP_DEFINES)
  121.           INSTALL = install
  122.                LD = ld
  123.              LINT = lint
  124.       LINTLIBFLAG = -C
  125.          LINTOPTS = -axz
  126.                LN = ln -s
  127.              MAKE = make
  128.                MV = mv
  129.                CP = cp
  130.            RANLIB = ranlib
  131.   RANLIBINSTFLAGS =
  132.                RM = rm -f
  133.      STD_INCLUDES =
  134.   STD_CPP_DEFINES =
  135.       STD_DEFINES =
  136.  EXTRA_LOAD_FLAGS =
  137.   EXTRA_LIBRARIES =
  138.              TAGS = ctags
  139.  
  140.     SHAREDCODEDEF = -DSHAREDCODE
  141.          SHLIBDEF = -DSUNSHLIB
  142.  
  143.     PROTO_DEFINES =
  144.  
  145.      INSTPGMFLAGS =
  146.  
  147.      INSTBINFLAGS = -m 0755
  148.      INSTUIDFLAGS = -m 4755
  149.      INSTLIBFLAGS = -m 0664
  150.      INSTINCFLAGS = -m 0444
  151.      INSTMANFLAGS = -m 0444
  152.      INSTDATFLAGS = -m 0444
  153.     INSTKMEMFLAGS = -m 4755
  154.  
  155.           DESTDIR =
  156.  
  157. #     TOP_INCLUDES = -I$(TOP)
  158.      TOP_INCLUDES = 
  159.  
  160.       CDEBUGFLAGS = -O
  161.         CCOPTIONS =
  162.       COMPATFLAGS =
  163.  
  164.       ALLINCLUDES = $(STD_INCLUDES) $(TOP_INCLUDES) $(INCLUDES) $(EXTRA_INCLUDES)
  165.        ALLDEFINES = $(ALLINCLUDES) $(STD_DEFINES) $(PROTO_DEFINES) $(DEFINES) $(COMPATFLAGS)
  166.            CFLAGS = $(CDEBUGFLAGS) $(CCOPTIONS) $(ALLDEFINES)
  167.         LINTFLAGS = $(LINTOPTS) -DLINT $(ALLDEFINES)
  168.            LDLIBS = $(SYS_LIBRARIES) $(EXTRA_LIBRARIES)
  169.         LDOPTIONS = $(CDEBUGFLAGS) $(CCOPTIONS)
  170.    LDCOMBINEFLAGS = -X -r
  171.  
  172.         MACROFILE = sun.cf
  173.            RM_CMD = $(RM) *.CKP *.ln *.BAK *.bak *.o core errs ,* *~ *.a .emacs_* tags TAGS make.log MakeOut
  174.  
  175.     IMAKE_DEFINES =
  176.  
  177.          IRULESRC = $(CONFIGSRC)
  178.         IMAKE_CMD = $(NEWTOP)$(IMAKE) -I$(NEWTOP)$(IRULESRC) $(IMAKE_DEFINES)
  179.  
  180.      ICONFIGFILES = $(IRULESRC)/Imake.tmpl $(IRULESRC)/Imake.rules \
  181.             $(IRULESRC)/Project.tmpl $(IRULESRC)/site.def \
  182.             $(IRULESRC)/$(MACROFILE) $(EXTRA_ICONFIGFILES)
  183.  
  184. ###########################################################################
  185. # X Window System Build Parameters
  186. # $XConsortium: Project.tmpl,v 1.63 89/12/18 16:46:44 jim Exp $
  187.  
  188. ###########################################################################
  189. # X Window System make variables; this need to be coordinated with rules
  190. # $XConsortium: Project.tmpl,v 1.63 89/12/18 16:46:44 jim Exp $
  191.  
  192.           PATHSEP = /
  193.         USRLIBDIR = $(DESTDIR)/usr/lib
  194.            BINDIR = $(DESTDIR)/usr/bin/X11
  195.           INCROOT = $(DESTDIR)/usr/include
  196.      BUILDINCROOT = $(TOP)
  197.       BUILDINCDIR = $(BUILDINCROOT)/X11
  198.       BUILDINCTOP = ..
  199.            INCDIR = $(INCROOT)/X11
  200.            ADMDIR = $(DESTDIR)/usr/adm
  201.            LIBDIR = $(USRLIBDIR)/X11
  202.         CONFIGDIR = $(LIBDIR)/config
  203.        LINTLIBDIR = $(USRLIBDIR)/lint
  204.  
  205.           FONTDIR = $(LIBDIR)/fonts
  206.          XINITDIR = $(LIBDIR)/xinit
  207.            XDMDIR = $(LIBDIR)/xdm
  208.            AWMDIR = $(LIBDIR)/awm
  209.            TWMDIR = $(LIBDIR)/twm
  210.            GWMDIR = $(LIBDIR)/gwm
  211.           MANPATH = $(DESTDIR)/usr/man
  212.     MANSOURCEPATH = $(MANPATH)/man
  213.            MANDIR = $(MANSOURCEPATH)n
  214.         LIBMANDIR = $(MANSOURCEPATH)3
  215.       XAPPLOADDIR = $(LIBDIR)/app-defaults
  216.  
  217.         SOXLIBREV = 4.2
  218.           SOXTREV = 4.0
  219.          SOXAWREV = 4.0
  220.         SOOLDXREV = 4.0
  221.          SOXMUREV = 4.0
  222.         SOXEXTREV = 4.0
  223.  
  224.        FONTCFLAGS = -t
  225.  
  226.      INSTAPPFLAGS = $(INSTDATFLAGS)
  227.  
  228.             IMAKE = $(IMAKESRC)/imake
  229.            DEPEND = $(DEPENDSRC)/makedepend
  230.               RGB = $(RGBSRC)/rgb
  231.             FONTC = $(BDFTOSNFSRC)/bdftosnf
  232.         MKFONTDIR = $(MKFONTDIRSRC)/mkfontdir
  233.         MKDIRHIER = /bin/sh $(SCRIPTSRC)/mkdirhier.sh
  234.  
  235.         CONFIGSRC = $(TOP)/config
  236.         CLIENTSRC = $(TOP)/clients
  237.           DEMOSRC = $(TOP)/demos
  238.            LIBSRC = $(TOP)/lib
  239.           FONTSRC = $(TOP)/fonts
  240.        INCLUDESRC = $(TOP)/X11
  241.         SERVERSRC = $(TOP)/server
  242.           UTILSRC = $(TOP)/util
  243.         SCRIPTSRC = $(UTILSRC)/scripts
  244.        EXAMPLESRC = $(TOP)/examples
  245.        CONTRIBSRC = $(TOP)/../contrib
  246.            DOCSRC = $(TOP)/doc
  247.            RGBSRC = $(TOP)/rgb
  248.         DEPENDSRC = $(UTILSRC)/makedepend
  249.          IMAKESRC = $(CONFIGSRC)
  250.          XAUTHSRC = $(LIBSRC)/Xau
  251.           XLIBSRC = $(LIBSRC)/X
  252.            XMUSRC = $(LIBSRC)/Xmu
  253.        TOOLKITSRC = $(LIBSRC)/Xt
  254.        AWIDGETSRC = $(LIBSRC)/Xaw
  255.        OLDXLIBSRC = $(LIBSRC)/oldX
  256.       XDMCPLIBSRC = $(LIBSRC)/Xdmcp
  257.       BDFTOSNFSRC = $(FONTSRC)/bdftosnf
  258.      MKFONTDIRSRC = $(FONTSRC)/mkfontdir
  259.      EXTENSIONSRC = $(TOP)/extensions
  260.  
  261. #  DEPEXTENSIONLIB = $(EXTENSIONSRC)/lib/libXext.a
  262. #     EXTENSIONLIB =   $(DEPEXTENSIONLIB)
  263.    DEPEXTENSIONLIB = 
  264.       EXTENSIONLIB =   /usr/lib/libXext.a
  265.  
  266.           DEPXLIB = $(DEPEXTENSIONLIB)
  267.              XLIB = $(EXTENSIONLIB) -L$(XLIBSRC) -lX11
  268.  
  269.       DEPXAUTHLIB = $(XAUTHSRC)/libXau.a
  270.          XAUTHLIB =  $(DEPXAUTHLIB)
  271.  
  272.         DEPXMULIB =
  273.            XMULIB = -L$(XMUSRC) -lXmu
  274.  
  275.        DEPOLDXLIB =
  276.           OLDXLIB = -L$(OLDXLIBSRC) -loldX
  277.  
  278.       DEPXTOOLLIB =
  279.          XTOOLLIB = -L$(TOOLKITSRC) -lXt
  280.  
  281.         DEPXAWLIB =
  282.            XAWLIB = -L$(AWIDGETSRC) -lXaw
  283.  
  284.  LINTEXTENSIONLIB = $(EXTENSIONSRC)/lib/llib-lXext.ln
  285.          LINTXLIB = $(XLIBSRC)/llib-lX11.ln
  286.           LINTXMU = $(XMUSRC)/llib-lXmu.ln
  287.         LINTXTOOL = $(TOOLKITSRC)/llib-lXt.ln
  288.           LINTXAW = $(AWIDGETSRC)/llib-lXaw.ln
  289.  
  290.           DEPLIBS = $(DEPXAWLIB) $(DEPXMULIB) $(DEPXTOOLLIB) $(DEPXLIB)
  291.  
  292.          DEPLIBS1 = $(DEPLIBS)
  293.          DEPLIBS2 = $(DEPLIBS)
  294.          DEPLIBS3 = $(DEPLIBS)
  295.  
  296. ###########################################################################
  297. # Imake rules for building libraries, programs, scripts, and data files
  298. # rules:  $XConsortium: Imake.rules,v 1.67 89/12/18 17:14:15 jim Exp $
  299.  
  300. ###########################################################################
  301. # start of Imakefile
  302.  
  303.           SRCS1 = xclipboard.c
  304.           OBJS1 = xclipboard.o
  305.           SRCS2 = xcutsel.c
  306.           OBJS2 = xcutsel.o
  307.        PROGRAMS = xclipboard 
  308.         DEPLIBS = $(DEPXAWLIB) $(DEPXMULIB) $(DEPXTOOLLIB) $(DEPXLIB)
  309. LOCAL_LIBRARIES = $(XAWLIB) $(XMULIB) $(XTOOLLIB) $(XLIB)
  310.  
  311.  OBJS = $(OBJS1) $(OBJS2) $(OBJS3)
  312.  SRCS = $(SRCS1) $(SRCS2) $(SRCS3)
  313.  
  314. all:: $(PROGRAMS)
  315.  
  316. xclipboard: $(OBJS1) $(DEPLIBS1)
  317.     $(RM) $@
  318.     $(CC) -o $@ $(LDOPTIONS) $(OBJS1) $(LOCAL_LIBRARIES) $(LDLIBS)   $(EXTRA_LOAD_FLAGS)
  319.  
  320. install:: xclipboard
  321.     $(INSTALL) -c $(INSTPGMFLAGS)   xclipboard $(BINDIR)
  322.  
  323. install.man:: xclipboard.man
  324.     $(INSTALL) -c $(INSTMANFLAGS) xclipboard.man $(MANDIR)/xclipboard.n
  325.  
  326. saber_xclipboard:
  327.     #load $(ALLDEFINES) $(SRCS1) $(LOCAL_LIBRARIES) $(SYS_LIBRARIES) $(EXTRA_LIBRARIES)
  328.  
  329. osaber_xclipboard:
  330.     #load $(ALLDEFINES) $(OBJS1) $(LOCAL_LIBRARIES) $(SYS_LIBRARIES) $(EXTRA_LIBRARIES)
  331.  
  332. depend:: $(DEPEND)
  333.  
  334. $(DEPEND):
  335.     @echo "checking $@ over in $(DEPENDSRC) first..."; \
  336.     cd $(DEPENDSRC); $(MAKE); \
  337.     echo "okay, continuing in $(CURRENT_DIR)"
  338.  
  339. depend::
  340.     $(DEPEND) -s "# DO NOT DELETE" -- $(ALLDEFINES) -- $(SRCS)
  341.  
  342. lint:
  343.     $(LINT) $(LINTFLAGS) $(SRCS) $(LINTLIBS)
  344. lint1:
  345.     $(LINT) $(LINTFLAGS) $(FILE) $(LINTLIBS)
  346.  
  347. clean::
  348.     $(RM) $(PROGRAMS)
  349.  
  350. xcutsel: $(OBJS2) $(DEPLIBS2)
  351.     $(RM) $@
  352.     $(CC) -o $@ $(LDOPTIONS) $(OBJS2) $(LOCAL_LIBRARIES) $(LDLIBS)   $(EXTRA_LOAD_FLAGS)
  353.  
  354. saber_xcutsel:
  355.     #load $(ALLDEFINES) $(SRCS2) $(LOCAL_LIBRARIES) $(SYS_LIBRARIES) $(EXTRA_LIBRARIES)
  356.  
  357. osaber_xcutsel:
  358.     #load $(ALLDEFINES) $(OBJS2) $(LOCAL_LIBRARIES) $(SYS_LIBRARIES) $(EXTRA_LIBRARIES)
  359.  
  360. install:: xcutsel
  361.     $(INSTALL) -c $(INSTPGMFLAGS)   xcutsel $(BINDIR)
  362.  
  363. install.man:: xcutsel.man
  364.     $(INSTALL) -c $(INSTMANFLAGS) xcutsel.man $(MANDIR)/xcutsel.n
  365.  
  366. install:: XClipboard.ad
  367.     $(INSTALL) -c $(INSTAPPFLAGS) XClipboard.ad $(XAPPLOADDIR)/XClipboard
  368.  
  369. ###########################################################################
  370. # common rules for all Makefiles - do not edit
  371.  
  372. emptyrule::
  373.  
  374. clean::
  375.     $(RM_CMD) \#*
  376.  
  377. Makefile:: $(IMAKE)
  378.  
  379. $(IMAKE):
  380.     @(cd $(IMAKESRC); if [ -f Makefile ]; then \
  381.     echo "checking $@ in $(IMAKESRC) first..."; $(MAKE) all; else \
  382.     echo "bootstrapping $@ from Makefile.ini in $(IMAKESRC) first..."; \
  383.     $(MAKE) -f Makefile.ini BOOTSTRAPCFLAGS=$(BOOTSTRAPCFLAGS); fi; \
  384.     echo "okay, continuing in $(CURRENT_DIR)")
  385.  
  386. Makefile::
  387.     -@if [ -f Makefile ]; then \
  388.     echo "    $(RM) Makefile.bak; $(MV) Makefile Makefile.bak"; \
  389.     $(RM) Makefile.bak; $(MV) Makefile Makefile.bak; \
  390.     else exit 0; fi
  391.     $(IMAKE_CMD) -DTOPDIR=$(TOP) -DCURDIR=$(CURRENT_DIR)
  392.  
  393. tags::
  394.     $(TAGS) -w *.[ch]
  395.     $(TAGS) -xw *.[ch] > TAGS
  396.  
  397. saber:
  398.     #load $(ALLDEFINES) $(SRCS)
  399.  
  400. osaber:
  401.     #load $(ALLDEFINES) $(OBJS)
  402.  
  403. ###########################################################################
  404. # empty rules for directories that do not have SUBDIRS - do not edit
  405.  
  406. install::
  407.     @echo "install in $(CURRENT_DIR) done"
  408.  
  409. install.man::
  410.     @echo "install.man in $(CURRENT_DIR) done"
  411.  
  412. Makefiles::
  413.  
  414. includes::
  415.  
  416. ###########################################################################
  417. # dependencies generated by makedepend
  418.  
  419. ***EOF xclipboard/Makefile***
  420. echo "Creating xclipboard/XClipboard.ad"
  421. cat > xclipboard/XClipboard.ad <<"***EOF xclipboard/XClipboard.ad***"
  422. XClipboard*quit.label:             Quit
  423. XClipboard*quit.top:             ChainTop
  424. XClipboard*quit.bottom:         ChainTop
  425. XClipboard*quit.left:             ChainLeft
  426. XClipboard*quit.right:             ChainLeft
  427. XClipboard*quit.translations:        #override<BtnUp>:Quit() unset()
  428.  
  429. XClipboard*delete.label:         Delete
  430. XClipboard*delete.fromHoriz:         quit
  431. XClipboard*delete.top:             ChainTop
  432. XClipboard*delete.bottom:        ChainTop
  433. XClipboard*delete.left:            ChainLeft
  434. XClipboard*delete.right:        ChainLeft
  435. XClipboard*delete.translations:        #override<BtnUp>:DeleteClip() unset()
  436.  
  437. XClipboard*new.label:             New
  438. XClipboard*new.fromHoriz:         delete
  439. XClipboard*new.top:             ChainTop
  440. XClipboard*new.bottom:            ChainTop
  441. XClipboard*new.left:            ChainLeft
  442. XClipboard*new.right:            ChainLeft
  443. XClipboard*new.translations:        #override<BtnUp>:NewClip() unset()
  444.  
  445. XClipboard*load.label:                   Load
  446. XClipboard*load.fromHoriz:               new
  447. XClipboard*load.top:                     ChainTop
  448. XClipboard*load.bottom:                  ChainTop
  449. XClipboard*load.left:                    ChainLeft
  450. XClipboard*load.right:                   ChainLeft
  451. XClipboard*load.translations:            #override<BtnUp>:Load() unset()
  452.  
  453. XClipboard*save.label:                   Save
  454. XClipboard*save.fromHoriz:               load
  455. XClipboard*save.top:                     ChainTop
  456. XClipboard*save.bottom:                  ChainTop
  457. XClipboard*save.left:                    ChainLeft
  458. XClipboard*save.right:                   ChainLeft
  459. XClipboard*save.translations:            #override<BtnUp>:Save() unset()
  460.  
  461. XClipboard*prnt.label:             Print
  462. XClipboard*prnt.fromHoriz:         save
  463. XClipboard*prnt.top:             ChainTop
  464. XClipboard*prnt.bottom:            ChainTop
  465. XClipboard*prnt.left:            ChainLeft
  466. XClipboard*prnt.right:            ChainLeft
  467. XClipboard*prnt.translations:        #override<BtnUp>:PrntClip() unset()
  468.  
  469. XClipboard*next.label:             Next
  470. XClipboard*next.fromHoriz:         prnt
  471. XClipboard*next.top:             ChainTop
  472. XClipboard*next.bottom:            ChainTop
  473. XClipboard*next.left:            ChainLeft
  474. XClipboard*next.right:            ChainLeft
  475. XClipboard*next.translations:        #override<BtnUp>:NextClip() unset()
  476.  
  477. XClipboard*prev.label:             Previous
  478. XClipboard*prev.fromHoriz:         next
  479. XClipboard*prev.top:             ChainTop
  480. XClipboard*prev.bottom:            ChainTop
  481. XClipboard*prev.left:            ChainLeft
  482. XClipboard*prev.right:            ChainLeft
  483. XClipboard*prev.translations:        #override<BtnUp>:PrevClip() unset()
  484.  
  485. XClipboard*text.scrollVertical:      WhenNeeded
  486. XClipboard*text.scrollHorizontal:      WhenNeeded
  487. XClipboard*text.autoFill:         on
  488.  
  489. XClipboard*text.fromVert:         quit
  490. XClipboard*text.top:             ChainTop
  491. XClipboard*text.bottom:         ChainBottom
  492. XClipboard*text.left:             ChainLeft
  493. XClipboard*text.right:             ChainRight
  494. XClipboard*text.width:            600
  495.  
  496. XClipboard.geometry:            600x200
  497. XClipboard*ShapeStyle:            oval
  498. XClipboard*printer_name:        ps
  499. ***EOF xclipboard/XClipboard.ad***
  500. echo "Creating xclipboard/xclipboard.c"
  501. cat > xclipboard/xclipboard.c <<"***EOF xclipboard/xclipboard.c***"
  502. /*
  503.  * $XConsortium: xclipboard.c,v 1.15 89/12/15 20:11:09 keith Exp $
  504.  *
  505.  * Copyright 1989 Massachusetts Institute of Technology
  506.  *
  507.  * Permission to use, copy, modify, and distribute this software and its
  508.  * documentation for any purpose and without fee is hereby granted, provided
  509.  * that the above copyright notice appear in all copies and that both that
  510.  * copyright notice and this permission notice appear in supporting
  511.  * documentation, and that the name of M.I.T. not be used in advertising
  512.  * or publicity pertaining to distribution of the software without specific,
  513.  * written prior permission.  M.I.T. makes no representations about the
  514.  * suitability of this software for any purpose.  It is provided "as is"
  515.  * without express or implied warranty.
  516.  *
  517.  * M.I.T. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
  518.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL M.I.T.
  519.  * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  520.  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
  521.  * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN 
  522.  * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  523.  *
  524.  * Author:  Ralph Swick, DEC/Project Athena
  525.  * Updated for R4:  Chris D. Peterson,  MIT X Consortium.
  526.  * Reauthored by: Keith Packard, MIT X Consortium.
  527.  *
  528.  * Enhancements: Amir H. Vafaei, Apertus Technologies Inc., Minneapolis, Minnesota.
  529.  *     Added Load, Save and Print capabilities     4/8/1992.
  530.  */
  531.  
  532. /* $XConsortium: xclipboard.c,v 1.15 89/12/15 20:11:09 keith Exp $ */
  533.  
  534. #include <stdio.h>
  535. #include <unistd.h>
  536. #include <pwd.h>
  537. #include <sys/param.h>
  538.  
  539. #include <X11/Intrinsic.h>
  540. #include <X11/StringDefs.h>
  541. #include <X11/Xatom.h>
  542.  
  543. #include <X11/Xmu/Atoms.h>
  544. #include <X11/Xmu/StdSel.h>
  545.  
  546. #include <X11/Xaw/Form.h>
  547. #include <X11/Xaw/Command.h>
  548. #include <X11/Xaw/AsciiText.h>
  549. #include <X11/Xaw/Cardinals.h>
  550.  
  551. #define Command commandWidgetClass
  552. #define Text    asciiTextWidgetClass
  553.  
  554. #define INFINITY 10000000    /* pretty big, huh? */
  555.  
  556. typedef struct _Clip {
  557.     struct _Clip    *next, *prev;
  558.     char        *clip;
  559.     int            avail;
  560. } ClipRec, *ClipPtr;
  561.  
  562. typedef struct{
  563.     char    *pn_name;
  564. }TEXT_DATA, *TEXT_DATA_PTR;
  565.  
  566. TEXT_DATA    text_data;
  567.  
  568. extern char *malloc ();
  569.  
  570. static long TextLength (w)
  571.     Widget  w;
  572. {
  573.     return XawTextSourceScan (XawTextGetSource (w),
  574.                   (XawTextPosition) 0,
  575.                    XawstAll, XawsdRight, 1, TRUE);
  576. }
  577.  
  578. SaveClip (w, clip)
  579.     Widget  w;
  580.     ClipPtr clip;
  581. {
  582.     Arg        args[1];
  583.     char    *data;
  584.     int        len;
  585.     Widget  source;
  586.  
  587.     source = XawTextGetSource (w);
  588.     XtSetArg (args[0], XtNstring, &data);
  589.     XtGetValues (source, args, 1);
  590.     len = strlen (data);
  591.     if (len >= clip->avail)
  592.     {
  593.     if (clip->clip)
  594.         free (clip->clip);
  595.     clip->clip = malloc (len + 1);
  596.     if (!clip->clip)
  597.         clip->avail = 0;
  598.     else
  599.         clip->avail = len + 1;
  600.     }
  601.     if (clip->avail)
  602.     {
  603.     strcpy (clip->clip, data);
  604.     }
  605. }
  606.  
  607. RestoreClip (w, clip)
  608.     Widget  w;
  609.     ClipPtr clip;
  610. {
  611.     Arg        args[1];
  612.     Widget  source;
  613.  
  614.     source = XawTextGetSource (w);
  615.     XtSetArg (args[0], XtNstring, clip->clip);
  616.     XtSetValues (source, args, 1);
  617. }
  618.  
  619. ClipPtr
  620. NewClip (w, old)
  621.     Widget  w;
  622.     ClipPtr old;
  623. {
  624.     ClipPtr newClip;
  625.  
  626.     newClip = (ClipPtr) malloc (sizeof (ClipRec));
  627.     if (!newClip)
  628.     return newClip;
  629.     newClip->clip = 0;
  630.     newClip->avail = 0;
  631.     newClip->prev = old;
  632.     newClip->next = NULL;
  633.     if (old)
  634.     {
  635.     newClip->next = old->next;
  636.     old->next = newClip;
  637.     }
  638.     return newClip;
  639. }
  640.  
  641. DeleteClip (w, clip)
  642.     Widget  w;
  643.     ClipPtr clip;
  644. {
  645.     if (clip->prev)
  646.     clip->prev->next = clip->next;
  647.     if (clip->next)
  648.     clip->next->prev = clip->prev;
  649.     if (clip->clip)
  650.     free (clip->clip);
  651.     free ((char *) clip);
  652. }
  653.  
  654. static ClipPtr    currentClip;
  655. static Widget    text, nextButton, prevButton, loadButton;
  656. static char    saveFile[MAXPATHLEN + 1];
  657.  
  658. static void set_button_state ()
  659. {
  660.     Boolean prevvalid, nextvalid;
  661.     Arg arg;
  662.  
  663.     prevvalid = False;
  664.     nextvalid = False;
  665.     if (currentClip)
  666.     {
  667.     prevvalid = currentClip->prev != NULL;
  668.     nextvalid = currentClip->next != NULL;
  669.     }
  670.     arg.name = XtNsensitive;
  671.     arg.value = (XtArgVal) prevvalid;
  672.     XtSetValues (prevButton, &arg, ONE);
  673.     arg.value = (XtArgVal) nextvalid;
  674.     XtSetValues (nextButton, &arg, ONE);
  675. }
  676.  
  677. static void
  678. NextCurrentClip ()
  679. {
  680.     if (currentClip && currentClip->next)
  681.     {
  682.     SaveClip (text, currentClip);
  683.     currentClip = currentClip->next;
  684.     RestoreClip (text, currentClip);
  685.     set_button_state ();
  686.     }
  687. }
  688.  
  689. static void
  690. PrevCurrentClip ()
  691. {
  692.     if (currentClip && currentClip->prev)
  693.     {
  694.     SaveClip (text, currentClip);
  695.     currentClip = currentClip->prev;
  696.     RestoreClip (text, currentClip);
  697.     set_button_state ();
  698.     }
  699. }
  700.  
  701. static void
  702. DeleteCurrentClip ()
  703. {
  704.     ClipPtr newCurrent;
  705.  
  706.     if (currentClip)
  707.     {
  708.     if (currentClip->prev)
  709.     {
  710.         newCurrent = currentClip->prev;
  711.     }
  712.     else
  713.     {
  714.         newCurrent = currentClip->next;
  715.     }
  716.     DeleteClip (text, currentClip);
  717.     currentClip = newCurrent;
  718.     if (currentClip)
  719.         RestoreClip (text, currentClip);
  720.     else
  721.     {
  722.         EraseTextWidget ();
  723.     }
  724.     set_button_state ();
  725.     }
  726.     else
  727.     EraseTextWidget();
  728. }
  729.  
  730. static void
  731. Quit ()
  732. {
  733.     XtCloseDisplay  (XtDisplay (text));
  734.     exit (0);
  735. }
  736.  
  737. static void
  738. erase_all()
  739. {
  740.     ClipPtr     tempClip, headClip;
  741.  
  742.     tempClip = currentClip;
  743.  
  744.     while (tempClip){
  745.     headClip = tempClip;
  746.     tempClip = tempClip->prev;
  747.     }
  748.  
  749.     while (headClip){
  750.     tempClip = headClip;
  751.     headClip = headClip->next;
  752.     DeleteClip(text, tempClip);
  753.     }
  754. }
  755.  
  756. static void
  757. PrntClip()
  758. {
  759.     Arg        args[1];
  760.     char    *data;
  761.     Widget  source;
  762.     char    template[17];
  763.     char    *tmp, *mktemp();
  764.     char    buf[80];
  765.     int        tmpfd;
  766.     int        len;
  767.  
  768.     source = XawTextGetSource (text);
  769.     XtSetArg (args[0], XtNstring, &data);
  770.     XtGetValues (source, args, 1);
  771.     if ((len = strlen(data)) <= 0)
  772.     return;
  773.     strcpy(template, "/tmp/oipfgXXXXXX");
  774.     tmp = mktemp(template);
  775.     if (template == ""){
  776.     fprintf(stderr, "Unable to make tmp file.\n");
  777.     return;
  778.     }
  779.  
  780.     tmpfd = open(tmp, O_RDWR|O_CREAT, 0666);
  781.     if (tmpfd < 0){
  782.     fprintf(stderr, "Unable to create tmp file.\n");
  783.     return;
  784.     }
  785.  
  786.     write(tmpfd, data, len + 1);
  787.     close(tmpfd);
  788.     if (!text_data.pn_name[0])
  789.     sprintf(buf, "lpr %s", tmp);
  790.     else
  791.     sprintf(buf, "lpr -P%s %s", text_data.pn_name, tmp);
  792.     system(buf);
  793.     unlink(tmp);
  794.  
  795. }
  796.  
  797. static void
  798. Save()
  799. {
  800.     ClipPtr    tempClip, headClip, saveClip;
  801.     FILE    *fp;
  802.     long    size;
  803.     long    count = 0;
  804.  
  805.     if (!(fp = fopen(saveFile, "w")))
  806.     return;
  807.  
  808.     tempClip = currentClip;
  809.     saveClip = (ClipPtr)0;
  810.  
  811.     if (!tempClip && TextLength(text))
  812.     saveClip = tempClip = NewClip(text, (ClipPtr)0);
  813.     
  814.     if (tempClip){
  815.     if (TextLength(text))
  816.         SaveClip (text, tempClip);
  817.     while (tempClip){
  818.         count++;
  819.         headClip = tempClip;
  820.         tempClip = tempClip->prev;
  821.     }
  822.  
  823.     fwrite(&count, sizeof(long), 1, fp);
  824.  
  825.     while (headClip){
  826.         if (headClip->clip){
  827.         size = strlen(headClip->clip) + 1;
  828.         fwrite(&size, sizeof(long), 1, fp); 
  829.         fwrite(headClip->clip, 1, size, fp);
  830.         }
  831.         else{
  832.         size = 0L;
  833.         fwrite(&size, sizeof(long), 1, fp);
  834.         }
  835.         headClip = headClip->next;
  836.     }
  837.     fclose(fp);
  838.     if (saveClip)
  839.         DeleteClip(text, saveClip);
  840.     }
  841.     else{
  842.     fclose(fp);
  843.     unlink(saveFile);
  844.     }
  845. }
  846.  
  847. static void
  848. Load()
  849. {
  850.     FILE    *fp;
  851.     ClipPtr    tempClip, oldClip;
  852.     long    size, count;
  853.  
  854.     if (!(fp = fopen(saveFile, "r")))
  855.     return;
  856.  
  857.     if (currentClip)
  858.     erase_all();
  859.  
  860.  
  861.     if (fread(&count, sizeof(long), 1, fp) <= 0)
  862.     return;
  863.     
  864.     oldClip = (ClipPtr)0;
  865.     currentClip = (ClipPtr)0;
  866.  
  867.     while (fread(&size, sizeof(long), 1, fp)){
  868.     tempClip = NewClip(text, oldClip);
  869.  
  870.     if (tempClip){
  871.         oldClip = tempClip;
  872.         if (!currentClip)
  873.         currentClip = tempClip;
  874.  
  875.         if (!(--count))
  876.         currentClip = tempClip;
  877.  
  878.         tempClip->clip = malloc(size);
  879.         if (tempClip->clip){
  880.         tempClip->avail = size;
  881.         fread(tempClip->clip, 1, size, fp);
  882.         }
  883.         else{
  884.         fseek(fp, size, SEEK_CUR);
  885.         count--;
  886.         }
  887.     }
  888.     else{
  889.         fseek(fp, size, 1);
  890.         count--;
  891.     }
  892.     }
  893.  
  894.     fclose(fp);
  895.     RestoreClip (text, currentClip);
  896.     set_button_state();
  897. }
  898.  
  899. static void
  900. NewCurrentClip ()
  901. {
  902.     NewCurrentClipContents ("", 0);
  903. }
  904.  
  905. NewCurrentClipContents (data, len)
  906.     char    *data;
  907.     int        len;
  908. {
  909.     XawTextBlock textBlock;
  910.     ClipPtr newCurrent;
  911.  
  912.     if (!currentClip && TextLength (text))
  913.     currentClip = NewClip (text, (ClipPtr) 0);
  914.     if (currentClip)
  915.     SaveClip (text, currentClip);
  916.     /* append new clips at the end */
  917.     while (currentClip && currentClip->next)
  918.     currentClip = currentClip->next;
  919.     newCurrent = NewClip (text, currentClip);
  920.     
  921.     currentClip = newCurrent;
  922.  
  923.     textBlock.ptr = data;
  924.     textBlock.firstPos = 0;
  925.     textBlock.length = len;
  926.     textBlock.format = FMT8BIT;
  927.     if (XawTextReplace(text, 0, TextLength (text), &textBlock))
  928.     XBell( XtDisplay(text), 0);
  929.     set_button_state ();
  930. }
  931.  
  932. EraseTextWidget ()
  933. {
  934.     XawTextBlock block;
  935.  
  936.     block.ptr = "";
  937.     block.length = 0;
  938.     block.firstPos = 0;
  939.     block.format = FMT8BIT;
  940.  
  941.     XawTextReplace(text, 0, INFINITY, &block);
  942.     /* If this fails, too bad. */
  943. }
  944.  
  945.  
  946. XtActionsRec xclipboard_actions[] = {
  947.     "NewClip", NewCurrentClip,
  948.     "NextClip",    NextCurrentClip,
  949.     "PrevClip", PrevCurrentClip,
  950.     "DeleteClip", DeleteCurrentClip,
  951.     "Load", Load,
  952.     "Save", Save,
  953.     "PrntClip", PrntClip,
  954.     "Quit", Quit,
  955. };
  956.  
  957. static XtResource    resources[] = {
  958. {"printer_name", "Printer_name", XtRString, sizeof(char *), XtOffset(TEXT_DATA_PTR, pn_name), XtRString, ""},
  959. };
  960.  
  961. static XrmOptionDescRec table[] = {
  962.     {"-w",        "*text*wrap",        XrmoptionNoArg,  "Word"},
  963.     {"-nw",        "*text*wrap",        XrmoptionNoArg,  "Never"},
  964.     {"-P",    "printer_name",            XrmoptionStickyArg, NULL},
  965. };
  966.  
  967. static void    LoseSelection ();
  968. static void    InsertClipboard ();
  969. static Boolean    ConvertSelection();
  970.  
  971. static void 
  972. InsertClipboard(w, client_data, selection, type, value, length, format)
  973. Widget w;
  974. caddr_t client_data;
  975. Atom *selection, *type;
  976. caddr_t value;
  977. unsigned long *length;
  978. int *format;
  979. {
  980.     if (*type == 0 /*XT_CONVERT_FAIL*/ || *length == 0) {
  981.     XBell( XtDisplay(w), 0 );
  982.     return;
  983.     }
  984.     
  985.     NewCurrentClipContents ((char *) value, *length);
  986.  
  987.     XtOwnSelection(w, XA_CLIPBOARD(XtDisplay(w)), CurrentTime,
  988.            ConvertSelection, LoseSelection, NULL);
  989.  
  990.     XtFree(value);
  991. }
  992.  
  993. static Boolean ConvertSelection(w, selection, target,
  994.                 type, value, length, format)
  995.     Widget w;
  996.     Atom *selection, *target, *type;
  997.     caddr_t *value;
  998.     unsigned long *length;
  999.     int *format;
  1000. {
  1001.     Display* d = XtDisplay(w);
  1002.     XSelectionRequestEvent* req =
  1003.     XtGetSelectionRequest(w, *selection, (XtRequestId)NULL);
  1004.  
  1005.     if (*target == XA_TARGETS(d)) {
  1006.     Atom* targetP;
  1007.     Atom* std_targets;
  1008.     unsigned long std_length;
  1009.     XmuConvertStandardSelection(w, req->time, selection, target, type,
  1010.                   (caddr_t*)&std_targets, &std_length, format);
  1011.     *value = XtMalloc(sizeof(Atom)*(std_length + 5));
  1012.     targetP = *(Atom**)value;
  1013.     *targetP++ = XA_STRING;
  1014.     *targetP++ = XA_TEXT(d);
  1015.     *targetP++ = XA_LENGTH(d);
  1016.     *targetP++ = XA_LIST_LENGTH(d);
  1017.     *targetP++ = XA_CHARACTER_POSITION(d);
  1018.     *length = std_length + (targetP - (*(Atom **) value));
  1019.     bcopy((char*)std_targets, (char*)targetP, sizeof(Atom)*std_length);
  1020.     XtFree((char*)std_targets);
  1021.     *type = XA_ATOM;
  1022.     *format = 32;
  1023.     return True;
  1024.     }
  1025.  
  1026.     if (*target == XA_LIST_LENGTH(d) ||
  1027.     *target == XA_LENGTH(d))
  1028.     {
  1029.         long * temp;
  1030.         
  1031.         temp = (long *) XtMalloc(sizeof(long));
  1032.         if (*target == XA_LIST_LENGTH(d))
  1033.             *temp = 1L;
  1034.         else            /* *target == XA_LENGTH(d) */
  1035.             *temp = (long) TextLength (w);
  1036.         
  1037.         *value = (caddr_t) temp;
  1038.         *type = XA_INTEGER;
  1039.         *length = 1L;
  1040.         *format = 32;
  1041.         return True;
  1042.     }
  1043.     
  1044.     if (*target == XA_CHARACTER_POSITION(d))
  1045.     {
  1046.         long * temp;
  1047.         
  1048.         temp = (long *) XtMalloc(2 * sizeof(long));
  1049.         temp[0] = (long) 0;
  1050.         temp[1] = TextLength (w);
  1051.         *value = (caddr_t) temp;
  1052.         *type = XA_SPAN(d);
  1053.         *length = 2L;
  1054.         *format = 32;
  1055.         return True;
  1056.     }
  1057.     
  1058.     if (*target == XA_STRING ||
  1059.       *target == XA_TEXT(d) ||
  1060.       *target == XA_COMPOUND_TEXT(d))
  1061.     {
  1062.     extern char *_XawTextGetSTRING();
  1063.         if (*target == XA_COMPOUND_TEXT(d))
  1064.         *type = *target;
  1065.         else
  1066.         *type = XA_STRING;
  1067.     *length = TextLength (w);
  1068.         *value = _XawTextGetSTRING((TextWidget) w, 0, *length);
  1069.         *format = 8;
  1070.         return True;
  1071.     }
  1072.     
  1073.     if (XmuConvertStandardSelection(w, req->time, selection, target, type,
  1074.                     value, length, format))
  1075.     return True;
  1076.  
  1077.     return False;
  1078. }
  1079.  
  1080. static void LoseSelection(w, selection)
  1081.     Widget w;
  1082.     Atom *selection;
  1083. {
  1084.     XtGetSelectionValue(w, *selection, XA_STRING, InsertClipboard,
  1085.             NULL, CurrentTime);
  1086. }
  1087.  
  1088. /*ARGSUSED*/
  1089. static Boolean RefuseSelection(w, selection, target,
  1090.                    type, value, length, format)
  1091.     Widget w;
  1092.     Atom *selection, *target, *type;
  1093.     caddr_t *value;
  1094.     unsigned long *length;
  1095.     int *format;
  1096. {
  1097.     return False;
  1098. }
  1099.  
  1100. /*ARGSUSED*/
  1101. static void LoseManager(w, selection)
  1102.     Widget w;
  1103.     Atom *selection;
  1104. {
  1105.     XtError("another clipboard has taken over control\n");
  1106. }
  1107.  
  1108. static void
  1109. get_savefile(s)
  1110. char    *s;
  1111. {
  1112.     struct passwd *pw;
  1113.  
  1114.     if (!(pw = getpwuid(getuid())))
  1115.     return;
  1116.  
  1117.     sprintf(s, "%s/.clipper", pw->pw_dir);
  1118. }
  1119.  
  1120.  
  1121. void
  1122. main(argc, argv)
  1123. int argc;
  1124. char **argv;
  1125. {
  1126.     Arg args[2];
  1127.     Widget top, parent, quit, delete, new, save, prnt;
  1128.     Atom manager;
  1129.  
  1130.     top = XtInitialize( "xclipboard", "XClipboard", table, XtNumber(table),
  1131.               &argc, argv);
  1132.  
  1133.     XtGetApplicationResources(top, &text_data, resources, XtNumber(resources), NULL, 0);
  1134.  
  1135.     get_savefile(saveFile);
  1136.  
  1137.     XtAddActions (xclipboard_actions, XtNumber (xclipboard_actions));
  1138.     /* CLIPBOARD_MANAGER is a non-standard mechanism */
  1139.     manager = XInternAtom(XtDisplay(top), "CLIPBOARD_MANAGER", False);
  1140.     if (XGetSelectionOwner(XtDisplay(top), manager))
  1141.     XtError("another clipboard is already running\n");
  1142.  
  1143.     parent = XtCreateManagedWidget("form", formWidgetClass, top, NULL, ZERO);
  1144.     quit = XtCreateManagedWidget("quit", Command, parent, NULL, ZERO);
  1145.     delete = XtCreateManagedWidget("delete", Command, parent, NULL, ZERO);
  1146.     new = XtCreateManagedWidget("new", Command, parent, NULL, ZERO);
  1147.     loadButton = XtCreateManagedWidget("load", Command, parent, NULL, ZERO);
  1148.     save = XtCreateManagedWidget("save", Command, parent, NULL, ZERO);
  1149.     prnt = XtCreateManagedWidget("prnt", Command, parent, NULL, ZERO);
  1150.     nextButton = XtCreateManagedWidget("next", Command, parent, NULL, ZERO);
  1151.     prevButton = XtCreateManagedWidget("prev", Command, parent, NULL, ZERO);
  1152.  
  1153.     XtSetArg(args[0], XtNtype, XawAsciiString);
  1154.     XtSetArg(args[1], XtNeditType, XawtextEdit);
  1155.     text = XtCreateManagedWidget( "text", Text, parent, args, TWO);
  1156.  
  1157.     set_button_state ();
  1158.  
  1159.     XtRealizeWidget(top);
  1160.  
  1161.     XtOwnSelection(text, manager, CurrentTime,
  1162.            RefuseSelection, LoseManager, NULL);
  1163.     XtOwnSelection(text, XA_CLIPBOARD(XtDisplay(text)), CurrentTime,
  1164.            ConvertSelection, LoseSelection, NULL);
  1165.  
  1166.     XtMainLoop();
  1167. }
  1168. ***EOF xclipboard/xclipboard.c***
  1169. echo "Creating xclipboard/xclipboard.man"
  1170. cat > xclipboard/xclipboard.man <<"***EOF xclipboard/xclipboard.man***"
  1171. TH XCLIPBOARD 1 "Release 4" "X Version 11"
  1172. de Ds
  1173. nf
  1174. \\$1D \\$2 \\$1
  1175. ft 1
  1176. ps \\n(PS
  1177. \".if \\n(VS>=40 .vs \\n(VSu
  1178. \".if \\n(VS<=39 .vs \\n(VSp
  1179.  
  1180. exit 0 # Just in case...
  1181. -- 
  1182.   // chris@IMD.Sterling.COM       | Send comp.sources.x submissions to:
  1183. \X/  Amiga - The only way to fly! |    sources-x@imd.sterling.com
  1184.  "It's intuitively obvious to the |
  1185.   most casual observer..."        | GCS d+/-- p+ c++ l+ m+ s++/+ g+ w+ t+ r+ x+
  1186.