v04i061: xtroff -- troff previewer for X11, Part16/18
Dan Heller
argv at island.uu.net
Wed Jul 19 19:13:51 AEST 1989
Submitted-by: Mark Moraes <moraes at ai.toronto.edu>
Posting-number: Volume 4, Issue 61
Archive-name: xtroff/part16
#! /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 16 (of 18)."
# Contents: xtroff/XtStuff/Minibuf.c
# Wrapped by moraes at neat.ai on Thu Jul 13 20:55:23 1989
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'xtroff/XtStuff/Minibuf.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'xtroff/XtStuff/Minibuf.c'\"
else
echo shar: Extracting \"'xtroff/XtStuff/Minibuf.c'\" \(29958 characters\)
sed "s/^X//" >'xtroff/XtStuff/Minibuf.c' <<'END_OF_FILE'
X/* $Header: Minibuf.c,v 1.5 89/06/30 03:38:22 moraes Exp $ */
X/*
X * This file should be edited with 4-column tabs! (:set ts=4 sw=4 in
X * vi, set internal-tabstop 4 in Jove, and use edit-tab-stops in Emacs
X * to get them
X */
X
X/*
X * This set of routines create and manipulate a simple one-line input
X * window. They offer a reasonable subset of EMACS like editing
X * capabilities, Like EMACS, the command-key to action bindings can be
X * altered. It does no data validation. The minibuffer can be created
X * using normal Xt calls, with args, and parsing the resources. Other
X * calls allow strings to be displayed or input or both. (prompted
X * input). There is no restriction on the length of the input line,
X * which will horizontally scroll in the window, EMACS-style, by half
X * the "screen" width. It can be used in dialog boxes, or as in xpic,
X * for an interaction line.
X */
X/*
X * Since this is the first (and only) widget I've written, there are
X * probably lots of things done wrong. Feel free to fix 'em. This was
X * written because the Text widgets available are more powerful than I
X * need, but aren't capable of performing the simple function that this
X * performs - display a prompt, a default chunk of text, and permit
X * editing of the default. MOST important, it must invoke some sort of
X * callback when the user hits RETURN or ^G/^C. As a minor point, I
X * hate the silly underline ^ cursor that the text widget allows. Give
X * me a solid blob anyday. It would be nice if someone could hack this
X * capability into the Text widget - after a bit of digging in its
X * code, I decided that preserving my sanity (or what's left of it) was
X * important, and chose to write this - it was much simpler.
X */
X/* Author: Mark Moraes (moraes at csri.toronto.edu)
X History: First written for X10 under the X10 tookit, for xpic in
X August 1987.
X This version was ported to X11, and then tuned and cleaned
X up - X11 is so much slower on Suns that the inefficient
X redisplay strategy used in the X10 version was unfeasible
X June 1988.
X */
X/* To do:
X Get it to understand the subtleties of reverse video
X */
X
X#include <strings.h>
X#include <ctype.h>
X#ifdef DEBUG
X#include <stdio.h>
X#endif
X#include <X11/Xlib.h>
X#include <X11/StringDefs.h>
X#include <X11/IntrinsicP.h>
X#include <X11/Intrinsic.h>
X#include <X11/keysymdef.h>
X#include <X11/CoreP.h>
X#include <X11/Core.h>
X#include "MinibufP.h"
X#include "Minibuf.h"
X
X#include "assert.h"
X
X/* To keep references to data less than six miles long */
X#define mbuf(x) buf->minibuf.x
X#define mcore(x) buf->core.x
X#define fontwidth(x) ((x)->max_bounds.width)
X#define fontheight(x) ((x)->max_bounds.ascent + (x)->max_bounds.descent)
X#define fontbaseline(x) ((x)->max_bounds.ascent)
X#define CheckMode() if (mbuf(inputMode) == FALSE) return; else ;
X
X
X/*
X * This should be larger than the expected filesize - if a XtRealloc
X * occurs in insert_s(), add_mess(), bad things will happen because the
X * f_complete routines don't expect the string to change while they're
X * working - fixing this is work that I don't feel upto right now - one
X * day....
X */
X#define BUF_BLOCK 128
X
X#define MIN_COLS 5
X#define DEFAULTFONT "8x13"
X#define ABORT_MSG "[Aborted]"
X#define DELAY 300000 /*
X * Microseconds of delay for cursor
X * flash in SetMark
X */
X
X/* The default bindings */
Xstatic char defaultTranslations[] =
X "Ctrl<Key>F: forward-character()\n\
X <Key>0xff53: forward-character()\n\
X Ctrl<Key>B: backward-character()\n\
X <Key>0xff51: backward-character()\n\
X Ctrl<Key>A: beginning-of-line()\n\
X Ctrl<Key>E: end-of-line()\n\
X Ctrl<Key>U: universal-argument()\n\
X Ctrl<Key>D: delete-next-character()\n\
X Ctrl<Key>H: delete-previous-character()\n\
X <Key>0xff7f: delete-previous-character()\n\
X <Key>0xffff: delete-previous-character()\n\
X <Key>0xff08: delete-previous-character()\n\
X Ctrl<Key>X: exchange-point-and-mark()\n\
X Ctrl<Key>W: kill-region()\n\
X Ctrl<Key>K: kill-to-end-of-line()\n\
X Meta<Key>D: kill-to-beginning-of-line()\n\
X Ctrl<Key>Y: yank-killed-text()\n\
X Ctrl<Key>J: newline()\n\
X <Key>0xff0a: newline()\n\
X Ctrl<Key>M: newline()\n\
X <Key>0xff0d: newline()\n\
X Ctrl<Key>G: abort()\n\
X Ctrl<Key>C: abort()\n\
X <Btn1Down>: set-cursor-to-mouse()\n\
X <Btn2Down>: get-x-buffer()\n\
X <Btn3Down>: set-mark-to-mouse()\n\
X Ctrl<Key>0x20: make-this-the-mark()\n\
X <Key>0x20: complete-filename()\n\
X Ctrl<Key>I: complete-filename()\n\
X <Key>0xff09: complete-filename()\n\
X Shift<Key>/: list-files()\n\
X <Key>/: insert-char()\n\
X <Key>?: list-files()\n\
X <Key>: insert-char()\n\
X";
X
X
Xstatic void CursorForward(), CursorBack(), BeginningOfBuf(), EndOfBuf(),
X UnivArgument(), DeleteCharForward(), DeleteCharBack(), KillToEnd(),
X KillToBeginning(), YankKilledStuff(), MakeMark(), ExchangeMarkAndPoint(),
X CutMarkToPoint(), FinishedInput(), QuitInput(), SetCursor(), SetMark(),
X GetXBuffer(), CharInsert(), CompleteFilename(), ListFiles();
X
X/* Actions Table */
Xstatic XtActionsRec actionsList [] = {
X/* motion bindings */
X {"forward-character", CursorForward},
X {"backward-character", CursorBack},
X {"beginning-of-line", BeginningOfBuf},
X {"end-of-line", EndOfBuf},
X {"universal-argument", UnivArgument},
X/* delete bindings */
X {"delete-next-character", DeleteCharForward},
X {"delete-previous-character", DeleteCharBack},
X/* kill bindings */
X {"kill-to-end-of-line", KillToEnd},
X {"kill-to-beginning-of-line", KillToBeginning},
X/* yank bindings */
X {"yank-killed-text", YankKilledStuff},
X {"make-this-the-mark", MakeMark},
X {"exchange-point-and-mark", ExchangeMarkAndPoint},
X {"kill-region", CutMarkToPoint},
X/* new line stuff */
X {"newline", FinishedInput},
X {"abort", QuitInput},
X/* Selection stuff */
X {"set-cursor-to-mouse", SetCursor},
X {"set-mark-to-mouse", SetMark},
X {"get-x-buffer", GetXBuffer},
X/* filename completion and listing of files */
X {"complete-filename", CompleteFilename},
X {"list-files", ListFiles},
X/* Insert character */
X {"insert-char", CharInsert},
X};
X
Xstatic int zero = 0;
X
X#define offset(field) XtOffset(MinibufWidget, field)
Xstatic XtResource resources[] = {
X {XtNforeground, XtCForeground, XtRPixel, sizeof(Pixel),
X offset(minibuf.foreground), XtRString, "Black"},
X {XtNfont, XtCFont, XtRFontStruct, sizeof(XFontStruct *),
X offset(minibuf.finfo),XtRString, DEFAULTFONT},
X {XtNcursor, XtCCursor, XtRCursor, sizeof(Cursor),
X offset(minibuf.cursor), XtRString, "xterm"},
X {XtNfinishedCallback, XtCCallback, XtRCallback, sizeof(XtProc),
X offset(minibuf.finishedCallback), XtRCallback, (caddr_t)NULL},
X#ifdef TYPEOUT
X {XtNtypeoutColumns, XtCTypeoutColumns, XtRInt, sizeof(int),
X offset(minibuf.typeoutColumns), XtRInt, (caddr_t)&zero},
X {XtNtypeout, XtCtypeout, XtRPointer, sizeof(Widget),
X offset(minibuf.typeout), XtRPointer, (caddr_t)NULL},
X#endif
X};
X
Xstatic void Initialize(), Realize(), Destroy(), Redisplay(), Resize();
X
X/*
X * ...ClassData must be initialized at compile time. Must initialize
X * all substructures. (Actually, last two here need not be initialized
X * since not used.)
X */
XMinibufClassRec minibufClassRec = {
X {
X (WidgetClass) &widgetClassRec, /* superclass */
X "Minibuf", /* class_name */
X sizeof(MinibufRec), /* size */
X NULL, /* class_initialize */
X NULL, /* class_part_initialize*/
X FALSE, /* class_inited */
X Initialize, /* initialize */
X NULL, /* initialize_hook */
X Realize, /* realize */
X actionsList, /* actions */
X XtNumber(actionsList), /* num_actions */
X resources, /* resources */
X XtNumber(resources), /* resource_count */
X NULLQUARK, /* xrm_class */
X TRUE, /* compress_motion */
X TRUE, /* compress_exposure */
X TRUE, /* compress_enterleave */
X FALSE, /* visible_interest */
X Destroy, /* destroy */
X Resize, /* resize */
X Redisplay, /* expose */
X NULL, /* set_values */
X NULL, /* set_values_hook */
X XtInheritSetValuesAlmost, /* set_values_almost */
X NULL, /* get_values_hook */
X NULL, /* accept_focus */
X XtVersion, /* version */
X NULL, /* callback_private */
X defaultTranslations, /* tm_table */
X NULL, /* query_geometry */
X#ifdef XtCAccelerators
X XtInheritDisplayAccelerator, /* display_accelerator */
X NULL /* extension */
X#endif /* XtCAccelerators */
X }, /* CoreClass fields initialization */
X {
X 0, /* field not used */
X }, /* MinibufClass fields initialization */
X};
X
X/* for public consumption */
XWidgetClass minibufWidgetClass = (WidgetClass)&minibufClassRec;
X
X/*ARGSUSED*/
Xstatic void Initialize(request, new)
XWidget request, new;
X{
X register MinibufWidget buf = (MinibufWidget) new;
X XGCValues gcv;
X
X mbuf(string) = mbuf(killBuffer) = NULL;
X mbuf(size) = mbuf(startPos) = mbuf(cursorPos) = mbuf(mark)
X = mbuf(killBufferLen) = mbuf(killBufferSize) = mbuf(len)
X = mbuf(cols) = mbuf(promptLen) = 0;
X mbuf(arg) = 1;
X mbuf(cursorX) = 0;
X mbuf(inputMode) = FALSE;
X gcv.foreground = mbuf(foreground);
X gcv.background = mcore(background_pixel);
X gcv.font = mbuf(finfo)->fid;
X mbuf(normal_gc) = XtGetGC(new, GCForeground | GCBackground | GCFont,
X &gcv);
X gcv.foreground = mbuf(foreground) ^ mcore(background_pixel);
X gcv.function = GXxor;
X mbuf(invert_gc) = XtGetGC(new, GCForeground | GCBackground | GCFont |
X GCFunction, &gcv);
X
X /* Compute these correctly */
X if (mcore(height) == 0)
X mcore(height) = fontheight(mbuf(finfo));
X
X if ((mbuf(cols) = mcore(width) / fontwidth(mbuf(finfo))) < MIN_COLS) {
X /* Set it to MIN_COLS */
X mcore(width) = MIN_COLS * fontwidth(mbuf(finfo));
X }
X}
X
X/* Wish the primitive widget had a cursor .. */
Xstatic void Realize(w, valueMask, attributes)
Xregister Widget w;
XMask *valueMask;
XXSetWindowAttributes *attributes;
X{
X if ((attributes->cursor = ((MinibufWidget)w)->minibuf.cursor) != None)
X *valueMask |= CWCursor;
X
X XtCreateWindow( w, (unsigned int)InputOutput, (Visual *)CopyFromParent,
X *valueMask, attributes );
X}
X
Xstatic void Destroy(w)
XWidget w;
X{
X register MinibufWidget buf = (MinibufWidget) w;
X
X if (mbuf(string) != NULL)
X free(mbuf(string));
X if (mbuf(killBuffer) != NULL)
X free(mbuf(killBuffer));
X XtDestroyGC(mbuf(normal_gc));
X XtDestroyGC(mbuf(invert_gc));
X}
X
X
X/*ARGSUSED*/
Xstatic void Redisplay(w, event, region)
XWidget w;
XXEvent *event;
XRegion region;
X{
X register MinibufWidget buf = (MinibufWidget) w;
X static void DisplayBuf(), DisplayCursor();
X
X if (!XtIsRealized(w))
X return;
X DisplayBuf(buf, TRUE);
X if (mbuf(cursorOn) == TRUE)
X DisplayCursor(buf);
X}
X
X
Xstatic void Resize(w)
XWidget w;
X{
X register MinibufWidget buf = (MinibufWidget) w;
X static void DisplayBuf(), DisplayCursor();
X
X /*
X * We should probably do some geometry management stuff here, if
X * the number of cols is less than MIN_COLS
X */
X mbuf(cols) = mcore(width) / fontwidth(mbuf(finfo));
X if (!XtIsRealized(w))
X return;
X DisplayBuf(buf, TRUE);
X if (mbuf(cursorOn) == TRUE)
X DisplayCursor(buf);
X}
X
X/*
X * Displays the buffer. When called with redraw = TRUE, it clears the
X * entire buffer and redraws it. If redraw = FALSE, then it clears from
X * the cursor position to the end of the buffer, and then redraws just
X * that section. This allows for fast update when a single character is
X * typed, or deleted, usually at the end of the line. If redraw is
X * FALSE, teh cursor must be turned off before this is called -
X * otherwise it may or may not vanish, causing problems. Typically, we
X * hide the cursor, then update the buffer string and data, and then
X * call this procedure. Note that for delete-char-forward, char-insert,
X * and StrInsert, this gets called AFTER the mbuf(string) is updated
X * but before the mbuf(cursorPos) is updated, which in delete-char-back
X * and cut-point-to-mark, it is called afetr the cursorPos is updated
X * as well, so that the changed region is redrawn.
X */
Xstatic void DisplayBuf(buf, redraw)
Xregister MinibufWidget buf;
Xint redraw;
X{
X register int nChars, isLonger;
X int start;
X register Widget w = (Widget) buf;
X
X if (redraw) {
X start = mbuf(startPos);
X XClearWindow(XtDisplay(w), XtWindow(w));
X } else {
X start = mbuf(cursorPos);
X mbuf(cursorX) = (mbuf(cursorPos) - mbuf(startPos)) *
X fontwidth(mbuf(finfo));
X XClearArea(XtDisplay(w), XtWindow(w), mbuf(cursorX), 0,
X mcore(width) - mbuf(cursorX), (unsigned) fontheight(mbuf(finfo)),
X False);
X }
X nChars = (mbuf(startPos) + mbuf(cols));
X isLonger = (nChars < mbuf(len));
X if (isLonger)
X nChars -= start + 1;
X else
X nChars = mbuf(len) - start;
X
X XDrawImageString(XtDisplay(w), XtWindow(w), mbuf(normal_gc),
X redraw? 0 : mbuf(cursorX), fontbaseline(mbuf(finfo)),
X mbuf(string) + start, nChars);
X
X if (isLonger)
X XDrawImageString(XtDisplay(w), XtWindow(w), mbuf(normal_gc),
X (mbuf(cols) - 1) * fontwidth(mbuf(finfo)),
X fontbaseline(mbuf(finfo)), "!", 1);
X}
X
X
X/*
X * Display the buffer cursor. It does the devious computations for
X * Horiz scrolling of the minibuffer, back and forward, and does a
X * 'hard' redisplay (i.e. with a clear) of the window if a horiz.
X * scroll is done.
X */
Xstatic void DisplayCursor(buf)
Xregister MinibufWidget buf;
X{
X register int col;
X register Widget w = (Widget) buf;
X
X if (mbuf(cursorPos) > mbuf(len))
X mbuf(cursorPos) = mbuf(len);
X if (mbuf(cursorPos) < mbuf(promptLen))
X mbuf(cursorPos) = mbuf(promptLen);
X
X col = (mbuf(cursorPos) - mbuf(startPos));
X
X if ((col >= mbuf(cols)) || (col < 0)) {
X if (mbuf(cursorPos) < mbuf(cols) - 1) {
X /*
X * The cursor will be seen if the start
X * position is 0, which looks nicer than half
X * the prompt showing
X */
X mbuf(startPos) = 0;
X col = mbuf(cursorPos);
X } else {
X /*
X * Horiz scroll the buffer to mbuf(cols)/2
X * before cursorPos. this acounts for both
X * forward and backward scrolling.
X */
X col = (mbuf(cols)) / 2 - 1;
X mbuf(startPos) = mbuf(cursorPos) - col;
X if (mbuf(startPos) < 0) {
X mbuf(startPos) = 0;
X col = (mbuf(cursorPos) - mbuf(startPos));
X }
X }
X DisplayBuf(buf, TRUE);
X }
X mbuf(cursorX) = col * fontwidth(mbuf(finfo));
X XFillRectangle(XtDisplay(w), XtWindow(w), mbuf(invert_gc),
X mbuf(cursorX), 0, (unsigned) fontwidth(mbuf(finfo)),
X (unsigned) fontheight(mbuf(finfo)));
X mbuf(cursorOn) = TRUE;
X}
X
X
X
X/*
X * Hide the cursor
X */
Xstatic void ConcealCursor(buf)
Xregister MinibufWidget buf;
X{
X register Widget w = (Widget) buf;
X if (mbuf(cursorOn) == TRUE) {
X XFillRectangle(XtDisplay(w), XtWindow(w), mbuf(invert_gc),
X mbuf(cursorX), 0, (unsigned) fontwidth(mbuf(finfo)),
X (unsigned) fontheight(mbuf(finfo)));
X mbuf(cursorOn) = FALSE;
X }
X}
X
X
X
X/*
X * Inserts len characters of string s into the buffer at the current
X * cursor position. Note that it does not re-display the cursor, while
X * CharInsert does.
X */
X/* The universal argument has no effect on this one */
Xstatic void StrInsert(s, len, buf)
Xregister char *s;
Xregister int len;
Xregister MinibufWidget buf;
X{
X register int newLen = mbuf(len) + len;
X static void QuitInput();
X
X while (newLen > mbuf(size)) {
X mbuf(size) += BUF_BLOCK;
X if (mbuf(string) == NULL)
X mbuf(string) = XtMalloc((unsigned) mbuf(size));
X else
X mbuf(string) = XtRealloc(mbuf(string), (unsigned) mbuf(size));
X if ( mbuf(string) == NULL) {
X mbuf(size) = 0;
X mbuf(len) = 0;
X mbuf(inputMode) = FALSE;
X QuitInput((Widget) buf, (XEvent *) NULL, (String *) NULL,
X (Cardinal *) NULL);
X return;
X }
X }
X bcopy(mbuf(string) + mbuf(cursorPos), mbuf(string) + mbuf(cursorPos) + len,
X mbuf(len) - mbuf(cursorPos));
X bcopy(s, mbuf(string) + mbuf(cursorPos), len);
X mbuf(len) += len;
X DisplayBuf(buf, FALSE);
X mbuf(cursorPos) += len;
X mbuf(arg) = 1;
X}
X
X
X
X/*
X * Inserts c arg times into buffer string at current position and moves
X * cursor forward
X */
X/*ARGSUSED*/
Xstatic void CharInsert(w, event, params, numparams)
XWidget w;
XXEvent *event;
XString *params;
XCardinal *numparams;
X{
X register MinibufWidget buf = (MinibufWidget) w;
X register int i = mbuf(cursorPos);
X register int j = mbuf(arg);
X static void QuitInput();
X KeySym keysym;
X XComposeStatus compose;
X int status;
X char c;
X
X CheckMode();
X status = XLookupString(&event->xkey, &c, 1, &keysym, &compose);
X if (!status || !isascii(c) || !isprint(c))
X return;
X ConcealCursor(buf);
X while (mbuf(size) < mbuf(len) + mbuf(arg)) { /* Need more space */
X mbuf(size) += BUF_BLOCK;
X if (mbuf(string) == NULL)
X mbuf(string) = XtMalloc((unsigned) mbuf(size));
X else
X mbuf(string) = XtRealloc(mbuf(string), (unsigned) mbuf(size));
X if (mbuf(string) == NULL) {
X mbuf(size) = 0;
X mbuf(len) = 0;
X mbuf(inputMode) = FALSE;
X QuitInput(w, event, params, numparams);
X return;
X }
X }
X
X bcopy(mbuf(string) + i, mbuf(string) + i + mbuf(arg),
X mbuf(len) - i);
X mbuf(len) += mbuf(arg);
X for (; j > 0; j--,i++) {
X mbuf(string)[i] = c;
X }
X DisplayBuf(buf, FALSE);
X mbuf(cursorPos) += mbuf(arg);
X mbuf(arg) = 1;
X DisplayCursor(buf);
X}
X
X
X/*ARGSUSED*/
Xstatic void CursorBack(w, event, params, numparams)
XWidget w;
XXEvent *event;
XString *params;
XCardinal *numparams;
X{
X register MinibufWidget buf = (MinibufWidget) w;
X register int i;
X
X CheckMode();
X if ((i = (mbuf(cursorPos) - mbuf(arg))) < mbuf(promptLen))
X i = mbuf(promptLen);
X
X ConcealCursor(buf);
X mbuf(cursorPos) = i;
X mbuf(arg) = 1;
X DisplayCursor(buf);
X}
X
X
X/*ARGSUSED*/
Xstatic void CursorForward(w, event, params, numparams)
XWidget w;
XXEvent *event;
XString *params;
XCardinal *numparams;
X{
X register MinibufWidget buf = (MinibufWidget) w;
X register int i;
X
X CheckMode();
X if ((i = (mbuf(cursorPos) + mbuf(arg))) > mbuf(len))
X i = mbuf(len);
X
X ConcealCursor(buf);
X mbuf(cursorPos) = i;
X mbuf(arg) = 1;
X DisplayCursor(buf);
X}
X
X
X/*ARGSUSED*/
Xstatic void SetCursor(w, event, params, numparams)
XWidget w;
XXEvent *event;
XString *params;
XCardinal *numparams;
X{
X register MinibufWidget buf = (MinibufWidget) w;
X Window foo1, foo2;
X int foo3, foo4;
X unsigned int foo5;
X int x, y;
X register int mCol;
X
X CheckMode();
X (void) XQueryPointer(XtDisplay(w), XtWindow(w),
X &foo1, &foo2, &foo3, &foo4, &x, &y, &foo5);
X mCol = x / fontwidth(mbuf(finfo));
X ConcealCursor(buf);
X mbuf(cursorPos) = mbuf(startPos) + mCol;
X mbuf(arg) = 1;
X DisplayCursor(buf);
X}
X
X/*
X * Tries to flash the cursor to the mark, and then back to the cursor
X * position. This will only be useful when bound to the mouse buttons.
X */
X/*ARGSUSED*/
Xstatic void SetMark(w, event, params, numparams)
XWidget w;
XXEvent *event;
XString *params;
XCardinal *numparams;
X{
X register MinibufWidget buf = (MinibufWidget) w;
X register int tmp;
X Window foo1, foo2;
X int foo3, foo4;
X unsigned int foo5;
X int x, y;
X register int mCol;
X
X CheckMode();
X tmp = mbuf(cursorPos);
X (void) XQueryPointer(XtDisplay(w), XtWindow(w),
X &foo1, &foo2, &foo3, &foo4, &x, &y, &foo5);
X mCol = x / fontwidth(mbuf(finfo));
X ConcealCursor(buf);
X mbuf(cursorPos) = mbuf(mark) = mbuf(startPos) + mCol;
X DisplayCursor(buf);
X XFlush(XtDisplay(w));
X usleep(DELAY);
X ConcealCursor(buf);
X mbuf(cursorPos) = tmp;
X DisplayCursor(buf);
X mbuf(arg) = 1;
X}
X
X
X
X/* The universal argument has no effect on this one */
X/*ARGSUSED*/
Xstatic void BeginningOfBuf(w, event, params, numparams)
XWidget w;
XXEvent *event;
XString *params;
XCardinal *numparams;
X{
X register MinibufWidget buf = (MinibufWidget) w;
X CheckMode();
X ConcealCursor(buf);
X mbuf(cursorPos) = mbuf(promptLen);
X DisplayCursor(buf);
X}
X
X
X
X/* The universal argument has no effect on this one */
X/*ARGSUSED*/
Xstatic void EndOfBuf(w, event, params, numparams)
XWidget w;
XXEvent *event;
XString *params;
XCardinal *numparams;
X{
X register MinibufWidget buf = (MinibufWidget) w;
X
X CheckMode();
X ConcealCursor(buf);
X mbuf(cursorPos) = mbuf(len);
X DisplayCursor(buf);
X}
X
X
X
X/*ARGSUSED*/
Xstatic void DeleteCharForward(w, event, params, numparams)
XWidget w;
XXEvent *event;
XString *params;
XCardinal *numparams;
X{
X register MinibufWidget buf = (MinibufWidget) w;
X register int i;
X
X CheckMode();
X if ((i = (mbuf(cursorPos) + mbuf(arg))) > mbuf(len))
X i = mbuf(len);
X
X ConcealCursor(buf);
X bcopy(mbuf(string) + i, mbuf(string) + mbuf(cursorPos), mbuf(len) - i);
X mbuf(len) -= i - mbuf(cursorPos);
X mbuf(arg) = 1;
X DisplayBuf(buf, FALSE);
X DisplayCursor(buf);
X}
X
X
X/*ARGSUSED*/
Xstatic void DeleteCharBack(w, event, params, numparams)
XWidget w;
XXEvent *event;
XString *params;
XCardinal *numparams;
X{
X register MinibufWidget buf = (MinibufWidget) w;
X register int i;
X
X CheckMode();
X if ((i = (mbuf(cursorPos) - mbuf(arg))) < mbuf(promptLen))
X i = mbuf(promptLen);
X
X ConcealCursor(buf);
X bcopy(mbuf(string) + mbuf(cursorPos), mbuf(string) + i, mbuf(len) - i);
X mbuf(len) += i - mbuf(cursorPos);
X mbuf(cursorPos) = i;
X mbuf(arg) = 1;
X DisplayBuf(buf, FALSE);
X DisplayCursor(buf);
X}
X
X
X
X
X/* The universal argument has no effect on this one */
X/* Like Setmark, this flashes the cursor */
X/*ARGSUSED*/
Xstatic void MakeMark(w, event, params, numparams)
XWidget w;
XXEvent *event;
XString *params;
XCardinal *numparams;
X{
X register MinibufWidget buf = (MinibufWidget) w;
X
X CheckMode();
X mbuf(mark) = mbuf(cursorPos);
X mbuf(arg) = 1;
X}
X
X
X
X/*ARGSUSED*/
Xstatic void ExchangeMarkAndPoint(w, event, params, numparams)
XWidget w;
XXEvent *event;
XString *params;
XCardinal *numparams;
X{
X register MinibufWidget buf = (MinibufWidget) w;
X register int tmp = mbuf(cursorPos);
X
X CheckMode();
X if (mbuf(mark) < mbuf(promptLen))
X mbuf(mark) = mbuf(promptLen);
X
X if (mbuf(mark) > mbuf(len))
X mbuf(mark) = mbuf(len);
X
X ConcealCursor(buf);
X mbuf(cursorPos) = mbuf(mark);
X mbuf(mark) = tmp;
X mbuf(arg) = 1;
X DisplayCursor(buf);
X
X}
X
X
X
X/* The universal argument has no effect on this one */
X/*ARGSUSED*/
Xstatic void CutMarkToPoint(w, event, params, numparams)
XWidget w;
XXEvent *event;
XString *params;
XCardinal *numparams;
X{
X register MinibufWidget buf = (MinibufWidget) w;
X register int lower, upper;
X static void QuitInput();
X
X CheckMode();
X
X if (mbuf(mark) < mbuf(promptLen))
X mbuf(mark) = mbuf(promptLen);
X
X if (mbuf(mark) > mbuf(len))
X mbuf(mark) = mbuf(len);
X
X if (mbuf(mark) < mbuf(cursorPos)) {
X lower = mbuf(mark);
X upper = mbuf(cursorPos);
X } else {
X lower = mbuf(cursorPos);
X upper = mbuf(mark);
X }
X
X mbuf(killBufferLen) = upper - lower;
X while (mbuf(killBufferLen) > mbuf(killBufferSize)) {
X mbuf(killBufferSize) += BUF_BLOCK;
X if (mbuf(killBuffer) == NULL)
X mbuf(killBuffer) = XtMalloc((unsigned) mbuf(size));
X else
X mbuf(killBuffer) = XtRealloc(mbuf(killBuffer),
X (unsigned) mbuf(size));
X if (mbuf(killBuffer) == NULL) {
X mbuf(killBufferSize) = 0;
X mbuf(killBufferLen) = 0;
X mbuf(inputMode) = FALSE;
X QuitInput(w, event, params, numparams);
X return;
X }
X }
X
X ConcealCursor(buf);
X bcopy(mbuf(string) + lower, mbuf(killBuffer), mbuf(killBufferLen));
X bcopy(mbuf(string) + upper, mbuf(string) + lower, mbuf(len) - upper);
X mbuf(cursorPos) = mbuf(mark) = lower;
X mbuf(len) -= mbuf(killBufferLen);
X mbuf(arg) = 1;
X DisplayBuf(buf, FALSE);
X DisplayCursor(buf);
X}
X
X
X
X/* The universal argument has no effect on this one */
X/*ARGSUSED*/
Xstatic void KillToEnd(w, event, params, numparams)
XWidget w;
XXEvent *event;
XString *params;
XCardinal *numparams;
X{
X register MinibufWidget buf = (MinibufWidget) w;
X register int tmp_mark;
X
X CheckMode();
X tmp_mark = mbuf(mark);
X mbuf(mark) = mbuf(len);
X CutMarkToPoint(w, event, params, numparams);
X mbuf(mark) = tmp_mark;
X}
X
X
X
X/* The universal argument has no effect on this one */
X/*ARGSUSED*/
Xstatic void KillToBeginning(w, event, params, numparams)
XWidget w;
XXEvent *event;
XString *params;
XCardinal *numparams;
X{
X register MinibufWidget buf = (MinibufWidget) w;
X register int tmp_mark;
X
X CheckMode();
X tmp_mark = mbuf(mark);
X mbuf(mark) = mbuf(promptLen);
X CutMarkToPoint(w, event, params, numparams);
X mbuf(mark) = tmp_mark;
X}
X
X
X
X/*ARGSUSED*/
Xstatic void UnivArgument(w, event, params, numparams)
XWidget w;
XXEvent *event;
XString *params;
XCardinal *numparams;
X{
X register MinibufWidget buf = (MinibufWidget) w;
X
X CheckMode();
X mbuf(arg) *= 4;
X}
X
X
X/*
X * The universal argument has no effect on this one - maybe it should,
X * I'm not sure. So I'll take the easy way out
X */
X/*ARGSUSED*/
Xstatic void YankKilledStuff(w, event, params, numparams)
XWidget w;
XXEvent *event;
XString *params;
XCardinal *numparams;
X{
X register MinibufWidget buf = (MinibufWidget) w;
X
X CheckMode();
X ConcealCursor(buf);
X mbuf(mark) = mbuf(cursorPos);
X StrInsert(mbuf(killBuffer), mbuf(killBufferLen), buf);
X DisplayCursor(buf);
X}
X
X
X/*ARGSUSED*/
Xstatic void GetXBuffer(w, event, params, numparams)
XWidget w;
XXEvent *event;
XString *params;
XCardinal *numparams;
X{
X register MinibufWidget buf = (MinibufWidget) w;
X register char *s;
X int nBytes;
X
X CheckMode();
X ConcealCursor(buf);
X s = XFetchBytes(XtDisplay(w), &nBytes);
X StrInsert(s, nBytes, buf);
X DisplayCursor(buf);
X}
X
X
X
X/*ARGSUSED*/
Xstatic void FinishedInput(w, event, params, numparams)
XWidget w;
XXEvent *event;
XString *params;
XCardinal *numparams;
X{
X register MinibufWidget buf = (MinibufWidget) w;
X register char *s;
X register int len = mbuf(len) - mbuf(promptLen);
X
X CheckMode();
X ConcealCursor(buf);
X XFlush(XtDisplay(w));
X mbuf(len) = 0;
X mbuf(cursorPos) = mbuf(startPos) = 0;
X mbuf(inputMode) = FALSE;
X if ((s = XtMalloc((unsigned) (len + 1))) != NULL) {
X bcopy(mbuf(string) + mbuf(promptLen), s, len);
X s[len] = '\0';
X }
X XtCallCallbacks(w, XtNfinishedCallback, s);
X}
X
X
X/*ARGSUSED*/
Xstatic void QuitInput(w, event, params, numparams)
XWidget w;
XXEvent *event;
XString *params;
XCardinal *numparams;
X{
X register MinibufWidget buf = (MinibufWidget) w;
X char *savestr;
X int savelen;
X
X CheckMode();
X ConcealCursor(buf);
X mbuf(len) = 0;
X mbuf(cursorPos) = mbuf(startPos) = 0;
X mbuf(inputMode) = FALSE;
X
X savestr = mbuf(string);
X savelen = mbuf(len);
X mbuf(string) = ABORT_MSG;
X mbuf(len) = strlen(ABORT_MSG);
X DisplayBuf(buf, TRUE);
X XFlush(XtDisplay(w));
X mbuf(string) = savestr;
X mbuf(len) = savelen;
X
X /*
X * We don't redisplay the cursor - we've gone out of input mode, but
X * we invoke the callback which tells the user about this
X */
X XtCallCallbacks(w, XtNfinishedCallback, (caddr_t) NULL);
X}
X
Xstatic MinibufWidget curbuf = NULL;
X
X/*ARGSUSED*/
Xstatic void CompleteFilename(w, event, params, numparams)
XWidget w;
XXEvent *event;
XString *params;
XCardinal *numparams;
X{
X register MinibufWidget buf = (MinibufWidget) w;
X
X CheckMode();
X if (!mbuf(completion)) {
X CharInsert(w, event, params, numparams);
X return;
X }
X ConcealCursor(buf);
X mbuf(string)[mbuf(len)] = '\0';
X mbuf(cursorPos) = mbuf(len);
X curbuf = buf;
X (void) f_complete(mbuf(string) + mbuf(promptLen),
X mbuf(cursorPos) - mbuf(promptLen), 0, ' ');
X DisplayCursor(buf);
X
X}
X
Xvoid rbell()
X{
X register MinibufWidget buf = curbuf;
X
X XBell(XtDisplay(mcore(self)), 0);
X}
X
X/*
X * 'at' is somewhere in mbuf(string), and we replace from 'at' to the
X * end of the line with the first 'len' chars of string 's' - 'curpos'
X * is updated.
X */
Xvoid insert_s(at, s, len, curpos)
Xchar *at;
Xchar *s;
Xint *curpos;
X{
X register MinibufWidget buf = curbuf;
X
X mbuf(len) = mbuf(cursorPos) = at - mbuf(string);
X *at = '\0';
X StrInsert(s, len, buf);
X *curpos = mbuf(cursorPos) - mbuf(promptLen);
X mbuf(string)[mbuf(len)] = '\0';
X}
X
X/* add_mess(s) char *s;
X * inserts 's' at the end of the buffer, then waits a respectable
X * interval, deletes 's', and returns
X */
Xvoid add_mess(s)
Xchar *s;
X{
X register MinibufWidget buf = curbuf;
X int savecursor = mbuf(cursorPos);
X
X StrInsert(s, strlen(s), buf);
X DisplayCursor(buf);
X ConcealCursor(buf);
X rbell();
X usleep(DELAY);
X mbuf(len) = mbuf(cursorPos) = savecursor;
X mbuf(string)[savecursor] = '\0';
X DisplayBuf(buf, FALSE);
X}
X
X/*ARGSUSED*/
Xstatic void ListFiles(w, event, params, numparams)
XWidget w;
XXEvent *event;
XString *params;
XCardinal *numparams;
X{
X register MinibufWidget buf = (MinibufWidget) w;
X
X CheckMode();
X if (!mbuf(completion)) {
X CharInsert(w, event, params, numparams);
X return;
X }
X /*
X * We haven't implemented a proper window typeout yet - if I
X * can manage it with the Text widget, but right now, it
X * redraws twice, and refuses to go away unless you take the
X * mouse into that window and click - yech!
X */
X curbuf = (MinibufWidget) w;
X#ifdef TYPEOUT
X if (mbuf(typeout)) {
X (void) f_complete(mbuf(string) + mbuf(promptLen),
X mbuf(cursorPos) - mbuf(promptLen), mbuf(typeoutColumns), '?');
X } else
X#endif TYPEOUT
X rbell();
X}
X
X/*
X * Public routines - these should probably be done with XtSetValues()
X * but that means more work... Sigh!
X */
Xvoid MinibufGetInput(w, prompt, defaultInput, complete)
XWidget w;
Xregister char *prompt;
Xregister char *defaultInput;
X{
X register MinibufWidget buf = (MinibufWidget) w;
X if (buf == NULL) {
X return;
X }
X
X mbuf(cursorPos) = mbuf(len) = 0;
X if (prompt != NULL) {
X StrInsert(prompt, strlen(prompt), buf);
X }
X
X mbuf(promptLen) = mbuf(cursorPos);
X
X if (defaultInput != NULL) {
X StrInsert(defaultInput, strlen(defaultInput), buf);
X mbuf(cursorPos) = mbuf(promptLen);
X }
X mbuf(inputMode) = TRUE;
X mbuf(completion) = complete;
X DisplayCursor(buf);
X /*
X * Focus events on the widget exclusively, not spring loaded - we
X * remove the grab in the callback
X */
X}
X
X
X/*
X * This displays msg in the buffer - since it uses the string passed in
X * directly, and does not affect the buffer string (which is saved and
X * restored), it should result in no more mallocs.
X */
Xvoid MinibufDisplayMessage(w, msg, ringbell)
XWidget w;
Xregister char *msg;
Xint ringbell; /* Do we want bell to sound */
X{
X register MinibufWidget buf = (MinibufWidget) w;
X char *savestr;
X int savelen;
X
X if (buf == NULL || msg == NULL) {
X return;
X }
X
X mbuf(inputMode) = FALSE;
X mbuf(len) = mbuf(cursorPos) = mbuf(startPos) = 0;
X savestr = mbuf(string);
X savelen = mbuf(len);
X mbuf(string) = msg;
X mbuf(len) = strlen(msg);
X
X DisplayBuf(buf, TRUE);
X XFlush(XtDisplay(w));
X if (ringbell) /* Maybe a visible bell for fun! One day...*/
X XBell(XtDisplay(w), 0);
X mbuf(string) = savestr;
X mbuf(len) = savelen;
X}
X
END_OF_FILE
if test 29958 -ne `wc -c <'xtroff/XtStuff/Minibuf.c'`; then
echo shar: \"'xtroff/XtStuff/Minibuf.c'\" unpacked with wrong size!
fi
# end of 'xtroff/XtStuff/Minibuf.c'
fi
echo shar: End of archive 16 \(of 18\).
cp /dev/null ark16isdone
MISSING=""
for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 ; do
if test ! -f ark${I}isdone ; then
MISSING="${MISSING} ${I}"
fi
done
if test "${MISSING}" = "" ; then
echo You have unpacked all 18 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
More information about the Comp.sources.x
mailing list