home *** CD-ROM | disk | FTP | other *** search
/ Carousel Volume 2 #1 / carousel.iso / mactosh / unix / windows4.hqx < prev    next >
Text File  |  1988-03-28  |  57KB  |  2,127 lines

  1. 20-Mar-88 20:15:20-MST,59467;000000000001
  2. Return-Path: <INFO-MAC-REQUEST@SUMEX-AIM.Stanford.EDU>
  3. Received: from SUMEX-AIM.Stanford.EDU by SIMTEL20.ARPA with TCP; Sun, 20 Mar 88 20:13:32 MST
  4. Return-Path: <rothberg@polya.stanford.edu>
  5. Received: from polya.stanford.edu by SUMEX-AIM.Stanford.EDU with TCP; Wed, 2 Mar 88 13:28:51 PST
  6. Received: by polya.stanford.edu (5.54/inc-1.2)
  7.     id AA05749; Wed, 2 Mar 88 09:59:58 PST
  8. Date: Wed, 2 Mar 88 09:59:58 PST
  9. From: rothberg@polya.stanford.edu (Edward Rothberg)
  10. Message-Id: <8803021759.AA05749@polya.stanford.edu>
  11. To: info-mac@sumex.stanford.edu
  12. Subject: Here's UW Version 4.2, in UNIX shar format, Part 1
  13. ReSent-Date: Sun, 20 Mar 88 19:11:37 PST
  14. ReSent-From: Lance Nakata <INFO-MAC-REQUEST@SUMEX-AIM.Stanford.EDU>
  15. ReSent-To: info-mac-redist: ;
  16. ReSent-Message-ID: <12383979586.16.INFO-MAC-REQUEST@SUMEX-AIM.Stanford.EDU>
  17.  
  18. : This is a shar archive.  Extract with sh, not csh.
  19. if test ! -d misc; then
  20.     echo mkdir misc
  21.     mkdir misc
  22. fi
  23. if test ! -d utility; then
  24.     echo mkdir utility
  25.     mkdir utility
  26. fi
  27. echo x - README
  28. sed -e 's/^X//' > README << '!EOF!README!'
  29. X                UW Version 4.2
  30. X                31 January 1988
  31. X
  32. XThis is version 4.2 of UW, a multiple-window interface to UNIX for
  33. Xthe Macintosh computer.  The distribution for UW consists of two
  34. Xbinary files for the Macintosh (in BinHex 4.0 format) and a number
  35. Xof source files for the (BSD) UNIX server.
  36. X
  37. XThe distribution includes the following directories:
  38. X
  39. X    h    - all UW include files
  40. X    server    - source code for the UW server
  41. X    lib    - source code for the UW programmer's library
  42. X    utility    - source code for miscellaneous utility programs
  43. X    doc    - [nt]roff documentation (-ms and -man formats)
  44. X    hqx    - Macintosh binary files
  45. X    misc    - other things of possible interest
  46. X
  47. XThe two Macintosh files are "uw.hqx", which is the executable binary
  48. Xand "uw.doc.hqx", which is a MacWrite-format document describing the
  49. XMacintosh user interface.
  50. X
  51. XUW was developed alternately on a Sun 3 and 4.3BSD VAX.  It also
  52. Xhas been tested (more briefly) on a Sun 2 (release 2.0), Integrated
  53. XSolutions VME 68020 (release 3.05), and a Pyramid. It depends quite a
  54. Xbit upon BSD-specific features such as interprocess communication and
  55. Xwill not run without modification on a System V UNIX system.
  56. X
  57. XThis distribution, like the version 3.4 distribution, includes
  58. Xmake files for both 4.2BSD and 4.3BSD.  The choice of make files
  59. Xand other configuration options is determined by the top-level
  60. X"Makefile".  Comments in that file describe the configuration options.
  61. X
  62. XA "make install" in the top-level directory will compile and install
  63. Xall of the (UNIX) pieces of the UW distribution.  As distributed,
  64. Xthis will create a link between the directory name "/usr/include/uw"
  65. Xand the "h" subdirectory and will create a "/usr/local/bin/libuw.a"
  66. Xlibrary file.  These two steps allow application program to use
  67. X    #include <uw/uwlib.h>
  68. Xand
  69. X    cc -o xyzzy xyzzy.o -luw
  70. Xfor greater convenience in creating programs that use the UW library.
  71. X
  72. XIf you do not have the "getopt" library routine, you will find the
  73. Xsource in "misc/getopt.c"  This source code was publicly distributed by
  74. XAT&T and is also available in the "mod.sources" archive.  You should
  75. Xcompile it and install it in your machine's "/lib/libc.a"  (Note that
  76. Xsince it uses "strchr", you should compile it on a BSD system with the
  77. Xcommand "cc -O -c getopt.c -Dstrchr=index".)  [Sorry, I can't find a
  78. Xmanual page which I can (legally) include.]  If you can't change
  79. X"libc.a", then you should add it to the makefiles in the "server"
  80. Xand "lib" directories.
  81. X
  82. XVersion 4.2 is primarily a maintenance release.  Because of constraints
  83. Xon the author's time, few things have changed since version 4.1.  Some
  84. Xof the differences are:
  85. X
  86. X    1)    UW v4.2 is compatible with Multifinder.  It understands background
  87. X    events, so it can receive input and update windows even when
  88. X    another application's window is active.
  89. X
  90. X    2)    Some problems relating to keyboard mapping have been fixed.
  91. X    UW recognizes the Control and ESC keys.  The mapping for the
  92. X    numeric keypad still seems to be incomplete.  The author is
  93. X    hampered by the fact that his development machine still has
  94. X    its original 512K Mac keyboard.  (He dislikes the Mac+ and
  95. X    SE keyboards.)
  96. X
  97. X    3)    A new window type -- plot -- has been defined.  This type of
  98. X    window can only be created by the host.  It interprets output
  99. X    in UNIX v7 plot(5) format.
  100. X
  101. X    4)    Windows may use 7, 9, 10, or 12 point fixed-width fonts.
  102. X    UW includes non-Apple-copyrighted Mishawaka fonts for these sizes.
  103. X
  104. XUW is not public domain.  It is copyrighted.  However, permission to
  105. Xcopy UW is given provided that the copies are not sold and that the
  106. Xcopyright notices are retained.
  107. X
  108. XComments about UW can be sent to the author (me) at the following
  109. Xaddresses:
  110. X
  111. X    ARPANET/MILNET:    jdb@mordor.s1.gov
  112. X
  113. X    UUCP:        {lll-crg,decwrl,caip}!mordor!jdb
  114. X
  115. X    U.S. Mail:    John Bruner
  116. X            Lawrence Livermore National Laboratory
  117. X            P.O. Box 5503, L-276
  118. X            Livermore, CA  94550
  119. X
  120. XI try to answer all mail, but sometimes am unable to do so for reasons
  121. Xbeyond my control (e.g. incomplete or incorrect return addresses,
  122. Xfinicky mailers).
  123. !EOF!README!
  124. echo x - Makefile
  125. sed -e 's/^X//' > Makefile << '!EOF!Makefile!'
  126. X#! /bin/make -f
  127. X#
  128. X#    Makefile for UW version 4.2
  129. X#
  130. X# Specify VERSION 4.3 for 4.3BSD, 4.2 for 4.2BSD (including Sun 3.x)
  131. X#
  132. X# DEFINES is a list of the site-dependent compile-time options:
  133. X#     -DUTMP        attempt to update "/etc/utmp" (who) file
  134. X#     -DV7TTYS    V7-format "/etc/ttys" (pre-4.3BSD)
  135. X#    -DSETOWN_BUG    fcntl(fd, F_SETOWN, pgrp) is broken (pre-4.3BSD)
  136. X#    -Dvoid=int    kludge around broken C compilers
  137. X#
  138. X# UTMP specifies that UW should attempt to update the "/etc/utmp" file.
  139. X# On some (foolish) systems this file is world-writeable.  Other
  140. X# installations may wish AFTER CAREFUL EXAMINATION OF THE ISSUES to
  141. X# install the UW server with group write access to the utmp file.
  142. X#
  143. X# V7TTYS should be used for V7-derived systems that do not have 4.3BSD's
  144. X# "/etc/ttys" file.  This includes 4.2BSD and Sun UNIX.  There is no
  145. X# support for USG's "/etc/inittab".
  146. X#
  147. X# SETOWN_BUG should be defined if the fcntl(fd, F_SETOWN, pgrp) system
  148. X# call is broken (as it is in 4.2BSD and Sun 3.0 UNIX).  On those
  149. X# machines the third argument must be negative to specify a process ID
  150. X# and positive to specify a process group.
  151. X#
  152. X# Some C compilers do not understand pointers to void functions.  The
  153. X# common kludge around this problem is to substitute "int" for "void"
  154. X# everywhere.  "lint" doesn't like this, but the program will compile
  155. X# into working code.
  156. X#
  157. XBINDIR    =    /usr/local/bin
  158. XINCDIR    =    /usr/include/uw
  159. XLIBDIR    =    /usr/local/lib
  160. XVERSION    =    4.3
  161. X
  162. XDEFINES    =    -DUTMP
  163. X
  164. XMKFILES    =    server/Makefile lib/Makefile utility/Makefile hqx/Makefile
  165. X
  166. Xall:    DEFINES $(MKFILES)
  167. X    cd server; make
  168. X    cd lib; make
  169. X    cd utility; make
  170. X    cd hqx; make
  171. X
  172. Xdepend:
  173. X    cd server; make depend
  174. X    cd lib; make depend
  175. X    cd utility; make depend
  176. X
  177. Xinstall:    all
  178. X    ln -s `pwd`/h $(INCDIR)
  179. X    install -s server/uw $(BINDIR)/uw
  180. X    install -s utility/uwtool $(BINDIR)/uwtool
  181. X    install -s utility/uwtitle $(BINDIR)/uwtitle
  182. X    install -s utility/uwterm $(BINDIR)/uwterm
  183. X    install -s utility/uwplot $(BINDIR)/uwplot
  184. X    cp lib/libuw.a $(LIBDIR); ranlib $(LIBDIR)/libuw.a
  185. X
  186. Xclean:
  187. X    cd server; make clean
  188. X    cd lib; make clean
  189. X    cd utility; make clean
  190. X
  191. XDEFINES:    Makefile
  192. X    echo "" $(DEFINES) > DEFINES
  193. X
  194. Xserver/Makefile:    Makefile server/Makefile_$(VERSION)
  195. X    cd server; cp Makefile_$(VERSION) Makefile; make depend
  196. X
  197. Xlib/Makefile:    Makefile lib/Makefile_$(VERSION)
  198. X    cd lib; cp Makefile_$(VERSION) Makefile; make depend
  199. X
  200. Xutility/Makefile:    Makefile utility/Makefile_$(VERSION)
  201. X    cd utility; cp Makefile_$(VERSION) Makefile; make depend
  202. !EOF!Makefile!
  203. echo x - utility/Makefile_4.2
  204. sed -e 's/^X//' > utility/Makefile_4.2 << '!EOF!utility/Makefile_4.2!'
  205. X#! /bin/make -f
  206. X#
  207. X#    uw utility makefile (4.2BSD)
  208. X#
  209. X#    INCDIR should be set to the directory containing header files.
  210. X#
  211. X#    LIBUW should be set to the name of the library file (or, if it is
  212. X#    installed in a system directory, "-luw").
  213. X#
  214. X#    Note: in order for "uwterm" to work on remote machines it is
  215. X#    necessary for it to be installed in a directly where "rsh"
  216. X#    will find it.  The #defined symbol UWTERM in the source can
  217. X#    be set to the desired absolute pathname, if necessary.
  218. X#
  219. X
  220. XINCDIR    =    ../h
  221. X
  222. XLIBUW    =    ../lib/libuw.a
  223. X
  224. XUWTOOL_OBJS =    uwtool.o
  225. XUWTITLE_OBJS =    uwtitle.o
  226. XUWTERM_OBJS =    uwterm.o
  227. XUWPLOT_OBJS =    uwplot.o
  228. X
  229. XOBJECTS    =    $(UWTOOL_OBJS) $(UWTITLE_OBJS) $(UWTERM_OBJS) $(UWPLOT_OBJS)
  230. X
  231. XSOURCES    =    `echo $(OBJECTS) | sed -e 's/\\.o/\\.c/g'`
  232. X
  233. XDEFINES    =    `cat ../DEFINES`
  234. X
  235. XCFLAGS    =    -O -I$(INCDIR) $(DEFINES)
  236. XLFLAGS    =
  237. X
  238. Xall:        uwtool uwtitle uwterm uwplot
  239. X
  240. Xuwtool:        $(UWTOOL_OBJS)
  241. X    $(CC) -o $@ $(LFLAGS) $(UWTOOL_OBJS) $(LIBUW)
  242. X
  243. Xuwtitle:    $(UWTITLE_OBJS)
  244. X    $(CC) -o $@ $(LFLAGS) $(UWTITLE_OBJS) $(LIBUW)
  245. X
  246. Xuwterm:        $(UWTERM_OBJS)
  247. X    $(CC) -o $@ $(LFLAGS) $(UWTERM_OBJS) $(LIBUW)
  248. X
  249. Xuwplot:        $(UWPLOT_OBJS)
  250. X    $(CC) -o $@ $(LFLAGS) $(UWPLOT_OBJS) $(LIBUW)
  251. X
  252. Xlint:
  253. X    for src in $(SOURCES); \
  254. X    do echo $$src:; lint -hubx -I$(INCDIR) $(DEFINES) $$src; done
  255. X
  256. Xtags:
  257. X    ctags $(SOURCES)
  258. X
  259. Xdepend: 
  260. X    grep '^#include' $(SOURCES) | \
  261. X    sed -e '/</d' \
  262. X        -e 's/:[^"]*"\([^"]*\)".*/: ..\/h\/\1/' \
  263. X        -e 's,^../[a-zA-Z0-9]*/\([^\.]*\)\.[cs],\1.o \1.L,' | \
  264. X    awk ' { if ($$1 != prev) { print rec; rec = $$0; prev = $$1; } \
  265. X        else { if (length(rec $$3) > 78) { print rec; rec = $$0; } \
  266. X               else rec = rec " " $$3 } } \
  267. X          END { print rec } ' > makedep
  268. X    echo '/^# DO NOT DELETE THIS LINE/+1,$$d' >eddep
  269. X    echo '$$r makedep' >>eddep
  270. X    echo 'w' >>eddep
  271. X    cp Makefile Makefile.bak
  272. X    ex - Makefile < eddep
  273. X    rm eddep makedep
  274. X
  275. Xclean:
  276. X    -rm -f *.o
  277. X
  278. X# DO NOT DELETE THIS LINE (or the following blank line) -- make depend uses it
  279. X
  280. !EOF!utility/Makefile_4.2!
  281. echo x - utility/Makefile_4.3
  282. sed -e 's/^X//' > utility/Makefile_4.3 << '!EOF!utility/Makefile_4.3!'
  283. X#! /bin/make -f
  284. X#
  285. X#    uw utility makefile (4.3BSD)
  286. X#
  287. X#    INCDIR should be set to the directory containing header files.
  288. X#
  289. X#    LIBUW should be set to the name of the library file (or, if it is
  290. X#    installed in a system directory, "-luw").
  291. X#
  292. X#    Note: in order for "uwterm" to work on remote machines it is
  293. X#    necessary for it to be installed in a directly where "rsh"
  294. X#    will find it.  The #defined symbol UWTERM in the source can
  295. X#    be set to the desired absolute pathname, if necessary.
  296. X#
  297. X
  298. XINCDIR    =    ../h
  299. X
  300. XLIBUW    =    ../lib/libuw.a
  301. X
  302. XUWTOOL_OBJS =    uwtool.o
  303. XUWTITLE_OBJS =    uwtitle.o
  304. XUWTERM_OBJS =    uwterm.o
  305. XUWPLOT_OBJS =    uwplot.o
  306. X
  307. XOBJECTS    =    $(UWTOOL_OBJS) $(UWTITLE_OBJS) $(UWTERM_OBJS) $(UWPLOT_OBJS)
  308. X
  309. XSOURCES    =    `echo $(OBJECTS) | sed -e 's/\\.o/\\.c/g'`
  310. X
  311. XDEFINES    =    `cat ../DEFINES`
  312. X
  313. XCFLAGS    =    -O -I$(INCDIR) $(DEFINES)
  314. XLFLAGS    =
  315. X
  316. Xall:        uwtool uwtitle uwterm uwplot
  317. X
  318. Xuwtool:        $(UWTOOL_OBJS)
  319. X    $(CC) -o $@ $(LFLAGS) $(UWTOOL_OBJS) $(LIBUW)
  320. X
  321. Xuwtitle:    $(UWTITLE_OBJS)
  322. X    $(CC) -o $@ $(LFLAGS) $(UWTITLE_OBJS) $(LIBUW)
  323. X
  324. Xuwterm:        $(UWTERM_OBJS)
  325. X    $(CC) -o $@ $(LFLAGS) $(UWTERM_OBJS) $(LIBUW)
  326. X
  327. Xuwplot:        $(UWPLOT_OBJS)
  328. X    $(CC) -o $@ $(LFLAGS) $(UWPLOT_OBJS) $(LIBUW)
  329. X
  330. Xlint:
  331. X    for src in $(SOURCES); \
  332. X    do echo $$src:; lint -hubx -I$(INCDIR) $(DEFINES) $$src; done
  333. X
  334. Xtags:
  335. X    ctags $(SOURCES)
  336. X
  337. Xdepend: 
  338. X    $(CC) -M -I$(INCDIR) $(DEFINES) $(SOURCES) | \
  339. X    sed -e ':loop' \
  340. X        -e 's/\.\.\/[^ /]*\/\.\./../' \
  341. X        -e 't loop' | \
  342. X    awk ' { if ($$1 != prev) { print rec; rec = $$0; prev = $$1; } \
  343. X        else { if (length(rec $$2) > 78) { print rec; rec = $$0; } \
  344. X               else rec = rec " " $$2 } } \
  345. X          END { print rec } ' >> makedep
  346. X    echo '/^# DO NOT DELETE THIS LINE/+1,$$d' >eddep
  347. X    echo '$$r makedep' >>eddep
  348. X    echo 'w' >>eddep
  349. X    cp Makefile Makefile.bak
  350. X    ex - Makefile < eddep
  351. X    rm eddep makedep
  352. X
  353. Xclean:
  354. X    -rm -f *.o
  355. X
  356. X# DO NOT DELETE THIS LINE (or the following blank line) -- make depend uses it
  357. X
  358. !EOF!utility/Makefile_4.3!
  359. echo x - utility/uwplot.c
  360. sed -e 's/^X//' > utility/uwplot.c << '!EOF!utility/uwplot.c!'
  361. X/*
  362. X *    uwplot
  363. X *
  364. X * Copyright 1986 by John D. Bruner.  All rights reserved.  Permission to
  365. X * copy this program is given provided that the copy is not sold and that
  366. X * this copyright notice is included.
  367. X */
  368. X
  369. X#include <sys/types.h>
  370. X#include <sys/socket.h>
  371. X#include <netinet/in.h>
  372. X#include <sys/signal.h>
  373. X#include <sys/errno.h>
  374. X#include <ctype.h>
  375. X#include <stdio.h>
  376. X
  377. X#include "uwlib.h"
  378. X
  379. Xchar *argv0;
  380. XUWIN uwin;
  381. X
  382. Xmain(argc, argv)
  383. Xchar **argv;
  384. X{
  385. X    register int c, len;
  386. X    register char *cp;
  387. X    register char *title;
  388. X    register struct sockaddr_in *sin;
  389. X    auto struct sockaddr_in sa;
  390. X    auto char buf[4096];
  391. X    extern char *optarg;
  392. X    extern int errno;
  393. X    extern onintr();
  394. X
  395. X    /*
  396. X     * Options which are recognized directly are:
  397. X     *
  398. X     *    -ninet    connect to server at address "inet"
  399. X     *    -ttitle    label window with "title" (default is argv[0])
  400. X     */
  401. X    argv0 = argv[0];
  402. X    sin = (struct sockaddr_in *)0;
  403. X    title = argv0;
  404. X    while ((c = getopt(argc, argv, "n:t:")) != EOF) {
  405. X        switch (c) {
  406. X        case 'n':
  407. X            sa.sin_family = AF_INET;
  408. X            sa.sin_addr.s_addr = 0;
  409. X            sa.sin_port = 0;
  410. X            bzero(sa.sin_zero, sizeof sa.sin_zero);
  411. X            for (cp=optarg; isxdigit(c = *cp); cp++) {
  412. X                /* Pyramid compiler botch */
  413. X                /* sa.sin_addr.s_addr *= 16; */
  414. X                sa.sin_addr.s_addr <<= 4;
  415. X                if (isdigit(c))
  416. X                    sa.sin_addr.s_addr += c - '0';
  417. X                else if (islower(c))
  418. X                    sa.sin_addr.s_addr += c-'a' + 10;
  419. X                else
  420. X                    sa.sin_addr.s_addr += c-'A' + 10;
  421. X            }
  422. X            if (c == '.')
  423. X                for (cp++; isdigit(c = *cp); cp++)
  424. X                    sa.sin_port = sa.sin_port*10 + c-'0';
  425. X            if (sa.sin_addr.s_addr == 0 || sa.sin_port == 0) {
  426. X                fprintf(stderr,
  427. X                    "%s: bad Internet address: %s\n",
  428. X                    argv0, optarg);
  429. X                return(1);
  430. X            }
  431. X            sa.sin_addr.s_addr = htonl(sa.sin_addr.s_addr);
  432. X            sa.sin_port = htons(sa.sin_port);
  433. X            sin = &sa;
  434. X            break;
  435. X        case 't':
  436. X            title = optarg;
  437. X            break;
  438. X        }
  439. X    }
  440. X
  441. X    /*
  442. X     * Catch hangup, interrupt, quit, and termination signals.  Kill
  443. X     * the window if one of these is received.
  444. X     */
  445. X    (void)signal(SIGHUP, onintr);
  446. X    (void)signal(SIGINT, onintr);
  447. X    (void)signal(SIGQUIT, onintr);
  448. X    (void)signal(SIGTERM, onintr);
  449. X
  450. X    /*
  451. X     * Create a new plot window, title it, and make it visible.
  452. X     */
  453. X    if ((uwin = uw_new(UWT_PLOT, sin)) == (UWIN)0) {
  454. X        uw_perror(argv[0], uwerrno, errno);
  455. X        return(1);
  456. X    }
  457. X    (void)uw_stitle(uwin, title);
  458. X    (void)uw_svis(uwin, 1);
  459. X
  460. X    /*
  461. X     * Copy the standard input to the plot window.
  462. X     */
  463. X    while ((len = read(0, buf, sizeof buf)) > 0 ||
  464. X        (len < 0 && errno == EINTR)) {
  465. X        if (len > 0)
  466. X            (void)write(UW_DATAFD(uwin), buf, len);
  467. X    }
  468. X
  469. X    /*
  470. X     * This is something of a hack.  We don't expect to be able to
  471. X     * read anything from the window.  The read will hang until the
  472. X     * window is killed.
  473. X     */
  474. X    while ((len = read(UW_DATAFD(uwin), buf, sizeof buf)) > 0 ||
  475. X        len < 0 && errno == EINTR)
  476. X        ;
  477. X    return(0);
  478. X}
  479. X
  480. Xonintr()
  481. X{
  482. X    uw_kill(uwin);
  483. X    exit(0);
  484. X}
  485. !EOF!utility/uwplot.c!
  486. echo x - utility/uwterm.c
  487. sed -e 's/^X//' > utility/uwterm.c << '!EOF!utility/uwterm.c!'
  488. X/*
  489. X *    uwterm
  490. X *
  491. X * Copyright 1986 by John D. Bruner.  All rights reserved.  Permission to
  492. X * copy this program is given provided that the copy is not sold and that
  493. X * this copyright notice is included.
  494. X */
  495. X#include <sys/types.h>
  496. X#include <sys/file.h>
  497. X#include <sys/ioctl.h>
  498. X#include <sys/socket.h>
  499. X#include <sys/time.h>
  500. X#include <sys/resource.h>
  501. X#include <sys/wait.h>
  502. X#include <netinet/in.h>
  503. X#include <signal.h>
  504. X#include <strings.h>
  505. X#include <ctype.h>
  506. X#include <errno.h>
  507. X#include <stdio.h>
  508. X
  509. X#include "openpty.h"
  510. X#include "uwlib.h"
  511. X
  512. X#ifndef UWTERM
  513. X#define    UWTERM    "uwterm"
  514. X#endif
  515. X
  516. X#define    CTL(c)        ((c)&037)
  517. X
  518. X#ifndef FD_SET
  519. X/* 4.2 retrofit: better definitions for these are in 4.3BSD's <sys/types.h> */
  520. X#define    FD_SET(n,p)    ((p)->fds_bits[0] |= (1 << (n)))
  521. X#define    FD_CLR(n,p)    ((p)->fds_bits[0] &= ~(1 << (n)))
  522. X#define    FD_ISSET(n,p)    ((p)->fds_bits[0] & (1 << (n)))
  523. X#define    FD_ZERO(p)    ((p)->fds_bits[0] = 0)
  524. X#define    FD_SETSIZE    (NBBY*sizeof(long))
  525. X#endif
  526. X
  527. Xextern int optind;
  528. Xextern char *optarg;
  529. Xextern char *getenv();
  530. Xextern char *malloc();
  531. Xextern deadkid();
  532. Xextern int errno;
  533. X
  534. X#ifndef htons
  535. X/* These should have been defined in <netinet/in.h>, but weren't (in 4.2BSD) */
  536. Xextern unsigned short htons(), ntohs();
  537. Xextern unsigned long htonl(), ntohl();
  538. X#endif
  539. X
  540. Xchar *argv0;
  541. X
  542. Xmain(argc, argv)
  543. Xint argc;
  544. Xchar **argv;
  545. X{
  546. X    register char *cp;
  547. X    register int c;
  548. X    int wflag;
  549. X    uwtype_t wtype;
  550. X    char *term, *title, *server, *login;
  551. X    struct sockaddr_in sa, *sin;
  552. X    char hostname[32];
  553. X
  554. X    /*
  555. X     * If called with no arguments, create a new window using the
  556. X     * current shell according to the SHELL environment variable
  557. X     * (or "/bin/sh" if that doesn't exist).
  558. X     *
  559. X     * Options which are recognized directly are:
  560. X     *
  561. X     *    -ninet    connect to server at address "inet"
  562. X     *    -wtype    create window with emulation "type"
  563. X     *    -ttitle    label window with "title"
  564. X     *    -llogin    use login name "login" on remote machine
  565. X     *
  566. X     * If no explicit title is specified, the command name is used.
  567. X     */
  568. X    argv0 = argv[0];
  569. X    sin = (struct sockaddr_in *)0;
  570. X    server = (char *)0;
  571. X    login = (char *)0;
  572. X    title = (char *)0;
  573. X    wflag = 0;
  574. X    term = (char *)0;
  575. X    while ((c = getopt(argc, argv, "l:n:t:w:")) != EOF) {
  576. X        switch (c) {
  577. X        case 'l':
  578. X            if (optarg[0] == '\0') {
  579. X                fprintf(stderr,
  580. X                    "%s: \"-l\" requires user name\n", argv0);
  581. X            } else
  582. X                login = optarg;
  583. X            break;
  584. X        case 'n':
  585. X            server = optarg;
  586. X            sa.sin_family = AF_INET;
  587. X            sa.sin_addr.s_addr = 0;
  588. X            sa.sin_port = 0;
  589. X            bzero(sa.sin_zero, sizeof sa.sin_zero);
  590. X            for (cp=optarg; isxdigit(c = *cp); cp++) {
  591. X                /* Pyramid compiler botch */
  592. X                /* sa.sin_addr.s_addr *= 16; */
  593. X                sa.sin_addr.s_addr <<= 4;
  594. X                if (isdigit(c))
  595. X                    sa.sin_addr.s_addr += c - '0';
  596. X                else if (islower(c))
  597. X                    sa.sin_addr.s_addr += c-'a' + 10;
  598. X                else
  599. X                    sa.sin_addr.s_addr += c-'A' + 10;
  600. X            }
  601. X            if (c == '.')
  602. X                for (cp++; isdigit(c = *cp); cp++)
  603. X                    sa.sin_port = sa.sin_port*10 + c-'0';
  604. X            if (sa.sin_addr.s_addr == 0 || sa.sin_port == 0) {
  605. X                fprintf(stderr,
  606. X                    "%s: bad Internet address: %s\n",
  607. X                    argv0, optarg);
  608. X                return(1);
  609. X            }
  610. X            sa.sin_addr.s_addr = htonl(sa.sin_addr.s_addr);
  611. X            sa.sin_port = htons(sa.sin_port);
  612. X            sin = &sa;
  613. X            break;
  614. X        case 'w':
  615. X            wflag++;
  616. X            term = optarg;
  617. X            wtype = uw_ttype(optarg);
  618. X            break;
  619. X        case 't':
  620. X            title = optarg;
  621. X            break;
  622. X        }
  623. X    }
  624. X
  625. X    gethostname(hostname, sizeof hostname);
  626. X    if (title == (char *)0) {
  627. X        /*
  628. X         * If there was no "-t" argument, then "title" will still
  629. X         * be NULL.  In this case we use the host name.
  630. X         */
  631. X        if (optind == argc)
  632. X            title = hostname;
  633. X        else
  634. X            title = argv[optind];
  635. X    }
  636. X    
  637. X    if (!term) {
  638. X        /*
  639. X         * If there was no "-w" argument, fetch the window
  640. X         * type from the environment.  If that fails, use
  641. X         * a default.
  642. X         */
  643. X        if ((term=getenv("TERM")) != (char *)0)
  644. X            wtype = uw_ttype(term);
  645. X        else
  646. X            wtype = UWT_ADM31;
  647. X    }
  648. X
  649. X    if (optind == argc-1) {
  650. X        /*
  651. X         * The remaining argument is the host name.  Fork an "rsh"
  652. X         * to execute this on the remote machine.
  653. X         */
  654. X        return(doremote(argv[optind], server, title, term, login));
  655. X    } else if (optind == argc) {
  656. X        /*
  657. X         * There are no other arguments.  Set up the connection
  658. X         * to this machine.
  659. X         */
  660. X        return(dolocal(sin, title, wtype, term));
  661. X    } else {
  662. X        fprintf(stderr,
  663. X            "Usage: \"%s [-ttitle] [-wtype] [-naddr] [-llogin] host\"\n",
  664. X            argv0);
  665. X        return(1);
  666. X    }
  667. X}
  668. X
  669. Xdoremote(host, server, title, term, login)
  670. Xchar *host;
  671. Xchar *server;
  672. Xchar *title;
  673. Xchar *term;
  674. Xchar *login;
  675. X{
  676. X    register int fd, i, pid;
  677. X    register char *cp;
  678. X    char *av[16];
  679. X
  680. X    /*
  681. X     * Invoke a remote "uwterm" via "rsh".
  682. X     */
  683. X    i = 0;
  684. X    av[i++] = "rsh";
  685. X    av[i++] = host;
  686. X    av[i++] = "-n";
  687. X    if (login != NULL) {
  688. X        av[i++] = "-l";
  689. X        av[i++] = login;
  690. X    }
  691. X    av[i++] = UWTERM;
  692. X    if (server == (char *)0) {
  693. X        if ((server = getenv("UW_INET")) == (char *)0) {
  694. X            fprintf(stderr,"%s: Can't find window server\n",argv0);
  695. X            return(1);
  696. X        }
  697. X    }
  698. X    if ((cp = malloc(3+strlen(server))) == (char *)0) {
  699. X        fprintf(stderr, "%s: out of memory\n", argv0);
  700. X        return(1);
  701. X    }
  702. X    (void)strcat(strcpy(cp, "-n"), server);
  703. X    av[i++] = cp;
  704. X
  705. X    if (title != (char *)0) {
  706. X        if ((cp = malloc(3+strlen(title))) == (char *)0) {
  707. X            fprintf(stderr, "%s: out of memory\n", argv0);
  708. X            return(1);
  709. X        }
  710. X        (void)strcat(strcpy(cp, "-t"), title);
  711. X        av[i++] = cp;
  712. X    }
  713. X
  714. X    if (term != (char *)0) {
  715. X        if ((cp = malloc(3+strlen(term))) == (char *)0) {
  716. X            fprintf(stderr, "%s: out of memory\n", argv0);
  717. X            return(1);
  718. X        }
  719. X        (void)strcat(strcpy(cp, "-w"), term);
  720. X        av[i++] = cp;
  721. X    }
  722. X
  723. X    av[i] = (char *)0;
  724. X
  725. X    for (fd=getdtablesize()-1; fd > 2; fd--)
  726. X        (void)fcntl(fd, F_SETFD, 1);
  727. X    (void)execvp(av[0], av);
  728. X    (void)execv("/usr/ucb/rsh", av);    /* last-ditch try */
  729. X    perror(av[0]);
  730. X    return(1);
  731. X}
  732. X
  733. X            
  734. Xdolocal(sin, title, wtype, term)
  735. Xstruct sockaddr_in *sin;
  736. Xchar *title;
  737. Xuwtype_t wtype;
  738. Xchar *term;
  739. X{
  740. X    register UWIN uwin;
  741. X    register int fd;
  742. X    register int s;
  743. X    struct ptydesc pt;
  744. X
  745. X    /*
  746. X     * Create and initialize a pseudo-terminal.
  747. X     */
  748. X    if (openpty(&pt) < 0) {
  749. X        fprintf(stderr, "No pseudo-terminals are available\n");
  750. X        return(1);
  751. X    }
  752. X    ttyinit(pt.pt_tfd);
  753. X
  754. X
  755. X    /*
  756. X     * Make fd's 0 and 1 be "/dev/null".  We'd like to force a known
  757. X     * definition for fd 2 at this point, but we may need it for
  758. X     * uw_perror() if uw_new() fails.
  759. X     */
  760. X    if ((fd = open("/dev/null", O_RDWR)) >= 0) {    /* should be zero */
  761. X        if (fd != 0 && pt.pt_tfd != 0 && pt.pt_pfd != 0)
  762. X            dup2(fd, 0);
  763. X        if (fd != 1 && pt.pt_tfd != 1 && pt.pt_pfd != 1)
  764. X            dup2(fd, 1);
  765. X        if (fd > 2)
  766. X            (void)close(fd);
  767. X    }
  768. X
  769. X    /*
  770. X     * Create and title the window.  Make it visible.
  771. X     */
  772. X    if ((uwin = uw_new(wtype, sin)) == (UWIN)0) {
  773. X        uw_perror(argv0, uwerrno, errno);
  774. X        return(1);
  775. X    }
  776. X    (void)uw_stitle(uwin, title);
  777. X    (void)uw_svis(uwin, 1);
  778. X
  779. X    /*
  780. X     * We no longer have use for fd 2, so make it "/dev/null" (the
  781. X     * same as fd 0.
  782. X     */
  783. X    (void)dup2(0, 2);
  784. X
  785. X    /*
  786. X     * Adjust the environment to contain the correct values of TERM,
  787. X     * UW_ID, and UW_INET.  These will be inherited by the child
  788. X     * we will create next.
  789. X     */
  790. X    adjenv(term, sin, UW_ID(uwin));
  791. X
  792. X    /*
  793. X     * Create a process to execute the command connected to the pty.
  794. X     */
  795. X    runcmd(pt.pt_tfd, pt.pt_tname);
  796. X
  797. X    /*
  798. X     * Ignore signals that might cause us trouble.  We do NOT ignore
  799. X     * SIGTSTP so that the user can move us from the foreground into
  800. X     * the background if desired.
  801. X     */
  802. X    signal(SIGINT, SIG_IGN);
  803. X    signal(SIGQUIT, SIG_IGN);
  804. X    signal(SIGCHLD, deadkid);
  805. X
  806. X#if defined(TIOCSWINSZ) || defined(TIOCSSIZE)
  807. X    /*
  808. X     * Install an option handling routine to catch window size
  809. X     * changes from the Mac and make the appropriate changes to
  810. X     * the pseudo-terminal.
  811. X     */
  812. X    setresize(uwin, pt.pt_pfd);
  813. X#endif
  814. X
  815. X    /*
  816. X     * Close the slave side of the pty.  Copy data between the pty
  817. X     * and the window.  The return value from copy() is the exit
  818. X     * status.
  819. X     */
  820. X    (void)close(pt.pt_tfd);
  821. X    s = copy(pt.pt_pfd, UW_DATAFD(uwin));
  822. X    uw_kill(uwin);
  823. X    return(s);
  824. X}
  825. X
  826. Xttyinit(ptyfd)
  827. Xregister int ptyfd;
  828. X{
  829. X    register int ttyfd;
  830. X    struct sgttyb sg;
  831. X    struct tchars tc;
  832. X    struct ltchars ltc;
  833. X    int ldisc;
  834. X    int lmode;
  835. X
  836. X    /*
  837. X     * Initialize the modes of the terminal whose file descriptor
  838. X     * is "ptyfd" to the same modes as the current terminal.  If there
  839. X     * isn't a "current terminal" handy, then use hardcoded defaults.
  840. X     */
  841. X    for (ttyfd=0; ttyfd < 3 && ioctl(ttyfd, TIOCGETD, &ldisc) < 0; ttyfd++)
  842. X        ;
  843. X    if (ttyfd < 3) {
  844. X        (void)ioctl(ttyfd, TIOCGETP, &sg);
  845. X        (void)ioctl(ttyfd, TIOCGETC, &tc);
  846. X        (void)ioctl(ttyfd, TIOCGLTC, <c);
  847. X        (void)ioctl(ttyfd, TIOCLGET, &lmode);
  848. X    } else {
  849. X        ldisc = NTTYDISC;
  850. X
  851. X        sg.sg_ispeed = sg.sg_ospeed = 13; /* doesn't really matter */
  852. X        sg.sg_erase = 0177;    /* ugh */
  853. X        sg.sg_kill = CTL('u');    /* ugh */
  854. X        sg.sg_flags = ECHO|CRMOD|ANYP;
  855. X
  856. X        tc.t_intrc = CTL('c');    /* yuck, should be 0177 */
  857. X        tc.t_quitc = CTL('\\');
  858. X        tc.t_startc = CTL('q');
  859. X        tc.t_stopc = CTL('s');
  860. X        tc.t_eofc = CTL('d');
  861. X        tc.t_brkc = -1;
  862. X
  863. X        ltc.t_suspc = CTL('z');
  864. X        ltc.t_dsuspc = CTL('y');
  865. X        ltc.t_rprntc = CTL('r');
  866. X        ltc.t_flushc = CTL('o');
  867. X        ltc.t_werasc = CTL('w');
  868. X        ltc.t_lnextc = CTL('v');
  869. X
  870. X        lmode = LCRTBS|LCRTERA|LCRTKIL|LCTLECH;
  871. X    }
  872. X    (void)ioctl(ptyfd, TIOCSETD, &ldisc);
  873. X    (void)ioctl(ptyfd, TIOCSETP, &sg);
  874. X    (void)ioctl(ptyfd, TIOCSETC, &tc);
  875. X    (void)ioctl(ptyfd, TIOCSLTC, <c);
  876. X    (void)ioctl(ptyfd, TIOCLSET, &lmode);
  877. X}
  878. X
  879. Xadjenv(term, sin, wid)
  880. Xchar *term;
  881. Xstruct sockaddr_in *sin;
  882. Xuwid_t wid;
  883. X{
  884. X    char *env[4];
  885. X    static char ttype[sizeof "TERM=" + 16];
  886. X    static char inet[sizeof INET_ENV + 16];
  887. X    static char idstr[sizeof "UW_ID=" + 20];
  888. X
  889. X    /*
  890. X     * Redefine the environment variable UW_ID.  Redefine UW_INET
  891. X     * if "sin" is non-NULL.  Redefine TERM.
  892. X     */
  893. X    (void)sprintf(ttype, "TERM=%.15s", term);
  894. X    env[0] = ttype;
  895. X    
  896. X    (void)sprintf(idstr, "UW_ID=%ld", wid);
  897. X    env[1] = idstr;
  898. X
  899. X    if (sin != NULL) {
  900. X        (void)sprintf(inet, "%s=%08lx.%d", INET_ENV,
  901. X            ntohl(sin->sin_addr.s_addr), ntohs(sin->sin_port));
  902. X        env[2] = inet;
  903. X        env[3] = (char *)0;
  904. X    }  else
  905. X        env[2] = (char *)0;
  906. X    env_set(env);
  907. X}
  908. X
  909. Xruncmd(fd, tname)
  910. Xint fd;
  911. Xchar *tname;
  912. X{
  913. X    register int pid;
  914. X    register char *shell;
  915. X
  916. X    /*
  917. X     * Figure out the name of the user's shell.  If unknown,
  918. X     * use a default.
  919. X     */
  920. X    if ((shell = getenv("SHELL")) == (char *)0)
  921. X        shell = "/bin/sh";
  922. X
  923. X    /*
  924. X     * Fork a new process and attach "fd" to fd's 0, 1, and 2 of
  925. X     * that new process.  Disassociate the current controlling
  926. X     * terminal and attach the new one (whose name is "tname").
  927. X     */
  928. X    while ((pid = fork()) < 0)
  929. X        sleep(5);
  930. X    if (pid == 0) {
  931. X        if (fd != 0)
  932. X            dup2(fd, 0);
  933. X        if (fd != 1)
  934. X            dup2(fd, 1);
  935. X        if (fd != 2)
  936. X            dup2(fd, 2);
  937. X        if ((fd = open("/dev/tty", O_RDWR)) >= 0) {
  938. X            (void)ioctl(fd, TIOCNOTTY, (char *)0);
  939. X            (void)close(fd);
  940. X        } else
  941. X            setpgrp(0, 0);
  942. X        (void)open(tname, O_RDWR);
  943. X        for (fd=getdtablesize()-1; fd > 2; fd--)
  944. X            (void)fcntl(fd, F_SETFD, 1);
  945. X        execlp(shell, "-", (char *)0);
  946. X        execl(shell, "-", (char *)0);
  947. X        _exit(1);
  948. X    }
  949. X}
  950. X
  951. Xcopy(fd1, fd2)
  952. Xint fd1, fd2;
  953. X{
  954. X    struct fdinfo {
  955. X        int    fi_fd;        /* associated file descriptor */
  956. X        int    fi_size;    /* amount of data in buffer */
  957. X        char    *fi_ptr;    /* pointer to data in fi_buf */
  958. X        char    fi_buf[1024];
  959. X    };
  960. X    register struct fdinfo *fi, *fo;
  961. X    register int n, nfds, len;
  962. X    struct fdinfo fdinfo[2];
  963. X    struct fd_set rdmask[2], wtmask[2], exmask[2];
  964. X    struct timeval tv;
  965. X
  966. X    /*
  967. X     * Copy data between file descriptors fd1 and fd2.  Return when an
  968. X     * EOF is read or an I/O error (other than an interrupted system
  969. X     * call or non-blocking I/O message) is encountered.
  970. X     */
  971. X    FD_ZERO(&rdmask[1]);
  972. X    FD_ZERO(&wtmask[1]);
  973. X    FD_ZERO(&exmask[1]);
  974. X
  975. X    fdinfo[0].fi_fd = fd1;
  976. X    fdinfo[0].fi_size = 0;
  977. X    fdinfo[1].fi_fd = fd2;
  978. X    fdinfo[1].fi_size = 0;
  979. X
  980. X    FD_SET(fd1, &rdmask[1]);
  981. X    FD_SET(fd2, &rdmask[1]);
  982. X
  983. X    (void)fcntl(fd1, F_SETFL, FNDELAY);
  984. X    (void)fcntl(fd2, F_SETFL, FNDELAY);
  985. X
  986. X    nfds = ((fd1 > fd2) ? fd1 : fd2) + 1;
  987. X
  988. X    while (1) {
  989. X        rdmask[0] = rdmask[1];
  990. X        wtmask[0] = wtmask[1];
  991. X        exmask[0] = exmask[1];
  992. X        errno = 0;
  993. X        if (fdinfo[0].fi_size != 0 || fdinfo[1].fi_size != 0) {
  994. X            /*
  995. X             * Select does not work correctly for writes on
  996. X             * some machines, so we must fake it.  If a write
  997. X             * is pending, we time out after 1/50 second and
  998. X             * pretend that select told us that writes could
  999. X             * now be performed.  The code below will do the
  1000. X             * correct thing if the write would still block.
  1001. X             */
  1002. X            tv.tv_sec = 0;
  1003. X            tv.tv_usec = 1000000 / 50;
  1004. X            n = select(nfds, rdmask, wtmask, exmask, &tv);
  1005. X            wtmask[0] = wtmask[1];
  1006. X        } else
  1007. X            n = select(nfds, rdmask, wtmask, exmask, (struct timeval *)0);
  1008. X        if (n < 0 && errno == EINTR) {
  1009. X            continue;
  1010. X        } else if (n <= 0) {
  1011. X            perror("select");
  1012. X            return(1);
  1013. X        }
  1014. X        for (fi=fdinfo; fi < fdinfo+2; fi++) {
  1015. X            fo = fdinfo + !(fi - fdinfo);
  1016. X            if (FD_ISSET(fi->fi_fd, rdmask)) {
  1017. X                /* data available for reading */
  1018. X                len = read(fi->fi_fd, fi->fi_buf,
  1019. X                    sizeof fi->fi_buf);
  1020. X                if (len > 0) {
  1021. X                    fi->fi_size = len;
  1022. X                    fi->fi_ptr = fi->fi_buf;
  1023. X                    FD_CLR(fi->fi_fd, &rdmask[1]);
  1024. X                    FD_SET(fo->fi_fd, &wtmask[1]);
  1025. X                    FD_SET(fo->fi_fd, &wtmask[0]);
  1026. X                } else if (len == 0) {
  1027. X                    /* EOF, exit */
  1028. X                    return(0);
  1029. X                } else if (errno != EWOULDBLOCK &&
  1030. X                    errno != EINTR) {
  1031. X                    /* error, exit */
  1032. X                    return(1);
  1033. X                }
  1034. X            }
  1035. X            if (FD_ISSET(fo->fi_fd, wtmask)) {
  1036. X                /* data ready for writing */
  1037. X                errno = 0;
  1038. X                len = write(fo->fi_fd, fi->fi_ptr, fi->fi_size);
  1039. X                if (len > 0) {
  1040. X                    fi->fi_ptr += len;
  1041. X                    fi->fi_size -= len;
  1042. X                    if (fi->fi_size == 0) {
  1043. X                        FD_SET(fi->fi_fd, &rdmask[1]);
  1044. X                        FD_CLR(fo->fi_fd, &wtmask[1]);
  1045. X                    }
  1046. X                } else if (errno != EWOULDBLOCK &&
  1047. X                    errno != EINTR) {
  1048. X                    /* error, exit */
  1049. X                    return(1);
  1050. X                }
  1051. X            }
  1052. X        }
  1053. X    }
  1054. X}
  1055. X
  1056. Xdeadkid()
  1057. X{
  1058. X    register int pid;
  1059. X
  1060. X    /*
  1061. X     * Collect dead children.  Don't bother with their exit status
  1062. X     * or resource usage.
  1063. X     */
  1064. X    while ((pid = wait3((union wait *)0, WNOHANG, (struct rusage *)0)) > 0)
  1065. X        ;
  1066. X}
  1067. X
  1068. X#if defined(TIOCSWINSZ) || defined(TIOCSSIZE)
  1069. Xstatic int ptyfd;
  1070. X
  1071. X#ifdef TIOCSWINSZ
  1072. Xstatic struct winsize winsz;
  1073. X
  1074. Xvoid
  1075. Xdoresize(uwin, optnum, optcmd, uwoptval)
  1076. XUWIN uwin;
  1077. Xuwopt_t optnum;
  1078. Xuwoptcmd_t optcmd;
  1079. Xunion uwoptval *uwoptval;
  1080. X{
  1081. X    uwtype_t wtype;
  1082. X
  1083. X    /*
  1084. X     * 4.3BSD-style window resizing
  1085. X     */
  1086. X    if (uw_gtype(uwin, &wtype) < 0)
  1087. X        wtype = UWT_ADM31;    /* probably wrong to do this here */
  1088. X    if (optcmd == UWOC_SET) {
  1089. X        switch (optnum) {
  1090. X        case UWOP_WSIZE:
  1091. X            winsz.ws_ypixel = uwoptval->uwov_point.v;
  1092. X            winsz.ws_xpixel = uwoptval->uwov_point.h;
  1093. X            break;
  1094. X        case UWOP_TSIZE:
  1095. X            if (wtype <= UWT_ANSI) {
  1096. X                winsz.ws_row = uwoptval->uwov_point.v;
  1097. X                winsz.ws_col = uwoptval->uwov_point.h;
  1098. X            }
  1099. X            break;
  1100. X        }
  1101. X        if (wtype <= UWT_ANSI &&
  1102. X            (optnum == UWOP_WSIZE || optnum == UWOP_TSIZE))
  1103. X            (void)ioctl(ptyfd, TIOCSWINSZ, &winsz);
  1104. X    }
  1105. X}
  1106. X
  1107. Xsetresize(uwin, fd)
  1108. XUWIN uwin;
  1109. Xint fd;
  1110. X{
  1111. X    struct uwpoint pt;
  1112. X    uwtype_t wtype;
  1113. X
  1114. X    /*
  1115. X     * Set up the option-handling routine "doresize".
  1116. X     */
  1117. X    ptyfd = fd;
  1118. X    uw_optfn(uwin, UWOP_TSIZE, doresize);
  1119. X    uw_optfn(uwin, UWOP_WSIZE, doresize);
  1120. X    winsz.ws_row = 24;    /* default to standard terminal size */
  1121. X    winsz.ws_col = 80;
  1122. X    if (uw_gwsize(uwin, &pt) == 0) {
  1123. X        winsz.ws_ypixel = pt.uwp_v;
  1124. X        winsz.ws_xpixel = pt.uwp_h;
  1125. X    } else {
  1126. X        /* make up something plausible */
  1127. X        winsz.ws_ypixel = 8 * winsz.ws_row;
  1128. X        winsz.ws_xpixel = 8 * winsz.ws_col;
  1129. X    }
  1130. X
  1131. X    if (uw_gtype(uwin, &wtype) == 0 && wtype <= UWT_ANSI)
  1132. X        (void)uw_optcmd(uwin, UWOP_TSIZE, UWOC_DO, (union uwoptval *)0);
  1133. X}
  1134. X
  1135. X#else
  1136. X#ifdef TIOCSSIZE
  1137. Xvoid
  1138. Xdoresize(uwin, optnum, optcmd, uwoptval)
  1139. XUWIN uwin;
  1140. Xuwopt_t optnum;
  1141. Xuwoptcmd_t optcmd;
  1142. Xunion uwoptval *uwoptval;
  1143. X{
  1144. X    struct ttysize ts;
  1145. X    uwtype_t wtype;
  1146. X
  1147. X    /*
  1148. X     * Sun-style window resizing
  1149. X     */
  1150. X    if (uw_gtype(uwin, &wtype) < 0)
  1151. X        wtype = UWT_ADM31;    /* probably wrong to do this here */
  1152. X    if (wtype <= UWT_ANSI && optnum == UWOP_TSIZE && optcmd == UWOC_SET) {
  1153. X        ts.ts_lines = uwoptval->uwov_point.v;
  1154. X        ts.ts_cols = uwoptval->uwov_point.h;
  1155. X        (void)ioctl(ptyfd, TIOCSSIZE, &ts);
  1156. X    }
  1157. X}
  1158. X
  1159. Xsetresize(uwin, fd)
  1160. XUWIN uwin;
  1161. Xint fd;
  1162. X{
  1163. X    uwtype_t wtype;
  1164. X
  1165. X    /*
  1166. X     * Set up the option-handling routine "doresize".
  1167. X     */
  1168. X    ptyfd = fd;
  1169. X    uw_optfn(uwin, UWOP_TSIZE, doresize);
  1170. X
  1171. X    if (uw_gtype(uwin, &wtype) == 0 && wtype <= UWT_ANSI)
  1172. X        (void)uw_optcmd(uwin, UWOP_TSIZE, UWOC_DO, (union uwoptval *)0);
  1173. X}
  1174. X#endif
  1175. X#endif
  1176. X#endif
  1177. !EOF!utility/uwterm.c!
  1178. echo x - utility/uwtitle.c
  1179. sed -e 's/^X//' > utility/uwtitle.c << '!EOF!utility/uwtitle.c!'
  1180. X/*
  1181. X *    uwtitle
  1182. X *
  1183. X * Copyright 1986 by John D. Bruner.  All rights reserved.  Permission to
  1184. X * copy this program is given provided that the copy is not sold and that
  1185. X * this copyright notice is included.
  1186. X */
  1187. X#include <strings.h>
  1188. X#include <stdio.h>
  1189. X
  1190. X#include "uwlib.h"
  1191. X
  1192. Xextern char *optarg;
  1193. Xextern int optind;
  1194. Xextern int errno;
  1195. X
  1196. Xextern char *getenv();
  1197. Xextern long atol();
  1198. X
  1199. Xmain(argc, argv)
  1200. Xint argc;
  1201. Xchar **argv;
  1202. X{
  1203. X    register int c;
  1204. X    register char *cp, *cq, **av;
  1205. X    register uwid_t uwid;
  1206. X    char *argv0;
  1207. X    char *cqlimit;
  1208. X    union uwoptval uwoptval;
  1209. X
  1210. X    /*
  1211. X     * If called with no arguments, print a syntax message.  Otherwise,
  1212. X     * set the title of the current window to argv[1..argc-1].  The
  1213. X     * window ID is obtained from the environment or the "-i" argument.
  1214. X     */
  1215. X    argv0 = argv[0];
  1216. X    uwid = 0;
  1217. X    while ((c = getopt(argc, argv, "i:")) != EOF) {
  1218. X        switch (c) {
  1219. X        case 'i':
  1220. X            if ((uwid = atol(optarg)) == 0) {
  1221. X                fprintf(stderr,
  1222. X                    "%s: malformed \"-i\" argument\n", argv0);
  1223. X                return(1);
  1224. X            }
  1225. X            break;
  1226. X        }
  1227. X    }
  1228. X    if (optind >= argc) {
  1229. X        fprintf(stderr, "Syntax: \"%s [-iID] title ...\"\n", *argv);
  1230. X        return(1);
  1231. X    }
  1232. X
  1233. X    if (uwid == 0) {
  1234. X        if ((cp = getenv("UW_ID")) == NULL) {
  1235. X            fprintf(stderr,
  1236. X                "%s: can't determine window ID\n", argv0);
  1237. X            return(1);
  1238. X        }
  1239. X
  1240. X        if ((uwid = (uwid_t)atol(cp)) == 0) {
  1241. X            fprintf(stderr,
  1242. X                "%s: garbaged window ID in environment: %s",
  1243. X                argv0, cp);
  1244. X            return(1);
  1245. X        }
  1246. X    }
  1247. X
  1248. X    /*
  1249. X     * Copy the argv list into "uwoptval" and change the title.
  1250. X     */
  1251. X    av = argv + optind - 1;
  1252. X    cq = uwoptval.uwov_string;
  1253. X    cqlimit = uwoptval.uwov_string + sizeof uwoptval.uwov_string;
  1254. X    while ((cp = *++av) != NULL && cq < cqlimit) {
  1255. X        while (cq < cqlimit && (*cq++ = *cp++) != '\0')
  1256. X            ;
  1257. X        cq[-1] = ' ';
  1258. X    }
  1259. X    cq[-1] = '\0';
  1260. X
  1261. X    if (uw_rsetopt(uwid, UWOP_TITLE, &uwoptval) < 0) {
  1262. X        uw_perror("uw_rsetopt", uwerrno, errno);
  1263. X        return(1);
  1264. X    } else
  1265. X        return(0);
  1266. X}
  1267. !EOF!utility/uwtitle.c!
  1268. echo x - utility/uwtool.c
  1269. sed -e 's/^X//' > utility/uwtool.c << '!EOF!utility/uwtool.c!'
  1270. X/*
  1271. X *    uwtool
  1272. X *
  1273. X * Copyright 1986 by John D. Bruner.  All rights reserved.  Permission to
  1274. X * copy this program is given provided that the copy is not sold and that
  1275. X * this copyright notice is included.
  1276. X */
  1277. X#include <strings.h>
  1278. X#include <stdio.h>
  1279. X
  1280. X#include "uwlib.h"
  1281. X
  1282. Xmain(argc, argv)
  1283. Xint argc;
  1284. Xchar **argv;
  1285. X{
  1286. X    register uwid_t uwid;
  1287. X    register char *fname, *term;
  1288. X    register int c;
  1289. X    register uwtype_t wtype;
  1290. X    char *argv0;
  1291. X    char *av[2];
  1292. X    int vflag;
  1293. X    int wflag;
  1294. X    char *title;
  1295. X    union uwoptval uwoptval;
  1296. X    extern int errno;
  1297. X    extern int optind;
  1298. X    extern char *optarg;
  1299. X    extern char *getenv();
  1300. X
  1301. X    /*
  1302. X     * If called with no arguments, create a new window using the
  1303. X     * current shell according to the SHELL environment variable
  1304. X     * (or "/bin/sh" if that doesn't exist).  If called with
  1305. X     * arguments, argv[optind] through argv[argc-1] are the arguments
  1306. X     * to the command.
  1307. X     *
  1308. X     * Options which are recognized directly are:
  1309. X     *
  1310. X     *    -v    (verbose) print new window ID on stdout
  1311. X     *    -wtype    create window with emulation "type"
  1312. X     *    -ttitle    label window with "title"
  1313. X     *
  1314. X     * If no explicit title is specified, the command name is used.
  1315. X     */
  1316. X    argv0 = argv[0];
  1317. X    wflag = 0;
  1318. X    vflag = 0;
  1319. X    title = (char *)0;
  1320. X    while ((c = getopt(argc, argv, "vw:t:")) != EOF) {
  1321. X        switch (c) {
  1322. X        case 'v':
  1323. X            vflag++;
  1324. X            break;
  1325. X        case 'w':
  1326. X            wflag++;
  1327. X            wtype = uw_ttype(optarg);
  1328. X            break;
  1329. X        case 't':
  1330. X            title = optarg;
  1331. X            break;
  1332. X        }
  1333. X    }
  1334. X            
  1335. X    if (optind < argc) {
  1336. X        /*
  1337. X         * Adjust the "argv" pointer according to the number of
  1338. X         * arguments we've processed.
  1339. X         */
  1340. X        argv += optind;
  1341. X        fname = *argv;
  1342. X    } else {
  1343. X        /*
  1344. X         * No (non-option) arguments -- use SHELL
  1345. X         */
  1346. X        if ((fname = getenv("SHELL")) == (char *)0)
  1347. X            fname = "/bin/sh";
  1348. X        av[0] = fname;
  1349. X        av[1] = (char *)0;
  1350. X        argv = av;
  1351. X    }
  1352. X
  1353. X    if (title == (char *)0) {
  1354. X        /*
  1355. X         * If there was no "-t" argument, then "title" will still
  1356. X         * be NULL.  In this case we use the command name as
  1357. X         * the title.
  1358. X         */
  1359. X        title = fname;
  1360. X    }
  1361. X    
  1362. X    if (!wflag) {
  1363. X        /*
  1364. X         * If there was no "-w" argument, fetch the window
  1365. X         * type from the environment.  If that fails, use
  1366. X         * a default.
  1367. X         */
  1368. X        if ((term=getenv("TERM")) != (char *)0)
  1369. X            wtype = uw_ttype(term);
  1370. X        else
  1371. X            wtype = UWT_ADM31;
  1372. X    }
  1373. X    
  1374. X    if ((uwid = uw_cmd(wtype, fname, argv)) > 0) {
  1375. X        (void)strncpy(uwoptval.uwov_string, title,
  1376. X            sizeof uwoptval.uwov_string);
  1377. X        (void)uw_rsetopt(uwid, UWOP_TITLE, &uwoptval);
  1378. X        if (vflag)
  1379. X            printf("%d\n", uwid);
  1380. X        return(0);
  1381. X    } else {
  1382. X        if (uwerrno != UWE_NXSERV)
  1383. X            uw_perror(fname, uwerrno, errno);
  1384. X        else
  1385. X            uw_perror(argv0, uwerrno, errno);
  1386. X        return(1);
  1387. X    }
  1388. X}
  1389. !EOF!utility/uwtool.c!
  1390. echo x - misc/README
  1391. sed -e 's/^X//' > misc/README << '!EOF!misc/README!'
  1392. XThis directory contains three items that may be of interest:
  1393. X
  1394. X
  1395. X    getopt.c    The AT&T version of the getopt() library
  1396. X            routine (for command-line processing).  This
  1397. X            version, to the best of my knowledge, was
  1398. X            placed into the public domain by AT&T.
  1399. X
  1400. X    
  1401. X    macmouse.ml    A package for use with Gosling's EMACS
  1402. X            which intreprets encoded mouse-down and
  1403. X            mouse-up events within windows to perform
  1404. X            various operations.
  1405. X
  1406. X            Author: Chris Kent (kent@decwrl.dec.com)
  1407. X
  1408. X
  1409. X    macmouse.el    A similar macro package for GNU EMACS.
  1410. X
  1411. X            Author: Gregory Lauer (glauer@bbn.arpa)
  1412. X
  1413. X
  1414. XThe two EMACS macro packages were developed for a previous version of
  1415. XUW (version 2.10).  Since I (John Bruner) am not an EMACS user, I do
  1416. Xnot know how well they will work with UW v4.2.
  1417. !EOF!misc/README!
  1418. echo x - misc/getopt.c
  1419. sed -e 's/^X//' > misc/getopt.c << '!EOF!misc/getopt.c!'
  1420. X/*LINTLIBRARY*/
  1421. X#define NULL    0
  1422. X#define EOF    (-1)
  1423. X#define ERR(s, c)    if(opterr){\
  1424. X    extern int strlen(), write();\
  1425. X    char errbuf[2];\
  1426. X    errbuf[0] = c; errbuf[1] = '\n';\
  1427. X    (void) write(2, argv[0], (unsigned)strlen(argv[0]));\
  1428. X    (void) write(2, s, (unsigned)strlen(s));\
  1429. X    (void) write(2, errbuf, 2);}
  1430. X
  1431. Xextern int strcmp();
  1432. Xextern char *strchr();
  1433. X
  1434. Xint    opterr = 1;
  1435. Xint    optind = 1;
  1436. Xint    optopt;
  1437. Xchar    *optarg;
  1438. X
  1439. Xint
  1440. Xgetopt(argc, argv, opts)
  1441. Xint    argc;
  1442. Xchar    **argv, *opts;
  1443. X{
  1444. X    static int sp = 1;
  1445. X    register int c;
  1446. X    register char *cp;
  1447. X
  1448. X    if(sp == 1)
  1449. X        if(optind >= argc ||
  1450. X           argv[optind][0] != '-' || argv[optind][1] == '\0')
  1451. X            return(EOF);
  1452. X        else if(strcmp(argv[optind], "--") == NULL) {
  1453. X            optind++;
  1454. X            return(EOF);
  1455. X        }
  1456. X    optopt = c = argv[optind][sp];
  1457. X    if(c == ':' || (cp=strchr(opts, c)) == NULL) {
  1458. X        ERR(": illegal option -- ", c);
  1459. X        if(argv[optind][++sp] == '\0') {
  1460. X            optind++;
  1461. X            sp = 1;
  1462. X        }
  1463. X        return('?');
  1464. X    }
  1465. X    if(*++cp == ':') {
  1466. X        if(argv[optind][sp+1] != '\0')
  1467. X            optarg = &argv[optind++][sp+1];
  1468. X        else if(++optind >= argc) {
  1469. X            ERR(": option requires an argument -- ", c);
  1470. X            sp = 1;
  1471. X            return('?');
  1472. X        } else
  1473. X            optarg = argv[optind++];
  1474. X        sp = 1;
  1475. X    } else {
  1476. X        if(argv[optind][++sp] == '\0') {
  1477. X            sp = 1;
  1478. X            optind++;
  1479. X        }
  1480. X        optarg = NULL;
  1481. X    }
  1482. X    return(c);
  1483. X}
  1484. !EOF!misc/getopt.c!
  1485. echo x - misc/macmouse.el
  1486. sed -e 's/^X//' > misc/macmouse.el << '!EOF!misc/macmouse.el!'
  1487. X;;;  macmouse.el (Version: 2.0)
  1488. X
  1489. X;;;  Copyright (C) Gregory S. Lauer (glauer@bbn), 1985. 
  1490. X;;;    Please send suggestions and corrections to the above address.
  1491. X;;;
  1492. X;;;  This file contains macmouse, a GNU Emacs mouse package for UW.
  1493. X
  1494. X
  1495. X;;
  1496. X;; GNU Emacs is distributed in the hope that it will be useful,
  1497. X;; but without any warranty.  No author or distributor
  1498. X;; accepts responsibility to anyone for the consequences of using it
  1499. X;; or for whether it serves any particular purpose or works at all,
  1500. X;; unless he says so in writing.
  1501. X
  1502. X;; Everyone is granted permission to copy, modify and redistribute
  1503. X;; GNU Emacs, but only under the conditions described in the
  1504. X;; document "GNU Emacs copying permission notice".   An exact copy
  1505. X;; of the document is supposed to have been given to you along with
  1506. X;; GNU Emacs so that you can know how you may redistribute it all.
  1507. X;; It should be in a file named COPYING.  Among other things, the
  1508. X;; copyright notice and this notice must be preserved on all copies.
  1509. X
  1510. X
  1511. X;;;  Original version for Gosling emacs by Chris Kent, Purdue University 1985.
  1512. X;;;  Modified by Gregory Lauer, BBN, Novemeber 1985.
  1513. X;
  1514. X;
  1515. X;
  1516. X; Macmouse provides the following features:
  1517. X;  Up or down mouse button in a window selects that window
  1518. X;
  1519. X;  A scroll bar/thumbing area for each window with the following features:
  1520. X;       the mode lines are horizontal scroll bars
  1521. X;           (running from rightmost column to under leftmost column)
  1522. X;       the unused right window bar and the dividing lines between
  1523. X;           windows are vertical scroll bars
  1524. X;           (running from top of window THRU modeline
  1525. X;   for vertical scroll bars:
  1526. X;     click at line 1 does previous page
  1527. X;    click at last line does next page
  1528. X;     click anywhere else "thumbs" to the relative portion of the buffer.
  1529. X;     shift-click at line 1 scrolls one line down
  1530. X;     shift-click at last line scrolls one line up
  1531. X;     shift-click elsewhere moves line to top of window
  1532. X;     option-shift-click elsewhere moves line to bottom of window
  1533. X;   for horizontal scroll bars:
  1534. X;       click at column 1 does scroll right one window width
  1535. X;       click at last column does scroll left one window width
  1536. X;       click anywhere else moves to that "percent" of the buffer width
  1537. X;       shift-click at column 1 scrolls one column right
  1538. X;       shift-click at last column scrolls one column left
  1539. X;       shift-click elsewhere moves column to right of window
  1540. X;       option-shift-click elsewhere moves column to left of window
  1541. X;
  1542. X; There is also basic positioning and kill-buffer support:
  1543. X;     click in a buffer moves dot there and selects that buffer
  1544. X;     drag copies the dragged region to the kill buffer
  1545. X;     shift-drag deletes the dragged region to the kill buffer
  1546. X;
  1547. X;   It is possible to use the scrolling and thumbing area to make the region
  1548. X;   larger than a single screen; just click, scroll, release. Make sure
  1549. X;   that the last scroll is just a down event; the up must be in the buffer.
  1550. X;   The last mouse position is remembered for each different buffer (not
  1551. X;   window), and thus you can start a drag in one buffer, select another,
  1552. X;   go back to the first buffer, etc.
  1553. X;
  1554. X;     option-click yanks from the kill buffer
  1555. X;     option-shift-click similarly yanks from a named buffer.
  1556. X; 
  1557. X
  1558. X(defconst mouse-max-x 95 "Maximum UW column returned on mouse click")
  1559. X(defconst mouse-max-y 95 "Maximum UW row returned on mouse click")
  1560. X
  1561. X(make-variable-buffer-local 'mouse-last-x) ; x of last event
  1562. X(set-default 'mouse-last-x 0)
  1563. X
  1564. X(make-variable-buffer-local 'mouse-last-y) ; y of last event
  1565. X(set-default 'mouse-last-y 0)
  1566. X
  1567. X(make-variable-buffer-local 'mouse-last-b) ; buttons at last event
  1568. X(set-default 'mouse-last-b 0)
  1569. X
  1570. X(make-variable-buffer-local 'mouse-last-dot) ; dot after last event
  1571. X(set-default 'mouse-last-dot 0)
  1572. X
  1573. X(make-variable-buffer-local 'scrolling-p)
  1574. X(set-default 'scrolling-p nil)
  1575. X
  1576. X(defun move-mac-cursor ()
  1577. X  (interactive)
  1578. X  (let (savest b x y up down lock shift option command)
  1579. X    (setq savest stack-trace-on-error)
  1580. X    (setq stack-trace-on-error nil)
  1581. X                    ; decode everything
  1582. X    (setq y (- (read-char) 32))
  1583. X    (setq x (- (read-char) 32))
  1584. X    (setq b (- (read-char) 32))
  1585. X    (setq command (< 0 (logand b 1)))    ; command key
  1586. X    (setq shift (< 0 (logand b 2)))    ; shift
  1587. X    (setq lock (< 0 (logand b 4)))    ; caps-lock
  1588. X    (setq option (< 0 (logand b 8)))    ; option
  1589. X    (setq down (< 0 (logand b 16)))    ; mouse down
  1590. X    (setq up (< 0 (logand b 32)))    ; mouse up
  1591. X    (condition-case ()
  1592. X    (progn
  1593. X      (select-window-containing-x-and-y x y) ; side-effect sets scrolling-p
  1594. X      (if scrolling-p
  1595. X          (mouse-scroll-region b x y)
  1596. X        (progn
  1597. X          (move-to-window-x-y x y)    ; move cursor to mouse-dot always
  1598. X          (if down (setq mouse-last-dot (dot)))
  1599. X          (mouse-edit-action))))
  1600. X      (error (message "Click not in selectable window")
  1601. X         (sit-for 1)
  1602. X         (message "")))
  1603. X    (setq stack-trace-on-error savest)
  1604. X    (if down
  1605. X    (progn 
  1606. X      (setq mouse-last-x x)
  1607. X      (setq mouse-last-y y)
  1608. X      (setq mouse-last-b b))
  1609. X      (progn 
  1610. X    (setq mouse-last-x 0)
  1611. X    (setq mouse-last-y 0)
  1612. X    (setq mouse-last-b 0)))))
  1613. X
  1614. X(defun mouse-edit-action ()
  1615. X                                ;marking and editing actions on buttons:
  1616. X                ;   if no movement, nothing.
  1617. X                ;   if movement, save mouse-last-dot,
  1618. X                ;      and edit.
  1619. X                ; editing (on upstrokes):
  1620. X                ;   unmodified, copy to kill buffer.
  1621. X                ;   SHIFTed, delete (cut) to kill buffer.
  1622. X                ; 
  1623. X                ; option-click yanks from kill buffer; 
  1624. X                ; shift-option-click from named buffer.
  1625. X  (let ((fun (get 'mouse-function b)))
  1626. X    (if fun (apply fun nil))))
  1627. X
  1628. X
  1629. X    ; individual button bindings
  1630. X    ; generally will only need up mouse button: mouse-last-dot
  1631. X    ; is saved automatically on down mouse button
  1632. X
  1633. X; only need to define functions for keys that get used
  1634. X
  1635. X(put 'mouse-function 32            ; up
  1636. X     '(lambda ()
  1637. X         (if (and (not (mouse-click-p))
  1638. X         (not scrolling-p))
  1639. X        (copy-region-as-kill (dot) mouse-last-dot))))
  1640. X
  1641. X(put 'mouse-function 34            ; up/shift
  1642. X     '(lambda ()
  1643. X         (if (and (not (mouse-click-p))
  1644. X         (not scrolling-p))
  1645. X           (kill-region (dot) mouse-last-dot))))
  1646. X
  1647. X(put 'mouse-function 40            ; up/option
  1648. X     '(lambda ()
  1649. X         (if (mouse-click-p)
  1650. X        (progn
  1651. X          (yank)
  1652. X          (exchange-dot-and-mark)))))
  1653. X
  1654. X(put 'mouse-function 42
  1655. X     '(lambda ()        ; up/option/shift
  1656. X    (if (mouse-click-p)
  1657. X        (insert-buffer (read-buffer "Insert contents of buffer: ")))))
  1658. X
  1659. X(defun mouse-click-p ()
  1660. X  (= (dot) mouse-last-dot))
  1661. X
  1662. X(defun set-window-boundaries ()
  1663. X  (let ((edges (window-edges)))
  1664. X    (setq xl (1+ (car edges)))
  1665. X    (setq yt (1+ (car (cdr edges))))
  1666. X    (let ((temp (car (cdr (cdr edges)))))
  1667. X      (setq xr (if (= (screen-width) temp) mouse-max-x temp)))
  1668. X    (let ((temp (car (cdr (cdr (cdr edges))))))
  1669. X      (setq yb (if (= (screen-height) temp) mouse-max-y temp )))))
  1670. X
  1671. X(defun select-window-containing-x-and-y (x y)
  1672. X  (let ((starting-window (selected-window)))
  1673. X    (set-window-boundaries)
  1674. X    (while (not (point-in-window x y))
  1675. X      (other-window 1)
  1676. X      (if (eq (selected-window) starting-window)
  1677. X      (error nil)
  1678. X    (set-window-boundaries)))
  1679. X    (if (or (= x xr) (= y yb))
  1680. X    (setq scrolling-p t)
  1681. X      (setq scrolling-p nil))))
  1682. X
  1683. X(defun point-in-window (x y)
  1684. X  (and (<= xl x)(<= x xr)(<= yt y)(<= y yb)))
  1685. X
  1686. X(defun move-to-window-x-y (x y)
  1687. X  (move-to-window-line (- y yt))
  1688. X  (move-to-window-column (- x xl)))
  1689. X
  1690. X(defun move-to-window-column (x)
  1691. X  (move-to-column (+ (max 0 (- (window-hscroll) 1)) x)))
  1692. X
  1693. X(defun mouse-scroll-region (b x y)
  1694. X  (if down
  1695. X      (if shift
  1696. X      (do-lines b x y)
  1697. X    (do-pages b x y)))
  1698. X  (if (and up
  1699. X       (or (/= x mouse-last-x)
  1700. X           (/= y mouse-last-y)))
  1701. X      (if shift
  1702. X      (do-lines b x y)
  1703. X    (do-pages b x y))))
  1704. X
  1705. X(defun do-lines (b x y)            ; fine control over lines
  1706. X  (if (= x xr)
  1707. X      (cond ((= y yt)(scroll-down 1))
  1708. X        ((= y yb)(scroll-up 1))
  1709. X        (t (if option
  1710. X           (scroll-down (- yb y 1))
  1711. X         (scroll-up (- y yt))))))
  1712. X  (if (and (= y yb) (/= x xr))
  1713. X      (cond ((<= x xl)(scroll-right 1))
  1714. X        ((>= x (1- xr))(scroll-left 1))
  1715. X        (t (if option
  1716. X           (move-column-right x)
  1717. X         (move-column-left x))))))
  1718. X
  1719. X(defun move-column-left (x)        ;need to mess about a bit because
  1720. X  (scroll-left                ;first scroll left of 1 just writes
  1721. X   (if (= (window-hscroll) 0)        ;a column of $s in column 1
  1722. X       (- x xl)
  1723. X     (- x xl 1))))
  1724. X
  1725. X(defun move-column-right (x)
  1726. X  (scroll-right (- xr x 2)))
  1727. X
  1728. X
  1729. X(defun do-pages (b x y)            ; large motions via pages and thumbing
  1730. X  (if (= x xr)
  1731. X      (cond ((= y yt)(scroll-down nil))
  1732. X        ((= y yb)(scroll-up nil))
  1733. X        (t (goto-percent (/ (* (- y yt 1) 100)
  1734. X                (- yb yt 2))))))
  1735. X  (if (and (= y yb)(/= x xr))
  1736. X      (cond ((<= x xl)(scroll-right (- (window-width)
  1737. X                       next-screen-context-lines)))
  1738. X        ((>= x (1- xr))(scroll-left (- (window-width)
  1739. X                       next-screen-context-lines)))
  1740. X        (t (goto-horizontal-percent (/ (* (- x xl 1) 100)
  1741. X                       (- xr xl 2)))))))
  1742. X
  1743. X(defun goto-percent (p)
  1744. X  (goto-char (/ (* (- (dot-max) (dot-min)) p) 100)))
  1745. X
  1746. X(defun goto-horizontal-percent (p)    ;try to put this percent of columns
  1747. X  (let ((window-offset (window-hscroll));in the center column of the window
  1748. X    delta)                ;unless that would move the first or
  1749. X    (setq delta                ;last column past the window edge
  1750. X      (- window-offset
  1751. X         (min (max 0 (- (/ (* (screen-width) p) 100)
  1752. X                (/ (- xr xl) 2)))
  1753. X          (- (screen-width) (- xr xl)))))
  1754. X    (scroll-right delta)))
  1755. X
  1756. X    
  1757. X(global-set-key "\em" 'move-mac-cursor)
  1758. !EOF!misc/macmouse.el!
  1759. echo x - misc/macmouse.ml
  1760. sed -e 's/^X//' > misc/macmouse.ml << '!EOF!misc/macmouse.ml!'
  1761. X; $Header: /c/cak/lib/mlisp/RCS/macmouse.ml,v 1.5 85/11/05 14:01:44 cak Rel $
  1762. X; 
  1763. X; Macintosh mouse routines for use with John Bruner's uw program.
  1764. X;     Chris Kent, Purdue University Fri Oct 25 1985
  1765. X;     Copyright 1985 by Christopher A. Kent. All rights reserved.
  1766. X;     Permission to copy is given provided that the copy is not
  1767. X;     sold and this copyright notice is included.
  1768. X; 
  1769. X; Provides a scroll bar/thumbing area in the unused scroll bar with the
  1770. X; following features:
  1771. X;     click at line 1 does previous page
  1772. X;    click at line 24 does next page
  1773. X;     click anywhere else "thumbs" to the relative portion of the buffer.
  1774. X;     shift-click at line 1 scrolls one line down
  1775. X;     shift-click at line 24 scrolls one line up
  1776. X;     shift-click elsewhere moves line to top of window
  1777. X;     option-shift-click elsewhere moves line to bottom of window
  1778. X; 
  1779. X; There is also basic positioning and kill-buffer support:
  1780. X;     click in a buffer moves dot there
  1781. X;     drag copies the dragged region to the kill buffer (mark is left
  1782. X;         at the beginning of the region.)
  1783. X;     shift-drag deletes the dragged region to the kill buffer
  1784. X;   it is possible to use the scrolling and thumbing area to make the region
  1785. X;   larger than a single screen; just click, scroll, release. Make sure
  1786. X;   that the last scroll is just a down event; the up must be in the buffer.
  1787. X;
  1788. X;     option-click yanks from the kill buffer, doesn't affect mark.
  1789. X;     option-shift-click similarly yanks from a named buffer.
  1790. X; 
  1791. X
  1792. X(declare-global
  1793. X    #mouse-last-x        ; x of last event
  1794. X    #mouse-last-y        ; y of last event
  1795. X    #mouse-last-b        ; buttons at last event
  1796. X    #mouse-last-dot        ; dot after last event
  1797. X    #mouse-last-action        ; whether last was scroll (1) or edit (2)
  1798. X)
  1799. X
  1800. X(defun
  1801. X    (move-mac-cursor savest b x y up down lock shift option command saveb
  1802. X    (setq savest stack-trace-on-error)
  1803. X    (setq stack-trace-on-error 0)
  1804. X    ; decode everything
  1805. X    (setq y (- (get-tty-character) 32))
  1806. X    (setq x (- (get-tty-character) 32))
  1807. X    (setq b (- (get-tty-character) 32))
  1808. X    (setq saveb b)
  1809. X    (setq command (% b 2))(setq b (/ b 2))    ; command key
  1810. X    (setq shift (% b 2))(setq b (/ b 2))    ; shift 
  1811. X    (setq lock (% b 2))(setq b (/ b 2))    ; caps-lock
  1812. X    (setq option (% b 2))(setq b (/ b 2))    ; option
  1813. X    (setq down (% b 2))(setq b (/ b 2))    ; mouse down
  1814. X    (setq up (% b 2))
  1815. X    
  1816. X    (if (= x 81)        ; right margin -- move-dot-to-x-y is wrong
  1817. X        (progn 
  1818. X           (#mouse-scroll-region)
  1819. X           (setq #mouse-last-action 1))
  1820. X        (if (error-occurred 
  1821. X            (if (= #mouse-last-action 2)    ; not if just scrolled
  1822. X            (setq #mouse-last-dot (dot)))
  1823. X            (move-dot-to-x-y x y)
  1824. X            (backward-character)(forward-character)
  1825. X            (#mouse-edit-action)
  1826. X            (setq #mouse-last-action 2)
  1827. X        )
  1828. X        (progn 
  1829. X               (#mouse-scroll-region b x y)
  1830. X               (setq #mouse-last-action 1))
  1831. X        ))
  1832. X    (setq stack-trace-on-error savest)
  1833. X    (if (= down 1)
  1834. X        (progn 
  1835. X           (setq #mouse-last-x x)
  1836. X           (setq #mouse-last-y y)
  1837. X           (setq #mouse-last-b saveb))
  1838. X        (progn 
  1839. X           (setq #mouse-last-x 0)
  1840. X           (setq #mouse-last-y 0)
  1841. X           (setq #mouse-last-b 0)))
  1842. X    )
  1843. X    
  1844. X    (#mouse-edit-action        ; marking and editing actions on buttons:
  1845. X                ;   if no movement, nothing.
  1846. X                ;   if movement, put  mark at #mouse-last-dot,
  1847. X                ;      leave dot here,and edit.
  1848. X                ; editing (on upstrokes):
  1849. X                ;   unmodified, copy to kill buffer.
  1850. X                ;   SHIFTed, delete (cut) to kill buffer.
  1851. X                ; 
  1852. X                ; option-click yanks from kill buffer; 
  1853. X                ; shift-option-click from named buffer.
  1854. X    (if (= saveb 16)
  1855. X        (#mouse-d))
  1856. X    (if (= saveb 17)
  1857. X        (#mouse-dc))
  1858. X    (if (= saveb 18)
  1859. X        (#mouse-ds))
  1860. X    (if (= saveb 19)
  1861. X        (#mouse-dsc))
  1862. X    (if (= saveb 20)
  1863. X        (#mouse-dl))
  1864. X    (if (= saveb 21)
  1865. X        (#mouse-dlc))
  1866. X    (if (= saveb 22)
  1867. X        (#mouse-dls))
  1868. X    (if (= saveb 23)
  1869. X        (#mouse-dlsc))
  1870. X    (if (= saveb 24)
  1871. X        (#mouse-do))
  1872. X    (if (= saveb 25)
  1873. X        (#mouse-doc))
  1874. X    (if (= saveb 26)
  1875. X        (#mouse-dos))
  1876. X    (if (= saveb 27)
  1877. X        (#mouse-dosc))
  1878. X    (if (= saveb 28)
  1879. X        (#mouse-dol))
  1880. X    (if (= saveb 29)
  1881. X        (#mouse-dolc))
  1882. X    (if (= saveb 30)
  1883. X        (#mouse-dols))
  1884. X    (if (= saveb 31)
  1885. X        (#mouse-dolsc))
  1886. X    (if (= saveb 32)
  1887. X        (#mouse-u))
  1888. X    (if (= saveb 33)
  1889. X        (#mouse-uc))
  1890. X    (if (= saveb 34)
  1891. X        (#mouse-us))
  1892. X    (if (= saveb 35)
  1893. X        (#mouse-usc))
  1894. X    (if (= saveb 36)
  1895. X        (#mouse-ul))
  1896. X    (if (= saveb 37)
  1897. X        (#mouse-ulc))
  1898. X    (if (= saveb 38)
  1899. X        (#mouse-uls))
  1900. X    (if (= saveb 39)
  1901. X        (#mouse-ulsc))
  1902. X    (if (= saveb 40)
  1903. X        (#mouse-uo))
  1904. X    (if (= saveb 41)
  1905. X        (#mouse-uoc))
  1906. X    (if (= saveb 42)
  1907. X        (#mouse-uos))
  1908. X    (if (= saveb 43)
  1909. X        (#mouse-uosc))
  1910. X    (if (= saveb 44)
  1911. X        (#mouse-uol))
  1912. X    (if (= saveb 45)
  1913. X        (#mouse-uolc))
  1914. X    (if (= saveb 46)
  1915. X        (#mouse-uols))
  1916. X    (if (= saveb 47)
  1917. X        (#mouse-uolsc))
  1918. X    )
  1919. X
  1920. X    ; individual button bindings
  1921. X
  1922. X    (#mouse-u            ; up
  1923. X         (if (! (#mouse-click-p))
  1924. X        (progn 
  1925. X           (#mouse-set-region)
  1926. X           (Copy-region-to-kill-buffer)
  1927. X        ))
  1928. X    )
  1929. X
  1930. X    (#mouse-uc            ; up/command
  1931. X    )
  1932. X
  1933. X    (#mouse-us            ; up/shift
  1934. X         (if (! (#mouse-click-p))
  1935. X        (progn 
  1936. X           (#mouse-set-region)
  1937. X           (delete-to-killbuffer)
  1938. X        ))
  1939. X    )
  1940. X
  1941. X    (#mouse-usc            ; up/shift/command
  1942. X    )
  1943. X
  1944. X    (#mouse-ul            ; up/lock
  1945. X    )
  1946. X
  1947. X    (#mouse-ulc            ; up/lock/command
  1948. X    )
  1949. X
  1950. X    (#mouse-uls            ; up/lock/shift
  1951. X    )
  1952. X
  1953. X    (#mouse-ulsc        ; up/lock/shift/command
  1954. X    )
  1955. X
  1956. X    (#mouse-uo            ; up/option
  1957. X         (if (#mouse-click-p)
  1958. X        (yank-from-killbuffer)
  1959. X    )
  1960. X    )
  1961. X
  1962. X    (#mouse-uoc            ; up/option/command
  1963. X    )
  1964. X
  1965. X    (#mouse-uos            ; up/option/shift
  1966. X    (if (#mouse-click-p)    ; click
  1967. X        (yank-buffer (get-tty-buffer "Insert contents of buffer: "))
  1968. X    )
  1969. X    )
  1970. X
  1971. X    (#mouse-uosc        ; up/option/shift
  1972. X    )
  1973. X
  1974. X    (#mouse-uol            ; up/option/lock
  1975. X    )
  1976. X
  1977. X    (#mouse-uolc        ; up/option/lock
  1978. X    )
  1979. X
  1980. X    (#mouse-uols        ; up/option/lock/shift
  1981. X    )
  1982. X
  1983. X    (#mouse-uolsc        ; up/option/lock/shift/command
  1984. X    )
  1985. X    
  1986. X    (#mouse-d            ; down
  1987. X    )
  1988. X
  1989. X    (#mouse-dc            ; down/command
  1990. X    )
  1991. X
  1992. X    (#mouse-ds            ; down/shift
  1993. X    )
  1994. X
  1995. X    (#mouse-dsc            ; down/shift/command
  1996. X    )
  1997. X
  1998. X    (#mouse-dl            ; down/lock
  1999. X    )
  2000. X
  2001. X    (#mouse-dlc            ; down/lock/command
  2002. X    )
  2003. X
  2004. X    (#mouse-dls            ; down/lock/shift
  2005. X    )
  2006. X
  2007. X    (#mouse-dlsc        ; down/lock/shift/command
  2008. X    )
  2009. X
  2010. X    (#mouse-do            ; down/option
  2011. X    )
  2012. X
  2013. X    (#mouse-doc            ; down/option/command
  2014. X    )
  2015. X
  2016. X    (#mouse-dos            ; down/option/shift
  2017. X    )
  2018. X
  2019. X    (#mouse-dosc        ; down/option/shift
  2020. X    )
  2021. X
  2022. X    (#mouse-dol            ; down/option/lock
  2023. X    )
  2024. X
  2025. X    (#mouse-dolc        ; down/option/lock
  2026. X    )
  2027. X
  2028. X    (#mouse-dols        ; down/option/lock/shift
  2029. X    )
  2030. X
  2031. X    (#mouse-dolsc        ; down/option/lock/shift/command
  2032. X    )
  2033. X
  2034. X    (#mouse-set-region        ; set the region to be from last dot to dot.
  2035. X    (set-mark)
  2036. X    (goto-character #mouse-last-dot)
  2037. X    (exchange-dot-and-mark)
  2038. X    )
  2039. X
  2040. X    (#mouse-click-p clickp
  2041. X         (if (= (dot) #mouse-last-dot)
  2042. X        (setq clickp 1)
  2043. X        (setq clickp 0)
  2044. X    ))
  2045. X    
  2046. X    (#mouse-scroll-region     ; out of range actions:
  2047. X                ;    left margin -- hard to generate, ignored
  2048. X                ;    right margin -- simulate scroll bar
  2049. X                ;      line 1 -- previous page
  2050. X                ;      line 24/25 -- next page
  2051. X                ;      other lines -- thumbing
  2052. X                ;    top margin -- previous page
  2053. X                ;    bottom margin -- next page
  2054. X                ; 
  2055. X                ; if shifted, deal with lines. 
  2056. X                ;    line 1 scrolls one line down
  2057. X                ;    line 24/25 scrolls one line up
  2058. X                ;    else line to top;  with option to bottom.
  2059. X                ;
  2060. X                ; if up stroke is in same place as down
  2061. X                ; stroke, don't do anything, so clicks in
  2062. X                ; the scroll region don't do the action
  2063. X                ; twice.
  2064. X    (if (= down 1)
  2065. X        (if (= shift 1)
  2066. X        (do-lines)
  2067. X        (do-pages))
  2068. X    )
  2069. X    (if (& (= up 1)
  2070. X           (| (!= x #mouse-last-x) (!= y #mouse-last-y)))
  2071. X        (if (= shift 1)
  2072. X        (do-lines)
  2073. X        (do-pages)
  2074. X        )
  2075. X    )
  2076. X    (#mouse-set-region)
  2077. X    )
  2078. X
  2079. X    (do-pages            ; large motions via pages and thumbing
  2080. X    (if (| (= y 0) (= y 1) (= y 24) (= y 25))
  2081. X        (progn 
  2082. X           (if (| (= y 0) (= y 1))
  2083. X               (previous-page)
  2084. X               (Next-Page)
  2085. X           ))
  2086. X        (if (= x 81)
  2087. X        (goto-percent (/ (* y 100) 25))
  2088. X        )
  2089. X    ))
  2090. X
  2091. X    (do-lines            ; fine control over lines
  2092. X    (if (= x 81)
  2093. X        (if (| (= y 1) (= y 24) (= y 25))
  2094. X        (if (| (= y 0) (= y 1))
  2095. X            (scroll-one-line-down)
  2096. X            (scroll-one-line-up)
  2097. X        )
  2098. X        (progn
  2099. X              (move-dot-to-x-y 1 y)
  2100. X              (if (= option 0)
  2101. X              (line-to-top-of-window)
  2102. X              (line-to-bottom-of-window))
  2103. X        )
  2104. X        )
  2105. X    )
  2106. X    )
  2107. X
  2108. X    (line-to-bottom-of-window nlines i
  2109. X    (line-to-top-of-window)
  2110. X    (setq i 0)
  2111. X    (setq nlines (- (window-height) 1))
  2112. X    (while (< i nlines)
  2113. X           (scroll-one-line-down)
  2114. X           (setq i (+ i 1))
  2115. X    )
  2116. X    )
  2117. X
  2118. X    (goto-percent
  2119. X       (goto-character (/ (* (buffer-size) (arg 1)) 100))
  2120. X   )
  2121. X)
  2122. X    
  2123. X(bind-to-key "move-mac-cursor" "\em")
  2124. !EOF!misc/macmouse.ml!
  2125. exit 0
  2126. : end of shell archive
  2127.