home *** CD-ROM | disk | FTP | other *** search
- From: guido@cwi.nl (Guido van Rossum)
- Newsgroups: alt.sources
- Subject: STDWIN 0.9.5, Part 06/19
- Message-ID: <3070@charon.cwi.nl>
- Date: 4 Mar 91 11:57:50 GMT
-
- Archive-name: stdwin/part06
-
- #! /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 6 (of 19)."
- # Contents: Appls/dpv/dpvoutput.c Doc/ABOUT Packs/textedit/textedit.c
- # Ports/x11/dialog.c
- # Wrapped by guido@voorn.cwi.nl on Mon Mar 4 12:37:25 1991
- PATH=/bin:/usr/bin:/usr/ucb ; export PATH
- if test -f 'Appls/dpv/dpvoutput.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'Appls/dpv/dpvoutput.c'\"
- else
- echo shar: Extracting \"'Appls/dpv/dpvoutput.c'\" \(5954 characters\)
- sed "s/^X//" >'Appls/dpv/dpvoutput.c' <<'END_OF_FILE'
- X/* dpv -- ditroff previewer. Output functions. */
- X
- X#include "dpv.h"
- X#include "dpvmachine.h"
- X#include "dpvoutput.h"
- X
- XWINDOW *win; /* output window */
- X
- X/* Scale factors (must be longs to avoid overflow) */
- X
- Xlong hscale, hdiv; /* Horizontal scaling factors */
- Xlong vscale, vdiv; /* Vertical scaling factors */
- X
- Xint paperwidth, paperheight; /* Paper dimenmsions */
- X
- X/* Variables used to make put1(c) as fast as possible */
- X
- Xint topdraw, botdraw; /* Top, bottom of rect to redraw */
- Xint baseline; /* Caches wbaseline() */
- Xint lineheight; /* Caches wlineheight() */
- Xint doit; /* Set if output makes sense */
- Xint vwindow; /* Caches VWINDOW - baseline */
- X
- Xextern void drawproc(); /* Draw procedore, in dpvcontrol.c */
- X
- X/* Create the window */
- X
- Xinitoutput(filename)
- X char *filename;
- X{
- X int winwidth, winheight;
- X int hmargin, vmargin;
- X
- X setscale();
- X wsetdefwinsize(paperwidth, paperheight);
- X win= wopen(filename, drawproc);
- X wsetdocsize(win, paperwidth, paperheight);
- X wsetwincursor(win, wfetchcursor("arrow"));
- X
- X /* Center the window in the document */
- X wgetwinsize(win, &winwidth, &winheight);
- X hmargin = (paperwidth - winwidth) / 2;
- X if (hmargin < 0)
- X hmargin = 0;
- X vmargin = (paperheight - winheight) / 2;
- X if (vmargin < 0)
- X vmargin = 0;
- X wshow(win, hmargin, vmargin,
- X paperwidth - hmargin, paperheight - hmargin);
- X}
- X
- X/* Compute scale factors from screen dimensions and device resolution.
- X Call before outputting anything, but after input device resolution
- X is known. */
- X
- Xstatic
- Xsetscale()
- X{
- X int scrwidth, scrheight, mmwidth, mmheight;
- X int hdpi, vdpi;
- X
- X wgetscrsize(&scrwidth, &scrheight);
- X wgetscrmm(&mmwidth, &mmheight);
- X hdpi = scrwidth * 254L / 10 / mmwidth;
- X vdpi = scrheight * 254L / 10 / mmwidth;
- X if (dbg) {
- X printf("screen %dx%d pixels, %dx%d mm.\n",
- X scrwidth, scrheight, mmwidth, mmheight);
- X printf("dots per inch %dx%d\n", hdpi, vdpi);
- X }
- X /* Adjust mm sizes to 75x75 dpi if a resolution less than 75 dpi
- X is reported (some servers lie!) */
- X if (hdpi < 75) {
- X fprintf(stderr,
- X "Adjusting horizontal resolution to 75 dpi\n");
- X mmwidth = scrwidth * 254L / 750;
- X }
- X if (vdpi < 75) {
- X fprintf(stderr,
- X "dpv: Adjusting vertical resolution to 75 dpi\n");
- X mmheight = scrheight * 254L / 750;
- X }
- X /* Dots/mm == scrwidth/mmwidth, etc.; there are 25.4 mm/inch */
- X hscale= 254L * scrwidth / 10;
- X hdiv= mmwidth * res;
- X vscale= 254L * scrheight / 10;
- X vdiv= mmheight * res;
- X /* Set desired width & height of paper */
- X paperwidth= 210 * scrwidth / mmwidth;
- X paperheight= 297 * scrheight / mmheight;
- X if (dbg) {
- X printf("hscale=%d, hdiv=%d, vscale=%d, vdiv=%d\n",
- X hscale, hdiv, vscale, vdiv);
- X printf("paper %dx%d\n", paperwidth, paperheight);
- X }
- X}
- X
- X/* Force a redraw event for the entire window.
- X Used after a new page is made current. */
- X
- Xchangeall()
- X{
- X wchange(win, 0, 0, paperwidth, paperheight);
- X}
- X
- X/* Recompute doit & vwindow.
- X Call after each font change and each vertical move.
- X Assumes topdraw and botdraw are set by drawproc(),
- X and lineheight and baseline are set by usefont(). */
- X
- Xrecheck()
- X{
- X if (ipage != showpage)
- X doit= FALSE;
- X else {
- X vwindow= VWINDOW - baseline;
- X doit= vwindow < botdraw && vwindow+lineheight > topdraw;
- X }
- X}
- X
- X/* Output a funny character, called in response to 'Cxx' input.
- X Don't rely on 'doit'; the character might be in a different font,
- X invalidating the clipping computations in recheck(). */
- X
- Xput1s(s)
- X char *s;
- X{
- X if (ipage == showpage)
- X drawfunny(s);
- X}
- X
- X/* Line drawing functions.
- X There really do some of the work that belongs in dpvmachine.c,
- X and even dpvparse.c. */
- X
- Xdrawline(dh, dv)
- X int dh, dv;
- X{
- X if (ipage == showpage)
- X wdrawline(HWINDOW, VWINDOW, HWIN(hpos+dh), VWIN(vpos+dv));
- X hpos += dh;
- X vpos += dv;
- X}
- X
- Xdrawcirc(diameter)
- X int diameter;
- X{
- X if (ipage == showpage)
- X wdrawcircle(HWIN(hpos+diameter/2), VWINDOW,
- X (int)(diameter/2*hscale/hdiv));
- X /* I assume hpos, vpos remain unchanged here */
- X}
- X
- Xdrawellip(haxis, vaxis)
- X int haxis, vaxis;
- X{
- X if (ipage == showpage) {
- X wdrawelarc(HWIN(hpos+haxis/2), VWIN(vpos),
- X (int) (haxis*hscale/hdiv/2),
- X (int) (vaxis*vscale/vdiv/2),
- X 0, 360);
- X }
- X}
- X
- X#define PI 3.1415726
- X
- Xdrawarc(n, m, n1, m1)
- X/* current position is start of arc
- X * n,m is position of center relative to current
- X * n1,m1 is intersection point of tangents at start- and endpoints
- X * of the arc
- X */
- X{
- X double rad, angle1, angle2, sqrt(), atan2(), c;
- X int iang1, iang2;
- X
- X c = 180.0/PI;
- X rad = sqrt((double)((n*n)+(m*m)));
- X angle1 = c*atan2((double)m,(double)-n);
- X angle2 = -2 * (angle1 + c * atan2((double)(m1-m),(double)(n1-n)));
- X iang1 = (int) (angle1 + 0.5);
- X iang2 = (int) (angle2 + 0.5);
- X while (iang1 < 0) iang1 += 360;
- X while (iang2 < 0) iang2 += 360;
- X while (iang1 >= 360) iang1 -= 360;
- X while (iang2 >= 360) iang2 -= 360;
- X /* params for wdrawelarc are
- X * x,y for center,
- X * horizontal and vertical radii (different for ellipses)
- X * start angle in degrees and number of degrees to draw.
- X * angles measured anticlockwise from positive x-axis
- X */
- X if (ipage == showpage)
- X wdrawelarc(HWIN(hpos+n), VWIN(vpos+m),
- X (int)(rad*hscale/hdiv), (int)(rad*vscale/vdiv),
- X iang1, iang2);
- X}
- X
- Xdrawwig(buf, fp, flag)
- X char *buf;
- X FILE *fp;
- X{
- X int dh, dv, x = hpos, y = vpos;
- X
- X while (getint(&buf, &dh) && getint(&buf, &dv))
- X if (ipage == showpage) {
- X /* HIRO: should always do this (for side effects)? */
- X drawline(x + dh/4 - hpos, y + dv/4 - vpos);
- X drawline(dh / 2, dv / 2);
- X x += dh;
- X y += dv;
- X }
- X drawline(dh / 4, dv / 4);
- X if (index(buf, EOL) == NULL) {
- X int c;
- X /* HIRO: don't know how to do handle this */
- X error(WARNING, "rest of very long wiggly line ignored");
- X do {
- X c = getc(fp);
- X } while (c != EOL && c != EOF);
- X }
- X}
- X
- Xstatic bool
- Xgetint(pbuf, px)
- X char **pbuf;
- X int *px;
- X{
- X char *buf= *pbuf;
- X while (*buf != EOS && isspace(*buf))
- X ++buf;
- X if (*buf == EOS || *buf != '-' && !isdigit(*buf))
- X return FALSE;
- X *px= atoi(buf);
- X while (*buf != EOS && !isspace(*buf))
- X ++buf;
- X *pbuf= buf;
- X return TRUE;
- X}
- END_OF_FILE
- if test 5954 -ne `wc -c <'Appls/dpv/dpvoutput.c'`; then
- echo shar: \"'Appls/dpv/dpvoutput.c'\" unpacked with wrong size!
- fi
- # end of 'Appls/dpv/dpvoutput.c'
- fi
- if test -f 'Doc/ABOUT' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'Doc/ABOUT'\"
- else
- echo shar: Extracting \"'Doc/ABOUT'\" \(15823 characters\)
- sed "s/^X//" >'Doc/ABOUT' <<'END_OF_FILE'
- X[Last modified on Sat Apr 15 20:19:00 MET DST 1989 by guido]
- X
- X
- X0. Copyright Notice
- X
- XSTDWIN is copyrighted: Copyright (c) 1988, 1989 by Stichting Mathematisch
- XCentrum, Amsterdam, The Netherlands. STDWIN is available for
- Xnoncommercial use only, free of charge, and with no guarantees. It can
- Xbe freely used and distributed provided these restrictions are honoured.
- X
- X
- X1. Target systems
- X
- XSTDWIN is aimed at C programs. It consists of a few header files (of
- Xwhich only one is visible to the user) and a library. In most cases
- Xsome system-provided libraries must also be used in the linking phase.
- X
- XCurrently, full STDWIN is available for the following environments:
- X
- X(Note that in all cases the code is in beta test state; there may be
- Xbugs, functionality may change slightly in the future and new
- Xfunctionality may be added, but the basic framework isn't going to
- Xchange much.)
- X
- X* X version 11, release 3 (should still work with release 2)
- X* Apple Macintosh, using either THINK C (3.01) or MPW C (2.02)
- X* Atari ST, using Mark Williams C (2.1)
- X
- XYou may volunteer to create a version for your favourite system, or to
- Xport it to your favourite C compiler for one of the mentioned micros.
- X(The micro versions are rather compiler-dependent, due to the many
- Xdifferences between compilers and especially libraries. Expect
- Xdifficulties if you have another compiler or version than the ones
- Xmentioned. Especially the Atari version is flakey.)
- X
- XA subset, emulating most of STDWIN's functionality on an alphanumeric
- Xdisplay (excluding line drawing, but including multiple (non-overlapping)
- Xwindows, menus, text editing etc.) is available for:
- X
- X* Any decent Unix that has termcap (tested with 4.{2,3} BSD)
- X* MS-DOS, using the Microsoft C compiler (4.0)
- X
- XSorry, there are no versions yet for SunTools, SunView, NeWS, X10,
- XMS-Windows, Presentation Manager or the Amiga. A hacker might be able
- Xto turn the Atari ST version into a general GEM version. The code is
- Xremarkably portable to different processor types and various Unix
- Xflavors, as long as they are derived from 4.xBSD.
- X
- X
- X2. Getting the full scoop
- X
- XI have written a paper about STDWIN which has been published as a
- XCWI report (Guido van Rossum: STDWIN -- A Standard Window System
- XInterface. Centre for Mathematics and Computer Science, report
- XCS-R8817. Amsterdam, 1988).
- X
- XYou can also get a source version for any or all of the above-mentioned
- Xsystems. This is essentially a directory dump of my working version,
- Xuntil I have the time or get some help to prepare a real distribution.
- XIt is available through anonymous ftp access from uunet.uu.net.
- XThe directory is amiga-sources/stdwin (thanks to the moderator, Peter
- Xda Silva) get the file README.txt for further instructions. A version
- Xof this file is in ABOUT.txt. (The version on gatekeeper no longer
- Xexists, although it may be revived in the near future).
- X
- XDistribution to to non-ftp-users is solely by electronic mail. Be
- Xprepared to receive up to half a megabyte (in 32K pieces in "shar"
- Xformat). If you're interested, write to guido@cwi.nl.
- X
- X
- X3. Basic functionality
- X
- XSTDWIN allows multiple "full-function" windows, roughly in Macintosh
- Xstyle (title bar, grow box, close box, scroll bars). The appearance of
- Xwindows is determined by the default of the underlying window manager,
- Xand so are other limitations (e.g., overlapping, maximum size, etc.).
- XWindows are dynamically created and destroyed by the application, never
- Xdirectly by the user or the window manager.
- X
- XSTDWIN uses a coordinate system derived from the display's coordinate
- Xsystem: (0, 0) is top left, with X pointing right and Y pointing down
- X(these are actually called h and v). Pixel size is that of the display.
- XThere are enquiry functions to ask for the display size in pixels and in
- Xmillimeters.
- X
- XThe application is responsible for redrawing the window contents when it
- Xis exposed. This is done by associating a "draw procedure" with each
- Xwindow, which knows how to draw the entire window's contents. It gets
- Xpassed a pointer to the window and the coordinates of the rectangle that
- Xneeds to be redrawn, so it can (although it needn't) restrict itself to
- Xthat area. STDWIN guarantees that a window's redraw procedure is only
- Xcalled while the application is waiting for an input event (most
- Ximplementations simply turn exposure events into calls to the draw
- Xprocedure).
- X
- XIf the application wants to change part of the graphics it is
- Xdisplaying, this is usually done in a two-phase process: first, STDWIN
- Xis told that a particular area of the screen must be changed; later,
- Xwhen the application starts waiting for input events again, the draw
- Xprocedure is called to update the indicated area (and any other area
- Xthat was exposed or damaged in some way).
- X
- XThe application defines the width and height of the area it wants to
- Xdraw; this needn't bear any relation to the window or screen size. This
- Xarea is called the "document" although you may also think of it as a
- Xvirtual window. The actual window generally displays a sub-area of the
- Xdocument; the window's scroll bars indicate the position of the window
- Xwith respect to the document. The application always uses the
- Xcoordinates of its document; STDWIN performs the translation to window
- Xor screen coordinates are required by the window manager, and ensures
- Xclipping of all output to the window.
- X
- XSTDWIN is event-based. An application is expected to have a main loop
- Xcontaining a "get event" call followed by a switch on the event type.
- XThere is no event mask; an application can simply ignore events it isn't
- Xinterested in. The most important event types are:
- X
- XACTIVATE: A window becomes active (keyboard attached and/or topmost)
- X
- XCHAR: ASCII character key pressed (except BS, TAB, CR)
- X
- XCOMMAND: special key or function (CLOSE, TAB, RETURN, BS, CANCEL,
- X arrow keys etc.)
- X
- XMOUSE: MOUSE DOWN, MOUSE MOVE (only while down), MOUSE UP;
- X fields in the event record indicate the h, v position,
- X the number of the button, and the "click number" if the
- X event is potentially part of a multiple-click sequence
- X
- XMENU: menu id and item number of a menu selection
- X
- XSIZE: user has resized the window
- X
- XTIMER: the window's timer went off; each window has one
- X programmable timer which can be set to go off at N/10
- X seconds in the future. When the timer goes off a TIMER
- X event is returned.
- X
- XNormally, STDWIN draws text in a single font. The actual font used
- Xdepends on the underlying window manager (and can sometimes be
- Xinfluenced by the application programmer and/or the end user in a
- Xsystem-dependent manner). The font may be proportionally spaced, and
- Xthere are enquiry functions to find out the dimensions of characters and
- Xstrings. There are also functions to change the font name and point
- Xsize dynamically; but these work different in different systems,
- Xespecially the allowed font names differ drastically. This feature is
- Xused with some success in the ditroff previewer that is supplied as a
- Xdemo.
- X
- XThere are functions to draw text and simple lines, rectangles and
- Xcircles, and ways to erase, shade or invert rectangular areas. There is
- Xno way (yet) to do general bitblt operations, or to influence the pen
- Xshape.
- X
- X
- X4. Higher level functionality
- X
- XSTDWIN provides a blinking vertical bar which can be used to indicate
- Xthe text insertion point, so the application needn't use TIMER events to
- Xdo the blinking.
- X
- XSTDWIN provides Macintosh-style menus. Each window has its own set of
- Xmenus, although by default all menus apply to all windows. A reasonably
- Xnumber of menus per window is allowed, each with a reasonable number of
- X(textual) menu items. Menus can be changed dynamically. Items can be
- Xenabled or disabled, and a 'tick mark' can be placed in front of an
- Xitem. Each menu item may have a shortcut character, which, when typed
- Xin combination with some system-defined meta key (e.g., ALT or an ESC-
- Xprefix) selects the menu item (if enabled). Menu selection is done
- Xcompletely "underwater"; all the application notices are MENU events.
- X
- XSTDWIN has a few simple routines to display Mac-style "dialog boxes",
- Xe.g., to show an error message, or to ask a yes/no question or to ask
- Xfor a string to be typed. There is also a predefined function to ask
- Xfor a file name, which may allow the user to browse the file system in
- Xsome implementations.
- X
- XSTDWIN comes with a package built on top of the basic functionality, to
- Xedit arbitrary blocks of text (cf. Macintosh TEXTEDIT). In the future,
- Xmore packages will be provided, e.g., a package to provide a simple file
- Xeditor (available now!), a package to display a scrolling list of items,
- Xa package to define a list of arbitrary labeled "buttons", and a package
- Xto simplify the binding of menus to functions somewhat, and a VT100
- Xemulator (available now!).
- X
- X
- X5. Function definitions
- X
- XHere follows a slightly edited listing of the <stdwin.h> header file,
- Xwhich more or less documents all available functions and data
- Xstructures. Note that the argument lists are given here as ANSI C
- Xprototypes (untested).
- X
- X#define bool int
- X
- Xvoid winit();
- Xvoid wdone();
- X
- Xvoid wsetdefwinsize(int width, int height);
- Xvoid wsetdefwinpos(int h, int v);
- X
- X#define MENU struct menu
- X
- X/* The contents of a text attributes struct are disclosed here because
- X the interface allows the programmer to declare objects of this type.
- X (I'm not so sure anymore that this is the right thing to do!) */
- X
- Xstruct textattr {
- X short font;
- X unsigned char size;
- X unsigned char style;
- X};
- X
- X#define TEXTATTR struct textattr
- X
- X#ifndef WINDOW
- X
- Xstruct window {
- X short tag;
- X};
- X
- X#define WINDOW struct window
- X
- X#endif
- X
- XWINDOW *wopen(char *title, void drawproc();
- Xvoid wclose(WINDOW *win);
- X#define wgettag(win) ((win)->tag)
- X#define wsettag(win, newtag) ((win)->tag= newtag)
- Xvoid wsetactive(WINDOW *win);
- XWINDOW *wgetactive();
- Xvoid wgetwinsize(WINDOW *win, int *width, int *height);
- Xvoid wsetdocsize(WINDOW *win, int width, int height);
- Xvoid wsettitle(WINDOW *win, char *title);
- X
- Xvoid wsetorigin(WINDOW *win, int h, int v);
- Xvoid wshow(WINDOW *win, int left, int top, int right, int bottom);
- Xvoid wchange(WINDOW *win, int left, int top, int right, int bottom);
- Xvoid wscroll(WINDOW *win, int left, int top, int right, int bottom,
- X int dh, int dv);
- X
- Xvoid wfleep();
- Xvoid wmessage(char *str);
- Xvoid wperror(char *name);
- Xbool waskstr(char *prompt, char *buf, int buflen);
- Xint waskync(char *question, int dflt);
- Xbool waskfile(char *prompt, char *buf, int buflen, bool new);
- X
- Xvoid wsetcaret(WINDOW *win, int h, int v);
- Xvoid wnocaret(WINDOW *win);
- X
- Xvoid wsettimer(WINDOW *win, int deciseconds);
- X
- XMENU *wmenucreate(int id, char *title);
- Xvoid wmenudelete(MENU *mp);
- Xint wmenuadditem(MENU *mp, char *text, char shortcut);
- Xvoid wmenusetitem(MENU *mp, int i, char *text);
- Xvoid wmenusetdeflocal(bool local);
- Xvoid wmenuattach(WINDOW *win, MENU *mp);
- Xvoid wmenudetach(WINDOW *win, MENU *mp);
- X
- X/* EVENT STRUCT DEFINITION */
- X
- Xstruct event {
- X int type;
- X WINDOW *window;
- X union {
- X /* case WE_CHAR: */
- X int character;
- X /* case WE_COMMAND: */
- X int command;
- X /* case WE_MENU: */
- X struct { int id; int item; } m;
- X /* case WE_DRAW: */
- X struct { int left, top, right, bottom; } area;
- X /* case WE_MOUSE_DOWN, WE_MOUSE_MOVE, WE_MOUSE_UP: */
- X struct {
- X int v;
- X int h;
- X int clicks;
- X int button;
- X int mask;
- X } where;
- X } u;
- X};
- X
- X#define EVENT struct event
- X
- X/* Event types */
- X
- X#define WE_NULL 0 /* (Used internally) */
- X#define WE_ACTIVATE 1 /* Window became active */
- X#define WE_CHAR 2 /* Character typed at keyboard */
- X#define WE_COMMAND 3 /* Special command, function key etc. */
- X#define WE_MOUSE_DOWN 4 /* Mouse button pressed */
- X#define WE_MOUSE_MOVE 5 /* Mouse moved with button down */
- X#define WE_MOUSE_UP 6 /* Mouse button released */
- X#define WE_MENU 7 /* Menu item selected */
- X#define WE_SIZE 8 /* Window size changed */
- X#define WE_MOVE 9 /* (Reserved) */
- X#define WE_DRAW 10 /* Request to redraw part of window */
- X#define WE_TIMER 11 /* Window's timer went off */
- X#define WE_DEACTIVATE 12 /* Window became inactive */
- X
- X/* Command codes for WE_COMMAND.
- X Special ways of entering these are usually available,
- X such as clicking icons, standard menu items or special keys.
- X Some ASCII keys are also passed back as commands since they
- X more often than not need special processing. */
- X
- X#define WC_CLOSE 1 /* Should become a separate event! */
- X/* The following four are arrow keys */
- X#define WC_LEFT 2
- X#define WC_RIGHT 3
- X#define WC_UP 4
- X#define WC_DOWN 5
- X/* ASCII keys */
- X#define WC_CANCEL 6
- X#define WC_BACKSPACE 7
- X#define WC_TAB 8
- X#define WC_RETURN 9
- X
- Xvoid wgetevent(EVENT *ep);
- Xvoid wungetevent(EVENT *ep);
- Xvoid wupdate(WINDOW *win);
- Xvoid wbegindrawing(WINDOW *win);
- Xvoid wenddrawing(WINDOW *win);
- Xvoid wflush();
- X
- Xvoid wdrawline(int h1, int v1, int h2, int v2);
- Xvoid wxorline(int h1, int v1, int h2, int v2);
- Xvoid wdrawcircle(int h, int v, int radius);
- Xvoid wdrawelarc(int h, int v, int radh, int radv, int angle1, int angle2);
- Xvoid wdrawbox(int left, int top, int right, int bottom);
- Xvoid werase(int left, int top, int right, int bottom);
- Xvoid wpaint(int left, int top, int right, int bottom);
- Xvoid winvert(int left, int top, int right, int bottom);
- Xvoid wshade(int left, int top, int right, int bottom, int percent);
- X
- Xint wdrawtext(int h, int v, char *str, int len);
- Xint wdrawchar(int h, int v, char c);
- Xint wlineheight();
- Xint wtextwidth(char *str, int len);
- Xint wcharwidth(char c);
- Xint wtextbreak(char *str, int len, int width);
- X
- Xvoid wgettextattr(TEXTATTR *attr);
- Xvoid wsettextattr(TEXTATTR *attr);
- Xvoid wgetwintextattr(WINDOW *win, TEXTATTR *attr);
- Xvoid wsetwintextattr(WINDOW *win, TEXTATTR *attr);
- X
- Xvoid wsetplain();
- Xvoid wsethilite();
- Xvoid wsetinverse();
- Xvoid wsetitalic();
- Xvoid wsetbold();
- Xvoid wsetbolditalic();
- Xvoid wsetunderline();
- X
- X/* TEXTEDIT PACKAGE DEFINITIONS */
- X
- X#define TEXTEDIT struct _textedit
- X
- XTEXTEDIT *tealloc(WINDOW *win, int left, int top, int width);
- XTEXTEDIT *tecreate(WINDOW *win,
- X int left, int top, int right, int bottom);
- Xvoid tefree(TEXTEDIT *tp);
- Xvoid tedestroy(TEXTEDIT *tp);
- X
- Xvoid tedraw(TEXTEDIT *tp);
- Xvoid tedrawnew(TEXTEDIT *tp, int left, int top, int right, int bottom);
- Xvoid temove(TEXTEDIT *tp, int left, int top, int width);
- Xvoid temovenew(TEXTEDIT *tp,
- X int left, int top, int right, int bottom);
- X
- Xvoid tesetfocus(TEXTEDIT *tp, int foc1, int foc2);
- Xvoid tereplace(TEXTEDIT *tp, char *str);
- Xvoid tesetbuf(TEXTEDIT *tp, char *buf, int buflen);
- X
- Xvoid tearrow(TEXTEDIT *tp, int code);
- Xvoid tebackspace(TEXTEDIT *tp);
- Xbool teclicknew(TEXTEDIT *tp, int h, int v, bool extend);
- Xbool tedoubleclick(TEXTEDIT *tp, int h, int v);
- Xbool teevent(TEXTEDIT *tp, EVENT *ep);
- X
- X#define teclick(tp, h, v) teclicknew(tp, h, v, FALSE)
- X#define teclickextend(tp, h, v) teclicknew(tp, h, v, TRUE)
- X
- Xchar *tegettext(TEXTEDIT *tp);
- Xint tegetlen(TEXTEDIT *tp);
- Xint tegetnlines(TEXTEDIT *tp);
- Xint tegetfoc1(TEXTEDIT *tp);
- Xint tegetfoc2(TEXTEDIT *tp);
- Xint tegetleft(TEXTEDIT *tp);
- Xint tegettop(TEXTEDIT *tp);
- Xint tegetright(TEXTEDIT *tp);
- Xint tegetbottom(TEXTEDIT *tp);
- X
- X/* Text paragraph drawing functions: */
- X
- Xint wdrawpar(int h, int v, char *text, int width);
- X /* Returns new v coord. */
- Xint wparheight(char *text, int width);
- X /* Returns height */
- END_OF_FILE
- if test 15823 -ne `wc -c <'Doc/ABOUT'`; then
- echo shar: \"'Doc/ABOUT'\" unpacked with wrong size!
- fi
- # end of 'Doc/ABOUT'
- fi
- if test -f 'Packs/textedit/textedit.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'Packs/textedit/textedit.c'\"
- else
- echo shar: Extracting \"'Packs/textedit/textedit.c'\" \(14543 characters\)
- sed "s/^X//" >'Packs/textedit/textedit.c' <<'END_OF_FILE'
- X/* Text Edit, high level routines */
- X
- X#include "text.h"
- X
- Xvoid
- Xtereplace(tp, str)
- X TEXTEDIT *tp;
- X char *str;
- X{
- X int len= strlen(str);
- X
- X if (len == 1 && teoptinschar(tp, (int) str[0]))
- X return;
- X
- X teinsert(tp, str, len);
- X}
- X
- Xstatic
- Xteinschar(tp, c)
- X TEXTEDIT *tp;
- X int c;
- X{
- X char cbuf[2];
- X
- X if (teoptinschar(tp, c))
- X return;
- X
- X cbuf[0]= c;
- X cbuf[1]= EOS;
- X teinsert(tp, cbuf, 1);
- X}
- X
- X/* Optimization for the common case insert char.
- X Assumes text measurement is additive. */
- X
- Xstatic
- Xtesetoptdata(tp)
- X TEXTEDIT *tp;
- X{
- X lineno i;
- X bufpos k, pos, end;
- X
- X zcheck();
- X zassert(tp->foclen == 0);
- X
- X pos= zaddgap(tp->foc);
- X tp->opt_i= i= tewhichline(tp, pos, FALSE);
- X tp->opt_h= tp->left + tetextwidth(tp, tp->start[i], pos);
- X tp->opt_v= tp->top + i*tp->vspace;
- X 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 for (k= pos; k < end; zincr(&k)) {
- X if (zcharat(k) == '\t')
- X break;
- X }
- X if (k < end) {
- X tp->opt_end=
- X tp->left + tetextwidth(tp, tp->start[i], znext(k));
- X tp->opt_avail= tp->opt_end -
- X (tp->left + tetextwidth(tp, tp->start[i], k));
- X }
- X else {
- X tp->opt_end= tp->right;
- X tp->opt_avail= tp->width - tetextwidth(tp, tp->start[i], end);
- X }
- X if (tp->start[i] > 0 && zcharbefore(tp->start[i]) != EOL) {
- X tp->opt_in_first_word= TRUE;
- X for (k= tp->start[i]; k < pos; zincr(&k)) {
- X if (isspace(zcharat(k))) {
- X tp->opt_in_first_word= FALSE;
- X break;
- X }
- X }
- X }
- X else
- X tp->opt_in_first_word= FALSE;
- X tp->opt_valid= TRUE;
- X}
- X
- Xstatic bool
- Xteoptinschar(tp, c)
- X TEXTEDIT *tp;
- X int c;
- X{
- X int w;
- X
- X if (tp->foclen != 0 || c == EOL || c == '\t' || tp->focprev)
- X return FALSE;
- X if (!tp->opt_valid)
- X tesetoptdata(tp);
- X if (c == ' ' && tp->opt_in_first_word)
- X return FALSE;
- X w= wcharwidth(c);
- X if (w >= tp->opt_avail)
- X return FALSE;
- X
- X temovegapto(tp, tp->foc);
- X if (tp->gaplen < 1)
- X tegrowgapby(tp, 1+RESERVE);
- X if (tp->start[tp->opt_i] == zgapend)
- X tp->start[tp->opt_i]= tp->gap;
- X ++tp->gap;
- X --tp->gaplen;
- X tp->buf[tp->foc]= c;
- X ++tp->foc;
- X
- X tp->opt_avail -= w;
- X if (tp->active)
- X wnocaret(tp->win);
- X wscroll(tp->win,
- X tp->opt_h, tp->opt_v,
- X tp->opt_end, tp->opt_v + tp->vspace,
- X w, 0);
- X wbegindrawing(tp->win);
- X wdrawchar(tp->opt_h, tp->opt_v, c);
- X wenddrawing(tp->win);
- X tp->opt_h += w;
- X if (tp->active) {
- X wsetcaret(tp->win, tp->opt_h, tp->opt_v);
- X wshow(tp->win,
- X tp->opt_h, tp->opt_v,
- X tp->opt_h, tp->opt_v + tp->vspace);
- X }
- X tp->aim= tp->opt_h;
- X
- X return TRUE;
- X}
- X
- Xstatic
- Xteinsert(tp, str, len)
- X TEXTEDIT *tp;
- X char *str;
- X int len;
- X{
- X focpos oldfoc= tp->foc;
- X
- X tehidefocus(tp);
- X temovegapto(tp, zfocend);
- X tp->gap= tp->foc;
- X tp->gaplen += tp->foclen;
- X teemptygap(tp);
- X tp->foclen= 0;
- X if (tp->gaplen < len)
- X tegrowgapby(tp, len-tp->gaplen+RESERVE);
- X strncpy(tp->buf+tp->gap, str, len);
- X tp->gap += len;
- X tp->gaplen -= len;
- X tp->foc += len;
- X terecompute(tp, zaddgap(oldfoc), zaddgap(tp->foc));
- X}
- X
- Xstatic int lasteol; /* Optimization trick for teendofline */
- X
- Xstatic
- Xterecompute(tp, first, last)
- X TEXTEDIT *tp;
- X int first, last;
- X{
- X lineno i;
- X lineno chfirst, chlast; /* Area to pass to wchange */
- X lineno shift= 0; /* Lines to shift down (negative: up) */
- X vcoord newbottom;
- X
- X tp->start[0]= zaddgap(0);
- X
- X i= 2;
- X while (i <= tp->nlines && tp->start[i] < first)
- X ++i;
- X i -= 2;
- X chfirst= tp->nlines;
- X chlast= i;
- X lasteol= -1;
- X
- X /* TO DO: scroll up/down if inserting/deleting lines */
- X
- X for (;; ++i) {
- X bufpos end= teendofline(tp, tp->start[i]);
- X bool unchanged= (i < tp->nlines && end == tp->start[i+1]);
- X if (!unchanged)
- X shift += tesetstart(tp, i+1, end, last);
- X if (!(unchanged && end < first)) {
- X if (i < chfirst)
- X chfirst= i;
- X chlast= i+1;
- X }
- X if (end >= tp->buflen) {
- X if (end > tp->start[i] && zcharbefore(end) == EOL)
- X continue;
- X else
- X break;
- X }
- X if (unchanged && end > last) {
- X i= tp->nlines-1;
- X break;
- X }
- X }
- X
- X zassert(tp->nlines > i);
- X
- X if (tp->drawing) {
- X if (shift != 0) {
- X lineno k= chlast;
- X if (shift > 0)
- X k -= shift;
- X wscroll(tp->win,
- X tp->left, tp->top + k*tp->vspace,
- X tp->right, tp->top + tp->nlines*tp->vspace,
- X 0, shift*tp->vspace);
- X }
- X
- X wchange(tp->win,
- X tp->left, tp->top + chfirst*tp->vspace,
- X tp->right, tp->top + chlast*tp->vspace);
- X }
- X
- X tp->nlines= i+1;
- X newbottom= tp->top + tp->vspace*tp->nlines;
- X if (newbottom < tp->bottom)
- X wchange(tp->win,
- X tp->left, newbottom, tp->right, tp->bottom);
- X tp->bottom= newbottom;
- X tp->aim= UNDEF;
- X tp->focprev= FALSE;
- X if (tp->drawing)
- X tesetcaret(tp);
- X
- X zcheck();
- X}
- X
- Xstatic int
- Xtesetstart(tp, i, pos, last)
- X register TEXTEDIT *tp;
- X register lineno i;
- X bufpos pos, last;
- X{
- X if (i > tp->nlines) {
- X tp->nlines= i;
- X if (tp->nlines >= tp->nstart) {
- X tp->nstart= tp->nlines + STARTINCR;
- X tp->start= (bufpos*)zrealloc((char*)tp->start,
- X tp->nstart*sizeof(int));
- X }
- X tp->start[i]= pos;
- X return 0;
- X }
- X else {
- X lineno shift= 0;
- X lineno k;
- X for (k= i; k < tp->nlines; ++k) {
- X if (tp->start[k] > pos)
- X break;
- X }
- X shift= k-1 - i;
- X /* start[k] should really be start[i+1] */
- X if (shift < 0 && tp->start[k] >= last) { /* Insert one */
- X ++tp->nlines;
- X if (tp->nlines >= tp->nstart) {
- X tp->nstart= tp->nlines + STARTINCR;
- X tp->start= (int*)zrealloc((char*)tp->start,
- X tp->nstart*sizeof(int));
- X }
- X for (k= tp->nlines; k > i; --k)
- X tp->start[k]= tp->start[k-1];
- X }
- X else if (shift > 0 && pos >= last) { /* Delete some */
- X for (; k <= tp->nlines; ++k)
- X tp->start[k-shift]= tp->start[k];
- X tp->nlines -= shift;
- X if (tp->nlines < tp->nstart - STARTINCR) {
- X tp->nstart= tp->nlines+1;
- X tp->start= (int*)zrealloc((char*)tp->start,
- X tp->nstart*sizeof(int));
- X }
- X }
- X else
- X shift= 0; /* Don't shift (yet) */
- X tp->start[i]= pos;
- X return -shift;
- X }
- X}
- X
- Xstatic int
- Xteendofline(tp, pos)
- X TEXTEDIT *tp;
- X bufpos pos;
- X{
- X bufpos end= tp->buflen;
- X bufpos k;
- X
- X /* Find first EOL if any */
- X if (lasteol >= pos)
- X k= lasteol;
- X else {
- X for (k= pos; k < end && zcharat(k) != EOL; zincr(&k))
- X ;
- X lasteol= k;
- X }
- X
- X end= tetextbreak(tp, pos, k, tp->width);
- X
- X /* Extend with any spaces immediately following end */
- X for (; end < tp->buflen && zcharat(end) == ' '; zincr(&end))
- X ;
- X
- X if (end < tp->buflen) {
- X /* Extend with immediately following EOL */
- X if (zcharat(end) == EOL)
- X zincr(&end);
- X else {
- X /* Search back for space before last word */
- X for (k= end; zdecr(&k) >= pos && !isspace(zcharat(k)); )
- X ;
- X
- X if (k >= pos)
- X end= znext(k);
- X }
- X }
- X
- X /* Each line must be at least one character long,
- X otherwise a very narrow text-edit box would cause
- X the size calculation to last forever */
- X if (end == pos && end < tp->buflen)
- X zincr(&end);
- X
- X return end;
- X}
- X
- Xbool
- Xteevent(tp, e)
- X TEXTEDIT *tp;
- X EVENT *e;
- X{
- X if (e->window != tp->win)
- X return FALSE;
- X
- X switch (e->type) {
- X
- X case WE_CHAR:
- X teinschar(tp, e->u.character);
- X break;
- X
- X case WE_COMMAND:
- X switch (e->u.command) {
- X case WC_BACKSPACE:
- X tebackspace(tp);
- X break;
- X case WC_RETURN:
- X teinschar(tp, EOL);
- X break;
- X case WC_TAB:
- X teinschar(tp, '\t');
- X break;
- X case WC_LEFT:
- X case WC_RIGHT:
- X case WC_UP:
- X case WC_DOWN:
- X tearrow(tp, e->u.command);
- X break;
- X default:
- X return FALSE;
- X }
- X break;
- X
- X case WE_MOUSE_DOWN:
- X {
- X int h= e->u.where.h, v= e->u.where.v;
- X if (h >= tp->left && h <= tp->right &&
- X v >= tp->top && v <= tp->bottom)
- X teclicknew(tp, h, v,
- X e->u.where.button == 2,
- X e->u.where.clicks > 1);
- X else
- X return FALSE;
- X }
- X break;
- X
- X case WE_MOUSE_MOVE:
- X case WE_MOUSE_UP:
- X if (!tp->mdown)
- X return FALSE;
- X teclicknew(tp, e->u.where.h, e->u.where.v, TRUE, tp->dclick);
- X if (e->type == WE_MOUSE_UP)
- X tp->mdown= FALSE;
- X break;
- X
- X case WE_DRAW:
- X wbegindrawing(tp->win);
- X tedrawnew(tp, e->u.area.left, e->u.area.top,
- X e->u.area.right, e->u.area.bottom);
- X wenddrawing(tp->win);
- X break;
- X
- X default:
- X return FALSE;
- X
- X }
- X
- X /* If broke out of switch: */
- X return TRUE;
- X}
- X
- Xvoid
- Xtearrow(tp, code)
- X TEXTEDIT *tp;
- X int code;
- X{
- X lineno i;
- X bufpos pos;
- X
- X tehidefocus(tp);
- X
- X switch (code) {
- X
- X case WC_LEFT:
- X if (tp->foclen != 0)
- X tp->foclen= 0;
- X else {
- X if (tp->foc > 0)
- X --tp->foc;
- X else
- X wfleep();
- X }
- X tp->aim= UNDEF;
- X tp->focprev= FALSE;
- X break;
- X
- X case WC_RIGHT:
- X if (tp->foclen != 0) {
- X tp->foc += tp->foclen;
- X tp->foclen= 0;
- X }
- X else {
- X if (tp->foc < tp->buflen-tp->gaplen)
- X ++tp->foc;
- X else
- X wfleep();
- X }
- X tp->aim= UNDEF;
- X tp->focprev= FALSE;
- X break;
- X
- X /* TO DO: merge the following two cases */
- X
- X case WC_UP:
- X if (tp->foclen > 0)
- X tp->foclen= 0;
- X else {
- X pos= zaddgap(tp->foc);
- X i= tewhichline(tp, pos, (bool) tp->focprev);
- X if (i <= 0)
- X wfleep();
- X else {
- X if (tp->aim == UNDEF)
- X tp->aim= tp->left + tetextwidth(tp,
- X tp->start[i], pos);
- X --i;
- X pos= tetextround(tp, i, tp->aim);
- X tp->foc= zsubgap(pos);
- X tp->focprev= (pos == tp->start[i+1]);
- X }
- X }
- X break;
- X
- X case WC_DOWN:
- X if (tp->foclen > 0) {
- X tp->foc += tp->foclen;
- X tp->foclen= 0;
- X }
- X else {
- X pos= zaddgap(tp->foc);
- X i= tewhichline(tp, pos, (bool) tp->focprev);
- X if (i+1 >= tp->nlines)
- X wfleep();
- X else {
- X if (tp->aim == UNDEF)
- X tp->aim= tp->left + tetextwidth(tp,
- X tp->start[i], pos);
- X ++i;
- X pos= tetextround(tp, i, tp->aim);
- X tp->foc= zsubgap(pos);
- X tp->focprev= (pos == tp->start[i+1]);
- X }
- X }
- X break;
- X
- X default:
- X dprintf("tearrow: bad code %d", code);
- X break;
- X
- X }
- X tesetcaret(tp);
- X}
- X
- Xvoid
- Xtebackspace(tp)
- X TEXTEDIT *tp;
- X{
- X if (tp->foclen == 0) {
- X if (tp->foc == 0) {
- X wfleep();
- X return;
- X }
- X --tp->foc;
- X tp->foclen= 1;
- X }
- X teinsert(tp, "", 0);
- X}
- X
- Xbool
- Xteclicknew(tp, h, v, extend, dclick)
- X TEXTEDIT *tp;
- X coord h, v;
- X bool extend, dclick;
- X{
- X lineno i;
- X bufpos pos;
- X focpos f;
- X
- X tp->dclick= dclick;
- X pos= tewhereis(tp, h, v, &i);
- X f= zsubgap(pos);
- X if (extend) {
- X if (!tp->mdown) {
- X tp->mdown= TRUE;
- X if (f - tp->foc < tp->foc + tp->foclen - f)
- X tp->anchor= tp->foc + tp->foclen;
- X else
- X tp->anchor= tp->foc;
- X tp->anchor2= tp->anchor;
- X }
- X if (f >= tp->anchor) {
- X if (dclick)
- X f= tewordend(tp, f);
- X techangefocus(tp, tp->anchor, f);
- X }
- X else {
- X if (dclick)
- X f= tewordbegin(tp, f);
- X techangefocus(tp, f, tp->anchor2);
- X }
- X }
- X else {
- X tp->mdown= TRUE;
- X tp->anchor= tp->anchor2= f;
- X if (dclick) {
- X tp->anchor= tewordbegin(tp, tp->anchor);
- X tp->anchor2= tewordend(tp, f);
- X }
- X techangefocus(tp, tp->anchor, tp->anchor2);
- X }
- X tp->aim= UNDEF;
- X tp->focprev= (tp->foclen == 0 && pos == tp->start[i+1]);
- X tesetcaret(tp);
- X return TRUE;
- X}
- X
- X/* Return f, 'rounded down' to a word begin */
- X
- Xstatic int
- Xtewordbegin(tp, f)
- X TEXTEDIT *tp;
- X int f;
- X{
- X f= zaddgap(f);
- X for (;;) {
- X if (f == 0 || isspace(zcharbefore(f)))
- X break;
- X zdecr(&f);
- X }
- X return zsubgap(f);
- X}
- X
- X/* Ditto to word end */
- X
- Xstatic int
- Xtewordend(tp, f)
- X TEXTEDIT *tp;
- X int f;
- X{
- X f= zaddgap(f);
- X for (;;) {
- X if (f >= tp->buflen || isspace(zcharat(f)))
- X break;
- X zincr(&f);
- X }
- X return zsubgap(f);
- X}
- X
- Xint
- Xtegetleft(tp)
- X TEXTEDIT *tp;
- X{
- X return tp->left;
- X}
- X
- Xint
- Xtegettop(tp)
- X TEXTEDIT *tp;
- X{
- X return tp->top;
- X}
- X
- Xint
- Xtegetright(tp)
- X TEXTEDIT *tp;
- X{
- X return tp->right;
- X}
- X
- Xint
- Xtegetbottom(tp)
- X TEXTEDIT *tp;
- X{
- X return tp->bottom;
- X}
- X
- Xvoid
- Xtemove(tp, left, top, width)
- X TEXTEDIT *tp;
- X coord left, top, width;
- X{
- X temovenew(tp, left, top, left+width, top + tp->nlines*tp->vspace);
- X}
- X
- X/*ARGSUSED*/
- Xvoid
- Xtemovenew(tp, left, top, right, bottom)
- X TEXTEDIT *tp;
- X int left, top, right, bottom;
- X{
- X int oldheight= tp->bottom - tp->top;
- X tp->left= left;
- X tp->top= top;
- X tp->right= right;
- X tp->bottom= tp->top + oldheight;
- X if (right - left != tp->width) {
- X tp->width= right - left;
- X tp->nlines= 0; /* Experimental! */
- X terecompute(tp, 0, tp->buflen);
- X }
- X}
- X
- Xvoid
- Xtesetfocus(tp, foc1, foc2)
- X TEXTEDIT *tp;
- X focpos foc1, foc2;
- X{
- X if (foc1 > tp->buflen - tp->gaplen)
- X foc1= tp->buflen - tp->gaplen;
- X if (foc2 > tp->buflen - tp->gaplen)
- X foc2= tp->buflen - tp->gaplen;
- X if (foc1 < 0)
- X foc1= 0;
- X if (foc2 < foc1)
- X foc2= foc1;
- X techangefocus(tp, foc1, foc2);
- X tp->aim= UNDEF;
- X tp->focprev= FALSE;
- X tesetcaret(tp);
- X}
- X
- Xint
- Xtegetfoc1(tp)
- X TEXTEDIT *tp;
- X{
- X return tp->foc;
- X}
- X
- Xint
- Xtegetfoc2(tp)
- X TEXTEDIT *tp;
- X{
- X return tp->foc + tp->foclen;
- X}
- X
- Xint
- Xtegetnlines(tp)
- X TEXTEDIT *tp;
- X{
- X return tp->nlines;
- X}
- X
- Xchar *
- Xtegettext(tp)
- X TEXTEDIT *tp;
- X{
- X temovegapto(tp, tp->buflen - tp->gaplen);
- X if (tp->gaplen < 1)
- X tegrowgapby(tp, 1+RESERVE);
- X tp->buf[tp->gap]= EOS;
- X return tp->buf;
- X}
- X
- Xint
- Xtegetlen(tp)
- X TEXTEDIT *tp;
- X{
- X return tp->buflen - tp->gaplen;
- X}
- X
- Xvoid
- Xtesetbuf(tp, buf, buflen)
- X TEXTEDIT *tp;
- X char *buf;
- X int buflen;
- X{
- X bool drawing= tp->drawing;
- X
- X if (buf == NULL || buflen < 0)
- X return;
- X if (drawing)
- X wchange(tp->win, tp->left, tp->top, tp->right, tp->bottom);
- X free(tp->buf);
- X tp->buf= buf;
- X tp->buflen= buflen;
- X tp->foc= tp->foclen= tp->gap= tp->gaplen= 0;
- X tp->drawing= FALSE;
- X terecompute(tp, 0, tp->buflen);
- X if (drawing) {
- X tp->drawing= TRUE;
- X wchange(tp->win, tp->left, tp->top, tp->right, tp->bottom);
- X }
- X}
- X
- X
- X/* The following paragraph-drawing routines are experimental.
- X They cannibalize on the existing text-edit code,
- X which makes it trivial to ensure the lay-out is the same,
- X but causes overhead to initialize a text-edit struct.
- X The flag 'drawing' has been added to the textedit struct,
- X which suppresses calls to tesetcaret, wchange and wscroll
- X from tesetup and terecompute.
- X It doesn't suppress actual drawing, which only occurs when
- X tedraw is called.
- X Note -- this could be optimized, but it is infrequently,
- X so I don't care until I get complaints. */
- X
- X/* Draw a paragraph of text, exactly like tedraw would draw it.
- X Parameters are the top left corner, the width, the text and its length.
- X Return value is the v coordinate of the bottom line.
- X An empty string is drawn as one blank line. */
- X
- Xint
- Xwdrawpar(left, top, text, width)
- X int left, top;
- X char *text;
- X int width;
- X{
- X return _wdrawpar(left, top, text, width, TRUE);
- X}
- X
- X/* Measure the height of a paragraph of text, when drawn with wdrawpar. */
- X
- Xint
- Xwparheight(text, width)
- X char *text;
- X int width;
- X{
- X return _wdrawpar(0, 0, text, width, FALSE);
- X}
- X
- X/* Routine to do the dirty work for the above two.
- X Size calculations are implemented by going through the normal
- X routine but suppressing the actual drawing. */
- X
- Xstatic int
- X_wdrawpar(left, top, text, width, draw)
- X int left, top;
- X char *text;
- X int width;
- X bool draw;
- X{
- X TEXTEDIT *tp= tesetup((WINDOW*)NULL, left, top, left+width, top, FALSE);
- X int v;
- X
- X tesetbuf(tp, text, strlen(text));
- X if (draw)
- X tedraw(tp);
- X v= tegetbottom(tp);
- X tp->buf= NULL;
- X tefree(tp);
- X return v;
- X}
- END_OF_FILE
- if test 14543 -ne `wc -c <'Packs/textedit/textedit.c'`; then
- echo shar: \"'Packs/textedit/textedit.c'\" unpacked with wrong size!
- fi
- # end of 'Packs/textedit/textedit.c'
- fi
- if test -f 'Ports/x11/dialog.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'Ports/x11/dialog.c'\"
- else
- echo shar: Extracting \"'Ports/x11/dialog.c'\" \(14224 characters\)
- sed "s/^X//" >'Ports/x11/dialog.c' <<'END_OF_FILE'
- X/* X11 STDWIN -- Dialog boxes */
- X
- X#include "x11.h"
- X#include "llevent.h"
- X
- X/* The kinds of dialogs we know */
- X
- X#define MESSAGEKIND 0
- X#define ASKYNCKIND 1
- X#define ASKSTRKIND 2
- X
- X/* Display a message and wait until acknowledged */
- X
- Xvoid
- Xwmessage(prompt)
- X char *prompt;
- X{
- X (void) dialog(prompt, (char*)NULL, 0, MESSAGEKIND, 0);
- X}
- X
- X/* Ask a yes/no question.
- X Return value: yes ==> 1, no ==> 0, cancel (^C) ==> -1.
- X Only the first non-blank character of the string typed is checked.
- X The 'def' parameter is returned when an empty string is typed. */
- X
- Xint
- Xwaskync(prompt, def)
- X char *prompt;
- X int def;
- X{
- X return dialog(prompt, (char*)NULL, 0, ASKYNCKIND, def);
- X}
- X
- X/* Ask for a string. */
- X
- Xbool
- Xwaskstr(prompt, buf, len)
- X char *prompt;
- X char *buf;
- X int len;
- X{
- X return dialog(prompt, buf, len, ASKSTRKIND, TRUE);
- X}
- X
- X/* Definition for the current dialog box */
- X
- Xstatic struct windata box; /* Window descriptor for the dialog box */
- Xstatic unsigned long fg, bg; /* Foreground, background pixel values */
- Xstatic GC b_gc; /* Corresponding Graphics Context */
- X
- X/* Definition for a command "button" or text item in a dialog box */
- X
- Xstruct button {
- X char type; /* Button, label or text */
- X char *text; /* The button label */
- X int ret; /* Value to return when chosen */
- X struct windata wd; /* Window description */
- X tbool down; /* Button is pressed */
- X tbool inside; /* Mouse inside button */
- X tbool hilite; /* Button is hilited */
- X tbool def; /* Set if default button */
- X};
- X
- X/* Constants used in button definition 'type' field above */
- X
- X#define LABEL 'l'
- X#define TEXT 't'
- X#define BUTTON 'b'
- X
- Xstatic int nbuttons; /* number of buttons and items */
- Xstatic struct button *buttonlist; /* Definition list */
- X
- X/* Constants guiding button dimensions */
- X
- Xstatic int charwidth, textheight;
- Xstatic int promptwidth;
- Xstatic int buttonwidth;
- X
- X/* Dialog routine.
- X Create the window and subwindows, then engage in interaction.
- X Return the proper return value for waskync or waskstr.
- X*/
- X
- X/* Dimension of buttons:
- X vertically:
- X - 1 pixel white space around text,
- X - 1 pixel wide border,
- X - q pixel white space around border
- X horizontally:
- X - 1 space character around text
- X - 1 pixel wide border
- X - 1 pixel white space around border
- X The prompt and reply are placed as buttons but their
- X border is white.
- X For a message, the OK button is to the right of the text,
- X separated from the prompt by two extra space characters.
- X*/
- X
- Xstatic int
- Xdialog(prompt, buf, len, kind, def)
- X char *prompt; /* Prompt string */
- X char *buf; /* Reply buffer, or NULL if unused */
- X int len; /* Size of reply buffer */
- X int kind; /* Dialog kind */
- X int def; /* Default return value */
- X{
- X WINDOW *act;
- X XFontStruct *save_wf= _wf;
- X int ret;
- X int textlen= 60;
- X
- X _wf= _wmf; /* So we can use wtextwidth() etc. */
- X
- X /* Compute various useful dimensions */
- X charwidth= wcharwidth(' ');
- X textheight= wlineheight();
- X promptwidth= wtextwidth(prompt, -1);
- X if (kind == MESSAGEKIND)
- X buttonwidth= wtextwidth("OK", 2);
- X else
- X buttonwidth= wtextwidth("Cancel", 6);
- X
- X /* Compute the outer box dimensions */
- X switch (kind) {
- X case MESSAGEKIND:
- X box.width= promptwidth + buttonwidth + 6*charwidth + 8;
- X box.height= textheight + 6;
- X break;
- X case ASKYNCKIND:
- X box.width= promptwidth + 2*charwidth + 4;
- X CLIPMIN(box.width, 3*(buttonwidth + 2*charwidth + 4));
- X box.height= 2 * (textheight + 6);
- X break;
- X default:
- X _wdebug(0, "dialog: bad kind");
- X kind= ASKSTRKIND;
- X /* Fall through */
- X case ASKSTRKIND:
- X box.width= promptwidth + 2*charwidth + 4;
- X CLIPMAX(textlen, len);
- X CLIPMIN(box.width, textlen*charwidth);
- X CLIPMIN(box.width, 2*(buttonwidth + 2*charwidth + 4));
- X box.height= 3 * (textheight + 6);
- X break;
- X }
- X CLIPMAX(box.width, WidthOfScreen(_ws));
- X CLIPMAX(box.height, HeightOfScreen(_ws));
- X
- X /* Compute the box position:
- X above a window if possible,
- X on the screen if necessary. */
- X
- X /* XXX Default placement could use an option resource */
- X
- X act= _w_get_last_active();
- X if (act != NULL) {
- X Window child_dummy;
- X if (!XTranslateCoordinates(_wd, act->wi.wid,
- X RootWindowOfScreen(_ws),
- X#ifdef CENTERED
- X (act->wi.width - box.width) / 2,
- X (act->wi.height - box.height) / 2,
- X#else
- X 0,
- X 0,
- X#endif
- X &box.x, &box.y, &child_dummy))
- X act= NULL; /* Couldn't do it -- center on screen */
- X }
- X if (act == NULL) {
- X /* No window to cover */
- X#ifdef CENTERED
- X /* center the box in the screen */
- X box.x= (WidthOfScreen(_ws) - box.width) / 2;
- X box.y= (HeightOfScreen(_ws) - box.height) / 2;
- X#else
- X /* use top left screen corner */
- X box.x= box.y = 2*IBORDER + 1;
- X /* well, 1 pixel from the corner, to fool twm */
- X#endif
- X }
- X
- X /* Clip the box to the screen */
- X
- X CLIPMAX(box.x, WidthOfScreen(_ws) - box.width);
- X CLIPMAX(box.y, HeightOfScreen(_ws) - box.height);
- X CLIPMIN(box.x, 0);
- X CLIPMIN(box.y, 0);
- X _wdebug(1, "dialog box: x=%d y=%d w=%d h=%d",
- X box.x, box.y, box.width, box.height);
- X
- X /* Create the box window and its GC */
- X
- X fg= _wgetpixel("menuForeground", "Foreground",
- X BlackPixelOfScreen(_ws));
- X bg= _wgetpixel("menuBackground", "Background",
- X WhitePixelOfScreen(_ws));
- X box.border= 2*IBORDER;
- X (void) _wcreate(&box, RootWindowOfScreen(_ws), 0, FALSE, fg, bg);
- X _wsaveunder(&box, True);
- X XSelectInput(_wd, box.wid,
- X ExposureMask|KeyPressMask|StructureNotifyMask);
- X b_gc= _wgcreate(box.wid, _wf->fid, fg, bg);
- X
- X /* Keep window managers happy:
- X a name for WM's that insist on displaying a window title;
- X class hints;
- X WM hints;
- X size hints to avoid interactive window placement;
- X and "transient hints" to link it to an existing window.
- X The latter two only if the dialog box belongs to a window. */
- X
- X /* XXX This code could be unified with similar code in windows.c */
- X
- X /* The name is taken from _wprogname, to make it clear what
- X application a dialog belongs to (especially if there is
- X no window for it yet). */
- X
- X XStoreName(_wd, box.wid, _wprogname);
- X
- X /* Set class hints */
- X {
- X XClassHint classhint;
- X classhint.res_name= _wprogname;
- X classhint.res_class= "StdwinDialog";
- X XSetClassHint(_wd, box.wid, &classhint);
- X }
- X
- X /* Set WM hints */
- X {
- X XWMHints wmhints;
- X wmhints.flags = InputHint | StateHint;
- X wmhints.input = 1;
- X wmhints.initial_state = NormalState;
- X XSetWMHints(_wd, box.wid, &wmhints);
- X }
- X
- X if (act != NULL) {
- X XSizeHints sizehints;
- X
- X /* Pretend the user specified the size and position,
- X in an attempt to avoid window manager interference */
- X sizehints.x= box.x - box.border;
- X sizehints.y= box.y - box.border;
- X sizehints.width= box.width;
- X sizehints.height= box.height;
- X sizehints.flags= USPosition|USSize;
- X XSetNormalHints(_wd, box.wid, &sizehints);
- X
- X XSetTransientForHint(_wd, box.wid, act->wo.wid);
- X }
- X
- X /* Create the prompt label */
- X
- X addbutton(LABEL, prompt, def, FALSE,
- X 2,
- X 2,
- X promptwidth + 2*charwidth,
- X textheight + 2);
- X
- X /* Create the command buttons and text field (for ASKSTRKIND).
- X Note that our x, y convention differs from XCreateWindow:
- X we don't include the border width. */
- X
- X switch (kind) {
- X case MESSAGEKIND:
- X addbutton(BUTTON, "OK", def, FALSE,
- X box.width - buttonwidth - 2*charwidth - 2, 2,
- X buttonwidth + 2*charwidth,
- X textheight + 2);
- X break;
- X case ASKYNCKIND:
- X addbutton(BUTTON, "Yes", 1, def==1,
- X 2,
- X box.height - textheight - 4,
- X buttonwidth + 2*charwidth,
- X textheight + 2);
- X addbutton(BUTTON, "No", 0, def==0,
- X buttonwidth + 2*charwidth + 6,
- X box.height - textheight - 4,
- X buttonwidth + 2*charwidth,
- X textheight + 2);
- X addbutton(BUTTON, "Cancel", -1, def==-1,
- X box.width - buttonwidth - 2*charwidth - 2,
- X box.height - textheight - 4,
- X buttonwidth + 2*charwidth,
- X textheight + 2);
- X break;
- X case ASKSTRKIND:
- X addbutton(BUTTON, "OK", 1, FALSE,
- X 2,
- X box.height - textheight - 4,
- X buttonwidth + 2*charwidth,
- X textheight + 2);
- X addbutton(BUTTON, "Cancel", 0, FALSE,
- X box.width - buttonwidth - 2*charwidth - 2,
- X box.height - textheight - 4,
- X buttonwidth + 2*charwidth,
- X textheight + 2);
- X addbutton(TEXT, buf, def, FALSE,
- X 2,
- X textheight + 8,
- X box.width - 4,
- X textheight + 2);
- X break;
- X }
- X
- X /* Finish the work.
- X Map the window, process events, extract text,
- X destroy everything, return value. */
- X
- X XMapRaised(_wd, box.wid);
- X
- X ret=dialogeventloop(def);
- X if (kind == ASKSTRKIND && ret < 0)
- X ret= 0;
- X
- X if (ret > 0 && len > 0)
- X gettext(buf, len);
- X
- X XFreeGC(_wd, b_gc);
- X killbuttons();
- X XDestroyWindow(_wd, box.wid);
- X XFlush(_wd);
- X
- X _wf= save_wf;
- X
- X return ret;
- X}
- X
- X/* Add a command button */
- X
- Xstatic
- Xaddbutton(type, text, ret, def, x, y, width, height)
- X int type;
- X char *text;
- X int ret;
- X bool def;
- X int x, y, width, height;
- X{
- X struct button b;
- X int cursor= (type == BUTTON) ? XC_arrow : 0;
- X
- X b.type= type;
- X b.text= strdup(text);
- X b.ret= ret;
- X b.def= def;
- X
- X b.wd.x= x;
- X b.wd.y= y;
- X b.wd.width= width;
- X b.wd.height= height;
- X
- X if (type == LABEL)
- X b.wd.border= 0;
- X else
- X b.wd.border= IBORDER;
- X (void) _wcreate(&b.wd, box.wid, cursor, TRUE, fg, bg);
- X XSelectInput(_wd, b.wd.wid,
- X type == BUTTON ?
- X ExposureMask|ButtonPressMask|ButtonReleaseMask|
- X EnterWindowMask|LeaveWindowMask
- X : ExposureMask);
- X
- X b.down= 0;
- X b.inside= FALSE;
- X b.hilite= type == TEXT && text[0] != EOS;
- X
- X L_APPEND(nbuttons, buttonlist, struct button, b);
- X}
- X
- X/* Dialog event processing loop.
- X Return number of button selected, -1 for Return, -2 for ^C. */
- X
- Xstatic struct button *whichbutton(); /* Forward */
- X
- Xstatic int
- Xdialogeventloop(def)
- X int def;
- X{
- X for (;;) {
- X XEvent e;
- X struct button *bp;
- X int c;
- X
- X XNextEvent(_wd, &e);
- X _wdebug(3, "dlog2: evt type %d", e.type);
- X bp= whichbutton(e.xbutton.window);
- X if (bp != NULL) {
- X if (buttonevent(bp, &e)) {
- X return bp->ret;
- X }
- X }
- X else if (e.xbutton.window == box.wid || e.type == KeyPress) {
- X switch (e.type) {
- X
- X case KeyPress:
- X switch (c= charcode(&e.xkey)) {
- X case EOS:
- X break;
- X case '\003': /* ^C, interrupt */
- X return -1;
- X /* Fall through */
- X case '\n':
- X case '\r':
- X return def;
- X default:
- X if (!addchar(c))
- X XBell(_wd, 0);
- X break;
- X }
- X break;
- X
- X case MapNotify:
- X /* Could set the input focus if another
- X of our windows has it */
- X break;
- X
- X default:
- X _wdebug(3, "dialog: box ev %d", e.type);
- X if (e.type == ButtonPress)
- X XBell(_wd, 0);
- X break;
- X
- X }
- X }
- X else {
- X switch (e.type) {
- X case ButtonPress:
- X case KeyPress:
- X _wdebug(3, "dialog: alien press %d", e.type);
- X XBell(_wd, 0);
- X break;
- X case ButtonRelease:
- X case MotionNotify:
- X _wdebug(3, "dialog: alien move %d", e.type);
- X break;
- X default:
- X _wdebug(3, "dialog: alien llev %d", e.type);
- X _w_ll_event(&e);
- X break;
- X }
- X }
- X }
- X}
- X
- X/* Find out which button a given Window ID belongs to (if any) */
- X
- Xstatic struct button *
- Xwhichbutton(w)
- X Window w;
- X{
- X int i;
- X
- X for (i= nbuttons; --i >= 0; ) {
- X if (w == buttonlist[i].wd.wid)
- X return &buttonlist[i];
- X }
- X return NULL;
- X}
- X
- X/* Return the character code corresponding to a key event.
- X Returns EOS if no ASCII character. */
- X
- Xstatic int
- Xcharcode(kep)
- X XKeyEvent *kep;
- X{
- X KeySym keysym;
- X char strbuf[10];
- X
- X if (XLookupString(kep, strbuf, sizeof strbuf,
- X &keysym, (XComposeStatus*)NULL) <= 0)
- X return EOS;
- X else
- X return strbuf[0];
- X}
- X
- X/* Append a character to the text item.
- X Here it is that we assume that the text item is last.
- X Unfortunately we can't use textedit (yet) to support all
- X desirable functionality, but we do support backspace
- X and overwriting the entire text. */
- X
- Xstatic bool
- Xaddchar(c)
- X int c;
- X{
- X struct button *bp= &buttonlist[nbuttons - 1];
- X int i;
- X
- X if (bp->type != TEXT || bp->text == NULL)
- X return FALSE;
- X i= strlen(bp->text);
- X if (c == '\b' || c == '\177' /*DEL*/ ) {
- X if (i > 0) {
- X bp->text[i-1]= EOS;
- X bp->hilite= FALSE;
- X }
- X }
- X else {
- X if (bp->hilite) {
- X i= 0;
- X bp->hilite= FALSE;
- X }
- X bp->text= realloc(bp->text, (unsigned)(i+2));
- X if (bp->text != NULL) {
- X bp->text[i]= c;
- X bp->text[i+1]= EOS;
- X }
- X }
- X drawbutton(bp);
- X return TRUE;
- X}
- X
- X/* Process an event directed to a given button.
- X This also updates the highlighting. */
- X
- Xstatic bool
- Xbuttonevent(bp, xep)
- X struct button *bp;
- X XEvent *xep;
- X{
- X bool hit= FALSE;
- X
- X switch (xep->type) {
- X
- X case Expose:
- X drawbutton(bp);
- X return FALSE;
- X
- X case ButtonPress:
- X if (bp->down == 0)
- X bp->down= xep->xbutton.button;
- X break;
- X
- X case ButtonRelease:
- X if (bp->down == xep->xbutton.button) {
- X hit= bp->inside;
- X bp->down= 0;
- X }
- X break;
- X
- X case EnterNotify:
- X bp->inside= TRUE;
- X break;
- X
- X case LeaveNotify:
- X bp->inside= FALSE;
- X break;
- X
- X default:
- X return FALSE;
- X
- X }
- X hilitebutton(bp, bp->down > 0 && bp->inside);
- X return hit;
- X}
- X
- X/* Draw procedure to draw a command button or text item */
- X
- Xstatic
- Xdrawbutton(bp)
- X struct button *bp;
- X{
- X char *text= bp->text == NULL ? "" : bp->text;
- X int len= strlen(text);
- X int width= XTextWidth(_wmf, text, len);
- X int x= (bp->type == BUTTON) ? (bp->wd.width - width) / 2 : charwidth;
- X int y= (bp->wd.height + _wmf->ascent - _wmf->descent) / 2;
- X
- X XClearWindow(_wd, bp->wd.wid);
- X XDrawString(_wd, bp->wd.wid, b_gc, x, y, text, len);
- X /* Indicate the default button with an underline */
- X if (bp->def) {
- X unsigned long ulpos, ulthick;
- X if (!XGetFontProperty(_wmf, XA_UNDERLINE_POSITION, &ulpos))
- X ulpos= _wmf->descent/2;
- X if (!XGetFontProperty(_wmf, XA_UNDERLINE_THICKNESS,&ulthick)) {
- X ulthick= _wmf->descent/3;
- X CLIPMIN(ulthick, 1);
- X }
- X _winvert(bp->wd.wid, b_gc,
- X x, (int)(y + ulpos), width, (int)ulthick);
- X }
- X if (bp->hilite)
- X _winvert(bp->wd.wid, b_gc,
- X 0, 0, bp->wd.width, bp->wd.height);
- X}
- X
- X/* Highlight or unhighlight a command button */
- X
- Xstatic
- Xhilitebutton(bp, hilite)
- X struct button *bp;
- X bool hilite;
- X{
- X if (bp->hilite != hilite) {
- X _winvert(bp->wd.wid, b_gc,
- X 0, 0, bp->wd.width, bp->wd.height);
- X bp->hilite= hilite;
- X }
- X}
- X
- X/* Extract the text from the text item */
- X
- Xstatic
- Xgettext(buf, len)
- X char *buf;
- X int len;
- X{
- X struct button *bp= &buttonlist[nbuttons - 1];
- X
- X if (bp->type != TEXT || bp->text == NULL)
- X return;
- X strncpy(buf, bp->text, len-1);
- X buf[len-1]= EOS;
- X}
- X
- X/* Destroy all buttons and associated data structures */
- X
- Xstatic
- Xkillbuttons()
- X{
- X int i;
- X for (i= 0; i < nbuttons; ++i)
- X free(buttonlist[i].text);
- X L_SETSIZE(nbuttons, buttonlist, struct button, 0);
- X}
- END_OF_FILE
- if test 14224 -ne `wc -c <'Ports/x11/dialog.c'`; then
- echo shar: \"'Ports/x11/dialog.c'\" unpacked with wrong size!
- fi
- # end of 'Ports/x11/dialog.c'
- fi
- echo shar: End of archive 6 \(of 19\).
- cp /dev/null ark6isdone
- 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
-