home *** CD-ROM | disk | FTP | other *** search
- From: argv@island.uu.net (Dan Heller)
- Newsgroups: comp.sources.x
- Subject: v04i082: xconf -- X-based conferencing tool, Part01/05
- Message-ID: <933@island.uu.net>
- Date: 25 Jul 89 08:10:11 GMT
- Approved: island!argv@sun.com
-
- Submitted-by: Jon Crowcroft <J.Crowcroft@Cs.Ucl.AC.UK>
- Posting-number: Volume 4, Issue 82
- Archive-name: xconf/part01
-
- [ This seems to be sun-specific since it uses sun rpc's. I didn't look
- at the code to be sure, tho. It compiled fine using the Makefile tho
- I had to modify it to point to a place where IntrinsicI.h is used (it
- is no longer in the X11 include files as it was in R2; it's now in the
- lib/Xt dir in the R3 source tree). Also, Text.c was too big so I hadda
- split it up into 3 parts (Text.c.a[abc] -- be sure to glue them back
- together before trying to make). By its description, it seems like a
- useful program. --argv ]
-
- #! /bin/sh
- # This is a shell archive. Remove anything before this line, then feed it
- # into a shell via "sh file" or similar. To overwrite existing files,
- # type "sh file -c".
- # The tool that generated this appeared in the comp.sources.unix newsgroup;
- # send mail to comp-sources-unix@uunet.uu.net if you want that tool.
- # If this archive is complete, you will see the following message at the end:
- # "End of archive 1 (of 5)."
- # Contents: xconf/HELP xconf/Text.c.aa xconf/xconf.c
- # Wrapped by argv@sumatra on Tue Jul 25 01:01:04 1989
- PATH=/bin:/usr/bin:/usr/ucb ; export PATH
- if test -f 'xconf/HELP' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'xconf/HELP'\"
- else
- echo shar: Extracting \"'xconf/HELP'\" \(2603 characters\)
- sed "s/^X//" >'xconf/HELP' <<'END_OF_FILE'
- XDESCRIPTION...
- XXconf is a simple text based conferencing program.
- X
- XIt works by opening multiple windows, one per conferee, one on each
- Xconferees displays (does not pre-empt user being in multiple
- Xconferences though).
- X
- XIt sets up a top level window with quit/help/accept buttons.
- XAccept popups a box widget with multiple asciiTextwidget's (one per
- Xconferee). One is for input, the rest show what every one is typeing
- Xon their input windows...
- X
- XNote that the ascii widget is like a jove edit window, and that edit
- Xcommands typed in it will have the same effect on the output windows
- Xon each other conferees display as on your input window. [Try typing
- XCtl-V to go down a page, Meta-V to go up].
- X
- XOne user starts the conference, specifying all the users (including
- Xthemselves) at startup.
- XUsers may choose not to accept the conference, by quiting immediately.
- XWhen the last person quits, the conference terminates.
- X
- XA User is specified by user name. This may be optionally appended by
- Xa machine (user@machine) and also by a display
- X(user@machine:Display#). if the user name appears alone, it can be
- Xused to find where the user is logged in, and which of possibly many
- Xlogins is least recently idle. If the machine/display is specified,
- Xthe user name is ignored, and used simply as a tag for their
- Xconference windows.
- X
- XThere is no floor control at present, so it is a "free for all"
- Xconference, just like an n-way talk.
- X
- X
- XNOTE BENE:
- X
- XUnder twm, you need to set NoTitleFocus in your .twmrc file, else
- Xkeyboard input never gets focused properly - a sort of feature of twm
- X- not really a bug in xconf though...
- X
- XUSAGE...
- XTo run, type
- X
- Xxconf <user@machine>+ [-typicalXArgs]
- X
- Xe.g.
- Xxconf jon@perky pp@lagavulin steve@lion -fg green -bg blue
- X
- XA box appears on each users display, with three command buttons:
- X
- XQuit
- XQuits now, or at any point in the conference.
- X
- XHelp
- XPopups a help window with soem assistance displayed, and a subsidery
- Xquit button.
- X
- XAccept
- XAccepts the conference, Popups a new box, with a text window for this
- Xuser to type in, and other users input to be output on. The windows
- Xare labelled to show whose is whose. If you quit, all the windows
- Xvanish on your display, and your output window vanishes onm each other
- Xpersons display.
- X
- XYou type at the widnow marked <= in.
- X
- XBUGS...
- XCurrently there are some odd problems with some window managers.
- X
- XIf the user who started the conference kills the program, the
- Xconference terminates for everyone else [although they may just quit
- Xwithout this happening].
- X
- XWhen you quit, you output window on other conferees display is
- Xdestroyed, but not the label.
- END_OF_FILE
- if test 2603 -ne `wc -c <'xconf/HELP'`; then
- echo shar: \"'xconf/HELP'\" unpacked with wrong size!
- fi
- # end of 'xconf/HELP'
- fi
- if test -f 'xconf/Text.c.aa' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'xconf/Text.c.aa'\"
- else
- echo shar: Extracting \"'xconf/Text.c.aa'\" \(30780 characters\)
- sed "s/^X//" >'xconf/Text.c.aa' <<'END_OF_FILE'
- X#ifndef lint
- Xstatic char Xrcsid[] = "$XConsortium: Text.c,v 1.77 88/10/25 00:14:46 jim Exp $";
- X#endif
- X
- X
- X/***********************************************************
- XCopyright 1987, 1988 by Digital Equipment Corporation, Maynard, Massachusetts,
- Xand the Massachusetts Institute of Technology, Cambridge, Massachusetts.
- X
- X All Rights Reserved
- X
- XPermission to use, copy, modify, and distribute this software and its
- Xdocumentation for any purpose and without fee is hereby granted,
- Xprovided that the above copyright notice appear in all copies and that
- Xboth that copyright notice and this permission notice appear in
- Xsupporting documentation, and that the names of Digital or MIT not be
- Xused in advertising or publicity pertaining to distribution of the
- Xsoftware without specific, written prior permission.
- X
- XDIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
- XALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
- XDIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
- XANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
- XWHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
- XARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
- XSOFTWARE.
- X
- X******************************************************************/
- X
- X#include <X11/IntrinsicP.h>
- X#include <X11/StringDefs.h>
- X#include <X11/Shell.h>
- X#include <X11/Xatom.h>
- X#include <X11/Xmu.h>
- X#include <X11/Cardinals.h>
- X#include <X11/Label.h>
- X#include <X11/Command.h>
- X#include <X11/Dialog.h>
- X#include <X11/Scroll.h>
- X#include "TextP.h"
- X
- XAtom FMT8BIT = NULL;
- X
- Xextern void bcopy();
- Xextern void LowerCase();
- Xextern int errno, sys_nerr;
- Xextern char* sys_errlist[];
- X
- X#define abs(x) (((x) < 0) ? (-(x)) : (x))
- X#define min(x,y) ((x) < (y) ? (x) : (y))
- X#define max(x,y) ((x) > (y) ? (x) : (y))
- X#define GETLASTPOS (*ctx->text.source->Scan) (ctx->text.source, 0, XtstAll, XtsdRight, 1, TRUE)
- X
- X#define zeroPosition ((XtTextPosition) 0)
- X#define BIGNUM ((Dimension)32023)
- X
- Xstatic void BuildLineTable ();
- Xstatic void ScrollUpDownProc();
- Xstatic void ThumbProc();
- X
- X/****************************************************************
- X *
- X * Full class record constant
- X *
- X ****************************************************************/
- X
- Xstatic XtTextSelectType defaultSelectTypes[] = {
- X XtselectPosition,
- X XtselectWord,
- X XtselectLine,
- X XtselectParagraph,
- X XtselectAll,
- X XtselectNull
- X};
- X
- Xstatic caddr_t defaultSelectTypesPtr = (caddr_t)defaultSelectTypes;
- Xextern char defaultTextTranslations[]; /* fwd ref */
- Xstatic Dimension defWidth = 100;
- Xstatic Dimension defHeight = DEFAULT_TEXT_HEIGHT;
- X
- X#define offset(field) XtOffset(TextWidget, field)
- Xstatic XtResource resources[] = {
- X {XtNwidth, XtCWidth, XtRDimension, sizeof(Dimension),
- X offset(core.width), XtRDimension, (caddr_t)&defWidth},
- X {XtNcursor, XtCCursor, XtRCursor, sizeof(Cursor),
- X offset(simple.cursor), XtRString, "xterm"},
- X {XtNheight, XtCHeight, XtRDimension, sizeof(Dimension),
- X offset(core.height), XtRDimension, (caddr_t)&defHeight},
- X {XtNtextOptions, XtCTextOptions, XtRInt, sizeof (int),
- X offset(text.options), XtRImmediate, (caddr_t)0},
- X {XtNdialogHOffset, XtCMargin, XtRInt, sizeof(int),
- X offset(text.dialog_horiz_offset), XtRImmediate, (caddr_t)0},
- X {XtNdialogVOffset, XtCMargin, XtRInt, sizeof(int),
- X offset(text.dialog_vert_offset), XtRImmediate, (caddr_t)0},
- X {XtNdisplayPosition, XtCTextPosition, XtRInt,
- X sizeof (XtTextPosition), offset(text.lt.top), XtRImmediate, (caddr_t)0},
- X {XtNinsertPosition, XtCTextPosition, XtRInt,
- X sizeof(XtTextPosition), offset(text.insertPos), XtRImmediate, (caddr_t)0},
- X {XtNleftMargin, XtCMargin, XtRDimension, sizeof (Dimension),
- X offset(text.client_leftmargin), XtRImmediate, (caddr_t)2},
- X {XtNselectTypes, XtCSelectTypes, XtRPointer,
- X sizeof(XtTextSelectType*), offset(text.sarray),
- X XtRPointer, (caddr_t)&defaultSelectTypesPtr},
- X {XtNtextSource, XtCTextSource, XtRPointer, sizeof (caddr_t),
- X offset(text.source), XtRPointer, NULL},
- X {XtNtextSink, XtCTextSink, XtRPointer, sizeof (caddr_t),
- X offset(text.sink), XtRPointer, NULL},
- X {XtNselection, XtCSelection, XtRPointer, sizeof(caddr_t),
- X offset(text.s), XtRPointer, NULL},
- X#ifdef JON
- X {XtNcallback, XtCCallback, XtRCallback, sizeof(caddr_t),
- X offset(text.callbacks), XtRCallback, (caddr_t)NULL},
- X#endif JON
- X};
- X#undef offset
- X
- X
- X#define done(address, type) \
- X { toVal->size = sizeof(type); toVal->addr = (caddr_t) address; }
- X
- X/* EditType enumeration constants */
- X
- Xstatic XrmQuark XtQTextRead;
- Xstatic XrmQuark XtQTextAppend;
- Xstatic XrmQuark XtQTextEdit;
- X
- X/* ARGSUSED */
- Xstatic void CvtStringToEditMode(args, num_args, fromVal, toVal)
- X XrmValuePtr args; /* unused */
- X Cardinal *num_args; /* unused */
- X XrmValuePtr fromVal;
- X XrmValuePtr toVal;
- X{
- X static XtTextEditType editType;
- X XrmQuark q;
- X char lowerName[1000];
- X
- X/* ||| where to put LowerCase */
- X LowerCase((char *)fromVal->addr, lowerName);
- X q = XrmStringToQuark(lowerName);
- X if (q == XtQTextRead ) {
- X editType = XttextRead;
- X done(&editType, XtTextEditType);
- X return;
- X }
- X if (q == XtQTextAppend) {
- X editType = XttextAppend;
- X done(&editType, XtTextEditType);
- X return;
- X }
- X if (q == XtQTextEdit) {
- X editType = XttextEdit;
- X done(&editType, XtTextEditType);
- X return;
- X }
- X toVal->size = 0;
- X toVal->addr = NULL;
- X};
- X
- X
- Xstatic void ClassInitialize()
- X{
- X XtQTextRead = XrmStringToQuark(XtEtextRead);
- X XtQTextAppend = XrmStringToQuark(XtEtextAppend);
- X XtQTextEdit = XrmStringToQuark(XtEtextEdit);
- X
- X XtAddConverter(XtRString, XtREditMode, CvtStringToEditMode, NULL, 0);
- X}
- X
- Xstatic void CreateScrollbar(w)
- X TextWidget w;
- X{
- X Arg args[1];
- X Dimension bw;
- X Widget sbar;
- X
- X XtSetArg(args[0], XtNheight, w->core.height);
- X w->text.sbar = sbar =
- X XtCreateWidget("scrollbar", scrollbarWidgetClass, w, args, ONE);
- X XtAddCallback( sbar, XtNscrollProc, ScrollUpDownProc, (caddr_t)w );
- X XtAddCallback( sbar, XtNjumpProc, ThumbProc, (caddr_t)w );
- X w->text.leftmargin += sbar->core.width + (bw = sbar->core.border_width);
- X XtMoveWidget( sbar, -(Position)bw, -(Position)bw );
- X}
- X
- X/* ARGSUSED */
- Xstatic void Initialize(request, new)
- X Widget request, new;
- X{
- X TextWidget ctx = (TextWidget) new;
- X
- X if (!FMT8BIT)
- X FMT8BIT = XInternAtom(XtDisplay(new), "FMT8BIT", False);
- X
- X if (ctx->core.height == DEFAULT_TEXT_HEIGHT) {
- X ctx->core.height = (2*yMargin) + 2;
- X if (ctx->text.sink)
- X ctx->core.height += (*ctx->text.sink->MaxHeight)(new, 1);
- X }
- X
- X ctx->text.lt.lines = 0;
- X ctx->text.lt.info = NULL;
- X ctx->text.s.left = ctx->text.s.right = 0;
- X ctx->text.s.type = XtselectPosition;
- X ctx->text.s.selections = NULL;
- X ctx->text.s.atom_count = ctx->text.s.array_size = 0;
- X ctx->text.sbar = ctx->text.outer = NULL;
- X ctx->text.lasttime = 0; /* ||| correct? */
- X ctx->text.time = 0; /* ||| correct? */
- X ctx->text.showposition = TRUE;
- X ctx->text.lastPos = ctx->text.source ? GETLASTPOS : 0;
- X ctx->text.dialog = NULL;
- X ctx->text.updateFrom = (XtTextPosition *) XtMalloc((unsigned)1);
- X ctx->text.updateTo = (XtTextPosition *) XtMalloc((unsigned)1);
- X ctx->text.numranges = ctx->text.maxranges = 0;
- X ctx->text.gc = DefaultGCOfScreen(XtScreen(ctx));
- X ctx->text.hasfocus = FALSE;
- X ctx->text.leftmargin = ctx->text.client_leftmargin;
- X ctx->text.update_disabled = False;
- X ctx->text.old_insert = -1;
- X
- X if (ctx->text.options & scrollVertical)
- X CreateScrollbar(ctx);
- X}
- X
- Xvoid ForceBuildLineTable();
- X
- Xstatic void Realize( w, valueMask, attributes )
- X Widget w;
- X Mask *valueMask;
- X XSetWindowAttributes *attributes;
- X{
- X TextWidget ctx = (TextWidget)w;
- X
- X *valueMask |= CWBitGravity;
- X attributes->bit_gravity =
- X (ctx->text.options & wordBreak) ? ForgetGravity : NorthWestGravity;
- X
- X (*textClassRec.core_class.superclass->core_class.realize)
- X (w, valueMask, attributes);
- X
- X if (ctx->text.sbar) {
- X XtRealizeWidget(ctx->text.sbar);
- X XtMapWidget(ctx->text.sbar);
- X }
- X ForceBuildLineTable(ctx);
- X}
- X
- X
- Xstatic /*void*/ _CreateCutBuffers(d)
- X Display *d;
- X{
- X static struct _DisplayRec {
- X struct _DisplayRec *next;
- X Display *dpy;
- X } *dpy_list = NULL;
- X struct _DisplayRec *dpy_ptr;
- X
- X for (dpy_ptr = dpy_list; dpy_ptr != NULL; dpy_ptr = dpy_ptr->next) {
- X if (dpy_ptr->dpy == d) return;
- X }
- X
- X dpy_ptr = XtNew(struct _DisplayRec);
- X dpy_ptr->next = dpy_list;
- X dpy_ptr->dpy = d;
- X dpy_list = dpy_ptr;
- X
- X#define Create(buffer) \
- X XChangeProperty(d, RootWindow(d, 0), buffer, XA_STRING, 8, \
- X PropModeAppend, NULL, 0 );
- X
- X Create( XA_CUT_BUFFER0 );
- X Create( XA_CUT_BUFFER1 );
- X Create( XA_CUT_BUFFER2 );
- X Create( XA_CUT_BUFFER3 );
- X Create( XA_CUT_BUFFER4 );
- X Create( XA_CUT_BUFFER5 );
- X Create( XA_CUT_BUFFER6 );
- X Create( XA_CUT_BUFFER7 );
- X
- X#undef Create
- X}
- X
- X/* Utility routines for support of Text */
- X
- X
- X/*
- X * Procedure to manage insert cursor visibility for editable text. It uses
- X * the value of ctx->insertPos and an implicit argument. In the event that
- X * position is immediately preceded by an eol graphic, then the insert cursor
- X * is displayed at the beginning of the next line.
- X*/
- Xstatic void InsertCursor (w, state)
- X Widget w;
- X XtTextInsertState state;
- X{
- X TextWidget ctx = (TextWidget)w;
- X Position x, y;
- X int dy, line, visible;
- X XtTextBlock text;
- X
- X if (ctx->text.lt.lines < 1) return;
- X visible = LineAndXYForPosition(ctx, ctx->text.insertPos, &line, &x, &y);
- X if (line < ctx->text.lt.lines)
- X dy = (ctx->text.lt.info[line + 1].y - ctx->text.lt.info[line].y) + 1;
- X else
- X dy = (ctx->text.lt.info[line].y - ctx->text.lt.info[line - 1].y) + 1;
- X
- X /** If the insert position is just after eol then put it on next line **/
- X if (x > ctx->text.leftmargin &&
- X ctx->text.insertPos > 0 &&
- X ctx->text.insertPos >= ctx->text.lastPos) {
- X /* reading the source is bogus and this code should use scan */
- X (*ctx->text.source->Read) (ctx->text.source, ctx->text.insertPos - 1, &text, 1);
- X if (text.ptr[0] == '\n') {
- X x = ctx->text.leftmargin;
- X y += dy;
- X }
- X }
- X y += dy;
- X if (visible)
- X (*ctx->text.sink->InsertCursor)(w, x, y, state);
- X ctx->text.ev_x = x;
- X ctx->text.ev_y = y;
- X}
- X
- X
- X/*
- X * Procedure to register a span of text that is no longer valid on the display
- X * It is used to avoid a number of small, and potentially overlapping, screen
- X * updates. [note: this is really a private procedure but is used in
- X * multiple modules].
- X*/
- X_XtTextNeedsUpdating(ctx, left, right)
- X TextWidget ctx;
- X XtTextPosition left, right;
- X{
- X int i;
- X if (left < right) {
- X for (i = 0; i < ctx->text.numranges; i++) {
- X if (left <= ctx->text.updateTo[i] && right >= ctx->text.updateFrom[i]) {
- X ctx->text.updateFrom[i] = min(left, ctx->text.updateFrom[i]);
- X ctx->text.updateTo[i] = max(right, ctx->text.updateTo[i]);
- X return;
- X }
- X }
- X ctx->text.numranges++;
- X if (ctx->text.numranges > ctx->text.maxranges) {
- X ctx->text.maxranges = ctx->text.numranges;
- X i = ctx->text.maxranges * sizeof(XtTextPosition);
- X ctx->text.updateFrom = (XtTextPosition *)
- X XtRealloc((char *)ctx->text.updateFrom, (unsigned) i);
- X ctx->text.updateTo = (XtTextPosition *)
- X XtRealloc((char *)ctx->text.updateTo, (unsigned) i);
- X }
- X ctx->text.updateFrom[ctx->text.numranges - 1] = left;
- X ctx->text.updateTo[ctx->text.numranges - 1] = right;
- X }
- X}
- X
- X
- X/*
- X * Procedure to read a span of text in Ascii form. This is purely a hack and
- X * we probably need to add a function to sources to provide this functionality.
- X * [note: this is really a private procedure but is used in multiple modules].
- X*/
- Xchar *_XtTextGetText(ctx, left, right)
- X TextWidget ctx;
- X XtTextPosition left, right;
- X{
- X char *result, *tempResult;
- X int length, resultLength;
- X XtTextBlock text;
- X XtTextPosition end, nend;
- X
- X resultLength = right - left + 10; /* Bogus? %%% */
- X result = (char *)XtMalloc((unsigned) resultLength);
- X end = (*ctx->text.source->Read)(ctx->text.source, left, &text, right - left);
- X (void) strncpy(result, text.ptr, text.length);
- X length = text.length;
- X while (end < right) {
- X nend = (*ctx->text.source->Read)(ctx->text.source, end, &text, right - end);
- X tempResult = result + length;
- X (void) strncpy(tempResult, text.ptr, text.length);
- X length += text.length;
- X end = nend;
- X }
- X result[length] = 0;
- X return result;
- X}
- X
- X
- X
- X/*
- X * This routine maps an x and y position in a window that is displaying text
- X * into the corresponding position in the source.
- X */
- Xstatic XtTextPosition PositionForXY (ctx, x, y)
- X TextWidget ctx;
- X Position x,y;
- X{
- X /* it is illegal to call this routine unless there is a valid line table! */
- X int width, fromx, line;
- X XtTextPosition position, resultstart, resultend;
- X
- X /*** figure out what line it is on ***/
- X if (ctx->text.lt.lines == 0) return 0;
- X
- X for (line = 0; line < ctx->text.lt.lines - 1; line++) {
- X if (y <= ctx->text.lt.info[line + 1].y)
- X break;
- X }
- X position = ctx->text.lt.info[line].position;
- X if (position >= ctx->text.lastPos)
- X return ctx->text.lastPos;
- X fromx = ctx->text.lt.info[line].x; /* starting x in line */
- X width = x - fromx; /* num of pix from starting of line */
- X (*ctx->text.sink->Resolve) (ctx, position, fromx, width,
- X &resultstart, &resultend);
- X if (resultstart >= ctx->text.lt.info[line + 1].position)
- X resultstart = (*ctx->text.source->Scan)(ctx->text.source,
- X ctx->text.lt.info[line + 1].position, XtstPositions, XtsdLeft, 1, TRUE);
- X return resultstart;
- X}
- X
- X/*
- X * This routine maps a source position in to the corresponding line number
- X * of the text that is displayed in the window.
- X*/
- Xstatic int LineForPosition (ctx, position)
- X TextWidget ctx;
- X XtTextPosition position;
- X /* it is illegal to call this routine unless there is a valid line table!*/
- X{
- X int line;
- X
- X if (position <= ctx->text.lt.info[0].position)
- X return 0;
- X for (line = 0; line < ctx->text.lt.lines; line++)
- X if (position < ctx->text.lt.info[line + 1].position)
- X break;
- X return line;
- X}
- X
- X/*
- X * This routine maps a source position into the corresponding line number
- X * and the x, y coordinates of the text that is displayed in the window.
- X*/
- Xstatic int LineAndXYForPosition (ctx, pos, line, x, y)
- X TextWidget ctx;
- X XtTextPosition pos;
- X int *line;
- X Position *x, *y;
- X /* it is illegal to call this routine unless there is a valid line table!*/
- X{
- X XtTextPosition linePos, endPos;
- X int visible, realW, realH;
- X
- X *line = 0;
- X *x = ctx->text.leftmargin;
- X *y = yMargin;
- X visible = IsPositionVisible(ctx, pos);
- X if (visible) {
- X *line = LineForPosition(ctx, pos);
- X *y = ctx->text.lt.info[*line].y;
- X *x = ctx->text.lt.info[*line].x;
- X linePos = ctx->text.lt.info[*line].position;
- X (*ctx->text.sink->FindDistance)((Widget)ctx, linePos,
- X *x, pos, &realW, &endPos, &realH);
- X *x = *x + realW;
- X }
- X return visible;
- X}
- X
- X/*
- X * This routine builds a line table. It does this by starting at the
- X * specified position and measuring text to determine the staring position
- X * of each line to be displayed. It also determines and saves in the
- X * linetable all the required metrics for displaying a given line (e.g.
- X * x offset, y offset, line length, etc.).
- X*/
- Xstatic void BuildLineTable (ctx, position)
- X TextWidget ctx;
- X XtTextPosition position;
- X{
- X Position x, y;
- X int width, realW, realH;
- X int line, lines;
- X XtTextPosition startPos, endPos;
- X Boolean rebuild;
- X
- X rebuild = (Boolean) (position != ctx->text.lt.top);
- X lines = (*ctx->text.sink->MaxLines)((Widget)ctx, ctx->core.height);
- X if (ctx->text.lt.info != NULL && lines != ctx->text.lt.lines) {
- X XtFree((char *) ctx->text.lt.info);
- X ctx->text.lt.info = NULL;
- X }
- X if (ctx->text.lt.info == NULL) {
- X ctx->text.lt.info = (XtTextLineTableEntry *)
- X XtCalloc((unsigned)lines + 1, (unsigned)sizeof(XtTextLineTableEntry));
- X rebuild = TRUE;
- X }
- X if (rebuild) {
- X XtTextLineTableEntry *lt;
- X int options = ctx->text.options;
- X int (*FindPosition)() = ctx->text.sink->FindPosition;
- X int (*Scan)() = ctx->text.source->Scan;
- X ctx->text.lt.top = position;
- X ctx->text.lt.lines = lines;
- X startPos = position;
- X x = ctx->text.leftmargin;
- X y = yMargin;
- X for (line = 0, lt = ctx->text.lt.info; line <= ctx->text.lt.lines;
- X line++, lt++) {
- X lt->x = x;
- X lt->y = y;
- X lt->position = startPos;
- X if (startPos <= ctx->text.lastPos) {
- X width = (options & resizeWidth) ? BIGNUM : ctx->core.width - x;
- X (*FindPosition)((Widget)ctx, startPos, x,
- X width, (options & wordBreak),
- X &endPos, &realW, &realH);
- X if (!(options & wordBreak) && endPos < ctx->text.lastPos) {
- X endPos = (*Scan)(ctx->text.source, startPos,
- X XtstEOL, XtsdRight, 1, TRUE);
- X if (endPos == startPos)
- X endPos = ctx->text.lastPos + 1;
- X }
- X lt->endX = realW + x;
- X startPos = endPos;
- X }
- X else lt->endX = x;
- X y = y + realH;
- X }
- X }
- X}
- X
- X/*
- X * This routine is used to re-display the entire window, independent of
- X * its current state.
- X*/
- Xvoid ForceBuildLineTable(ctx)
- X TextWidget ctx;
- X{
- X XtTextPosition position;
- X
- X position = ctx->text.lt.top;
- X ctx->text.lt.top++; /* ugly, but it works */
- X BuildLineTable(ctx, position);
- X}
- X
- X/*
- X * This routine is used by Text to notify an associated scrollbar of the
- X * correct metrics (position and shown fraction) for the text being currently
- X * displayed in the window.
- X*/
- Xstatic void SetScrollBar(ctx)
- X TextWidget ctx;
- X{
- X float first, last;
- X if (ctx->text.sbar) {
- X if ((ctx->text.lastPos > 0) && (ctx->text.lt.lines > 0)) {
- X first = ctx->text.lt.top;
- X first /= ctx->text.lastPos;
- X /* Just an approximation */
- X last = ctx->text.lt.info[ctx->text.lt.lines].position;
- X last /= ctx->text.lastPos;
- X }
- X else {
- X first = 0.0;
- X last = 1.0;
- X }
- X XtScrollBarSetThumb(ctx->text.sbar, first, last - first);
- X }
- X}
- X
- X
- X/*
- X * The routine will scroll the displayed text by lines. If the arg is
- X * positive, move up; otherwise, move down. [note: this is really a private
- X * procedure but is used in multiple modules].
- X*/
- X_XtTextScroll(ctx, n)
- X TextWidget ctx;
- X int n; /* assumed <= ctx->text.lt.lines */
- X{
- X XtTextPosition top, target;
- X if (n >= 0) {
- X top = min(ctx->text.lt.info[n].position, ctx->text.lastPos);
- X BuildLineTable(ctx, top);
- X if (top >= ctx->text.lastPos)
- X DisplayTextWindow(ctx);
- X else {
- X XCopyArea(XtDisplay(ctx), XtWindow(ctx), XtWindow(ctx), ctx->text.gc,
- X 0, ctx->text.lt.info[n].y, (int)ctx->core.width,
- X (int)ctx->core.height - ctx->text.lt.info[n].y,
- X 0, ctx->text.lt.info[0].y);
- X (*ctx->text.sink->ClearToBackground)(ctx, 0,
- X ctx->text.lt.info[0].y + ctx->core.height - ctx->text.lt.info[n].y,
- X (int)ctx->core.width, (int)ctx->core.height);
- X if (n < ctx->text.lt.lines) n++; /* update descenders at bottom */
- X _XtTextNeedsUpdating(ctx,
- X ctx->text.lt.info[ctx->text.lt.lines - n].position, ctx->text.lastPos);
- X SetScrollBar(ctx);
- X }
- X } else {
- X int tempHeight;
- X n = -n;
- X target = ctx->text.lt.top;
- X top = (*ctx->text.source->Scan)(ctx->text.source, target, XtstEOL,
- X XtsdLeft, n+1, FALSE);
- X BuildLineTable(ctx, top);
- X if (ctx->text.lt.info[n].position == target) {
- X tempHeight = ctx->text.lt.info[ctx->text.lt.lines-n].y - 1;
- X XCopyArea(XtDisplay(ctx), XtWindow(ctx), XtWindow(ctx), ctx->text.gc,
- X 0, ctx->text.lt.info[0].y, (int)ctx->core.width, tempHeight,
- X 0, ctx->text.lt.info[n].y);
- X (*ctx->text.sink->ClearToBackground)(ctx, 0,
- X ctx->text.lt.info[0].y,
- X (int)ctx->core.width, ctx->text.lt.info[n].y - 1);
- X _XtTextNeedsUpdating(ctx,
- X ctx->text.lt.info[0].position, ctx->text.lt.info[n].position);
- X SetScrollBar(ctx);
- X } else if (ctx->text.lt.top != target) DisplayTextWindow(ctx);
- X }
- X}
- X
- X/*
- X * The routine will scroll the displayed text by pixels. If the arg is
- X * positive, move up; otherwise, move down.
- X*/
- X/*ARGSUSED*/
- Xstatic void ScrollUpDownProc (w, closure, callData)
- X Widget w;
- X caddr_t closure; /* TextWidget */
- X caddr_t callData; /* #pixels */
- X{
- X TextWidget ctx = (TextWidget)closure;
- X int apix, line;
- X _XtTextPrepareToUpdate(ctx);
- X apix = abs((int)callData);
- X for (line = 1;
- X line < ctx->text.lt.lines && apix > ctx->text.lt.info[line + 1].y;
- X line++);
- X if (((int)callData) >= 0)
- X _XtTextScroll(ctx, line);
- X else
- X _XtTextScroll(ctx, -line);
- X _XtTextExecuteUpdate(ctx);
- X}
- X
- X/*
- X * The routine "thumbs" the displayed text. Thumbing means reposition the
- X * displayed view of the source to a new position determined by a fraction
- X * of the way from beginning to end. Ideally, this should be determined by
- X * the number of displayable lines in the source. This routine does it as a
- X * fraction of the first position and last position and then normalizes to
- X * the start of the line containing the position.
- X*/
- X/*ARGSUSED*/
- Xstatic void ThumbProc (w, closure, callData)
- X Widget w;
- X caddr_t closure; /* TextWidget */
- X float *callData;
- X /* BUG/deficiency: The normalize to line portion of this routine will
- X * cause thumbing to always position to the start of the source.
- X */
- X{
- X TextWidget ctx= (TextWidget)closure;
- X XtTextPosition position, old_top, old_bot;
- X _XtTextPrepareToUpdate(ctx);
- X old_top = ctx->text.lt.top;
- X old_bot = ctx->text.lt.info[ctx->text.lt.lines-1].position;
- X position = *callData * ctx->text.lastPos;
- X position = (*ctx->text.source->
- X Scan)(ctx->text.source, position, XtstEOL, XtsdLeft, 1, FALSE);
- X if (position >= old_top && position <= old_bot) {
- X int line;
- X for (line = 0; line < ctx->text.lt.lines &&
- X position > ctx->text.lt.info[line].position; line++);
- X if (line)
- X _XtTextScroll(ctx, line);
- X }
- X else {
- X BuildLineTable(ctx, position);
- X if (old_top >= ctx->text.lt.top &&
- X old_top <= ctx->text.lt.info[ctx->text.lt.lines-1].position) {
- X int line;
- X for (line = 0;
- X line < ctx->text.lt.lines &&
- X old_top > ctx->text.lt.info[line].position; line++);
- X BuildLineTable(ctx, old_top);
- X if (line)
- X _XtTextScroll(ctx, -line);
- X }
- X else {
- X DisplayTextWindow(ctx);
- X }
- X }
- X _XtTextExecuteUpdate(ctx);
- X}
- X
- X
- Xstatic Boolean ConvertSelection(w, selection, target,
- X type, value, length, format)
- X Widget w;
- X Atom *selection, *target, *type;
- X caddr_t *value;
- X unsigned long *length;
- X int *format;
- X{
- X Display* d = XtDisplay(w);
- X TextWidget ctx = (TextWidget)w;
- X
- X if (*target == XA_TARGETS(d)) {
- X Atom* targetP;
- X Atom* std_targets;
- X unsigned long std_length;
- X if (ctx->text.source->ConvertSelection == NULL ||
- X !(*ctx->text.source->
- X ConvertSelection) (d, ctx->text.source, selection, target,
- X type, value, length, format)) {
- X *value = NULL;
- X *length = 0;
- X }
- X XmuConvertStandardSelection(w, ctx->text.time, selection, target, type,
- X (caddr_t*)&std_targets, &std_length, format);
- X *value = XtRealloc(*value, sizeof(Atom)*(std_length + 6 + *length));
- X targetP = *(Atom**)value + *length;
- X *length += std_length + 5;
- X if (ctx->text.source->edit_mode == XttextEdit)
- X (*length)++;
- X *targetP++ = XA_STRING;
- X *targetP++ = XA_TEXT(d);
- X *targetP++ = XA_LENGTH(d);
- X *targetP++ = XA_LIST_LENGTH(d);
- X *targetP++ = XA_CHARACTER_POSITION(d);
- X if (ctx->text.source->edit_mode == XttextEdit)
- X *targetP++ = XA_DELETE(d);
- X bcopy((char*)std_targets, (char*)targetP, sizeof(Atom)*std_length);
- X XtFree((char*)std_targets);
- X *type = XA_ATOM;
- X *format = 32;
- X return True;
- X }
- X
- X if (ctx->text.source->ConvertSelection != NULL &&
- X (*ctx->text.source->
- X ConvertSelection) (d, ctx->text.source, selection,
- X target, type, value, length, format))
- X return True;
- X
- X if (*target == XA_STRING || *target == XA_TEXT(d)) {
- X *type = XA_STRING;
- X *value = _XtTextGetText(ctx, ctx->text.s.left, ctx->text.s.right);
- X *length = strlen(*value);
- X *format = 8;
- X return True;
- X }
- X if (*target == XA_LIST_LENGTH(d)) {
- X *value = XtMalloc(4);
- X if (sizeof(long) == 4)
- X *(long*)*value = 1;
- X else {
- X long temp = 1;
- X bcopy( ((char*)&temp)+sizeof(long)-4, (char*)*value, 4);
- X }
- X *type = XA_INTEGER;
- X *length = 1;
- X *format = 32;
- X return True;
- X }
- X if (*target == XA_LENGTH(d)) {
- X *value = XtMalloc(4);
- X if (sizeof(long) == 4)
- X *(long*)*value = ctx->text.s.right - ctx->text.s.left;
- X else {
- X long temp = ctx->text.s.right - ctx->text.s.left;
- X bcopy( ((char*)&temp)+sizeof(long)-4, (char*)*value, 4);
- X }
- X *type = XA_INTEGER;
- X *length = 1;
- X *format = 32;
- X return True;
- X }
- X if (*target == XA_CHARACTER_POSITION(d)) {
- X *value = XtMalloc(8);
- X (*(long**)value)[0] = ctx->text.s.left + 1;
- X (*(long**)value)[1] = ctx->text.s.right;
- X *type = XA_SPAN(d);
- X *length = 2;
- X *format = 32;
- X return True;
- X }
- X if (*target == XA_DELETE(d)) {
- X void KillCurrentSelection();
- X KillCurrentSelection(ctx, (XEvent*)NULL);
- X *value = NULL;
- X *type = XA_NULL(d);
- X *length = 0;
- X *format = 32;
- X return True;
- X }
- X if (XmuConvertStandardSelection(w, ctx->text.time, selection, target, type,
- X value, length, format))
- X return True;
- X
- X /* else */
- X return False;
- X}
- X
- X
- Xstatic void LoseSelection(w, selection)
- X Widget w;
- X Atom *selection;
- X{
- X TextWidget ctx = (TextWidget)w;
- X Boolean update_in_progress = (ctx->text.old_insert >= 0);
- X register Atom* atomP;
- X int i, empty;
- X
- X _XtTextPrepareToUpdate(ctx);
- X
- X for (i = 0, atomP = ctx->text.s.selections;
- X i < ctx->text.s.atom_count; i++, atomP++)
- X {
- X if (*selection == *atomP) *atomP = (Atom)0;
- X switch (*atomP) {
- X case XA_CUT_BUFFER0:
- X case XA_CUT_BUFFER1:
- X case XA_CUT_BUFFER2:
- X case XA_CUT_BUFFER3:
- X case XA_CUT_BUFFER4:
- X case XA_CUT_BUFFER5:
- X case XA_CUT_BUFFER6:
- X case XA_CUT_BUFFER7: *atomP = (Atom)0;
- X }
- X }
- X
- X for (i = ctx->text.s.atom_count; i; i--) {
- X if (ctx->text.s.selections[i-1] != 0) break;
- X }
- X ctx->text.s.atom_count = i;
- X
- X for (i = 0, atomP = ctx->text.s.selections;
- X i < ctx->text.s.atom_count; i++, atomP++)
- X {
- X if (*atomP == (Atom)0) {
- X *atomP = ctx->text.s.selections[--ctx->text.s.atom_count];
- X }
- X }
- X
- X if (ctx->text.s.atom_count == 0)
- X _XtTextSetNewSelection(ctx, ctx->text.insertPos, ctx->text.insertPos,
- X NULL, ZERO);
- X
- X if (!update_in_progress) {
- X _XtTextExecuteUpdate(ctx);
- X }
- X}
- X
- X
- Xstatic int _XtTextSetNewSelection(ctx, left, right, selections, count)
- X TextWidget ctx;
- X XtTextPosition left, right;
- X Atom *selections;
- X Cardinal count;
- X{
- X XtTextPosition pos;
- X void (*nullProc)() = NULL;
- X
- X if (left < ctx->text.s.left) {
- X pos = min(right, ctx->text.s.left);
- X _XtTextNeedsUpdating(ctx, left, pos);
- X }
- X if (left > ctx->text.s.left) {
- X pos = min(left, ctx->text.s.right);
- X _XtTextNeedsUpdating(ctx, ctx->text.s.left, pos);
- X }
- X if (right < ctx->text.s.right) {
- X pos = max(right, ctx->text.s.left);
- X _XtTextNeedsUpdating(ctx, pos, ctx->text.s.right);
- X }
- X if (right > ctx->text.s.right) {
- X pos = max(left, ctx->text.s.right);
- X _XtTextNeedsUpdating(ctx, pos, right);
- X }
- X
- X ctx->text.s.left = left;
- X ctx->text.s.right = right;
- X if (ctx->text.source->SetSelection != nullProc) {
- X (*ctx->text.source->SetSelection) (ctx->text.source,
- X left, right,
- X count ? selections[0] : NULL);
- X }
- X if (left < right) {
- X int buffer;
- X while (count) {
- X Atom selection = selections[--count];
- X switch (selection) {
- X case XA_CUT_BUFFER0: buffer = 0; break;
- X case XA_CUT_BUFFER1: buffer = 1; break;
- X case XA_CUT_BUFFER2: buffer = 2; break;
- X case XA_CUT_BUFFER3: buffer = 3; break;
- X case XA_CUT_BUFFER4: buffer = 4; break;
- X case XA_CUT_BUFFER5: buffer = 5; break;
- X case XA_CUT_BUFFER6: buffer = 6; break;
- X case XA_CUT_BUFFER7: buffer = 7; break;
- X default: buffer = -1;
- X }
- X if (buffer >= 0) {
- X char *ptr =
- X _XtTextGetText(ctx, ctx->text.s.left, ctx->text.s.right);
- X if (buffer == 0) {
- X _CreateCutBuffers(XtDisplay((Widget)ctx));
- X XRotateBuffers(XtDisplay((Widget)ctx), 1);
- X }
- X XStoreBuffer(XtDisplay((Widget)ctx), ptr,
- X min(strlen(ptr), MAXCUT), buffer);
- X XtFree (ptr);
- X } else {
- X XtOwnSelection((Widget)ctx, selection, ctx->text.time,
- X ConvertSelection, LoseSelection, NULL);
- X }
- X }
- X }
- X}
- X
- X
- X
- X/*
- X * This internal routine deletes the text from pos1 to pos2 in a source and
- X * then inserts, at pos1, the text that was passed. As a side effect it
- X * "invalidates" that portion of the displayed text (if any).
- X*/
- Xstatic
- Xint ReplaceText (ctx, pos1, pos2, text)
- X TextWidget ctx;
- X XtTextPosition pos1, pos2;
- X XtTextBlock *text;
- X
- X /* it is illegal to call this routine unless there is a valid line table!*/
- X{
- X int i, line1, visible, delta, error;
- X Position x, y;
- X int realW, realH, width;
- X XtTextPosition startPos, endPos, updateFrom;
- X int (*Scan)() = ctx->text.source->Scan;
- X
- X /* the insertPos may not always be set to the right spot in XttextAppend */
- X if ((pos1 == ctx->text.insertPos) &&
- X (ctx->text.source->edit_mode == XttextAppend)) {
- X ctx->text.insertPos = ctx->text.lastPos;
- X pos2 = pos2 - pos1 + ctx->text.insertPos;
- X pos1 = ctx->text.insertPos;
- X }
- X updateFrom = (*Scan)(ctx->text.source, pos1, XtstWhiteSpace, XtsdLeft,
- X 1, TRUE);
- X updateFrom = (*Scan)(ctx->text.source, updateFrom, XtstPositions, XtsdLeft,
- X 1, TRUE);
- X startPos = max(updateFrom, ctx->text.lt.top);
- X visible = LineAndXYForPosition(ctx, startPos, &line1, &x, &y);
- X error = (*ctx->text.source->Replace)(ctx->text.source, pos1, pos2, text);
- X if (error) return error;
- X ctx->text.lastPos = GETLASTPOS;
- X if (ctx->text.lt.top >= ctx->text.lastPos) {
- X BuildLineTable(ctx, ctx->text.lastPos);
- X ClearWindow(ctx);
- X SetScrollBar(ctx);
- X return error;
- X }
- X delta = text->length - (pos2 - pos1);
- X if (delta < ctx->text.lastPos) {
- X pos2 += delta;
- X for (i = 0; i < ctx->text.numranges; i++) {
- X if (ctx->text.updateFrom[i] > pos1)
- X ctx->text.updateFrom[i] += delta;
- X if (ctx->text.updateTo[i] >= pos1)
- X ctx->text.updateTo[i] += delta;
- X }
- X }
- X
- X /*
- X * fixup all current line table entries to reflect edit.
- X * %%% it is not legal to do arithmetic on positions.
- X * using Scan would be more proper.
- X */
- X if (delta) {
- X XtTextLineTableEntry *lineP;
- X int line2 = LineForPosition(ctx, pos1) + 1;
- X for (i = line2, lineP = ctx->text.lt.info + line2;
- X i <= ctx->text.lt.lines; i++, lineP++)
- X lineP->position += delta;
- X }
- X
- X /*
- X * Now process the line table and fixup in case edits caused
- X * changes in line breaks. If we are breaking on word boundaries,
- X * this code checks for moving words to and from lines.
- X */
- END_OF_FILE
- if test 30780 -ne `wc -c <'xconf/Text.c.aa'`; then
- echo shar: \"'xconf/Text.c.aa'\" unpacked with wrong size!
- fi
- # end of 'xconf/Text.c.aa'
- fi
- if test -f 'xconf/xconf.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'xconf/xconf.c'\"
- else
- echo shar: Extracting \"'xconf/xconf.c'\" \(18989 characters\)
- sed "s/^X//" >'xconf/xconf.c' <<'END_OF_FILE'
- X#include "xconf.h"
- X#ifndef lint
- Xstatic char *rcsid = "$Header: $";
- X#endif
- X
- X/*
- X * Written By Jon Crowcroft, May 1989
- X * yours to do with as you wish
- X *
- X * I do not claim it has any value whatsoever...
- X *
- X * TOFIX
- X * Unsatisfactory nature of the conference starter having to name
- X * themselves in the argument list.
- X *
- X */
- X
- Xchar *usage = "user@host user@host ... [-e] [-X typicalXargs]";
- X
- X/*
- X * For help, click help
- X */
- Xextern char defaultTextTranslations[];
- X/*
- X * Some dimensions for the conference windows.
- X */
- Xstatic int widthb = DEFWIDTHB, heightb = DEFHEIGHTB;
- Xstatic int widthw = DEFWIDTHW, heightw = DEFHEIGHTB;
- X
- X
- X/*
- X * The conference/window desription structures as far as xa is concerned
- X * These are xa private structures, not X-Windows ones...
- X */
- Xxconf_t Conference[MAXCONF];
- Xstatic XtAppContext context;
- Xstatic int numberofthem = 0;
- Xstatic int numberlive = 0;
- X
- Xstatic Arg args[10];
- Xstatic Cardinal nargs;
- X
- Xstatic char **saved_argv;
- Xstatic int saved_argc;
- X
- Xstatic int firsttime = True;
- Xstatic int exptl = False;
- X
- X
- Xmain(argc, argv)
- Xchar *argv[];
- X{
- X int i, max;
- X/*
- X * Must be talking to at least one person
- X */
- X if (argc < 2) {
- X (void)fprintf(stderr, "%s %s\n", argv[0], usage);
- X exit(-1);
- X }
- X
- X/*
- X * Parse cmd line args
- X * [User[@host[:Display#]]]+ -X TypicalXArgs
- X * and count number of users...
- X */
- X max = (argc-1 > MAXCONF) ? MAXCONF : argc-1;
- X for(i = 1; i <= max; i++) {
- X/*
- X * ignore real X args here
- X */
- X if (strcmp(argv[i], "-X") == 0)
- X break;
- X if (strcmp(argv[i], "-e") == 0) {
- X exptl = True;
- X continue;
- X }
- X ParseUserDisplay(&Conference[numberofthem], argv[i]);
- X numberofthem += 1;
- X }
- X
- X if (numberofthem <= 0) {
- X (void)fprintf(stderr, "No confederates?\n");
- X exit(-1);
- X }
- X
- X/*
- X * Start talking Xt
- X * Create Application Context
- X */
- X XtToolkitInitialize();
- X context = XtCreateApplicationContext();
- X
- X/*
- X * For each user(display),
- X * there is 1 display which we open a window for their input,
- X * on which is for each other user
- X * a window for their output
- X *
- X * TODO:
- X * Should invite user first - could ask them simply to
- X * do xhost <confhost>
- X * where <confhost> is the conference chair...
- X */
- X for(i = 0; i < numberofthem; i++)
- X (void)StartConference(context,
- X i,
- X Conference,
- X numberofthem,
- X argc,
- X argv);
- X firsttime = False;
- X numberlive = i;
- X/*
- X * And let X take over
- X */
- X XtAppMainLoop(context);
- X}
- X
- XParseUserDisplay(conf, arg)
- Xxconf_t *conf;
- Xchar *arg;
- X{
- X char *cp, *FindMostRecentActiveLogin();
- X (void)strcpy(conf->user, arg);
- X if ((cp = strchr(arg, '@')) == NULL) {
- X#ifdef SUNRPC
- X (void)strcpy(conf->display, FindMostRecentActiveLogin(arg));
- X#else SUNRPC
- X (void)strcpy(conf->display, "");
- X#endif SUNRPC
- X } else {
- X cp += 1;
- X (void)strcpy(conf->display, cp);
- X if (strchr(arg, ':') == NULL)
- X (void)strcat(conf->display, ":0");
- X }
- X}
- X
- X
- X/*
- X * This is called by X, when someone clicks on the qb (QUIT)
- X * TODO: Fix box to re-layout after conferee exits
- X */
- X
- X/* ARGSUSED */
- Xvoid Alldone(widget, data, event)
- XWidget widget;
- Xcaddr_t data, event;
- X{
- X int i, j, someleft = 0;
- X int w,h;
- X XtGeometryResult res;
- X XtWidgetGeometry preferred, intended;
- X int foundsize = False;
- X
- X for(i=0; i < numberofthem; i++) {
- X if (Conference[i].qb == widget) {
- X XtDestroyWidget(Conference[i].toplevel);
- X Conference[i].live = False;
- X for(j=0; j< numberofthem; j++) {
- X if (j != i && Conference[j].live) {
- X XtDestroyWidget(Conference[j].them[i].v);
- X if (!foundsize) {
- X intended.request_mode =
- X preferred.request_mode =
- X XtCWQueryOnly|CWWidth|CWHeight;
- X intended.width = intended.height = 1000;
- X res = XtQueryGeometry(Conference[j].box,
- X &intended, &preferred);
- X w = preferred.width;
- X h = preferred.height;
- X foundsize = True;
- X }
- X XtSetArg(args[0], XtNwidth, w);
- X XtSetArg(args[1], XtNheight, h);
- X XtSetValues(Conference[j].pop, args, TWO);
- X XtResizeWindow(Conference[j].pop);
- X
- X XtSetArg(args[0], XtNwidth, w);
- X XtSetArg(args[1], XtNheight, h);
- X XtSetValues(Conference[j].box, args, TWO);
- X XtResizeWindow(Conference[j].box);
- X }
- X }
- X (void)fprintf(stderr,"%s has left the conference\n",
- X Conference[i].user);
- X numberlive--;
- X }
- X if (XtIsRealized(Conference[i].toplevel))
- X someleft++;
- X }
- X if (!someleft || numberlive <= 0) {
- X (void)fprintf(stderr, "The Conference is now Closed\n");
- X exit(0);
- X }
- X}
- X
- X/*
- X * Call back to accept conference and pop up all windows
- X */
- X/* ARGSUSED */
- Xvoid Accept(widget, data, event)
- XWidget widget;
- Xcaddr_t data, event;
- X{
- X xconf_t *conf = (xconf_t *)data;
- X XtPopup(conf->pop, XtGrabNone);
- X XtSetKeyboardFocus(conf->box, XtNameToWidget(conf->box, "value"));
- X}
- X
- X/*
- X * Call back to pop up add conferee thingy
- X */
- X/* ARGSUSED */
- Xvoid Add(widget, data, event)
- XWidget widget;
- Xcaddr_t data, event;
- X{
- X xconf_t *conf = (xconf_t *)data;
- X XtPopup(conf->npop, XtGrabNone);
- X}
- X
- X/*
- X * Actually add the new conferee
- X */
- X/* ARGSUSED */
- Xvoid AddOk(widget, data, event)
- XWidget widget;
- Xcaddr_t data, event;
- X{
- X int i, j;
- X char *cp;
- X xconf_t *conf = (xconf_t *)data;
- X int newconf = numberofthem;
- X int w,h;
- X XtGeometryResult res;
- X XtWidgetGeometry preferred, intended;
- X
- X cp = XtDialogGetValueString(conf->nap);
- X ParseUserDisplay(&Conference[newconf], cp);
- X numberofthem++;
- X if (!StartConference(context,
- X newconf,
- X Conference,
- X numberofthem,
- X 0,
- X NO(char **))) {
- X numberofthem--;
- X XtSetArg(args[0], XtNvalue, "Cannot find User");
- X XtSetValues(conf->nap, args, ONE);
- X return;
- X }
- X
- X/*
- X * set size of old conferences by new one i.e. let
- X * box choose size for this number of children
- X */
- X intended.request_mode =
- X preferred.request_mode =
- X XtCWQueryOnly|CWWidth|CWHeight;
- X intended.width = intended.height = 1000;
- X res = XtQueryGeometry(Conference[newconf].box,
- X &intended, &preferred);
- X w = preferred.width;
- X h = preferred.height;
- X
- X/*
- X * And add output for everyone else, resizing as we go
- X */
- X for(j=0; j<numberofthem; j++) {
- X if (Conference[j].live && j != newconf) {
- X place(&Conference[j],
- X Conference[newconf].user,
- X newconf, j);
- X/*
- X * Seems to be that you cannot just resize one or the other,
- X * and expect them to "do the right thing"
- X */
- X XtSetArg(args[0], XtNwidth, w);
- X XtSetArg(args[1], XtNheight, h);
- X XtSetValues(Conference[j].pop, args, TWO);
- X XtResizeWindow(Conference[j].pop);
- X
- X XtSetArg(args[0], XtNwidth, w);
- X XtSetArg(args[1], XtNheight, h);
- X XtSetValues(Conference[j].box, args, TWO);
- X XtResizeWindow(Conference[j].box);
- X }
- X }
- X numberlive++;
- X XtPopdown(conf->npop);
- X}
- X/* ARGSUSED */
- Xvoid AddQuit(widget, data, event)
- XWidget widget;
- Xcaddr_t data, event;
- X{
- X xconf_t *conf = (xconf_t *)data;
- X XtPopdown(conf->npop);
- X}
- X
- X/* ARGSUSED */
- Xvoid KeyIn(widget, data, event)
- XWidget widget;
- Xcaddr_t data;
- XXEvent *event;
- X{
- X int i,j;
- X Widget w;
- X
- X for(i=0; i<numberofthem; i++) {
- X if (Conference[i].me.w == widget) {
- X for(j=0; j<numberofthem; j++) {
- X if ((j != i) && Conference[j].live) {
- X static XEvent ev;
- X w = Conference[j].them[i].w;
- X ev = *event;
- X ev.xany.display = XtDisplay(w);
- X ev.xany.window = XtWindow(w);
- X XtDispatchEvent(&ev);
- X }
- X }
- X return;
- X }
- X }
- X (void)fprintf(stderr,"input from nobody\n");
- X}
- X
- X/* ARGSUSED */
- Xvoid Help(widget, data, event)
- XWidget widget;
- Xcaddr_t data, event;
- X{
- X xconf_t *conf = (xconf_t *)data;
- X XtPopup(conf->hpop, XtGrabNone);
- X XtSetKeyboardFocus(conf->hap, XtNameToWidget(conf->hap, "value"));
- X}
- X
- X
- X/* ARGSUSED */
- Xvoid HelpQuit(widget, data, event)
- XWidget widget;
- Xcaddr_t data, event;
- X{
- X xconf_t *conf = (xconf_t *)data;
- X XtPopdown(conf->hpop);
- X}
- X
- X/* ARGSUSED */
- Xvoid Hapropos(widget, data, event)
- XWidget widget;
- Xcaddr_t data, event;
- X{
- X xconf_t *conf = (xconf_t *)data;
- X Arg arg[1];
- X char *cp = "", *dohap();
- X
- X cp = XtDialogGetValueString(conf->hap);
- X XtSetArg(arg[0], XtNlabel, dohap(cp));
- X XtSetValues(conf->hapres, arg, ONE);
- X}
- X
- X/*
- X * Extract string from default text translations - need
- X * to hack round the newlines, tabs and colons to get
- X * out a normal looking string
- X */
- Xchar *
- Xdohap(cp)
- Xchar *cp;
- X{
- X char *dp = defaultTextTranslations, *cdp;
- X static char buf[80], *cb = buf;
- X
- X if (cp != '\0') {
- X while(*dp != '\0') {
- X if (strncmp(cp, dp, strlen(cp)) == 0) {
- X cdp = dp;
- X while((*cdp != '\0') && (*cdp != '\n'))
- X cdp--;
- X cdp++;
- X while (*cdp != ':')
- X *cb++ = *cdp++;
- X *cb = '\0';
- X return buf;
- X }
- X dp++;
- X }
- X }
- X return "Nothing Apt";
- X}
- X
- X#ifdef JOKE
- Xvoid Joke(widget, data, event)
- XWidget widget;
- Xcaddr_t data, event;
- X{
- X Arg arg[1];
- X XtSetArg(arg[0], XtNlabel, "I told you Not to");
- X XtSetValues(widget, arg, ONE);
- X}
- X#endif JOKE
- X
- X
- X#ifdef EXPTL
- X/*
- X * Call backs for assertion etc...
- X */
- X/* ARGSUSED */
- Xassert(widget, data, event)
- XWidget widget;
- Xcaddr_t data, event;
- X{
- X int i;
- X/*
- X * Assertion = This fact is the case...
- X * Bell for Assertion
- X */
- X for(i=0;i<numberofthem; i++)
- X if(Conference[i].live)
- X XBell(XtDisplay(Conference[i].toplevel), 50);
- X}
- X
- X/* ARGSUSED */
- Xcommit(widget, data, event)
- XWidget widget;
- Xcaddr_t data, event;
- X{
- X/*
- X * Committing = I will do this...
- X */
- X}
- X
- X/* ARGSUSED */
- Xdirect(widget, data, event)
- XWidget widget;
- Xcaddr_t data, event;
- X{
- X/*
- X * Direction = You will do this...
- X */
- X}
- X
- X/* ARGSUSED */
- Xdeclare(widget, data, event)
- XWidget widget;
- Xcaddr_t data, event;
- X{
- X/*
- X * Declaration = Varialbe <- Value, from now on...
- X */
- X}
- X
- X/* ARGSUSED */
- Xexpress(widget, data, event)
- XWidget widget;
- Xcaddr_t data, event;
- X{
- X/*
- X * Expression = This is how i feel about this
- X *
- X * This one really needs a scale most of all
- X * color might be used to express here
- X */
- X}
- X#endif EXPTL
- X
- X/*
- X *******************************************************************
- X * Set up a toplevel and sub windows on each conf display...
- X *******************************************************************
- X */
- XStartConference(context, nth, confs, nconf, argc, argv)
- XXtAppContext context;
- Xint nth;
- Xxconf_t *confs;
- Xint nconf;
- Xint argc;
- Xchar *argv[];
- X{
- X Screen *scrn;
- X int i;
- X xconf_t *conf = &confs[nth];
- X char *ptr = "";
- X
- X/*
- X * Tie to approprate display, copy args to saved_args
- X */
- X saved_argc = argc;
- X saved_argv = (char **) XtCalloc(
- X (unsigned) ((argc) + 1), (unsigned)sizeof(*saved_argv));
- X for(i=0; i<argc; i++)
- X saved_argv[i] = argv[i];
- X saved_argv[i] = NULL;
- X conf->dpy = XtOpenDisplay(context,
- X conf->display,
- X "xconf",
- X "XConf",
- X NULL, 0,
- X &saved_argc, saved_argv);
- X
- X if (conf->dpy == NO(Display *)) {
- X (void)fprintf(stderr,"oops, cannot open display %s\n",
- X conf->display);
- X/*
- X * maye we should continue with less people...
- X*/
- X if (firsttime)
- X exit(-1);
- X else
- X return False;
- X }
- X/*
- X * Find right screen for the toplevel...
- X * And do some scaling
- X * Note, after this, added conferees may clutter the screen...nis
- X */
- X if (firsttime)
- X Scale(conf->dpy, nconf, &widthb, &heightb, &widthw, &heightw);
- X
- X/*
- X * Create a shell widget to put all the others in
- X */
- X nargs = 0;
- X scrn = DefaultScreenOfDisplay(conf->dpy);
- X XtSetArg(args[nargs], XtNscreen, scrn); nargs++;
- X XtSetArg(args[nargs], XtNargc, saved_argc); nargs++;
- X XtSetArg(args[nargs], XtNargv, saved_argv); nargs++;
- X conf->toplevel = XtAppCreateShell("xconf",
- X "XConf",
- X#ifdef OVERRIDE
- X overrideShellWidgetClass,
- X#else OVERRIDE
- X applicationShellWidgetClass,
- X#endif OVERRIDE
- X conf->dpy,
- X args,
- X nargs);
- X/*
- X * Request Box...
- X */
- X conf->tbox = XtCreateManagedWidget("ConfCtlBox",
- X boxWidgetClass, conf->toplevel, NO(Arg *), ZERO);
- X/*
- X * And a quit command
- X */
- X conf->qb = XtCreateManagedWidget("Quit Conference",
- X commandWidgetClass, conf->tbox, NO(Arg *), ZERO);
- X XtAddCallback(conf->qb, XtNcallback, Alldone, (caddr_t) conf);
- X/*
- X * And an add conferee button
- X */
- X conf->nb = XtCreateManagedWidget("Add Conferee",
- X commandWidgetClass, conf->tbox, NO(Arg *), ZERO);
- X XtAddCallback(conf->nb, XtNcallback, Add, (caddr_t) conf);
- X conf->npop = XtCreatePopupShell("AddConf",
- X topLevelShellWidgetClass, conf->toplevel, NULL, ZERO);
- X/*
- X * and the rest to do conferee adding...
- X */
- X conf->nbox = XtCreateManagedWidget("ABox",
- X boxWidgetClass, conf->npop, NO(Arg *), ZERO);
- X XtSetArg(args[0], XtNlabel, "Add: ");
- X XtSetArg(args[1], XtNvalue, ptr);
- X conf->nap = XtCreateManagedWidget("AddPop",
- X dialogWidgetClass, conf->nbox, args, TWO);
- X conf->nok = XtCreateManagedWidget("Add ok?",
- X commandWidgetClass, conf->nap, NO(Arg *), ZERO);
- X XtAddCallback(conf->nok, XtNcallback, AddOk, (caddr_t)conf);
- X conf->nq = XtCreateManagedWidget("Add Quit?",
- X commandWidgetClass, conf->nap, NO(Arg *), ZERO);
- X XtAddCallback(conf->nq, XtNcallback, AddQuit, (caddr_t)conf);
- X
- X/*
- X * And a accept command
- X */
- X conf->ab = XtCreateManagedWidget("Accept Conference",
- X commandWidgetClass, conf->tbox, NO(Arg *), ZERO);
- X XtAddCallback(conf->ab, XtNcallback, Accept, (caddr_t)conf);
- X/*
- X * And a Help Button
- X */
- X conf->hb = XtCreateManagedWidget("Help",
- X commandWidgetClass, conf->tbox, NO(Arg *), ZERO);
- X XtAddCallback(conf->hb, XtNcallback, Help, (caddr_t)conf);
- X
- X/*
- X * Do each conf as a popup application window...
- X */
- X XtSetArg(args[0], XtNallowResize, True);
- X conf->pop = XtCreatePopupShell("xonferee",
- X topLevelShellWidgetClass, conf->toplevel, args, ONE);
- X/*
- X * Make a box, with dimensions
- X */
- X XtSetArg(args[0], XtNallowResize, True);
- X conf->box = XtCreateManagedWidget("confereebox",
- X boxWidgetClass, conf->pop, args, ONE);
- X
- X/*
- X * And a popup help window
- X */
- X conf->hpop = XtCreatePopupShell("HelpPop",
- X topLevelShellWidgetClass, conf->toplevel, NULL, ZERO);
- X/*
- X * was topLevel
- X */
- X conf->hbox = XtCreateManagedWidget("HelpBox",
- X boxWidgetClass, conf->hpop, args, TWO);
- X/*
- X * Why the following?, coz of defects in X{t}whatever
- X * it doesnt quite work as we'd like
- X */
- X XtAppAddConverter(context, XtRString, XtROrientation,
- X XmuCvtStringToOrientation, NULL, (Cardinal)0 );
- X
- X XtSetArg(args[0], XtNfile, (XtArgVal)HELPFILE);
- X XtSetArg(args[1], XtNtextOptions, scrollVertical|wordBreak);
- X XtSetArg(args[2], XtNwidth, widthw);
- X XtSetArg(args[3], XtNheight, heightw);
- X XtSetArg(args[4], XtNeditType, (XtArgVal)XttextEdit);
- X conf->htxt = XtCreateManagedWidget("Help",
- X asciiDiskWidgetClass, conf->hbox, args, FIVE);
- X XtSetArg(args[0], XtNlabel, "Hapropos: ");
- X XtSetArg(args[1], XtNvalue, ptr);
- X conf->hap = XtCreateManagedWidget("Hapropos",
- X dialogWidgetClass, conf->hbox, args, TWO);
- X conf->hapok = XtCreateManagedWidget("apropos ok?",
- X commandWidgetClass, conf->hap, NO(Arg *), ZERO);
- X XtAddCallback(conf->hapok, XtNcallback, Hapropos, (caddr_t)conf);
- X conf->hapres = XtCreateManagedWidget("apropos res:",
- X labelWidgetClass, conf->hbox, NO(Arg *), ZERO);
- X conf->hq = XtCreateManagedWidget("Quit Help",
- X commandWidgetClass, conf->hbox, NO(Arg *), ZERO);
- X XtAddCallback(conf->hq, XtNcallback, HelpQuit, (caddr_t)conf);
- X
- X#ifdef JOKE
- X conf->jb = XtCreateManagedWidget("Do Not Press This Button",
- X commandWidgetClass, conf->tbox, NULL, 0);
- X XtAddCallback(conf->jb, XtNcallback, Joke, (caddr_t)conf);
- X#endif JOKE
- X
- X/*
- X * Now the windows for user typing in, and
- X * others output
- X */
- X conf->live = True;
- X for(i=0; i < nconf; i++)
- X if (firsttime || Conference[i].live)
- X place(conf, Conference[i].user, i, nth);
- X
- X/*
- X * And realize this conferees top level
- X */
- X XtRealizeWidget(conf->toplevel);
- X XBell(XtDisplay(conf->toplevel), 50);
- X
- X return True;
- X}
- X
- X/*
- X * Set up a ascii String class widget, (called lotsaa times, once per
- X * conferee
- X */
- Xplace(conf, name, j, nth)
- Xxconf_t *conf;
- Xchar *name;
- Xint j;
- Xint nth;
- X{
- X int i;
- X char nb[80];
- X xwin_t *ww = &(conf->them[j]);
- X/*
- X * Set Xt ascii string class arguments such as
- X * string
- X * edit style
- X * text options for scollbar and word breaking
- X * width and height
- X */
- X
- X nargs = 0;
- X XtSetArg(args[nargs], XtNallowResize, True);
- X nargs++;
- X XtSetArg(args[nargs], XtNwidth, widthw+16);
- X nargs++;
- X XtSetArg(args[nargs], XtNheight, heightw+16);
- X nargs++;
- X ww->v = XtCreateManagedWidget("win", vPanedWidgetClass,
- X conf->box, args, nargs);
- X
- X for(i=0; i<BUFFSIZE; i++)
- X ww->buff[i] = ' ';
- X nargs = 0;
- X XtSetArg(args[nargs], XtNstring, (XtArgVal)ww->buff);
- X nargs++;
- X XtSetArg(args[nargs], XtNtextSource, ww->source);
- X nargs++;
- X XtSetArg(args[nargs], XtNeditType, (XtArgVal)XttextEdit);
- X nargs++;
- X XtSetArg(args[nargs], XtNwidth, widthw);
- X nargs++;
- X XtSetArg(args[nargs], XtNheight, heightw);
- X nargs++;
- X XtSetArg(args[nargs], XtNtextOptions, scrollVertical|wordBreak);
- X nargs++;
- X/*
- X * Distinguish input and output windows by reverse video
- X */
- X if ( j != nth ) {
- X XtSetArg(args[nargs], XtNbackground, XtDefaultForeground);
- X nargs++;
- X XtSetArg(args[nargs], XtNforeground, XtDefaultBackground);
- X nargs++;
- X }
- X
- X/*
- X * Note could be asciiDiskWidgetClass, with tmp fil nam, top record procedings
- X */
- X ww->w = XtCreateManagedWidget("win", asciiStringWidgetClass,
- X ww->v, args, nargs);
- X if (ww->w == NULL) {
- X (void)fprintf(stderr, "win create failed...\n");
- X exit(-1);
- X }
- X
- X/*
- X * and our funky text widget callback
- X */
- X if (j == nth) {
- X Conference[nth].me.w = ww->w;
- X XtAddCallback(ww->w, XtNcallback, KeyIn, (caddr_t)conf);
- X (void)sprintf(nb, "<- In %10s", name);
- X } else {
- X (void)sprintf(nb, "<- Out %10s", name);
- X }
- X
- X XtTextSetLastPos(ww->w, 0);
- X XtTextEnableRedisplay(ww->w);
- X/*
- X * And a label to say who we are
- X */
- X XtSetArg(args[0], XtNlabel, (XtArgVal)nb);
- X XtSetArg(args[1], XtNallowResize, True);
- X XtSetArg(args[2], XtNheight, 12);
- X ww->lab = XtCreateManagedWidget(name, labelWidgetClass,
- X ww->v, args, THREE);
- X
- X#ifdef EXPTL
- X/*
- X * And a bunch of illocutionary buttons (see Searle)
- X */
- X if (exptl && (j == nth)) {
- X ww->assert = XtCreateManagedWidget("Assert",
- X commandWidgetClass,
- X ww->v, NO(Arg *), ZERO);
- X XtAddCallback(ww->assert, XtNcallback, assert, (caddr_t)conf);
- X
- X ww->commit = XtCreateManagedWidget("Commit",
- X commandWidgetClass,
- X ww->v, NO(Arg *), ZERO);
- X XtAddCallback(ww->commit, XtNcallback, commit, (caddr_t)conf);
- X
- X ww->direct = XtCreateManagedWidget("Direct",
- X commandWidgetClass,
- X ww->v, NO(Arg *), ZERO);
- X XtAddCallback(ww->direct, XtNcallback, direct, (caddr_t)conf);
- X
- X ww->declare = XtCreateManagedWidget("Declare",
- X commandWidgetClass,
- X ww->v, NO(Arg *), ZERO);
- X XtAddCallback(ww->declare, XtNcallback, declare, (caddr_t)conf);
- X
- X ww->express = XtCreateManagedWidget("Express",
- X commandWidgetClass,
- X ww->v, NO(Arg *), ZERO);
- X XtAddCallback(ww->express, XtNcallback, express, (caddr_t)conf);
- X }
- X#endif EXPTL
- X/*
- X * Get round munge mess that box widget seems to get into if sizeing
- X * in a popup
- X {
- X int foo;
- X XtSetArg(args[0], XtNheight, &foo);
- X XtGetValues(conf->box, args, ONE);
- X XtSetArg(args[0], XtNheight, foo);
- X XtSetValues(ww->v, args, ONE);
- X }
- X */
- X}
- X
- X
- XScale(d, n, wb, hb, ww, hw)
- XDisplay *d;
- Xint n;
- Xint *wb, *hb, *ww, *hw;
- X{
- X Dimension w, h;
- X int s = DefaultScreen(d);
- X
- X w = DisplayWidth(d, s);
- X h = DisplayHeight(d, s);
- X
- X *wb = (w * 5) / 6;
- X *hb = (h * 5) / 6;
- X
- X *ww = (*wb) / (n+2);
- X *hw = (*hb) / (n+2);
- X}
- X/*
- X * EOF :-)
- X */
- END_OF_FILE
- if test 18989 -ne `wc -c <'xconf/xconf.c'`; then
- echo shar: \"'xconf/xconf.c'\" unpacked with wrong size!
- fi
- # end of 'xconf/xconf.c'
- fi
- echo shar: End of archive 1 \(of 5\).
- cp /dev/null ark1isdone
- MISSING=""
- for I in 1 2 3 4 5 ; do
- if test ! -f ark${I}isdone ; then
- MISSING="${MISSING} ${I}"
- fi
- done
- if test "${MISSING}" = "" ; then
- echo You have unpacked all 5 archives.
- rm -f ark[1-9]isdone
- else
- echo You still need to unpack the following archives:
- echo " " ${MISSING}
- fi
- ## End of shell archive.
- exit 0
-