home *** CD-ROM | disk | FTP | other *** search
- From: guido@cwi.nl (Guido van Rossum)
- Newsgroups: alt.sources
- Subject: STDWIN 0.9.5, Part 08/19
- Message-ID: <3072@charon.cwi.nl>
- Date: 4 Mar 91 11:57:58 GMT
-
- Archive-name: stdwin/part08
-
- #! /bin/sh
- # This is a shell archive. Remove anything before this line, then unpack
- # it by saving it into a file and typing "sh file". To overwrite existing
- # files, type "sh file -c". You can also feed this as standard input via
- # unshar, or by typing "sh <file", e.g.. If this archive is complete, you
- # will see the following message at the end:
- # "End of archive 8 (of 19)."
- # Contents: Appls/dpv/dpvfonts.c Doc/seldoc.ms
- # Packs/textedit/textlow.c Ports/mac/event.c Ports/mac/menu.h
- # Wrapped by guido@voorn.cwi.nl on Mon Mar 4 12:37:27 1991
- PATH=/bin:/usr/bin:/usr/ucb ; export PATH
- if test -f 'Appls/dpv/dpvfonts.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'Appls/dpv/dpvfonts.c'\"
- else
- echo shar: Extracting \"'Appls/dpv/dpvfonts.c'\" \(12151 characters\)
- sed "s/^X//" >'Appls/dpv/dpvfonts.c' <<'END_OF_FILE'
- X/* dpv -- ditroff previewer. Font translation. */
- X
- X#include "dpv.h"
- X#include "dpvmachine.h"
- X#include "dpvoutput.h"
- X
- X/* Font translation table, to map ditroff font names to font names
- X STDWIN (really the underlying window system) understands.
- X This information should really be read from a configuration file.
- X For now, we know to map some ditroff names for Harris and PostScript
- X fonts to more or less equivalent X11 and Mac fonts.
- X (The X fonts used are to be found in the Andrew distribution).
- X Because the current font scheme in STDWIN for X doesn't know about
- X wsetsize and wsetbold c.s., the translation process is different
- X for X than for the Macintosh. */
- X
- X#define NSIZES 10
- X
- X#define R 0
- X#define B 1
- X#define I 2
- X#define BI 3
- X
- Xstatic struct _translate {
- X char *harname;
- X char *xname;
- X int style;
- X int sizes[NSIZES+1];
- X} default_translate[]= {
- X#ifdef macintosh
- X {"R", "Times", R},
- X {"I", "Times", I},
- X {"B", "Times", B},
- X {"BI", "Times", BI},
- X
- X {"H", "Helvetica", R},
- X {"HO", "Helvetica", I},
- X {"HB", "Helvetica", B},
- X {"HD", "Helvetica", BI},
- X
- X {"C", "Courier", R},
- X {"CO", "Courier", I},
- X {"CB", "Courier", B},
- X {"CD", "Courier", BI},
- X
- X {"lp", "Courier", R},
- X
- X {"Vl", "Helvetica", R},
- X {"vl", "Helvetica", R},
- X {"V", "Helvetica", R},
- X {"v", "Helvetica", R},
- X
- X /* Font used by funny character translation */
- X
- X {"Symbol", "Symbol", R},
- X#else
- X#ifdef X11R2
- X /* X11 Release 2, using fonts from Andrew */
- X
- X /* PostScript font names */
- X
- X {"R", "times%d", R, 8, 10, 12, 16, 22, 0},
- X {"I", "times%di", R, 8, 10, 12, 16, 22, 0},
- X {"B", "times%db", R, 8, 10, 12, 16, 22, 0},
- X {"BI", "times%dbi", R, 8, 10, 12, 16, 22, 0},
- X
- X {"H", "helvetica%d", R, 8, 10, 12, 16, 22, 0},
- X {"HO", "helvetica%di", R, 8, 10, 12, 16, 22, 0},
- X {"HB", "helvetica%db", R, 8, 10, 12, 16, 22, 0},
- X {"HD", "helvetica%dbi",R, 8, 10, 12, 16, 22, 0},
- X
- X {"C", "courier%df", R, 8, 10, 12, 16, 22, 0},
- X {"CO", "courier%dif", R, 8, 10, 12, 16, 22, 0},
- X {"CB", "courier%dbf", R, 8, 10, 12, 16, 22, 0},
- X {"CD", "courier%dbif", R, 8, 10, 12, 16, 22, 0},
- X
- X /* CWI Harris font names (also R, I, B, BI) */
- X
- X /* Vega light, Vega, Vega medium (Helvetica look-alike) */
- X {"Vl", "helvetica%d", R, 8, 10, 12, 16, 22, 0},
- X {"vl", "helvetica%di", R, 8, 10, 12, 16, 22, 0},
- X {"V", "helvetica%d", R, 8, 10, 12, 16, 22, 0},
- X {"v", "helvetica%di", R, 8, 10, 12, 16, 22, 0},
- X {"Vm", "helvetica%db", R, 8, 10, 12, 16, 22, 0,},
- X {"vm", "helvetica%dbi",R, 8, 10, 12, 16, 22, 0,},
- X
- X /* Baskerville (see also small caps) */
- X {"br", "times%d", R, 8, 10, 12, 16, 22, 0,},
- X {"bi", "times%di", R, 8, 10, 12, 16, 22, 0,},
- X {"bb", "times%db", R, 8, 10, 12, 16, 22, 0,},
- X {"bI", "times%dbi", R, 8, 10, 12, 16, 22, 0,},
- X
- X /* Century Schoolbook */
- X {"cr", "times%d", R, 8, 10, 12, 16, 22, 0,},
- X {"ci", "times%di", R, 8, 10, 12, 16, 22, 0,},
- X {"cb", "times%db", R, 8, 10, 12, 16, 22, 0,},
- X {"cI", "times%dbi", R, 8, 10, 12, 16, 22, 0,},
- X
- X /* Laurel */
- X {"lr", "times%d", R, 8, 10, 12, 16, 22, 0,},
- X {"li", "times%di", R, 8, 10, 12, 16, 22, 0,},
- X {"lb", "times%db", R, 8, 10, 12, 16, 22, 0,},
- X {"lI", "times%dbi", R, 8, 10, 12, 16, 22, 0,},
- X
- X /* Funny fonts mapped to Helvetica, at least they differ from Times */
- X {"G3", "helvetica%d", R, 8, 10, 12, 16, 22, 0,}, /* German no 3 */
- X {"fs", "helvetica%d", R, 8, 10, 12, 16, 22, 0,}, /* French Script */
- X {"RS", "helvetica%di", R, 8, 10, 12, 16, 22, 0,}, /* Rose Script */
- X {"SO", "helvetica%db", R, 8, 10, 12, 16, 22, 0,}, /* Scitype Open */
- X
- X /* OCR-B (line printer font) */
- X {"lp", "courier%dbf", R, 8, 10, 12, 0},
- X
- X /* Small caps fonts mapped to normal fonts */
- X {"Rs", "times%d", R, 8, 10, 12, 16, 22, 0,}, /* Times */
- X {"Bs", "times%db", R, 8, 10, 12, 16, 22, 0,}, /* Times bold */
- X {"bs", "times%d", R, 8, 10, 12, 16, 22, 0,}, /* Baskerville */
- X {"bS", "times%db", R, 8, 10, 12, 16, 22, 0,}, /* Baskerv. bold */
- X
- X /* Fonts used by funny character translation */
- X
- X {"symbol", "symbol%d", R, 8, 10, 12, 16, 22, 0},
- X {"symbola","symbola%d", R, 8, 10, 12, 16, 22, 0},
- X#else /* ! X11R3 */
- X /* X11 Release 3 fonts */
- X /* Also works for Release 4 */
- X
- X /* PostScript font names */
- X
- X {"R", "-*-times-medium-r-*--%d-*", R, 8, 10, 12, 14, 18, 24, 0},
- X {"I", "-*-times-medium-i-*--%d-*", R, 8, 10, 12, 14, 18, 24, 0},
- X {"B", "-*-times-bold-r-*--%d-*", R, 8, 10, 12, 14, 18, 24, 0},
- X {"BI", "-*-times-bold-i-*--%d-*", R, 8, 10, 12, 14, 18, 24, 0},
- X
- X {"H", "-*-helvetica-medium-r-*--%d-*", R, 8, 10, 12, 14, 18, 24, 0},
- X {"HO", "-*-helvetica-medium-o-*--%d-*", R, 8, 10, 12, 14, 18, 24, 0},
- X {"HB", "-*-helvetica-bold-r-*--%d-*", R, 8, 10, 12, 14, 18, 24, 0},
- X {"HD", "-*-helvetica-bold-o-*--%d-*",R, 8, 10, 12, 14, 18, 24, 0},
- X
- X {"C", "-*-courier-medium-r-*--%d-*", R, 8, 10, 12, 14, 18, 24, 0},
- X {"CO", "-*-courier-medium-o-*--%d-*", R, 8, 10, 12, 14, 18, 24, 0},
- X {"CB", "-*-courier-bold-r-*--%d-*", R, 8, 10, 12, 14, 18, 24, 0},
- X {"CD", "-*-courier-bold-o-*--%d-*", R, 8, 10, 12, 14, 18, 24, 0},
- X
- X /* CW is a common alias for C */
- X {"CW", "-*-courier-medium-r-*--%d-*", R, 8, 10, 12, 14, 18, 24, 0},
- X
- X /* CWI Harris font names (also R, I, B, BI) */
- X
- X /* Vega light, Vega, Vega medium (Helvetica look-alike) */
- X {"Vl", "-*-helvetica-medium-r-*--%d-*", R, 8, 10, 12, 14, 18, 24, 0},
- X {"vl", "-*-helvetica-medium-o-*--%d-*", R, 8, 10, 12, 14, 18, 24, 0},
- X {"V", "-*-helvetica-medium-r-*--%d-*", R, 8, 10, 12, 14, 18, 24, 0},
- X {"v", "-*-helvetica-medium-o-*--%d-*", R, 8, 10, 12, 14, 18, 24, 0},
- X {"Vm", "-*-helvetica-bold-r-*--%d-*", R, 8, 10, 12, 14, 18, 24, 0,},
- X {"vm", "-*-helvetica-bold-o-*--%d-*",R, 8, 10, 12, 14, 18, 24, 0,},
- X
- X /* Baskerville (see also small caps) */
- X {"br", "-*-times-medium-r-*--%d-*", R, 8, 10, 12, 14, 18, 24, 0,},
- X {"bi", "-*-times-medium-i-*--%d-*", R, 8, 10, 12, 14, 18, 24, 0,},
- X {"bb", "-*-times-bold-r-*--%d-*", R, 8, 10, 12, 14, 18, 24, 0,},
- X {"bI", "-*-times-bold-i-*--%d-*", R, 8, 10, 12, 14, 18, 24, 0,},
- X
- X /* Century Schoolbook */
- X {"cr", "-*-new century schoolbook-medium-r-*--%d-*",
- X R, 8, 10, 12, 14, 18, 24, 0,},
- X {"ci", "-*-new century schoolbook-medium-i-*--%d-*",
- X R, 8, 10, 12, 14, 18, 24, 0,},
- X {"cb", "-*-new century schoolbook-bold-r-*--%d-*",
- X R, 8, 10, 12, 14, 18, 24, 0,},
- X {"cI", "-*-new century schoolbook-bold-i-*--%d-*",
- X R, 8, 10, 12, 14, 18, 24, 0,},
- X
- X /* Laurel */
- X {"lr", "-*-times-medium-r-*--%d-*", R, 8, 10, 12, 14, 18, 24, 0,},
- X {"li", "-*-times-medium-i-*--%d-*", R, 8, 10, 12, 14, 18, 24, 0,},
- X {"lb", "-*-times-bold-r-*--%d-*", R, 8, 10, 12, 14, 18, 24, 0,},
- X {"lI", "-*-times-bold-i-*--%d-*", R, 8, 10, 12, 14, 18, 24, 0,},
- X
- X /* Funny fonts mapped to Helvetica, at least they differ from Times */
- X {"G3", "-*-helvetica-medium-r-*--%d-*", R, 8, 10, 12, 14, 18, 24, 0,},
- X /* German no 3 */
- X {"fs", "-*-helvetica-medium-r-*--%d-*", R, 8, 10, 12, 14, 18, 24, 0,},
- X /* French Script */
- X {"RS", "-*-helvetica-medium-o-*--%d-*", R, 8, 10, 12, 14, 18, 24, 0,},
- X /* Rose Script */
- X {"SO", "-*-helvetica-bold-r-*--%d-*", R, 8, 10, 12, 14, 18, 24, 0,},
- X /* Scitype Open */
- X
- X /* OCR-B (line printer font) */
- X {"lp", "-*-courier-bold-r-*--%d-*", R, 8, 10, 12, 0},
- X
- X /* Small caps fonts mapped to normal fonts */
- X {"Rs", "-*-times-medium-r-*--%d-*", R, 8, 10, 12, 14, 18, 24, 0,},
- X /* Times */
- X {"Bs", "-*-times-bold-r-*--%d-*", R, 8, 10, 12, 14, 18, 24, 0,},
- X /* Times bold */
- X {"bs", "-*-times-medium-r-*--%d-*", R, 8, 10, 12, 14, 18, 24, 0,},
- X /* Baskerville */
- X {"bS", "-*-times-bold-r-*--%d-*", R, 8, 10, 12, 14, 18, 24, 0,},
- X /* Baskerville bold */
- X
- X /* Fonts used by funny character translation */
- X
- X {"r3symbol", "*-*-symbol-medium-r-*--%d-*", R, 8, 10, 12, 14, 18, 24, 0},
- X#endif /* ! X11R2 */
- X#endif /* ! macintosh */
- X
- X {NULL, NULL}
- X};
- X
- Xstatic struct _translate *translate = default_translate;
- X
- X/* Tell STDWIN to use the desired font and size.
- X Call at start of page and after each font or size change. */
- X
- Xusefont()
- X{
- X char *fontname;
- X
- X if (showpage != ipage)
- X return;
- X
- X fontname= fonts.name[font];
- X if (fontname != NULL)
- X fonthack(fontname);
- X /* Else, font not loaded -- assume in initialization phase */
- X baseline= wbaseline();
- X lineheight= wlineheight();
- X recheck();
- X}
- X
- Xfonthack(fontname)
- X char *fontname;
- X{
- X int i;
- X int havesize;
- X char *harname;
- X char buf[256];
- X struct _translate *t;
- X
- X for (t= translate; t->harname != NULL; ++t) {
- X if (strcmp(t->harname, fontname) == 0)
- X break;
- X }
- X if (t->harname == NULL) {
- X fontwarning(fontname);
- X }
- X else {
- X#ifdef macintosh
- X wsetfont(t->xname);
- X wsetsize(size);
- X wsetplain();
- X switch (t->style) {
- X case I: wsetitalic(); break;
- X case B: wsetbold(); break;
- X case BI: wsetbolditalic(); break;
- X }
- X#else
- X havesize= size;
- X for (i= 0; ; ++i) {
- X if (t->sizes[i] >= havesize || t->sizes[i+1] == 0) {
- X havesize= t->sizes[i];
- X break;
- X }
- X }
- X sprintf(buf, t->xname, havesize);
- X wsetfont(buf);
- X#endif
- X }
- X}
- X
- X/* Issue a warning.
- X Avoid warning many times in a row about the same font. */
- X
- Xfontwarning(fontname)
- X char *fontname;
- X{
- X static char lastwarning[200];
- X char buf[256];
- X
- X if (strncmp(lastwarning, fontname, sizeof lastwarning) != 0) {
- X strncpy(lastwarning, fontname, sizeof lastwarning);
- X sprintf(buf, "mapping for font %s unknown", fontname);
- X error(WARNING, buf);
- X }
- X}
- X
- X/* Get a token */
- X
- Xstatic char *
- Xgettok(pp)
- X char **pp;
- X{
- X char *p = *pp;
- X char *start;
- X char c;
- X
- X while (isspace(c = *p++)) /* Skip to start of token */
- X ;
- X if (c == '\0' || c == '\n' || c == '#') {
- X if (dbg > 2)
- X if (c == '#')
- X fprintf(stderr, "next token is comment\n");
- X else if (c == '\n')
- X fprintf(stderr, "next token is newline\n");
- X else
- X fprintf(stderr, "next token is EOS\n");
- X return NULL; /* End of line of comment */
- X }
- X start = p-1; /* Remember start of token */
- X while (!isspace(c = *p++) && c != '\0') /* Skip to end of token */
- X ;
- X if (c == '\0')
- X p--;
- X else
- X p[-1] = '\0'; /* Zero-terminate token */
- X *pp = p; /* Start point for next token */
- X if (dbg > 2)
- X fprintf(stderr, "next token: %s\n", start);
- X return start;
- X}
- X
- Xstatic void
- Xaddtrans(pnt, pt, harname, xname, style, sizes)
- X int *pnt;
- X struct _translate **pt;
- X char *harname;
- X char *xname;
- X int style;
- X int sizes[];
- X{
- X int i = (*pnt)++;
- X struct _translate *t = *pt;
- X
- X if (i == 0)
- X t = (struct _translate *) malloc(sizeof(struct _translate));
- X else
- X t = (struct _translate *)
- X realloc((char *)t, sizeof(struct _translate) * *pnt);
- X if (t == NULL)
- X error(FATAL, "not enough memory for font translations");
- X *pt = t;
- X t += i;
- X t->harname = strdup(harname);
- X t->xname = strdup(xname);
- X t->style = style;
- X for (i = 0; i <= NSIZES; i++)
- X t->sizes[i] = sizes[i];
- X}
- X
- X/* Read a file of alternative font translations. */
- X
- Xreadtrans(filename)
- X char *filename;
- X{
- X struct _translate *t;
- X int nt;
- X FILE *fp;
- X int line;
- X char buf[1000];
- X char *p;
- X char *harname;
- X char *xname;
- X char *sizetemp;
- X int sizes[NSIZES+1];
- X static int defsizes[NSIZES+1] = {8, 10, 12, 14, 18, 24, 0};
- X int nsizes;
- X
- X fp = fopen(filename, "r");
- X if (fp == NULL)
- X error(FATAL, "can't find font translations file %s", filename);
- X if (dbg > 0)
- X fprintf(stderr, "reading translations from %s\n", filename);
- X t = NULL;
- X nt = 0;
- X line = 0;
- X while (fgets(buf, sizeof buf, fp) != NULL) {
- X line++;
- X if (dbg > 1)
- X fprintf(stderr, "line %d: %s\n", line, buf);
- X p = buf;
- X harname = gettok(&p);
- X if (harname == NULL)
- X continue; /* Blank line or comment */
- X xname = gettok(&p);
- X if (xname == NULL) {
- X error(WARNING, "%s(%d): incomplete line (only '%s')",
- X filename, line, harname);
- X continue;
- X }
- X /* Style is always R */
- X nsizes = 0;
- X while (nsizes < NSIZES && (sizetemp = gettok(&p)) != NULL) {
- X sizes[nsizes] = atoi(sizetemp);
- X if (sizes[nsizes] <= 0 ||
- X nsizes > 0 &&
- X sizes[nsizes] <= sizes[nsizes-1]) {
- X error(WARNING,
- X "%s(%d): bad or non-increasing size '%s'",
- X filename, line, sizetemp);
- X }
- X else
- X nsizes++;
- X }
- X if (nsizes > 0)
- X while (nsizes <= NSIZES)
- X sizes[nsizes++] = 0;
- X addtrans(&nt, &t, harname, xname, R,
- X nsizes == 0 ? defsizes : sizes);
- X }
- X if (dbg > 0)
- X fprintf(stderr, "done reading translations.\n");
- X fclose(fp);
- X if (nt == 0)
- X error(FATAL, "%s: no valid font translations", filename);
- X addtrans(&nt, &t, (char *)NULL, (char *)NULL, R, defsizes);
- X translate = t;
- X}
- END_OF_FILE
- if test 12151 -ne `wc -c <'Appls/dpv/dpvfonts.c'`; then
- echo shar: \"'Appls/dpv/dpvfonts.c'\" unpacked with wrong size!
- fi
- # end of 'Appls/dpv/dpvfonts.c'
- fi
- if test -f 'Doc/seldoc.ms' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'Doc/seldoc.ms'\"
- else
- echo shar: Extracting \"'Doc/seldoc.ms'\" \(12081 characters\)
- sed "s/^X//" >'Doc/seldoc.ms' <<'END_OF_FILE'
- X.\" To format, use (di)troff -ms; and make sure macros.ms is around!
- X.so macros.ms
- X.SH
- XUsing X11 Selections and Cut Buffers in STDWIN
- X.LP
- XThe C STDWIN interface has been extended to support the
- X.I selection
- Xmechanism used by X11.
- XSupport for the ring of 8 cut buffers is also provided.
- X.PP
- XThis document assumes you are familiar with STDWIN as a programmer and
- Xwith X11 as an end user (at least xterm experience and some idea of the
- Xclient-server model).
- X.NH
- XWhat are Selections?
- X.LP
- XX11 supports an arbitrary number of selections, but version 1.0 of the
- XICCCM (Inter-Client Communication Conventions Manual, by David Rosenthal)
- Xrequires only that clients support three selections called PRIMARY,
- XSECONDARY and CLIPBOARD.
- XI will further reference these in lower case.
- X.PP
- XThe
- X.I "primary selection"
- Xis the mechanism you normally use to transfer data interactively
- Xbetween clients (or within one client).
- XIn xterm and text-oriented toolkit clients, you make a primary
- Xselection by dragging with the left mouse button.
- XThe contents of the selection are highlighted using inverse video.
- XThe contents of the primary selection can be pasted into the same or
- Xanother (toolkit) client by pressing the middle mouse button.
- X.PP
- XConventions for use of the
- X.I "secondary selection"
- Xare less well-known.
- XIt is used as the second argument of operations with two arguments,
- Xsuch as swap or replace operations.
- XThere is no default support for it in the toolkit, but it is
- Xpossible to customize toolkit clients to use it.
- X.PP
- XThe
- X.I clipboard
- Xis intended to hold data that the user has deleted and wants to insert
- Xsomewhere later.
- XIt is supported by the standard X11 client
- X.I xclipboard ,
- Xwhich displays the current contents of the clipboard.
- XOther toolkit clients can be customized to use it.
- X.NH
- XSelections From the Client's Point of View
- X.LP
- XIt is important to realize that the contents of selections are
- Xtransferred between clients at the time they are pasted; selections are
- Xnot normally stored by the server.
- XAt any time, a selection is ``owned'' by at most one client, the
- X.I "selection owner" .
- XDifferent selections may be owned by different clients.
- XThe server keeps track of selection owners.
- XWhen a client wants to become owner of a particular selection, it tells
- Xthe server so, and the server will send the previous owner an event to
- Xtell it that it no longer owns the selection.
- X.PP
- XThe protocol to transfer the contents of a selection between clients is
- Xfairly involved.
- XSomewhat simplified, it works as follows:
- X.IP \(bu
- XA client requests the contents of a selection from the server.
- X.IP \(bu 2
- XThe server sends the owner an event asking ``please give me this
- Xselection.''
- X.IP \(bu 2
- XThe owner stores the contents of the selection as a
- X.I property\(dg
- X.FS
- X\(dg
- XA window
- X.I property
- Xis a named arbitrary piece of data associated with a window, stored by
- Xthe server.
- X.FE
- Xon the requestor's window, and sends an event back (via the server)
- Xtelling the requestor that the selection is stored.
- X.IP \(bu 2
- XThe requestor fetches the contents of the property, and deletes
- Xthe property.
- X.PP
- XVarious complications are possible:
- X.IP \(bu 2
- XRace conditions: a client may be slow to respond to a mouse click, and
- Xthe impatient user may have clicked again in another client's window.
- XWhen the first client finally decides it wants to become selection
- Xowner, the second client may already own it.
- X.IP \(bu
- XCrashes: a selection owner may crash before it has responded to a
- Xrequest for the selection's contents.
- X.IP \(bu
- XSpace limitations on the server.
- X.IP \(bu
- XNegotiations about the type of the selection: a string could be stored
- Xin simple ASCII or in a special format that retains font information,
- Xand in fact a selection may contain a picture or an arbitrarily
- Xcomplicated data structure that only a few clients know about.
- X.NH
- XThe STDWIN Interface to Selections
- X.LP
- XSTDWIN simplifies the concept of a selection somewhat and takes care of
- Xmost details of communicating with other clients.
- XIn STDWIN, selections are always ASCII strings and only the three
- Xstandard selections are supported.
- XThe strings are null-terminated but may also contain embedded null
- Xcharacters, so a length is always provided.
- X.PP
- XThe header
- X.cW <stdwin.h>
- Xdefines constants that identify the selections:
- X.cW WS_PRIMARY ,
- X.cW WS_SECONDARY ,
- Xand
- X.cW WS_CLIPBOARD .
- XThe application calls the function
- X.cW wsetselection()
- Xto become owner of a selection.
- XIt may later receive an event of type
- X.cW WE_LOST_SEL
- Xtelling it that it lost ownership again.
- XIt is also possible to voluntarily give up selection ownership by
- Xcalling
- X.cW wresetselection() .
- XTo access the contents of a selection, whether you own it or not, call
- Xthe function
- X.cW wgetselection() .
- XTransfer of selection contents to other clients is done automatically by
- X.cW wgetevent()
- Xand
- X.cW wpollevent() .
- XDetailed descriptions of the new functions follow:
- X.NH 2
- XFunction \*<wsetselection()\*>
- X.LP
- X.sC L
- Xbool wsetselection(win, sel, data, len)
- XWINDOW *win;
- Xint sel;
- Xchar *data;
- Xint len;
- X.eC
- X.LP
- XParameters:
- X.IP \*<win\*> 6n
- XSpecifies a window that will be associated with the selection.
- XThis has no other meaning that limiting the lifetime of the selection to
- Xthe lifetime of the window.
- XIt will not be reported in
- X.cW WE_LOST_SEL
- Xevents.
- X.IP \*<sel\*>
- XSpecifies which selection should be set.
- XIt should be one of the codes
- X.cW WS_PRIMARY ,
- X.cW WS_SECONDARY ,
- Xor
- X.cW WS_CLIPBOARD .
- X.IP \*<data\*>
- XSpecifies the data comprising the selection's contents.
- XThis need not be null-terminated.
- XIt is copied to a safe place by the function so it can be sent to
- Xother clients later.
- X.IP \*<len\*>
- XSpecifies the length of the data, not including a terminating null byte.
- X.LP
- XThis function attempts to acquirpe ownership of the specified selection.
- XThis may fail because of race conditions.
- XThe function returns nonzero if it succeeds.
- XIf it fails, the application should give the user visual feedback of the
- Xfailure,
- X.I e.g. ,
- Xby not inverting the selected text.
- X.NH 2
- XFunction \*<wresetselection()\*>
- X.LP
- X.sC L
- Xvoid wresetselection(sel)
- Xint sel;
- X.eC
- X.LP
- XParameters:
- X.IP \*<sel\*> 6n
- XSpecifies which selection should be reset.
- XIt should be one of the codes
- X.cW WS_PRIMARY ,
- X.cW WS_SECONDARY ,
- Xor
- X.cW WS_CLIPBOARD .
- X.LP
- XIf the application owns the specified selection, this function cancels
- Xownership.
- XNo
- X.cW WE_LOST_SEL
- Xevents are generated for the selection.
- X.NH 2
- XFunction \*<wgetselection()\*>
- X.LP
- X.sC L
- Xchar *wgetselection(sel, plen)
- Xint sel;
- Xint *plen;
- X.eC
- XParameters:
- X.IP \*<sel\*> 6n
- XSpecifies which selection should be retrieved.
- XIt should be one of the codes
- X.cW WS_PRIMARY ,
- X.cW WS_SECONDARY ,
- Xor
- X.cW WS_CLIPBOARD .
- X.IP \*<plen\*>
- XInto this parameter, the length of the data is returned, excluding the
- Xterminating null byte.
- X.LP
- XThis function retrieves the contents of the specified selection.
- XIf it succeeds, a pointer to its data is returned.
- XThe data is terminated by a null byte but may contain null bytes, so the
- Xlength is returned separately.
- XThe data pointer points to space internal to the STDWIN library.
- XIt remains valid until the next call involving selections.
- XIf the selection could not be retrieved somehow, a NULL pointer is
- Xreturned.
- XSelections longer that 32K may be truncated.
- XSince the transfer mechanism requires the use of a window, a NULL
- Xpointer is returned when the application currently has no windows open.
- X.NH 2
- XThe \*<WE_LOST_SEL\*> event type
- X.LP
- XA STDWIN application receives this event type when it owns a selection
- X(a call to
- X.cW wsetselection()
- Xhas succeeded) and another client has become the new owner.
- XThe
- X.cW window
- Xmember of the
- X.cW EVENT
- Xis set to
- X.cW NULL .
- XThe
- X.cW u.sel
- Xunion member is set to the code for the selection.
- XThis event is not generated when selection ownership is given up by
- Xcalling
- X.cW wresetselection()
- Xor by deleting its window.
- X.NH
- XThe STDWIN Interface to Cut Buffers
- X.LP
- XFor compatibility with old STDWIN or X11 clients and Andrew clients,
- Xan interface to the cut buffer interface is also provided.
- XThis is a ring of 8 buffers maintained at the server.
- XThe following functions are available:
- X.NH 2
- XFunction \*<wsetcutbuffer()\*>
- X.LP
- X.sC L
- Xvoid wsetcutbuffer(ibuffer, data, len)
- Xint ibuffer;
- Xchar *data;
- Xint len;
- X.eC
- X.LP
- XParameters:
- X.IP \*<ibuffer\*> 10n
- XSpecifies which buffer should be set, in the range [0 ... 7].
- X.IP \*<data\*>
- XSpecifies the data.
- XIt need not be null-terminated.
- X.IP \*<len\*>
- XSpecifies the length of the data, excluding a terminating null byte.
- X.LP
- XThis function sets the contents of the specified cut buffer to the given
- Xdata.
- XNo indication of success or failure is given.
- X.NH 2
- XFunction \*<wgetcutbuffer()\*>
- X.LP
- X.sC L
- Xchar *wgetcutbuffer(ibuffer, plen)
- Xint ibuffer;
- Xint *plen;
- X.eC
- X.LP
- XParameters:
- X.IP \*<ibuffer\*> 10n
- XSpecifies which buffer should be retrieved, in the range [0 ... 7].
- X.IP \*<plen\*>
- XReturns the length of the data, excluding the terminating null byte.
- X.LP
- XThis function returns the contents of the specified cut buffer,
- Xterminated by a null byte.
- XIf the cut buffer is not accessible, it returns
- X.cW NULL .
- X.NH 2
- XFunction \*<wrotatecutbuffers()\*>
- X.LP
- X.sC L
- Xvoid wrotatecutbuffers(n)
- Xint n;
- X.eC
- X.LP
- XParameters:
- X.IP \*<n\*> 4n
- XSpecifies the amount of rotation.
- XThis may be negative.
- X.LP
- XThe cut buffers are rotated as follows:
- Xbuffer n gets the contents of buffer 0, buffer n+1 (mod 8) gets the
- Xcontents of buffer 1, etc.
- X.NH 2
- XFunction \*<wsetclip()\*>
- X.LP
- X.sC L
- Xvoid wsetclip(data, len)
- Xchar *data;
- Xint len;
- X.eC
- XThis function is equivalent to
- X.sC
- Xwsetcutbuffer(0, data, len);
- Xwrotatecutbuffers(1);
- X.eC
- X.NH 2
- XFunction \*<wgetclip()\*>
- X.LP
- X.sC L
- Xchar *wgetclip()
- X.eC
- XThis function is equivalent to
- X.sC
- Xint len;
- Xreturn wgetcutbuffer(0, &len);
- X.eC
- X(It throws away the length.)
- X.NH
- XSuggested Usage
- X.LP
- XTo conform to X11 conventions, STDWIN applications should normally use
- Xthe primary selection, but use the cut buffers as a ``fall-back''
- Xmechanism.
- X.PP
- XWhen the user has selected some text, the application should transfer
- Xthe text to cut buffer 0 and rotate the buffers (the easiest way to do
- Xthis is to call
- X.cW wsetclip() ),
- Xand then call
- X.cW wsetselection()
- Xto set the primary selection to the text.
- XIf the latter call fails, the inverse video on the selected text should
- Xbe removed.
- XThe inverse video should also be removed when a
- X.cW WE_LOST_SEL
- Xevent is received.
- XIf there is a text insertion point associated with the selection, it
- Xshould be left at the position indicated by the last mouse click, or to
- Xthe beginning of the selected text.
- X.PP
- XWhen the user desires to paste some text, the applcation should first
- Xget the contents of the primary selection, and if this returns a NULL
- Xpointer, it should get the contents of cut buffer 0.
- XIf this returns a NULL pointer as well, the paste request should be
- Xrefused (with a beep, or something similar).
- X.PP
- XThe conventions for selecting and pasting text are:
- X.IP \(bu 2
- XDragging with the left (first) mouse button is used to make a selection.
- XDouble-clicking selects ``words.''
- X.IP \(bu
- XClicking with the middle mouse button requests a ``paste'' operation.
- XIt does not move the insert point to the position of the click.
- X.IP \(bu
- XClicking with the right mouse button extends the selection at the end
- Xclosest to the button click.
- X.NH
- XSelections and Macintosh STDWIN
- X.LP
- XThe Macintosh user interface standards prescribe only a single cut
- Xbuffer, called the Clipboard.
- XFor source compatibility with STDWIN applications developed for X11,
- Xdummy versions of the selection functions are provided:
- X.cW wsetselection()
- Xand
- X.cW wgetselection()
- Xalways fail, and
- X.cW wresetselection()
- Xis ignored.
- XVersions of the cut buffer functions are provided that identify cut
- Xbuffer 0 with the Macintosh Clipboard and ignore the other cut buffers.
- X.PP
- XThe net effect is that STDWIN applications written for X11 selections
- Xthat use the cut buffers as a fall-back mechanism will support the
- XMacintosh Clipboard, albeit with an X11-like interface.
- XMacintosh applications are encouraged to provide a standard Edit menu
- Xwith the operations Cut, Copy and Paste and the standard shortcuts for
- Xthem: Command-X, Command-C and Command-V.
- END_OF_FILE
- if test 12081 -ne `wc -c <'Doc/seldoc.ms'`; then
- echo shar: \"'Doc/seldoc.ms'\" unpacked with wrong size!
- fi
- # end of 'Doc/seldoc.ms'
- fi
- if test -f 'Packs/textedit/textlow.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'Packs/textedit/textlow.c'\"
- else
- echo shar: Extracting \"'Packs/textedit/textlow.c'\" \(12558 characters\)
- sed "s/^X//" >'Packs/textedit/textlow.c' <<'END_OF_FILE'
- X/* Text Edit, low-level routines */
- X
- X/* CONVENTION:
- X routines beginning with te... have a first parameter 'tp';
- X routines beginning with z... don't, or are macros that
- X implicitly use a variable or parameter 'tp'
- X*/
- X
- X#include "text.h"
- X
- X/* Variants on wtextwidth, wtextbreak, wdrawtext taking the gap in account.
- X These have two buffer offsets as parameters instead of a text pointer
- X and a length; tetextbreak also returns a buffer offset */
- X
- X/* These routines now also take tabs into account.
- X They should now only be called with a line start for 'pos' ! */
- X
- Xint
- Xtetextwidth(tp, pos, end)
- X register TEXTEDIT *tp;
- X bufpos pos, end;
- X{
- X char *p= tp->buf + pos;
- X register char *e= tp->buf +
- X (tp->gap >= pos && tp->gap < end ? tp->gap : end);
- X int w= 0;
- X register char *k;
- X
- X zcheckpos(pos);
- X zcheckpos(end);
- X zassert(pos <= end);
- X
- X /* This do loop is executed once or twice only! */
- X do {
- X for (k= p; k < e; ++k) {
- X if (*k == '\t') {
- X if (k > p)
- X w += wtextwidth(p, (int)(k-p));
- X w= znexttab(w);
- X p= k+1;
- X }
- X }
- X if (k > p)
- X w += wtextwidth(p, (int)(k-p));
- X if (tp->gap >= pos) {
- X p= tp->buf + zgapend;
- X e= tp->buf + end;
- X }
- X } while (k < e);
- X
- X return w;
- X}
- X
- Xbufpos
- Xtetextbreak(tp, pos, end, width)
- X register TEXTEDIT *tp;
- X bufpos pos, end;
- X int width;
- X{
- X char *p= tp->buf + pos;
- X register char *e= tp->buf +
- X (tp->gap >= pos && tp->gap < end ? tp->gap : end);
- X int w= 0;
- X register char *k;
- X
- X zcheckpos(pos);
- X zcheckpos(end);
- X zassert(pos <= end);
- X
- X /* This do loop is executed once or twice only! */
- X do {
- X for (k= p; k < e; ++k) {
- X if (*k == '\t') {
- X if (k > p) {
- X int n= wtextbreak(p, (int)(k-p),
- X width-w);
- X if (n < k-p)
- X return p - tp->buf + n;
- X w += wtextwidth(p, (int)(k-p));
- X }
- X w= znexttab(w);
- X if (w > width)
- X return k - tp->buf;
- X p= k+1;
- X }
- X }
- X if (k > p) {
- X int n= wtextbreak(p, (int)(k-p), width-w);
- X if (n < k-p)
- X return p - tp->buf + n;
- X w += wtextwidth(p, (int)(k-p));
- X }
- X if (tp->gap >= pos) {
- X p= tp->buf + zgapend;
- X e= tp->buf + end;
- X }
- X } while (k < e);
- X
- X return end;
- X}
- X
- Xhcoord
- Xtedrawtext(tp, h, v, pos, end)
- X register TEXTEDIT *tp;
- X int h, v;
- X bufpos pos, end;
- X{
- X char *p= tp->buf + pos;
- X register char *e= tp->buf +
- X (tp->gap >= pos && tp->gap < end ? tp->gap : end);
- X int w= 0;
- X register char *k;
- X
- X zcheckpos(pos);
- X zcheckpos(end);
- X zassert(pos <= end);
- X
- X /* This do loop is executed once or twice only! */
- X do {
- X for (k= p; k < e; ++k) {
- X if (*k == '\t') {
- X if (k > p)
- X wdrawtext(h+w, v, p, (int)(k-p));
- X w += wtextwidth(p, (int)(k-p));
- X w= znexttab(w);
- X p= k+1;
- X }
- X }
- X if (k > p) {
- X wdrawtext(h+w, v, p, (int)(k-p));
- X w += wtextwidth(p, (int)(k-p));
- X }
- X if (tp->gap >= pos) {
- X p= tp->buf + zgapend;
- X e= tp->buf + end;
- X }
- X } while (k < e);
- X
- X return h+w;
- X}
- X
- X/* Safe memory allocation - these abort instead of returning NULL */
- X
- Xchar *
- Xzmalloc(n)
- X int n;
- X{
- X char *p= malloc((unsigned)n);
- X
- X if (p == NULL) {
- X dprintf("zmalloc(%d): out of mem", n);
- X exit(1);
- X }
- X return p;
- X}
- X
- Xchar *
- Xzrealloc(p, n)
- X char *p;
- X int n;
- X{
- X char *q= realloc(p, (unsigned)n);
- X if (q == NULL) {
- X dprintf("zrealloc(0x%lx, %d): out of mem", (long)p, n);
- X exit(1);
- X }
- X return q;
- X}
- X
- X/* Create/destroy a text-edit record */
- X
- XTEXTEDIT *
- Xtealloc(win, left, top, width)
- X WINDOW *win;
- X{
- X return tesetup(win, left, top, left+width, top, TRUE);
- X}
- X
- XTEXTEDIT *
- Xtecreate(win, left, top, right, bottom)
- X WINDOW *win;
- X int left, top, right, bottom;
- X{
- X return tesetup(win, left, top, right, bottom, TRUE);
- X}
- X
- X/*ARGSUSED*/
- XTEXTEDIT *
- Xtesetup(win, left, top, right, bottom, drawing)
- X WINDOW *win;
- X int left, top, right, bottom;
- X bool drawing;
- X{
- X TEXTEDIT *tp= (TEXTEDIT*) zmalloc(sizeof(TEXTEDIT));
- X TEXTATTR saveattr;
- X
- X tp->win= win;
- X tp->left= left;
- X tp->top= top;
- X tp->right= right;
- X tp->width= right-left;
- X
- X wgettextattr(&saveattr);
- X if (win != NULL) {
- X wgetwintextattr(win, &tp->attr);
- X wsettextattr(&tp->attr);
- X }
- X else
- X tp->attr = saveattr;
- X tp->vspace= wlineheight();
- X tp->tabsize= 8*wcharwidth(' ');
- X if (win != NULL)
- X wsettextattr(&saveattr);
- X
- X tp->bottom= tp->top + tp->vspace;
- X
- X tp->foc= tp->foclen= 0;
- X
- X tp->buflen= 1;
- X tp->buf= zmalloc(tp->buflen);
- X
- X tp->gap= 0;
- X tp->gaplen= tp->buflen;
- X
- X tp->nlines= 1;
- X tp->nstart= STARTINCR;
- X tp->start= (bufpos*) zmalloc(tp->nstart*sizeof(bufpos));
- X tp->start[0]= tp->start[1]= tp->buflen;
- X
- X tp->aim= UNDEF;
- X tp->focprev= FALSE;
- X tp->hilite= FALSE;
- X tp->mdown= FALSE;
- X tp->drawing= tp->active= drawing;
- X tp->opt_valid= FALSE;
- X
- X if (tp->active)
- X tesetcaret(tp);
- X
- X zcheck();
- X
- X return tp;
- X}
- X
- X
- Xvoid
- Xtedestroy(tp)
- X register TEXTEDIT *tp;
- X{
- X wchange(tp->win, tp->left, tp->top, tp->right, tp->bottom);
- X tefree(tp);
- X}
- X
- Xvoid
- Xtefree(tp)
- X register TEXTEDIT *tp;
- X{
- X if (tp->active) {
- X wnocaret(tp->win);
- X tehidefocus(tp);
- X }
- X if (tp->buf != NULL)
- X free(tp->buf);
- X if (tp->start != NULL)
- X free((char*)tp->start);
- X free((char*)tp);
- X}
- X
- Xvoid
- Xtesetactive(tp, active)
- X register TEXTEDIT *tp;
- X bool active;
- X{
- X if (!tp->drawing || tp->active == active)
- X return;
- X tp->active = active;
- X if (active) {
- X tesetcaret(tp);
- X }
- X else {
- X wnocaret(tp->win);
- X tehidefocus(tp);
- X }
- X}
- X
- X/* Show/hide the focus highlighting.
- X The boolean hilite is set when highlighting is visible.
- X teshowfocus ensures the highlighting is visible (if applicable);
- X tehidefocus ensures it is invisible.
- X teinvertfocus does the hard work (it is also called from zdraw) */
- X
- Xteshowfocus(tp)
- X register TEXTEDIT *tp;
- X{
- X if (tp->active && !tp->hilite && tp->foclen > 0) {
- X wbegindrawing(tp->win);
- X teinvertfocus(tp);
- X wenddrawing(tp->win);
- X tp->hilite= TRUE;
- X }
- X}
- X
- Xtehidefocus(tp)
- X register TEXTEDIT *tp;
- X{
- X if (tp->hilite) {
- X wbegindrawing(tp->win);
- X teinvertfocus(tp);
- X wenddrawing(tp->win);
- X tp->hilite= FALSE;
- X }
- X}
- X
- Xstatic
- Xteinvertfocus(tp)
- X register TEXTEDIT *tp;
- X{
- X teinvert(tp, tp->foc, zfocend);
- X}
- X
- X/* Change to a new focus.
- X Sometimes this may keep the focus visible, sometimes not. */
- X
- Xtechangefocus(tp, f1, f2)
- X register TEXTEDIT *tp;
- X int f1, f2;
- X{
- X if (tp->hilite) {
- X wbegindrawing(tp->win);
- X if (f1 == tp->foc)
- X teinvert(tp, zfocend, f2);
- X else if (f2 == zfocend)
- X teinvert(tp, f1, tp->foc);
- X else {
- X teinvert(tp, tp->foc, zfocend);
- X tp->hilite= FALSE;
- X }
- X wenddrawing(tp->win);
- X }
- X tp->foc= f1;
- X tp->foclen= f2-f1;
- X}
- X
- X/* Low-level interface: invert the area between f1 and f2 */
- X
- Xstatic
- Xteinvert(tp, f1, f2)
- X register TEXTEDIT *tp;
- X int f1, f2;
- X{
- X coord h, v, hlast, vlast;
- X
- X if (f1 == f2)
- X return;
- X if (f2 < f1) {
- X int temp= f1;
- X f1= f2;
- X f2= temp;
- X }
- X
- X tewhichpoint(tp, f1, &h, &v);
- X tewhichpoint(tp, f2, &hlast, &vlast);
- X
- X if (v == vlast)
- X winvert(h, v, hlast, v + tp->vspace);
- X else {
- X winvert(h, v, tp->right, v + tp->vspace);
- X winvert(tp->left, v + tp->vspace, tp->right, vlast);
- X winvert(tp->left, vlast, hlast, vlast + tp->vspace);
- X }
- X}
- X
- X/* Draw procedure */
- X
- Xvoid
- Xtedraw(tp)
- X register TEXTEDIT *tp;
- X{
- X tedrawnew(tp, tp->left, tp->top, tp->right, tp->bottom);
- X}
- X
- X/*ARGSUSED*/
- Xvoid
- Xtedrawnew(tp, left, top, right, bottom)
- X register TEXTEDIT *tp;
- X coord left, top, right, bottom;
- X{
- X lineno ifirst, ilast, i;
- X
- X /* Compute first, last line to be drawn */
- X ifirst= (top - tp->top)/tp->vspace;
- X if (ifirst < 0)
- X ifirst= 0;
- X ilast= (bottom - tp->top + tp->vspace - 1)/tp->vspace;
- X if (ilast > tp->nlines)
- X ilast= tp->nlines;
- X
- X /* Draw lines ifirst...ilast-1 */
- X for (i= ifirst; i < ilast; ++i) {
- X bufpos pos= tp->start[i];
- X bufpos end= tp->start[i+1];
- X if (end > pos && zcharbefore(end) == EOL)
- X zdecr(&end);
- X while (end > pos && zcharbefore(end) == ' ')
- X zdecr(&end);
- X (void) tedrawtext(tp, tp->left, tp->top + i*tp->vspace,
- X pos, end);
- X }
- X if (tp->hilite)
- X teinvertfocus(tp);
- X}
- X
- X/* Move the gap to a new position */
- X
- Xtemovegapto(tp, newgap)
- X register TEXTEDIT *tp;
- X bufpos newgap;
- X{
- X zcheck();
- X zassert(0<=newgap && newgap+tp->gaplen<=tp->buflen);
- X
- X if (newgap < tp->gap)
- X teshift(tp, tp->gaplen, newgap, tp->gap);
- X else if (newgap > tp->gap)
- X teshift(tp, -tp->gaplen, zgapend, newgap+tp->gaplen);
- X tp->gap= newgap;
- X
- X zcheck();
- X}
- X
- X/* Extend the gap */
- X
- Xtegrowgapby(tp, add)
- X register TEXTEDIT *tp;
- X int add;
- X{
- X zcheck();
- X zassert(add>=0);
- X
- X tp->buf= zrealloc(tp->buf, tp->buflen + add);
- X teshift(tp, add, zgapend, tp->buflen);
- X tp->gaplen += add;
- X if (tp->start[tp->nlines-1] == tp->buflen)
- X tp->start[tp->nlines-1]= tp->buflen+add;
- X tp->start[tp->nlines]= (tp->buflen += add);
- X
- X zcheck();
- X}
- X
- X/* Shift buf[first..last-1] n bytes (positive right, negative left) */
- X
- Xstatic
- Xteshift(tp, n, first, last)
- X register TEXTEDIT *tp;
- X int n;
- X bufpos first, last;
- X{
- X teoffset(tp, n, first, last);
- X if (n < 0)
- X temovedown(tp, last-first, tp->buf+first, tp->buf+first+n);
- X else if (n > 0)
- X temoveup(tp, last-first, tp->buf+first, tp->buf+first+n);
- X}
- X
- Xstatic
- Xteoffset(tp, n, first, last)
- X register TEXTEDIT *tp;
- X int n;
- X int first, last;
- X{
- X int i;
- X
- X zassert(0<=first&&first<=last&&last<=tp->buflen);
- X
- X i= 0;
- X while (tp->start[i] < first)
- X ++i;
- X while (tp->start[i] < last) {
- X tp->start[i] += n;
- X ++i;
- X }
- X}
- X
- X/*ARGSUSED*/
- Xstatic
- Xtemoveup(tp, n, from, to)
- X TEXTEDIT *tp;
- X int n;
- X char *from, *to;
- X{
- X zassert(from <= to);
- X
- X from += n, to += n;
- X while (--n >= 0)
- X *--to = *--from;
- X}
- X
- X/*ARGSUSED*/
- Xstatic
- Xtemovedown(tp, n, from, to)
- X TEXTEDIT *tp;
- X int n;
- X char *from, *to;
- X{
- X zassert(from >= to);
- X
- X while (--n >= 0)
- X *to++ = *from++;
- X}
- X
- X/* Make all start entries pointing into the gap point to beyond it
- X TO DO: replace by a routine to delete the focus??? */
- X
- Xteemptygap(tp)
- X register TEXTEDIT *tp;
- X{
- X lineno i;
- X
- X for (i= 0; tp->start[i] < tp->gap; ++i)
- X ;
- X for (; tp->start[i] < zgapend; ++i)
- X tp->start[i]= zgapend;
- X}
- X
- X/* Set the caret at the new focus position,
- X or display the focus highlighting, if applicable.
- X Also call wshow() of the focus.
- X As a side effect, the optimization data is invalidated */
- X
- Xtesetcaret(tp)
- X register TEXTEDIT *tp;
- X{
- X coord h, v, hlast, vlast;
- X
- X tp->opt_valid = FALSE;
- X if (!tp->active)
- X return;
- X
- X tewhichpoint(tp, tp->foc, &h, &v);
- X
- X if (tp->foclen == 0) {
- X wsetcaret(tp->win, h, v);
- X hlast= h;
- X vlast= v;
- X }
- X else {
- X tewhichpoint(tp, zfocend, &hlast, &vlast);
- X wnocaret(tp->win);
- X teshowfocus(tp);
- X }
- X wshow(tp->win, h, v, hlast, vlast + tp->vspace);
- X}
- X
- X/* Coordinate transformations.
- X The following coordinate systems exist;
- X a position in the text can be expressed in any of these:
- X
- X A) offset in buffer with gap removed (used for focus)
- X B) offset in buffer (used for start[] array)
- X C) (line number, offset in line taking gap into account)
- X D) (h, v) on screen
- X
- X Conversions exist between successive pairs:
- X
- X A -> B: pos= zaddgap(foc)
- X B -> A: foc= zsubgap(pos)
- X
- X B -> C: line= zwhichline(pos, prev); offset= pos-start[line]
- X C -> B: pos= offset + start[line]
- X
- X C -> D: v= i*vspace; h= ztextwidth(start[i], start[i]+offset)
- X D -> C: i= v/wlh; offset= ztextround(i, h) - start[i]
- X*/
- X
- X/* Find (h, v) corresponding to focus position */
- X
- Xtewhichpoint(tp, f, h_ret, v_ret)
- X TEXTEDIT *tp;
- X focpos f;
- X coord *h_ret, *v_ret;
- X{
- X bufpos pos= zaddgap(f);
- X lineno i= tewhichline(tp, pos, f == tp->foc && tp->focprev);
- X hcoord h= tetextwidth(tp, tp->start[i], pos);
- X
- X *h_ret= h + tp->left;
- X *v_ret= i*tp->vspace + tp->top;
- X}
- X
- X/* To which line does the given buffer position belong? */
- X
- Xlineno
- Xtewhichline(tp, pos, prev)
- X register TEXTEDIT *tp;
- X bufpos pos;
- X bool prev; /* Cf. focprev */
- X{
- X lineno i;
- X
- X for (i= 0; pos > tp->start[i+1]; ++i)
- X ;
- X if (pos == tp->start[i+1] && i+1 < tp->nlines) {
- X ++i;
- X if (prev && zcharbefore(tp->start[i]) != EOL)
- X --i;
- X }
- X
- X return i;
- X}
- X
- X/* Convert point in window to buffer position,
- X possibly taking double-clicking into account.
- X If required, the line number is also returned. */
- X
- Xbufpos
- Xtewhereis(tp, h, v, line_return)
- X register TEXTEDIT *tp;
- X coord h, v;
- X int *line_return;
- X{
- X bufpos pos;
- X lineno i;
- X
- X i= (v - tp->top)/tp->vspace;
- X if (i >= tp->nlines) {
- X i= tp->nlines;
- X pos= tp->buflen;
- X }
- X else if (i < 0) {
- X i= 0;
- X pos= 0;
- X }
- X else
- X pos= tetextround(tp, i, h);
- X if (line_return != NULL)
- X *line_return= i;
- X return pos;
- X}
- X
- X/* Find the buffer position nearest to the given h coordinate,
- X in the given line */
- X
- Xbufpos
- Xtetextround(tp, i, h)
- X register TEXTEDIT *tp;
- X lineno i;
- X hcoord h;
- X{
- X bufpos pos;
- X bufpos end= tp->start[i+1];
- X
- X h -= tp->left;
- X if (end > tp->start[i] && zcharbefore(end) == EOL)
- X zdecr(&end);
- X pos= tetextbreak(tp, tp->start[i], end, h);
- X
- X if (pos < end) {
- X if (h - tetextwidth(tp, tp->start[i], pos) >=
- X tetextwidth(tp, tp->start[i], znext(pos)) - h)
- X zincr(&pos);
- X }
- X
- X return pos;
- X}
- END_OF_FILE
- if test 12558 -ne `wc -c <'Packs/textedit/textlow.c'`; then
- echo shar: \"'Packs/textedit/textlow.c'\" unpacked with wrong size!
- fi
- # end of 'Packs/textedit/textlow.c'
- fi
- if test -f 'Ports/mac/event.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'Ports/mac/event.c'\"
- else
- echo shar: Extracting \"'Ports/mac/event.c'\" \(12997 characters\)
- sed "s/^X//" >'Ports/mac/event.c' <<'END_OF_FILE'
- X/* MAC STDWIN -- EVENT HANDLING. */
- X
- X#include "macwin.h"
- X#ifdef MPW
- X#include <Events.h>
- X#include <Menus.h>
- X#include <Desk.h>
- X#include <ToolUtils.h>
- X#endif
- X#ifdef THINK_C
- X#include <EventMgr.h>
- X#endif
- X
- Xvoid (*_w_idle_proc)(); /* Function to call in idle loop */
- X
- XWINDOW *active= NULL; /* The active window */
- X /* XXX should be a less obvious name */
- Xbool _wm_down; /* Set if mouse is down in content rect */
- X
- Xstatic EventRecord e; /* Global, so it's accessible to all subroutines */
- X /* XXX the name is too short */
- X
- X/* Function prototypes */
- X
- XSTATIC void make_mouse_event _ARGS((EVENT *ep, Point *pwhere));
- XSTATIC void do_idle _ARGS((EVENT *ep));
- XSTATIC void do_update _ARGS((EVENT *ep));
- XSTATIC void do_mouse_down _ARGS((EVENT *ep));
- XSTATIC void do_mouse_up _ARGS((EVENT *ep));
- XSTATIC void do_key _ARGS((EVENT *ep));
- XSTATIC void do_activate _ARGS((EVENT *ep));
- XSTATIC void do_disk _ARGS((EVENT *ep));
- XSTATIC void activate _ARGS((WINDOW *win));
- XSTATIC void deactivate _ARGS((void));
- X
- XSTATIC void do_click _ARGS((EVENT *ep, WindowPtr w));
- XSTATIC void do_unclick _ARGS((EVENT *ep));
- XSTATIC void do_drag _ARGS((WindowPtr w));
- XSTATIC void do_grow _ARGS((EVENT *ep, WindowPtr w));
- XSTATIC void do_goaway _ARGS((EVENT *ep, WindowPtr w));
- XSTATIC void do_zoom _ARGS((EVENT *ep, WindowPtr w, int code));
- XSTATIC void do_size _ARGS((EVENT *ep, WindowPtr w));
- X
- X# ifndef NO_STDIO
- X/* Some applications (e.g., Python) want events passed to the stdio console.
- X They must call wsetstdio(1) before their first wgetevent() call. */
- X
- Xstatic int pass_to_stdio = 0;
- X
- Xvoid
- Xwsetstdio(flag)
- X int flag;
- X{
- X pass_to_stdio = flag;
- X}
- X#endif
- X
- Xstatic EVENT pushback= {WE_NULL};
- X
- Xvoid
- Xwungetevent(ep)
- X EVENT *ep;
- X{
- X pushback= *ep;
- X}
- X
- Xstatic void
- Xwwaitevent(ep, wait)
- X EVENT *ep;
- X bool wait;
- X{
- X _wfreeclip();
- X if (pushback.type != WE_NULL) {
- X *ep= pushback;
- X pushback.type= WE_NULL;
- X return;
- X }
- X
- X if (_wmenuhilite) {
- X HiliteMenu(0);
- X _wmenuhilite= FALSE;
- X }
- X
- X if (active == NULL)
- X set_arrow();
- X
- X ep->type= WE_NULL;
- X ep->window= NULL;
- X
- X do {
- X if (!GetNextEvent(everyEvent, &e)) {
- X if (e.what == nullEvent) {
- X if (wait) do_idle(ep);
- X else return;
- X }
- X }
- X else {
- X#ifndef NO_STDIO
- X /* Give THINK C stdio a chance to handle the event.
- X Unfortunately it also eats up clicks in
- X title bars, so, to save our Option-click feature,
- X we don't feed it those. */
- X if (pass_to_stdio &&
- X !(e.what == mouseDown &&
- X (e.modifiers & optionKey))) {
- X if (StdEvent(&e))
- X continue;
- X }
- X#endif
- X switch (e.what) {
- X case mouseDown:
- X do_mouse_down(ep);
- X break;
- X case mouseUp:
- X do_mouse_up(ep);
- X break;
- X case keyDown:
- X case autoKey:
- X do_key(ep);
- X break;
- X case updateEvt:
- X do_update(ep);
- X break;
- X case diskEvt:
- X do_disk(ep);
- X break;
- X case activateEvt:
- X do_activate(ep);
- X break;
- X }
- X }
- X } while (ep->type == WE_NULL);
- X
- X if (ep->window == NULL)
- X ep->window= whichwin(FrontWindow());
- X if (!_wm_down)
- X set_watch();
- X}
- X
- Xint
- Xwpollevent(ep)
- X EVENT *ep;
- X{
- X ep->type = WE_NULL;
- X wwaitevent(ep, FALSE);
- X return ep->type != WE_NULL;
- X}
- X
- Xvoid
- Xwgetevent(ep)
- X EVENT *ep;
- X{
- X wwaitevent(ep, TRUE);
- X}
- X
- Xstatic void
- Xdo_idle(ep)
- X EVENT *ep;
- X{
- X if (checktimer(ep))
- X return;
- X
- X if (_w_idle_proc != NULL)
- X (*_w_idle_proc)();
- X
- X /* The user idle proc may have called wungetevent: */
- X if (pushback.type != WE_NULL) {
- X *ep= pushback;
- X pushback.type= WE_NULL;
- X return;
- X }
- X
- X SystemTask();
- X
- X if (active != NULL) {
- X Point where;
- X Rect r;
- X
- X where= e.where;
- X SetPort(active->w);
- X GlobalToLocal(&where);
- X if (_wm_down) {
- X autoscroll(active, where.h, where.v);
- X make_mouse_event(ep, &where);
- X return;
- X }
- X getwinrect(active, &r);
- X if (PtInRect(PASSPOINT where, &r)) {
- X if (e.modifiers & optionKey)
- X set_hand();
- X else
- X set_applcursor();
- X }
- X else
- X set_arrow();
- X blinkcaret(active);
- X }
- X}
- X
- Xstatic void
- Xdo_update(ep)
- X EVENT *ep;
- X{
- X WINDOW *win;
- X Rect r;
- X
- X win= whichwin((WindowPtr) e.message);
- X if (win == NULL) {
- X /* dprintf("update evt for alien window"); */
- X return;
- X }
- X _wupdate(win, &r);
- X if (win->drawproc == NULL && !EmptyRect(&r)) {
- X ep->type= WE_DRAW;
- X ep->window= win;
- X ep->u.area.left= r.left;
- X ep->u.area.top= r.top;
- X ep->u.area.right= r.right;
- X ep->u.area.bottom= r.bottom;
- X }
- X}
- X
- Xstatic void
- Xdo_mouse_down(ep)
- X EVENT *ep;
- X{
- X WindowPtr w;
- X int code= FindWindow(PASSPOINT e.where, &w);
- X
- X /* XXX This doesn't look incredibly necessary:
- X if (active != NULL) {
- X SetPort(active->win);
- X rmcaret(active);
- X }
- X */
- X
- X if (code != inContent && code != inSysWindow)
- X set_arrow();
- X switch (code) {
- X case inMenuBar:
- X _wdo_menu(ep, MenuSelect(PASSPOINT e.where));
- X break;
- X case inSysWindow:
- X SystemClick(&e, w);
- X break;
- X case inContent:
- X do_click(ep, w);
- X break;
- X case inDrag:
- X do_drag(w);
- X break;
- X case inGrow:
- X do_grow(ep, w);
- X break;
- X case inGoAway:
- X do_goaway(ep, w);
- X break;
- X case inZoomIn:
- X case inZoomOut:
- X do_zoom(ep, w, code);
- X break;
- X }
- X}
- X
- Xstatic void
- Xdo_mouse_up(ep)
- X EVENT *ep;
- X{
- X do_unclick(ep);
- X}
- X
- Xstatic void
- Xdo_key(ep)
- X EVENT *ep;
- X{
- X char c= e.message & charCodeMask;
- X
- X /* XXX shouldn't mess at all with non-stdwin windows */
- X
- X if (e.modifiers & cmdKey) {
- X if (c == '.') {
- X ep->type= WE_COMMAND;
- X ep->u.command= WC_CANCEL;
- X }
- X else
- X _wdo_menu(ep, MenuKey(c));
- X }
- X else {
- X ep->type= WE_COMMAND;
- X switch (c) {
- X
- X default:
- X ObscureCursor();
- X ep->type= WE_CHAR;
- X ep->u.character= c;
- X break;
- X
- X case LEFT_ARROW:
- X case RIGHT_ARROW:
- X case UP_ARROW:
- X case DOWN_ARROW:
- X ep->u.command= c-LEFT_ARROW + WC_LEFT;
- X break;
- X
- X case '\b':
- X ObscureCursor();
- X ep->u.command= WC_BACKSPACE;
- X break;
- X
- X case '\t':
- X ObscureCursor();
- X ep->u.command= WC_TAB;
- X break;
- X
- X case '\r':
- X case ENTER_KEY:
- X ep->u.command= WC_RETURN;
- X break;
- X
- X }
- X }
- X}
- X
- Xstatic void
- Xdo_disk(ep)
- X EVENT *ep;
- X{
- X /* XXX Disk events not implemented -- who cares. */
- X}
- X
- X/* XXX Need to be easier for cases where we seem to have missed events */
- X
- Xstatic void
- Xdo_activate(ep)
- X EVENT *ep;
- X{
- X WINDOW *win= whichwin((WindowPtr)e.message);
- X
- X if (win == NULL) {
- X /* dprintf("(de)activate evt for alien window"); */
- X return;
- X }
- X
- X if (e.modifiers & activeFlag) { /* Activation */
- X if (active != NULL) {
- X /* Perhaps reactivation after modal dialog */
- X#ifdef NO_STDIO
- X /* But perhaps THINK C stdio is fooling us */
- X if (active == win)
- X return;
- X /* If we get here we've missed a
- X deactivate event... */
- X dprintf("activate without deactivate");
- X#endif
- X }
- X activate(win);
- X ep->type= WE_ACTIVATE;
- X ep->window= active;
- X }
- X else { /* Deactivation */
- X if (win != active) {
- X /* Spurious deactivation event.
- X This always happens when we open
- X two or more windows without intervening
- X call to wgetevent().
- X Perhaps an conscious hack in the
- X ROM to "help" programs that believe
- X windows are created active? */
- X return;
- X }
- X ep->type= WE_DEACTIVATE;
- X ep->window= active;
- X deactivate();
- X }
- X}
- X
- Xstatic void
- Xdeactivate()
- X{
- X SetPort(active->w);
- X rmcaret(active);
- X hidescrollbars(active);
- X rmlocalmenus(active);
- X DrawGrowIcon(active->w);
- X active= NULL;
- X set_arrow();
- X}
- X
- Xstatic void
- Xactivate(win)
- X WINDOW *win;
- X{
- X if (active != NULL)
- X deactivate();
- X if (win != NULL) {
- X SetPort(win->w);
- X active= win;
- X showscrollbars(win);
- X addlocalmenus(active);
- X valid_border(win->w); /* Avoid flicker when window pops up */
- X }
- X}
- X
- Xstatic void
- Xdo_click(ep, w)
- X EVENT *ep;
- X WindowPtr w;
- X{
- X WINDOW *win= whichwin(w);
- X Point where;
- X int pcode;
- X ControlHandle bar;
- X
- X if (win == NULL) {
- X /* dprintf("click in alien window"); */
- X return;
- X }
- X if (win != active) {
- X set_arrow();
- X if (e.modifiers & optionKey) {
- X /* Option-click sends a window behind. */
- X SendBehind(w, (WindowPtr) NULL);
- X }
- X else
- X SelectWindow(win->w);
- X return;
- X /* Let activate events do the rest. */
- X }
- X where= e.where;
- X SetPort(win->w);
- X GlobalToLocal(&where);
- X pcode= FindControl(PASSPOINT where, w, &bar);
- X if (pcode != 0) {
- X set_arrow();
- X do_scroll(&where, win, bar, pcode);
- X }
- X else {
- X Rect r;
- X
- X getwinrect(win, &r);
- X if (PtInRect(PASSPOINT where, &r)) {
- X if (e.modifiers & optionKey) {
- X set_hand();
- X dragscroll(win,
- X where.h, where.v,
- X e.modifiers & shiftKey);
- X }
- X else {
- X set_applcursor();
- X make_mouse_event(ep, &where);
- X }
- X }
- X }
- X}
- X
- Xstatic void
- Xdo_unclick(ep)
- X EVENT *ep;
- X{
- X if (active != NULL) {
- X Point where;
- X
- X where= e.where;
- X SetPort(active->w);
- X GlobalToLocal(&where);
- X make_mouse_event(ep, &where);
- X }
- X}
- X
- Xstatic void
- Xdo_drag(w)
- X WindowPtr w;
- X{
- X if (e.modifiers & optionKey) {
- X /* Nonstandard: option-click sends a window behind. */
- X SendBehind(w, (WindowPtr) NULL);
- X }
- X else {
- X Rect r;
- X
- X r= screen->portRect;
- X r.top += MENUBARHEIGHT;
- X InsetRect(&r, 4, 4);
- X DragWindow(w, PASSPOINT e.where, &r);
- X }
- X}
- X
- Xstatic void
- Xdo_grow(ep, w)
- X EVENT *ep;
- X WindowPtr w;
- X{
- X Rect r;
- X long reply;
- X
- X /* XXX shouldn't mess at all with non-stdwin windows */
- X
- X /* Set minimal window size */
- X r.left= LSLOP + MIN_WIDTH + RSLOP + BAR;
- X r.top= MIN_HEIGHT + BAR;
- X
- X /* The max size is derived from the document size.
- X If there is no document size, it is unlimited.
- X (There is nothing wrong with windows larger than
- X the screen, really.) */
- X r.right = r.bottom = 0x7fff;
- X {
- X /* Max size restriction based on doc size, if specified */
- X WINDOW *win = whichwin(w);
- X int docwidth = win->docwidth;
- X int docheight = win->docheight;
- X if (win->docwidth > 0) {
- X CLIPMIN(docwidth, MIN_WIDTH);
- X r.right = LSLOP + docwidth + RSLOP + BAR + 1;
- X }
- X if (win->docheight > 0) {
- X CLIPMIN(docheight, MIN_HEIGHT);
- X r.bottom = docheight + BAR + 1;
- X }
- X /* For some reason 1 has to be added. Sigh. */
- X }
- X
- X reply= GrowWindow(w, PASSPOINT e.where, &r);
- X if (reply != 0) {
- X SetPort(w);
- X inval_border(w);
- X SizeWindow(w, LoWord(reply), HiWord(reply), TRUE);
- X do_size(ep, w);
- X }
- X}
- X
- Xstatic void
- Xdo_goaway(ep, w)
- X EVENT *ep;
- X WindowPtr w;
- X{
- X /* XXX shouldn't mess at all with non-stdwin windows */
- X
- X if (TrackGoAway(w, PASSPOINT e.where)) {
- X ep->type= WE_COMMAND;
- X ep->window= whichwin(w);
- X ep->u.command= WC_CLOSE;
- X }
- X}
- X
- Xstatic void
- Xdo_zoom(ep, w, code)
- X EVENT *ep;
- X WindowPtr w;
- X int code;
- X{
- X /* XXX shouldn't mess at all with non-stdwin windows */
- X
- X /* This code will never be reached on a machine
- X with old (64K) ROMs, because FindWindow will
- X never return inZoomIn or inZoomOut.
- X Therefore, no check for new ROMs is necessary.
- X A warning in Inside Macintosh IV says that
- X it is necessary to make the zoomed window
- X the current GrafPort before calling ZoomWindow.
- X True enough, it fails spectacularly otherwise,
- X but still this looks like a bug to me - there
- X are no similar requirements for SizeWindow
- X or DragWindow. */
- X
- X SetPort(w);
- X if (TrackBox(w, PASSPOINT e.where, code)) {
- X inval_border(w);
- X ZoomWindow(w, code, TRUE);
- X do_size(ep, w);
- X }
- X}
- X
- X/* do_size assumes w is already the current grafport */
- X
- Xstatic void
- Xdo_size(ep, w)
- X EVENT *ep;
- X WindowPtr w;
- X{
- X WINDOW *win= whichwin(w);
- X
- X if (win == NULL) {
- X /* dprintf("alien window resized"); */
- X return;
- X }
- X inval_border(w);
- X movescrollbars(win);
- X ep->type= WE_SIZE;
- X ep->window= win;
- X _wfixorigin(win);
- X}
- X
- Xvoid
- Xinval_border(w)
- X WindowPtr w;
- X{
- X Rect r;
- X
- X r= w->portRect;
- X r.left= r.right - BAR;
- X InvalRect(&r);
- X r= w->portRect;
- X r.top= r.bottom - BAR;
- X InvalRect(&r);
- X}
- X
- Xvoid
- Xvalid_border(w)
- X WindowPtr w;
- X{
- X Rect r;
- X
- X r= w->portRect;
- X r.left= r.right - BAR;
- X ValidRect(&r);
- X r= w->portRect;
- X r.top= r.bottom - BAR;
- X ValidRect(&r);
- X}
- X
- X/* Variables needed in click and move detection. */
- X
- Xstatic int m_h, m_v; /* Doc. coord. of last mouse evt. */
- Xstatic long m_when; /* TickCount of last mouse evt. */
- Xstatic int m_clicks; /* N-fold click stage */
- Xstatic int m_button; /* Which 'button';
- X 1=normal, 2=shift, 3=command. */
- X
- Xstatic void
- Xmake_mouse_event(ep, pwhere)
- X EVENT *ep;
- X Point *pwhere; /* Mouse pos. in local coord. */
- X{
- X WINDOW *win= active;
- X int h= pwhere->h + win->orgh;
- X int v= pwhere->v + win->orgv;
- X int dh= h - m_h;
- X int dv= v - m_v;
- X
- X if (dh*dh + dv*dv > CLICK_DIST*CLICK_DIST)
- X m_clicks= 0; /* Moved too much for a click */
- X
- X if (e.what == mouseDown) {
- X if (e.when > m_when + GetDblTime())
- X m_clicks= 1;
- X else
- X ++m_clicks;
- X ep->type= WE_MOUSE_DOWN;
- X _wm_down= TRUE;
- X /* XXX Should swap buttons 2 & 3 (also in textedit)
- X since X11 (e.g., xterm) uses button 3 for extend */
- X m_button= (e.modifiers & cmdKey) ? 3 :
- X (e.modifiers & shiftKey) ? 2 : 1;
- X }
- X else if (e.what == mouseUp) {
- X if (!_wm_down)
- X return;
- X ep->type= WE_MOUSE_UP;
- X _wm_down= FALSE;
- X }
- X else {
- X if (!_wm_down || m_clicks > 0 || (dh == 0 && dv == 0))
- X return;
- X ep->type= WE_MOUSE_MOVE;
- X }
- X ep->u.where.h= m_h= h;
- X ep->u.where.v= m_v= v;
- X ep->u.where.clicks= m_clicks;
- X ep->u.where.button= m_button;
- X ep->u.where.mask= (ep->type == WE_MOUSE_UP) ? 0 : 1;
- X ep->window= win;
- X m_when= e.when;
- X}
- X
- X/* Reset the mouse state.
- X Called when a dialog is started. */
- X
- Xvoid
- X_wresetmouse()
- X{
- X _wm_down= FALSE;
- X}
- END_OF_FILE
- if test 12997 -ne `wc -c <'Ports/mac/event.c'`; then
- echo shar: \"'Ports/mac/event.c'\" unpacked with wrong size!
- fi
- # end of 'Ports/mac/event.c'
- fi
- if test -f 'Ports/mac/menu.h' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'Ports/mac/menu.h'\"
- else
- echo shar: Extracting \"'Ports/mac/menu.h'\" \(354 characters\)
- sed "s/^X//" >'Ports/mac/menu.h' <<'END_OF_FILE'
- X/* MAC STDWIN -- MENU DEFINITIONS. */
- X
- X/* Note -- struct menu isn't defined here.
- X MENU * is taken to be equivalent to MenuPtr, whenever appropriate.
- X I know this is a hack -- I'll fix it later. */
- X
- Xstruct menubar {
- X int nmenus; /* Number of menus in the list */
- X MENU **menulist; /* Pointer to list of MENU pointers */
- X};
- X
- X#define APPLE_MENU 32000
- END_OF_FILE
- if test 354 -ne `wc -c <'Ports/mac/menu.h'`; then
- echo shar: \"'Ports/mac/menu.h'\" unpacked with wrong size!
- fi
- # end of 'Ports/mac/menu.h'
- fi
- echo shar: End of archive 8 \(of 19\).
- cp /dev/null ark8isdone
- MISSING=""
- for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 ; do
- if test ! -f ark${I}isdone ; then
- MISSING="${MISSING} ${I}"
- fi
- done
- if test "${MISSING}" = "" ; then
- echo You have unpacked all 19 archives.
- rm -f ark[1-9]isdone ark[1-9][0-9]isdone
- else
- echo You still need to unpack the following archives:
- echo " " ${MISSING}
- fi
- ## End of shell archive.
- exit 0
-