home *** CD-ROM | disk | FTP | other *** search
- From: argv@island.uu.net (Dan Heller)
- Newsgroups: comp.sources.x
- Subject: v04i083: xconf -- X-based conferencing tool, Part02/05
- Message-ID: <934@island.uu.net>
- Date: 25 Jul 89 08:10:51 GMT
- Approved: island!argv@sun.com
-
- Submitted-by: Jon Crowcroft <J.Crowcroft@Cs.Ucl.AC.UK>
- Posting-number: Volume 4, Issue 83
- Archive-name: xconf/part02
-
-
-
- #! /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 2 (of 5)."
- # Contents: xconf/AsciiSink.c xconf/GCManager.c xconf/Makefile
- # xconf/Text.c.ab
- # Wrapped by argv@sumatra on Tue Jul 25 01:01:05 1989
- PATH=/bin:/usr/bin:/usr/ucb ; export PATH
- if test -f 'xconf/AsciiSink.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'xconf/AsciiSink.c'\"
- else
- echo shar: Extracting \"'xconf/AsciiSink.c'\" \(15302 characters\)
- sed "s/^X//" >'xconf/AsciiSink.c' <<'END_OF_FILE'
- X#ifndef lint
- Xstatic char Xrcsid[] = "$XConsortium: AsciiSink.c,v 1.26 88/10/19 20:08:51 swick Exp $";
- X#endif lint
- 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/Xlib.h>
- X#include <X11/Xutil.h>
- X#include <X11/Xatom.h>
- X#include <X11/IntrinsicP.h>
- X#include <X11/StringDefs.h>
- X#ifdef JON
- X#include "TextP.h"
- X#else JON
- X#include <X11/TextP.h>
- X#endif JON
- X
- X
- X#define GETLASTPOS (*source->Scan)(source, 0, XtstAll, XtsdRight, 1, TRUE)
- X/* Private Ascii TextSink Definitions */
- X
- Xstatic unsigned bufferSize = 200;
- X
- Xtypedef struct _AsciiSinkData {
- X Pixel foreground;
- X GC normgc, invgc, xorgc;
- X XFontStruct *font;
- X int em;
- X Pixmap insertCursorOn;
- X XtTextInsertState laststate;
- X int tab_count;
- X Position *tabs;
- X} AsciiSinkData, *AsciiSinkPtr;
- X
- Xstatic char *buf = NULL;
- X
- X/* XXX foreground default should be XtDefaultFGPixel. How do i do that?? */
- X
- Xstatic XtResource SinkResources[] = {
- X {XtNfont, XtCFont, XtRFontStruct, sizeof (XFontStruct *),
- X XtOffset(AsciiSinkPtr, font), XtRString, "Fixed"},
- X {XtNforeground, XtCForeground, XtRPixel, sizeof (int),
- X XtOffset(AsciiSinkPtr, foreground), XtRString, "Black"},
- X};
- X
- X/* Utilities */
- X
- Xstatic int CharWidth (w, x, c)
- X Widget w;
- X int x;
- X char c;
- X{
- X AsciiSinkData *data = (AsciiSinkData*) ((TextWidget)w)->text.sink->data;
- X int width, nonPrinting;
- X XFontStruct *font = data->font;
- X
- X if (c == '\t') {
- X int i;
- X Position *tab;
- X if (x >= w->core.width) return 0;
- X for (i=0, tab=data->tabs; i<data->tab_count; i++, tab++) {
- X if (x < *tab) {
- X if (*tab < w->core.width)
- X return *tab - x;
- X else
- X return 0;
- X }
- X }
- X return 0;
- X }
- X if (c == LF)
- X c = SP;
- X nonPrinting = (c < SP);
- X if (nonPrinting) c += '@';
- X
- X if (font->per_char &&
- X (c >= font->min_char_or_byte2 && c <= font->max_char_or_byte2))
- X width = font->per_char[c - font->min_char_or_byte2].width;
- X else
- X width = font->min_bounds.width;
- X
- X if (nonPrinting)
- X width += CharWidth(w, x, '^');
- X
- X return width;
- X}
- X
- X/* Sink Object Functions */
- X
- Xstatic int AsciiDisplayText (w, x, y, pos1, pos2, highlight)
- X Widget w;
- X Position x, y;
- X int highlight;
- X XtTextPosition pos1, pos2;
- X{
- X XtTextSink sink = ((TextWidget)w)->text.sink;
- X XtTextSource source = ((TextWidget)w)->text.source;
- X AsciiSinkData *data = (AsciiSinkData *) sink->data ;
- X
- X XFontStruct *font = data->font;
- X int j, k;
- X Dimension width;
- X XtTextBlock blk;
- X GC gc = highlight ? data->invgc : data->normgc;
- X GC invgc = highlight ? data->normgc : data->invgc;
- X
- X y += font->ascent;
- X j = 0;
- X while (pos1 < pos2) {
- X pos1 = (*source->Read)(source, pos1, &blk, pos2 - pos1);
- X for (k = 0; k < blk.length; k++) {
- X if (j >= bufferSize - 5) {
- X bufferSize *= 2;
- X buf = XtRealloc(buf, bufferSize);
- X }
- X buf[j] = blk.ptr[k];
- X if (buf[j] == LF)
- X buf[j] = ' ';
- X else if (buf[j] == '\t') {
- X XDrawImageString(XtDisplay(w), XtWindow(w),
- X gc, x, y, buf, j);
- X buf[j] = 0;
- X x += XTextWidth(data->font, buf, j);
- X width = CharWidth(w, x, '\t');
- X XFillRectangle(XtDisplay(w), XtWindow(w), invgc, x,
- X y - font->ascent, width,
- X (Dimension) (data->font->ascent +
- X data->font->descent));
- X x += width;
- X j = -1;
- X }
- X else
- X if (buf[j] < ' ') {
- X buf[j + 1] = buf[j] + '@';
- X buf[j] = '^';
- X j++;
- X }
- X j++;
- X }
- X }
- X XDrawImageString(XtDisplay(w), XtWindow(w), gc, x, y, buf, j);
- X}
- X
- X
- X#define insertCursor_width 6
- X#define insertCursor_height 3
- Xstatic char insertCursor_bits[] = {0x0c, 0x1e, 0x33};
- X
- X#ifdef SERVERNOTBROKEN
- Xstatic Pixmap CreateInsertCursor(s)
- XScreen *s;
- X{
- X return (XCreateBitmapFromData (DisplayOfScreen(s), RootWindowOfScreen(s),
- X insertCursor_bits, insertCursor_width, insertCursor_height));
- X}
- X#endif
- X
- X/*
- X * The following procedure manages the "insert" cursor.
- X */
- X
- Xstatic AsciiInsertCursor (w, x, y, state)
- X Widget w;
- X Position x, y;
- X XtTextInsertState state;
- X{
- X XtTextSink sink = ((TextWidget)w)->text.sink;
- X AsciiSinkData *data = (AsciiSinkData *) sink->data;
- X
- X/*
- X XCopyArea(sink->dpy,
- X (state == XtisOn) ? data->insertCursorOn : data->insertCursorOff,
- X w, data->normgc, 0, 0, insertCursor_width, insertCursor_height,
- X x - (insertCursor_width >> 1), y - (insertCursor_height));
- X*/
- X
- X if (state != data->laststate && XtIsRealized(w)) {
- X#ifdef SERVERNOTBROKEN
- X XCopyPlane(XtDisplay(w),
- X data->insertCursorOn, XtWindow(w),
- X data->xorgc, 0, 0, insertCursor_width, insertCursor_height,
- X x - (insertCursor_width >> 1), y - (insertCursor_height), 1);
- X#else /* SERVER is BROKEN */
- X /*
- X * See the comment down at the bottom where the pixmap gets built
- X * for why we are doing this this way.
- X */
- X XCopyArea (XtDisplay(w), data->insertCursorOn, XtWindow (w),
- X data->xorgc, 0, 0, insertCursor_width, insertCursor_height,
- X x - (insertCursor_width >> 1), y - (insertCursor_height));
- X#endif /* SERVERNOTBROKEN */
- X }
- X data->laststate = state;
- X}
- X
- X/*
- X * Clear the passed region to the background color.
- X */
- X
- Xstatic AsciiClearToBackground (w, x, y, width, height)
- X Widget w;
- X Position x, y;
- X Dimension width, height;
- X{
- X#ifndef USE_CLEAR_AREA
- X XFillRectangle(XtDisplay(w), XtWindow(w),
- X ((AsciiSinkData*)((TextWidget)w)->text.sink->data)->invgc,
- X x, y, width, height);
- X#else
- X XClearArea(XtDisplay(w), XtWindow(w), x, y, width, height, False);
- X#endif /*USE_CLEAR_AREA*/
- X}
- X
- X/*
- X * Given two positions, find the distance between them.
- X */
- X
- Xstatic AsciiFindDistance (w, fromPos, fromx, toPos,
- X resWidth, resPos, resHeight)
- X Widget w;
- X XtTextPosition fromPos; /* First position. */
- X int fromx; /* Horizontal location of first position. */
- X XtTextPosition toPos; /* Second position. */
- X int *resWidth; /* Distance between fromPos and resPos. */
- X XtTextPosition *resPos; /* Actual second position used. */
- X int *resHeight; /* Height required. */
- X{
- X XtTextSink sink = ((TextWidget)w)->text.sink;
- X XtTextSource source = ((TextWidget)w)->text.source;
- X
- X AsciiSinkData *data;
- X register XtTextPosition index, lastPos;
- X register char c;
- X XtTextBlock blk;
- X
- X data = (AsciiSinkData *) sink->data;
- X /* we may not need this */
- X lastPos = GETLASTPOS;
- X (*source->Read)(source, fromPos, &blk, toPos - fromPos);
- X *resWidth = 0;
- X for (index = fromPos; index != toPos && index < lastPos; index++) {
- X if (index - blk.firstPos >= blk.length)
- X (*source->Read)(source, index, &blk, toPos - fromPos);
- X c = blk.ptr[index - blk.firstPos];
- X if (c == LF) {
- X *resWidth += CharWidth(w, fromx + *resWidth, SP);
- X index++;
- X break;
- X }
- X *resWidth += CharWidth(w, fromx + *resWidth, c);
- X }
- X *resPos = index;
- X *resHeight = data->font->ascent + data->font->descent;
- X}
- X
- X
- Xstatic AsciiFindPosition(w, fromPos, fromx, width, stopAtWordBreak,
- X resPos, resWidth, resHeight)
- X Widget w;
- X XtTextPosition fromPos; /* Starting position. */
- X int fromx; /* Horizontal location of starting position. */
- X int width; /* Desired width. */
- X int stopAtWordBreak; /* Whether the resulting position should be at
- X a word break. */
- X XtTextPosition *resPos; /* Resulting position. */
- X int *resWidth; /* Actual width used. */
- X int *resHeight; /* Height required. */
- X{
- X XtTextSink sink = ((TextWidget)w)->text.sink;
- X XtTextSource source = ((TextWidget)w)->text.source;
- X AsciiSinkData *data;
- X XtTextPosition lastPos, index, whiteSpacePosition;
- X int lastWidth, whiteSpaceWidth;
- X Boolean whiteSpaceSeen;
- X char c;
- X XtTextBlock blk;
- X data = (AsciiSinkData *) sink->data;
- X lastPos = GETLASTPOS;
- X
- X (*source->Read)(source, fromPos, &blk, bufferSize);
- X *resWidth = 0;
- X whiteSpaceSeen = FALSE;
- X c = 0;
- X for (index = fromPos; *resWidth <= width && index < lastPos; index++) {
- X lastWidth = *resWidth;
- X if (index - blk.firstPos >= blk.length)
- X (*source->Read)(source, index, &blk, bufferSize);
- X c = blk.ptr[index - blk.firstPos];
- X if (c == LF) {
- X *resWidth += CharWidth(w, fromx + *resWidth, SP);
- X index++;
- X break;
- X }
- X *resWidth += CharWidth(w, fromx + *resWidth, c);
- X if ((c == SP || c == TAB) && *resWidth <= width) {
- X whiteSpaceSeen = TRUE;
- X whiteSpacePosition = index;
- X whiteSpaceWidth = *resWidth;
- X }
- X }
- X if (*resWidth > width && index > fromPos) {
- X *resWidth = lastWidth;
- X index--;
- X if (stopAtWordBreak && whiteSpaceSeen) {
- X index = whiteSpacePosition + 1;
- X *resWidth = whiteSpaceWidth;
- X }
- X }
- X if (index == lastPos && c != LF) index = lastPos + 1;
- X *resPos = index;
- X *resHeight = data->font->ascent + data->font->descent;
- X}
- X
- X
- Xstatic int AsciiResolveToPosition (w, pos, fromx, width,
- X leftPos, rightPos)
- X Widget w;
- X XtTextPosition pos;
- X int fromx,width;
- X XtTextPosition *leftPos, *rightPos;
- X{
- X int resWidth, resHeight;
- X XtTextSource source = ((TextWidget)w)->text.source;
- X
- X AsciiFindPosition(w, pos, fromx, width, FALSE,
- X leftPos, &resWidth, &resHeight);
- X if (*leftPos > GETLASTPOS)
- X *leftPos = GETLASTPOS;
- X *rightPos = *leftPos;
- X}
- X
- X
- Xstatic int AsciiMaxLinesForHeight (w, height)
- X Widget w;
- X Dimension height;
- X{
- X AsciiSinkData *data;
- X XtTextSink sink = ((TextWidget)w)->text.sink;
- X
- X data = (AsciiSinkData *) sink->data;
- X return(height / (data->font->ascent + data->font->descent));
- X}
- X
- X
- Xstatic int AsciiMaxHeightForLines (w, lines)
- X Widget w;
- X int lines;
- X{
- X AsciiSinkData *data;
- X XtTextSink sink = ((TextWidget)w)->text.sink;
- X
- X data = (AsciiSinkData *) sink->data;
- X return(lines * (data->font->ascent + data->font->descent));
- X}
- X
- X
- Xstatic void AsciiSetTabs (w, offset, tab_count, tabs)
- X Widget w; /* for context */
- X Position offset; /* from left, for margin */
- X int tab_count; /* count of entries in tabs */
- X Position *tabs; /* list of character positions */
- X{
- X AsciiSinkData *data = (AsciiSinkData*)((TextWidget)w)->text.sink->data;
- X int i;
- X
- X if (tab_count > data->tab_count) {
- X data->tabs = (Position*)XtRealloc(data->tabs,
- X (unsigned)tab_count * sizeof(Position*));
- X }
- X
- X for (i=0; i < tab_count; i++) {
- X data->tabs[i] = offset + tabs[i] * data->em;
- X }
- X data->tab_count = tab_count;
- X}
- X
- X/***** Public routines *****/
- X
- XXtTextSink XtAsciiSinkCreate (parent, args, num_args)
- X Widget parent;
- X ArgList args;
- X Cardinal num_args;
- X{
- X XtTextSink sink;
- X AsciiSinkData *data;
- X unsigned long valuemask = (GCFont | GCGraphicsExposures |
- X GCForeground | GCBackground | GCFunction);
- X XGCValues values;
- X long wid;
- X XFontStruct *font;
- X
- X if (!buf) buf = XtMalloc(bufferSize);
- X
- X sink = XtNew(XtTextSinkRec);
- X sink->Display = AsciiDisplayText;
- X sink->InsertCursor = AsciiInsertCursor;
- X sink->ClearToBackground = AsciiClearToBackground;
- X sink->FindPosition = AsciiFindPosition;
- X sink->FindDistance = AsciiFindDistance;
- X sink->Resolve = AsciiResolveToPosition;
- X sink->MaxLines = AsciiMaxLinesForHeight;
- X sink->MaxHeight = AsciiMaxHeightForLines;
- X sink->SetTabs = AsciiSetTabs;
- X data = XtNew(AsciiSinkData);
- X sink->data = (caddr_t)data;
- X
- X XtGetSubresources (parent, (caddr_t)data, XtNtextSink, XtCTextSink,
- X SinkResources, XtNumber(SinkResources),
- X args, num_args);
- X
- X font = data->font;
- X values.function = GXcopy;
- X values.font = font->fid;
- X values.graphics_exposures = (Bool) FALSE;
- X values.foreground = data->foreground;
- X values.background = parent->core.background_pixel;
- X data->normgc = XtGetGC(parent, valuemask, &values);
- X values.foreground = parent->core.background_pixel;
- X values.background = data->foreground;
- X data->invgc = XtGetGC(parent, valuemask, &values);
- X values.function = GXxor;
- X values.foreground = data->foreground ^ parent->core.background_pixel;
- X values.background = 0;
- X data->xorgc = XtGetGC(parent, valuemask, &values);
- X
- X
- X wid = -1;
- X if ((!XGetFontProperty(font, XA_QUAD_WIDTH, &wid)) || wid <= 0) {
- X if (font->per_char && font->min_char_or_byte2 <= '0' &&
- X font->max_char_or_byte2 >= '0')
- X wid = font->per_char['0' - font->min_char_or_byte2].width;
- X else
- X wid = font->max_bounds.width;
- X }
- X if (wid <= 0)
- X data->em = 1;
- X else
- X data->em = wid;
- X
- X data->font = font;
- X#ifdef SERVERNOTBROKEN
- X data->insertCursorOn = CreateInsertCursor(XtScreen(parent));
- X#else
- X /*
- X * This is the work around for not being able to do CopyPlane with XOR.
- X * However, there is another bug which doesn't let us use the new
- X * CreatePixmapFromBitmapData routine to build the pixmap that we will
- X * use CopyArea with.
- X */
- X#ifdef SERVERNOTBROKEN2
- X data->insertCursorOn =
- X XCreatePixmapFromBitmapData (XtDisplay (parent),
- X RootWindowOfScreen(XtScreen(parent)),
- X insertCursor_bits, insertCursor_width,
- X insertCursor_height, data->foreground,
- X parent->core.background_pixel,
- X parent->core.depth);
- X#else /* SERVER is BROKEN the second way */
- X {
- X Screen *screen = XtScreen (parent);
- X Display *dpy = XtDisplay (parent);
- X Window root = RootWindowOfScreen(screen);
- X Pixmap bitmap = XCreateBitmapFromData (dpy, root, insertCursor_bits,
- X insertCursor_width,
- X insertCursor_height);
- X Pixmap pixmap = XCreatePixmap (dpy, root, insertCursor_width,
- X insertCursor_height,
- X DefaultDepthOfScreen (screen));
- X XGCValues gcv;
- X GC gc;
- X
- X gcv.function = GXcopy;
- X gcv.foreground = data->foreground ^ parent->core.background_pixel;
- X gcv.background = 0;
- X gcv.graphics_exposures = False;
- X gc = XtGetGC (parent, (GCFunction | GCForeground | GCBackground |
- X GCGraphicsExposures), &gcv);
- X XCopyPlane (dpy, bitmap, pixmap, gc, 0, 0, insertCursor_width,
- X insertCursor_height, 0, 0, 1);
- X XtDestroyGC (gc);
- X data->insertCursorOn = pixmap;
- X }
- X#endif /* SERVERNOTBROKEN2 */
- X#endif /* SERVERNOTBROKEN */
- X data->laststate = XtisOff;
- X data->tab_count = 0;
- X data->tabs = NULL;
- X return sink;
- X}
- X
- Xvoid XtAsciiSinkDestroy (sink)
- X XtTextSink sink;
- X{
- X AsciiSinkData *data;
- X
- X data = (AsciiSinkData *) sink->data;
- X XtFree((char *) data->tabs);
- X XtFree((char *) data);
- X XtFree((char *) sink);
- X}
- END_OF_FILE
- if test 15302 -ne `wc -c <'xconf/AsciiSink.c'`; then
- echo shar: \"'xconf/AsciiSink.c'\" unpacked with wrong size!
- fi
- # end of 'xconf/AsciiSink.c'
- fi
- if test -f 'xconf/GCManager.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'xconf/GCManager.c'\"
- else
- echo shar: Extracting \"'xconf/GCManager.c'\" \(6869 characters\)
- sed "s/^X//" >'xconf/GCManager.c' <<'END_OF_FILE'
- X#ifndef lint
- Xstatic char Xrcsid[] = "$XConsortium: GCManager.c,v 1.31 88/09/06 16:27:54 jim Exp $";
- X/* $oHeader: GCManager.c,v 1.4 88/08/19 14:19:51 asente Exp $ */
- X#endif lint
- 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 <stdio.h>
- X#include "IntrinsicI.h"
- X
- X
- Xtypedef struct _GCrec {
- X Display *dpy; /* Display for GC */
- X Screen *screen; /* Screen for GC */
- X Cardinal depth; /* Depth for GC */
- X Cardinal ref_count; /* # of shareholders */
- X GC gc; /* The GC itself. */
- X XtValueMask valueMask; /* What fields are being used right now. */
- X XGCValues values; /* What values those fields have. */
- X struct _GCrec *next; /* Next GC for this widgetkind. */
- X} GCrec, *GCptr;
- X
- Xstatic Drawable GCparents[256]; /* static initialized to zero, K&R ss 4.9 */
- Xstatic GCrec *GClist = NULL;
- X
- Xstatic Bool Matches(ptr, valueMask, v)
- X GCptr ptr;
- X register XtValueMask valueMask;
- X register XGCValues *v;
- X{
- X register XGCValues *p = &(ptr->values);
- X
- X#define CheckGCField(MaskBit,fieldName) \
- X if ((valueMask & MaskBit) && (p->fieldName != v->fieldName)) return False
- X
- X /* Check most common fields specified for GCs first */
- X CheckGCField( GCForeground, foreground);
- X CheckGCField( GCBackground, background);
- X CheckGCField( GCFont, font);
- X CheckGCField( GCFillStyle, fill_style);
- X CheckGCField( GCLineWidth, line_width);
- X /* Are we done yet ? */
- X if (! (valueMask
- X & ~(GCForeground | GCBackground | GCFont | GCFillStyle | GCLineWidth)))
- X return True;
- X
- X /* Check next most common */
- X CheckGCField( GCFunction, function);
- X CheckGCField( GCGraphicsExposures, graphics_exposures);
- X CheckGCField( GCTile, tile);
- X CheckGCField( GCSubwindowMode, subwindow_mode);
- X CheckGCField( GCPlaneMask, plane_mask);
- X /* Now are we done ? */
- X if (! (valueMask
- X & ~(GCForeground | GCBackground | GCFont | GCFillStyle | GCLineWidth
- X | GCFunction | GCGraphicsExposures | GCTile | GCSubwindowMode
- X | GCPlaneMask))) return True;
- X
- X CheckGCField( GCLineStyle, line_style);
- X CheckGCField( GCCapStyle, cap_style);
- X CheckGCField( GCJoinStyle, join_style);
- X CheckGCField( GCFillRule, fill_rule);
- X CheckGCField( GCArcMode, arc_mode);
- X CheckGCField( GCStipple, stipple);
- X CheckGCField( GCTileStipXOrigin, ts_x_origin);
- X CheckGCField( GCTileStipYOrigin, ts_y_origin);
- X CheckGCField( GCClipXOrigin, clip_x_origin);
- X CheckGCField( GCClipYOrigin, clip_y_origin);
- X CheckGCField( GCClipMask, clip_mask);
- X CheckGCField( GCDashOffset, dash_offset);
- X CheckGCField( GCDashList, dashes);
- X#undef CheckGCField
- X return True;
- X} /* Matches */
- X
- X
- X/*
- X * Return a read-only GC with the given values.
- X */
- X
- XGC XtGetGC(widget, valueMask, values)
- X Widget widget;
- X register XtGCMask valueMask;
- X XGCValues *values;
- X{
- X GCptr prev;
- X register GCptr cur;
- X register Cardinal depth = widget->core.depth;
- X register Screen *screen = XtScreen(widget);
- X Drawable drawable;
- X register Display *dpy = XtDisplay(widget);
- X
- X /* Search for existing GC that matches exactly */
- X for (cur = GClist, prev = NULL; cur != NULL; prev = cur, cur = cur->next) {
- X if (cur->valueMask == valueMask && cur->depth == depth
- X && cur->screen == screen && cur->dpy == dpy
- X && Matches(cur, valueMask, values)) {
- X cur->ref_count++;
- X /* Move this GC to front of list if not already there */
- X if (prev != NULL) {
- X prev->next = cur->next;
- X cur->next = GClist;
- X GClist = cur;
- X }
- X return cur->gc;
- X }
- X }
- X
- X /* No matches, have to create a new one */
- X cur = XtNew(GCrec);
- X cur->next = GClist;
- X GClist = cur;
- X
- X cur->dpy = XtDisplay(widget);
- X cur->screen = screen;
- X cur->depth = depth;
- X cur->ref_count = 1;
- X cur->valueMask = valueMask;
- X cur->values = *values;
- X if (XtWindow(widget) == NULL) {
- X /* Have to create a bogus pixmap for the GC. Stupid X protocol. */
- X#ifdef JON
- X if (depth == DefaultDepthOfScreen(screen))
- X drawable = RootWindowOfScreen(screen);
- X else
- X drawable = XCreatePixmap(cur->dpy, screen->root, 1, 1,
- Xdepth);
- X#else
- X if (GCparents[depth] != 0) {
- X drawable = GCparents[depth];
- X } else {
- X if (depth == DefaultDepthOfScreen(screen))
- X drawable = RootWindowOfScreen(screen);
- X else
- X drawable = XCreatePixmap(cur->dpy, screen->root, 1, 1, depth);
- X GCparents[depth] = drawable;
- X }
- X#endif
- X } else {
- X drawable = XtWindow(widget);
- X }
- X cur->gc = XCreateGC(cur->dpy, drawable, valueMask, values);
- X return cur->gc;
- X} /* XtGetGC */
- X
- Xvoid XtReleaseGC(widget, gc)
- X Widget widget;
- X GC gc;
- X{
- X register GCptr cur, prev;
- X
- X for (cur = GClist, prev = NULL; cur != NULL; prev = cur, cur = cur->next) {
- X if (cur->gc == gc && cur->dpy == XtDisplay(widget)) {
- X if (--(cur->ref_count) == 0) {
- X if (prev != NULL) prev->next = cur->next;
- X else GClist = cur->next;
- X XFreeGC(cur->dpy, gc);
- X XtFree((char *) cur);
- X break;
- X }
- X }
- X }
- X} /* XtReleaseGC */
- X
- X/* The following interface is broken and supplied only for backwards
- X * compatibility. It will work properly in all cases only if there
- X * is exactly 1 Display created by the application.
- X */
- X
- Xvoid XtDestroyGC(gc)
- X GC gc;
- X{
- X register GCptr cur, prev;
- X
- X for (cur = GClist, prev = NULL; cur != NULL; prev = cur, cur = cur->next) {
- X if (cur->gc == gc) {
- X if (--(cur->ref_count) == 0) {
- X if (prev != NULL) prev->next = cur->next;
- X else GClist = cur->next;
- X XFreeGC(cur->dpy, gc);
- X XtFree((char *) cur);
- X break;
- X }
- X }
- X }
- X} /* XtDestroyGC */
- END_OF_FILE
- if test 6869 -ne `wc -c <'xconf/GCManager.c'`; then
- echo shar: \"'xconf/GCManager.c'\" unpacked with wrong size!
- fi
- # end of 'xconf/GCManager.c'
- fi
- if test -f 'xconf/Makefile' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'xconf/Makefile'\"
- else
- echo shar: Extracting \"'xconf/Makefile'\" \(437 characters\)
- sed "s/^X//" >'xconf/Makefile' <<'END_OF_FILE'
- XH = AsciiText.h Text.h TextSrcP.h AsciiTextP.h TextP.h xconf.h
- XS = xconf.c ru.c Text.c AsciiText.c
- XO = xconf.o ru.o Text.o AsciiText.o AsciiSink.o \
- X StringSrc.o DiskSrc.o \
- X Dialog.o \
- X GCManager.o Converters.o
- XL = -lXaw -lXt -lXmu -lX11 -lrpcsvc
- XCFLAGS = -I/usr/src/X11R3/lib/Xt -DJON -DDEBUG -DJOKE -DEXPTL -DSUNRPC -g
- X
- Xall: xconf
- X
- Xxconf: $O $H
- X cc $(CFLAGS) -o xconf $O $L
- X
- Xlint: $S
- X lint -I/usr/ucl/include -DJON -DDEBUG xconf.c
- END_OF_FILE
- if test 437 -ne `wc -c <'xconf/Makefile'`; then
- echo shar: \"'xconf/Makefile'\" unpacked with wrong size!
- fi
- # end of 'xconf/Makefile'
- fi
- if test -f 'xconf/Text.c.ab' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'xconf/Text.c.ab'\"
- else
- echo shar: Extracting \"'xconf/Text.c.ab'\" \(29444 characters\)
- sed "s/^X//" >'xconf/Text.c.ab' <<'END_OF_FILE'
- X if (visible) {
- X XtTextLineTableEntry *thisLine, *nextLine = ctx->text.lt.info + line1;
- X Boolean resizeable = ctx->text.options & resizeWidth;
- X Boolean wordwrap = ctx->text.options & wordBreak;
- X int (*FindPosition)() = ctx->text.sink->FindPosition;
- X int (*ClearToBackground)() = ctx->text.sink->ClearToBackground;
- X register XtTextPosition lastPos = ctx->text.lastPos;
- X for (i = line1; i < ctx->text.lt.lines; i++) {/* fixup line table */
- X thisLine = nextLine++;
- X width = resizeable ? BIGNUM : ctx->core.width - x;
- X if (startPos <= lastPos) {
- X (*FindPosition)(ctx, startPos, x, width, wordwrap,
- X &endPos, &realW, &realH);
- X if (!wordwrap && endPos < lastPos) {
- X /* if not wordBreak, skip remainder of this line */
- X endPos = (*Scan)(ctx->text.source, startPos,
- X XtstEOL, XtsdRight, 1, TRUE);
- X if (endPos == startPos)
- X endPos = lastPos + 1;
- X }
- X thisLine->endX = x + realW;
- X nextLine->y = thisLine->y + realH;
- X if ((endPos > pos1) && (endPos == nextLine->position))
- X break; /* %%% why not update remaining y's? */
- X startPos = endPos;
- X }
- X if (startPos > lastPos) {
- X if (nextLine->position <= lastPos) {
- X (*ClearToBackground) (ctx, nextLine->x, nextLine->y,
- X nextLine->endX,
- X (nextLine+1)->y - nextLine->y);
- X }
- X nextLine->endX = ctx->text.leftmargin;
- X }
- X nextLine->position = startPos;
- X x = nextLine->x;
- X }
- X if (delta >= lastPos)
- X endPos = lastPos;
- X if (endPos < pos2) /* might scroll if word wrapped off bottom */
- X endPos = pos2;
- X if (endPos > lastPos && delta > 0)
- X endPos = lastPos; /* optimize insert at end; don't clear below */
- X if (pos2 >= ctx->text.lt.top || delta >= lastPos)
- X _XtTextNeedsUpdating(ctx, updateFrom, endPos);
- X }
- X SetScrollBar(ctx);
- X return error;
- X}
- X
- X
- X/*
- X * This routine will display text between two arbitrary source positions.
- X * In the event that this span contains highlighted text for the selection,
- X * only that portion will be displayed highlighted.
- X */
- Xstatic void DisplayText(w, pos1, pos2)
- X Widget w;
- X XtTextPosition pos1, pos2;
- X /* it is illegal to call this routine unless there is a valid line table! */
- X{
- X TextWidget ctx = (TextWidget)w;
- X Position x, y;
- X int height;
- X int line, i, visible;
- X XtTextPosition startPos, endPos;
- X int lastPos = ctx->text.lastPos;
- X Boolean clear_eol;
- X Boolean clear_eos = True;
- X
- X if (pos1 < ctx->text.lt.top)
- X pos1 = ctx->text.lt.top;
- X if (pos2 > ctx->text.lastPos)
- X pos2 = ctx->text.lastPos;
- X else if (pos2 == ctx->text.lastPos)
- X clear_eos = False;
- X if (pos1 >= pos2) return;
- X visible = LineAndXYForPosition(ctx, pos1, &line, &x, &y);
- X if (!visible)
- X return;
- X startPos = pos1;
- X for (i = line; i < ctx->text.lt.lines; i++) {
- X endPos = ctx->text.lt.info[i + 1].position;
- X if (endPos > pos2) {
- X if (endPos >= lastPos)
- X clear_eol = True;
- X else
- X clear_eol = False;
- X endPos = pos2;
- X }
- X else clear_eol = True;
- X height = ctx->text.lt.info[i + 1].y - ctx->text.lt.info[i].y;
- X if (endPos > startPos) {
- X if (x == ctx->text.leftmargin)
- X (*ctx->text.sink->ClearToBackground)
- X (w, 0, y, ctx->text.leftmargin, height);
- X if (startPos >= ctx->text.s.right || endPos <= ctx->text.s.left) {
- X (*ctx->text.sink->Display) (w, x, y, startPos, endPos, FALSE);
- X } else if (startPos >= ctx->text.s.left && endPos <= ctx->text.s.right) {
- X (*ctx->text.sink->Display) (w, x, y, startPos, endPos, TRUE);
- X } else {
- X DisplayText(w, startPos, ctx->text.s.left);
- X DisplayText(w, max(startPos, ctx->text.s.left),
- X min(endPos, ctx->text.s.right));
- X DisplayText(w, ctx->text.s.right, endPos);
- X }
- X }
- X startPos = endPos;
- X if (clear_eol)
- X (*ctx->text.sink->ClearToBackground)(ctx,
- X ctx->text.lt.info[i].endX, y, (int)ctx->core.width, height);
- X x = ctx->text.leftmargin;
- X y = ctx->text.lt.info[i + 1].y;
- X if ((endPos == pos2) && !clear_eos)
- X break;
- X }
- X}
- X
- X/*
- X * This routine implements multi-click selection in a hardwired manner.
- X * It supports multi-click entity cycling (char, word, line, file) and mouse
- X * motion adjustment of the selected entitie (i.e. select a word then, with
- X * button still down, adjust wich word you really meant by moving the mouse).
- X * [NOTE: This routine is to be replaced by a set of procedures that
- X * will allows clients to implements a wide class of draw through and
- X * multi-click selection user interfaces.]
- X*/
- Xstatic void DoSelection (ctx, position, time, motion)
- X TextWidget ctx;
- X XtTextPosition position;
- X Time time;
- X Boolean motion;
- X{
- X int delta;
- X XtTextPosition newLeft, newRight;
- X XtTextSelectType newType;
- X XtTextSelectType *sarray;
- X
- X delta = (time < ctx->text.lasttime) ?
- X ctx->text.lasttime - time : time - ctx->text.lasttime;
- X if (motion)
- X newType = ctx->text.s.type;
- X else {
- X if ((delta < 500) && ((position >= ctx->text.s.left)
- X && (position <= ctx->text.s.right))) { /* multi-click event */
- X for (sarray = ctx->text.sarray;
- X *sarray != XtselectNull && *sarray != ctx->text.s.type;
- X sarray++) ;
- X if (*sarray != XtselectNull) sarray++;
- X if (*sarray == XtselectNull) sarray = ctx->text.sarray;
- X newType = *sarray;
- X } else { /* single-click event */
- X newType = *(ctx->text.sarray);
- X }
- X ctx->text.lasttime = time;
- X }
- X switch (newType) {
- X case XtselectPosition:
- X newLeft = newRight = position;
- X break;
- X case XtselectChar:
- X newLeft = position;
- X newRight = (*ctx->text.source->Scan)(
- X ctx->text.source, position, position, XtsdRight, 1, FALSE);
- X break;
- X case XtselectWord:
- X newLeft = (*ctx->text.source->Scan)(
- X ctx->text.source, position, XtstWhiteSpace, XtsdLeft, 1, FALSE);
- X newRight = (*ctx->text.source->Scan)(
- X ctx->text.source, position, XtstWhiteSpace, XtsdRight, 1, FALSE);
- X break;
- X case XtselectLine:
- X case XtselectParagraph: /* need "para" scan mode to implement pargraph */
- X newLeft = (*ctx->text.source->Scan)(
- X ctx->text.source, position, XtstEOL, XtsdLeft, 1, FALSE);
- X newRight = (*ctx->text.source->Scan)(
- X ctx->text.source, position, XtstEOL, XtsdRight, 1, FALSE);
- X break;
- X case XtselectAll:
- X newLeft = (*ctx->text.source->Scan)(
- X ctx->text.source, position, XtstAll, XtsdLeft, 1, FALSE);
- X newRight = (*ctx->text.source->Scan)(
- X ctx->text.source, position, XtstAll, XtsdRight, 1, FALSE);
- X break;
- X }
- X if ((newLeft != ctx->text.s.left) || (newRight != ctx->text.s.right)
- X || (newType != ctx->text.s.type)) {
- X _XtTextSetNewSelection(ctx, newLeft, newRight, NULL, ZERO);
- X ctx->text.s.type = newType;
- X if (position - ctx->text.s.left < ctx->text.s.right - position)
- X ctx->text.insertPos = newLeft;
- X else
- X ctx->text.insertPos = newRight;
- X }
- X if (!motion) { /* setup so we can freely mix select extend calls*/
- X ctx->text.origSel.type = ctx->text.s.type;
- X ctx->text.origSel.left = ctx->text.s.left;
- X ctx->text.origSel.right = ctx->text.s.right;
- X if (position >= ctx->text.s.left + ((ctx->text.s.right - ctx->text.s.left) / 2))
- X ctx->text.extendDir = XtsdRight;
- X else
- X ctx->text.extendDir = XtsdLeft;
- X }
- X}
- X
- X/*
- X * This routine implements extension of the currently selected text in
- X * the "current" mode (i.e. char word, line, etc.). It worries about
- X * extending from either end of the selection and handles the case when you
- X * cross through the "center" of the current selection (e.g. switch which
- X * end you are extending!).
- X * [NOTE: This routine will be replaced by a set of procedures that
- X * will allows clients to implements a wide class of draw through and
- X * multi-click selection user interfaces.]
- X*/
- Xstatic void ExtendSelection (ctx, position, motion)
- X TextWidget ctx;
- X XtTextPosition position;
- X Boolean motion;
- X{
- X XtTextPosition newLeft, newRight;
- X
- X
- X if (!motion) { /* setup for extending selection */
- X ctx->text.origSel.type = ctx->text.s.type;
- X ctx->text.origSel.left = ctx->text.s.left;
- X ctx->text.origSel.right = ctx->text.s.right;
- X if (position >= ctx->text.s.left + ((ctx->text.s.right - ctx->text.s.left) / 2))
- X ctx->text.extendDir = XtsdRight;
- X else
- X ctx->text.extendDir = XtsdLeft;
- X }
- X else /* check for change in extend direction */
- X if ((ctx->text.extendDir == XtsdRight && position < ctx->text.origSel.left) ||
- X (ctx->text.extendDir == XtsdLeft && position > ctx->text.origSel.right)) {
- X ctx->text.extendDir = (ctx->text.extendDir == XtsdRight)? XtsdLeft : XtsdRight;
- X _XtTextSetNewSelection(ctx, ctx->text.origSel.left, ctx->text.origSel.right, NULL, ZERO);
- X }
- X newLeft = ctx->text.s.left;
- X newRight = ctx->text.s.right;
- X switch (ctx->text.s.type) {
- X case XtselectPosition:
- X if (ctx->text.extendDir == XtsdRight)
- X newRight = position;
- X else
- X newLeft = position;
- X break;
- X case XtselectWord:
- X if (ctx->text.extendDir == XtsdRight)
- X newRight = position = (*ctx->text.source->Scan)(
- X ctx->text.source, position, XtstWhiteSpace, XtsdRight, 1, FALSE);
- X else
- X newLeft = position = (*ctx->text.source->Scan)(
- X ctx->text.source, position, XtstWhiteSpace, XtsdLeft, 1, FALSE);
- X break;
- X case XtselectLine:
- X case XtselectParagraph: /* need "para" scan mode to implement pargraph */
- X if (ctx->text.extendDir == XtsdRight)
- X newRight = position = (*ctx->text.source->Scan)(
- X ctx->text.source, position, XtstEOL, XtsdRight, 1, TRUE);
- X else
- X newLeft = position = (*ctx->text.source->Scan)(
- X ctx->text.source, position, XtstEOL, XtsdLeft, 1, FALSE);
- X break;
- X case XtselectAll:
- X position = ctx->text.insertPos;
- X break;
- X }
- X _XtTextSetNewSelection(ctx, newLeft, newRight, NULL, ZERO);
- X ctx->text.insertPos = position;
- X}
- X
- X
- X/*
- X * Clear the window to background color.
- X */
- Xstatic ClearWindow (w)
- X Widget w;
- X{
- X if (XtIsRealized(w))
- X (*((TextWidget)w)->text.sink->
- X ClearToBackground) (w, 0, 0, (int)w->core.width, (int)w->core.height);
- X}
- X
- X
- X/*
- X * Internal redisplay entire window.
- X * Legal to call only if widget is realized.
- X */
- XDisplayTextWindow (w)
- X Widget w;
- X{
- X TextWidget ctx = (TextWidget) w;
- X ClearWindow(w);
- X BuildLineTable(ctx, ctx->text.lt.top);
- X _XtTextNeedsUpdating(ctx, zeroPosition, ctx->text.lastPos);
- X SetScrollBar(ctx);
- X}
- X
- X/*
- X * This routine checks to see if the window should be resized (grown or
- X * shrunk) or scrolled when text to be painted overflows to the right or
- X * the bottom of the window. It is used by the keyboard input routine.
- X*/
- Xstatic CheckResizeOrOverflow(ctx)
- X TextWidget ctx;
- X{
- X XtTextPosition posToCheck;
- X int visible, line, width;
- X XtWidgetGeometry rbox;
- X XtGeometryResult reply;
- X register int options = ctx->text.options;
- X
- X if (options & resizeWidth) {
- X XtTextLineTableEntry *lt;
- X width = 0;
- X for (line=0, lt=ctx->text.lt.info; line<ctx->text.lt.lines; line++) {
- X if (width < lt->endX)
- X width = lt->endX;
- X lt++;
- X }
- X if (width > ctx->core.width) {
- X rbox.request_mode = CWWidth;
- X rbox.width = width;
- X reply = XtMakeGeometryRequest((Widget)ctx, &rbox, &rbox);
- X if (reply == XtGeometryAlmost)
- X reply = XtMakeGeometryRequest((Widget)ctx, &rbox, NULL);
- X }
- X }
- X if ((options & resizeHeight) || (options & scrollOnOverflow)) {
- X if (options & scrollOnOverflow)
- X posToCheck = ctx->text.insertPos;
- X else
- X posToCheck = ctx->text.lastPos;
- X visible = IsPositionVisible(ctx, posToCheck);
- X if (visible)
- X line = LineForPosition(ctx, posToCheck);
- X else
- X line = ctx->text.lt.lines;
- X if ((options & scrollOnOverflow) && (line + 1 > ctx->text.lt.lines)) {
- X BuildLineTable(ctx, ctx->text.lt.info[1].position);
- X XCopyArea(XtDisplay(ctx), XtWindow(ctx), XtWindow(ctx),
- X ctx->text.gc, (int)ctx->text.leftmargin,
- X (int)ctx->text.lt.info[1].y,
- X (int)ctx->core.width, (int)ctx->core.height,
- X (int)ctx->text.leftmargin, ctx->text.lt.info[0].y);
- X }
- X else
- X if ((options & resizeHeight) && (line + 1 != ctx->text.lt.lines)) {
- X int oldHeight = ctx->core.height;
- X rbox.request_mode = CWHeight;
- X rbox.height = (*ctx->text.sink->MaxHeight)
- X (ctx, line + 1) + (2*yMargin)+2;
- X reply = XtMakeGeometryRequest(ctx, &rbox, &rbox);
- X if (reply == XtGeometryAlmost)
- X reply = XtMakeGeometryRequest((Widget)ctx, &rbox, NULL);
- X if (reply == XtGeometryYes) {
- X BuildLineTable(ctx, ctx->text.lt.top);
- X if (!(options & wordBreak) /* if NorthEastGravity */
- X && rbox.height < oldHeight) {
- X /* clear cruft from bottom margin */
- X (*ctx->text.sink->ClearToBackground)
- X (ctx, ctx->text.leftmargin,
- X ctx->text.lt.info[ctx->text.lt.lines].y,
- X (int)ctx->core.width, oldHeight - rbox.height);
- X }
- X }
- X }
- X }
- X}
- X
- Xstatic Atom* _SelectionList(ctx, params, num_params)
- X TextWidget ctx;
- X String *params;
- X Cardinal num_params;
- X{
- X /* converts (params, num_params) to a list of atoms & caches the
- X * list in the TextWidget instance.
- X */
- X
- X if (num_params > ctx->text.s.array_size) {
- X ctx->text.s.selections =
- X (Atom*)XtRealloc(ctx->text.s.selections, num_params*sizeof(Atom));
- X ctx->text.s.array_size = num_params;
- X }
- X XmuInternStrings( XtDisplay((Widget)ctx), params, num_params,
- X ctx->text.s.selections );
- X ctx->text.s.atom_count = num_params;
- X return ctx->text.s.selections;
- X}
- X
- X
- X/*
- X * This routine is used to perform various selection functions. The goal is
- X * to be able to specify all the more popular forms of draw-through and
- X * multi-click selection user interfaces from the outside.
- X */
- Xvoid AlterSelection (ctx, mode, action, params, num_params)
- X TextWidget ctx;
- X XtTextSelectionMode mode; /* {XtsmTextSelect, XtsmTextExtend} */
- X XtTextSelectionAction action; /* {XtactionStart, XtactionAdjust, XtactionEnd} */
- X String *params;
- X Cardinal *num_params;
- X{
- X XtTextPosition position;
- X
- X position = PositionForXY (ctx, (int) ctx->text.ev_x, (int) ctx->text.ev_y);
- X if (action == XtactionStart) {
- X switch (mode) {
- X case XtsmTextSelect:
- X DoSelection (ctx, position, ctx->text.time, FALSE);
- X break;
- X case XtsmTextExtend:
- X ExtendSelection (ctx, position, FALSE);
- X break;
- X }
- X }
- X else {
- X switch (mode) {
- X case XtsmTextSelect:
- X DoSelection (ctx, position, ctx->text.time, TRUE);
- X break;
- X case XtsmTextExtend:
- X ExtendSelection (ctx, position, TRUE);
- X break;
- X }
- X }
- X if (action == XtactionEnd) {
- X if (ctx->text.s.left < ctx->text.s.right) {
- X Cardinal count = *num_params;
- X if (count == 0) {
- X static String defaultSelection = "CUT_BUFFER0";
- X params = &defaultSelection;
- X count = 1;
- X }
- X _XtTextSetNewSelection(
- X ctx, ctx->text.s.left, ctx->text.s.right,
- X _SelectionList(ctx, params, count),
- X count );
- X }
- X else XtTextUnsetSelection((Widget)ctx);
- X }
- X}
- X
- X/*
- X * This routine processes all "expose region" XEvents. In general, its job
- X * is to the best job at minimal re-paint of the text, displayed in the
- X * window, that it can.
- X*/
- Xstatic void ProcessExposeRegion(w, event)
- X Widget w;
- X XEvent *event;
- X{
- X TextWidget ctx = (TextWidget) w;
- X XtTextPosition pos1, pos2, resultend;
- X int line;
- X int x = event->xexpose.x;
- X int y = event->xexpose.y;
- X int width = event->xexpose.width;
- X int height = event->xexpose.height;
- X XtTextLineTableEntry *info;
- X
- X _XtTextPrepareToUpdate(ctx);
- X if (x < ctx->text.leftmargin) /* stomp on caret tracks */
- X (*ctx->text.sink->ClearToBackground)(ctx, x, y, width, height);
- X /* figure out starting line that was exposed */
- X line = LineForPosition(ctx, PositionForXY(ctx, x, y));
- X while (line < ctx->text.lt.lines && ctx->text.lt.info[line + 1].y < y)
- X line++;
- X while (line < ctx->text.lt.lines) {
- X info = &(ctx->text.lt.info[line]);
- X if (info->y >= y + height)
- X break;
- X (*ctx->text.sink->Resolve)(ctx,
- X info->position, info->x,
- X x - info->x, &pos1, &resultend);
- X (*ctx->text.sink->Resolve)(ctx,
- X info->position, info->x,
- X x + width - info->x, &pos2,
- X &resultend);
- X pos2 = (*ctx->text.source->Scan)(ctx->text.source, pos2, XtstPositions,
- X XtsdRight, 1, TRUE);
- X _XtTextNeedsUpdating(ctx, pos1, pos2);
- X line++;
- X }
- X _XtTextExecuteUpdate(ctx);
- X}
- X
- X/*
- X * This routine does all setup required to syncronize batched screen updates
- X*/
- Xint _XtTextPrepareToUpdate(ctx)
- X TextWidget ctx;
- X{
- X if (ctx->text.old_insert < 0) {
- X InsertCursor((Widget)ctx, XtisOff);
- X ctx->text.numranges = 0;
- X ctx->text.showposition = FALSE;
- X ctx->text.old_insert = ctx->text.insertPos;
- X }
- X}
- X
- X
- X/*
- X * This is a private utility routine used by _XtTextExecuteUpdate. It
- X * processes all the outstanding update requests and merges update
- X * ranges where possible.
- X*/
- Xstatic void FlushUpdate(ctx)
- X TextWidget ctx;
- X{
- X int i, w;
- X XtTextPosition updateFrom, updateTo;
- X if (!XtIsRealized((Widget)ctx)) {
- X ctx->text.numranges = 0;
- X return;
- X }
- X while (ctx->text.numranges > 0) {
- X updateFrom = ctx->text.updateFrom[0];
- X w = 0;
- X for (i=1 ; i<ctx->text.numranges ; i++) {
- X if (ctx->text.updateFrom[i] < updateFrom) {
- X updateFrom = ctx->text.updateFrom[i];
- X w = i;
- X }
- X }
- X updateTo = ctx->text.updateTo[w];
- X ctx->text.numranges--;
- X ctx->text.updateFrom[w] = ctx->text.updateFrom[ctx->text.numranges];
- X ctx->text.updateTo[w] = ctx->text.updateTo[ctx->text.numranges];
- X for (i=ctx->text.numranges-1 ; i>=0 ; i--) {
- X while (ctx->text.updateFrom[i] <= updateTo && i < ctx->text.numranges) {
- X updateTo = ctx->text.updateTo[i];
- X ctx->text.numranges--;
- X ctx->text.updateFrom[i] = ctx->text.updateFrom[ctx->text.numranges];
- X ctx->text.updateTo[i] = ctx->text.updateTo[ctx->text.numranges];
- X }
- X }
- X DisplayText((Widget)ctx, updateFrom, updateTo);
- X }
- X}
- X
- X
- X/*
- X * This is a private utility routine used by _XtTextExecuteUpdate. This routine
- X * worries about edits causing new data or the insertion point becoming
- X * invisible (off the screen). Currently it always makes it visible by
- X * scrolling. It probably needs generalization to allow more options.
- X*/
- X_XtTextShowPosition(ctx)
- X TextWidget ctx;
- X{
- X XtTextPosition top, first, second;
- X if (!XtIsRealized((Widget)ctx)) return;
- X if (ctx->text.insertPos < ctx->text.lt.top ||
- X ctx->text.insertPos >= ctx->text.lt.info[ctx->text.lt.lines].position) {
- X if (ctx->text.lt.lines > 0 && (ctx->text.insertPos < ctx->text.lt.top
- X || ctx->text.lt.info[ctx->text.lt.lines].position <= ctx->text.lastPos)) {
- X first = ctx->text.lt.top;
- X second = ctx->text.lt.info[1].position;
- X if (ctx->text.insertPos < first)
- X top = (*ctx->text.source->Scan)(
- X ctx->text.source, ctx->text.insertPos, XtstEOL,
- X XtsdLeft, 1, FALSE);
- X else
- X top = (*ctx->text.source->Scan)(
- X ctx->text.source, ctx->text.insertPos, XtstEOL,
- X XtsdLeft, ctx->text.lt.lines, FALSE);
- X BuildLineTable(ctx, top);
- X while (ctx->text.insertPos >= ctx->text.lt.info[ctx->text.lt.lines].position) {
- X if (ctx->text.lt.info[ctx->text.lt.lines].position > ctx->text.lastPos)
- X break;
- X BuildLineTable(ctx, ctx->text.lt.info[1].position);
- X }
- X if (ctx->text.lt.top == second) {
- X BuildLineTable(ctx, first);
- X _XtTextScroll(ctx, 1);
- X } else if (ctx->text.lt.info[1].position == first) {
- X BuildLineTable(ctx, first);
- X _XtTextScroll(ctx, -1);
- X } else {
- X ctx->text.numranges = 0;
- X if (ctx->text.lt.top != first)
- X DisplayTextWindow((Widget)ctx);
- X }
- X }
- X }
- X}
- X
- X
- X
- X/*
- X * This routine causes all batched screen updates to be performed
- X*/
- X_XtTextExecuteUpdate(ctx)
- X TextWidget ctx;
- X{
- X if (ctx->text.update_disabled) return;
- X
- X if (ctx->text.old_insert >= 0) {
- X if (ctx->text.old_insert != ctx->text.insertPos
- X || ctx->text.showposition)
- X _XtTextShowPosition(ctx);
- X FlushUpdate(ctx);
- X InsertCursor((Widget)ctx, XtisOn);
- X ctx->text.old_insert = -1;
- X }
- X}
- X
- X
- Xstatic void TextDestroy(w)
- X Widget w;
- X{
- X TextWidget ctx = (TextWidget)w;
- X register struct _dialog *dialog, *next;
- X
- X for (dialog = ctx->text.dialog; dialog; dialog = next) {
- X /* no need to destroy the widgets here; they should go automatically */
- X next = dialog->next;
- X XtFree( dialog );
- X }
- X if (ctx->text.outer)
- X (void) XtDestroyWidget(ctx->text.outer);
- X if (ctx->text.sbar)
- X (void) XtDestroyWidget(ctx->text.sbar);
- X XtFree((char *)ctx->text.updateFrom);
- X XtFree((char *)ctx->text.updateTo);
- X}
- X
- X
- X/* by the time we are managed (and get this far),
- X * we had better have both a source and a sink */
- Xstatic void Resize(w)
- X Widget w;
- X{
- X TextWidget ctx = (TextWidget) w;
- X
- X if (ctx->text.sbar) {
- X Widget sbar = ctx->text.sbar;
- X XtResizeWidget( sbar, sbar->core.width, ctx->core.height,
- X sbar->core.border_width );
- X }
- X _XtTextPrepareToUpdate(ctx);
- X ForceBuildLineTable(ctx);
- X _XtTextExecuteUpdate(ctx);
- X}
- X
- X
- X/*
- X * This routine allow the application program to Set attributes.
- X */
- X
- X/*ARGSUSED*/
- Xstatic Boolean SetValues(current, request, new)
- XWidget current, request, new;
- X{
- X TextWidget oldtw = (TextWidget) current;
- X TextWidget newtw = (TextWidget) new;
- X Boolean redisplay = FALSE;
- X
- X _XtTextPrepareToUpdate(newtw);
- X
- X if ((oldtw->text.options & scrollVertical)
- X != (newtw->text.options & scrollVertical)) {
- X newtw->text.leftmargin = newtw->text.client_leftmargin;
- X if (newtw->text.options & scrollVertical)
- X CreateScrollbar(newtw);
- X else {
- X XtDestroyWidget(oldtw->text.sbar);
- X newtw->text.sbar = NULL;
- X }
- X }
- X else if (oldtw->text.client_leftmargin != newtw->text.client_leftmargin) {
- X newtw->text.leftmargin = newtw->text.client_leftmargin;
- X if (newtw->text.options & scrollVertical) {
- X newtw->text.leftmargin +=
- X newtw->text.sbar->core.width +
- X newtw->text.sbar->core.border_width;
- X }
- X }
- X
- X if (oldtw->text.source != newtw->text.source ||
- X oldtw->text.sink != newtw->text.sink ||
- X oldtw->text.lt.top != newtw->text.lt.top ||
- X oldtw->text.leftmargin != newtw->text.leftmargin ||
- X ((oldtw->text.options & wordBreak)
- X != (newtw->text.options & wordBreak)))
- X {
- X ForceBuildLineTable(newtw);
- X SetScrollBar(newtw);
- X redisplay = TRUE;
- X }
- X
- X if (oldtw->text.insertPos != newtw->text.insertPos)
- X newtw->text.showposition = TRUE;
- X
- X if (XtIsRealized(newtw)
- X && ((oldtw->text.options & wordBreak)
- X != (newtw->text.options & wordBreak))) {
- X XSetWindowAttributes attributes;
- X Mask valueMask;
- X valueMask = CWBitGravity;
- X attributes.bit_gravity =
- X (newtw->text.options & wordBreak) ? ForgetGravity : NorthWestGravity;
- X XChangeWindowAttributes(XtDisplay(newtw), XtWindow(newtw),
- X valueMask, &attributes);
- X redisplay = TRUE;
- X }
- X
- X
- X if (!redisplay)
- X _XtTextExecuteUpdate(newtw);
- X
- X return redisplay;
- X}
- X
- X
- X
- Xvoid XtTextDisplay (w)
- X Widget w;
- X{
- X TextWidget ctx = (TextWidget) w;
- X
- X if (!XtIsRealized(w)) return;
- X
- X _XtTextPrepareToUpdate(ctx);
- X DisplayTextWindow(w);
- X _XtTextExecuteUpdate(ctx);
- X}
- X
- X/*******************************************************************
- XThe following routines provide procedural interfaces to Text window state
- Xsetting and getting. They need to be redone so than the args code can use
- Xthem. I suggest we create a complete set that takes the context as an
- Xargument and then have the public version lookup the context and call the
- Xinternal one. The major value of this set is that they have actual application
- Xclients and therefore the functionality provided is required for any future
- Xversion of Text.
- X********************************************************************/
- X
- Xvoid XtTextSetSelectionArray(w, sarray)
- X Widget w;
- X XtTextSelectType *sarray;
- X{
- X ((TextWidget)w)->text.sarray = sarray;
- X}
- X
- X#ifdef JON
- XXtTextPosition XtTextGetLastPos(w)
- X Widget w;
- X{
- X TextWidget ctx = (TextWidget) w;;
- X return GETLASTPOS;
- X}
- X#endif JON
- X
- Xvoid XtTextSetLastPos (w, lastPos)
- X Widget w;
- X XtTextPosition lastPos;
- X{
- X TextWidget ctx = (TextWidget) w;
- X
- X _XtTextPrepareToUpdate(ctx);
- X (*ctx->text.source->SetLastPos)(ctx->text.source, lastPos);
- X ctx->text.lastPos = GETLASTPOS;
- X ForceBuildLineTable(ctx);
- X if (XtIsRealized(w))
- X DisplayTextWindow(w);
- X _XtTextExecuteUpdate(ctx);
- X}
- X
- X
- Xvoid XtTextGetSelectionPos(w, left, right)
- X Widget w;
- X XtTextPosition *left, *right;
- X{
- X TextWidget ctx = (TextWidget) w;
- X *left = ctx->text.s.left;
- X *right = ctx->text.s.right;
- X}
- X
- X
- Xvoid XtTextSetSource(w, source, startPos)
- X Widget w;
- X XtTextSource source;
- X XtTextPosition startPos;
- X{
- X TextWidget ctx = (TextWidget) w;
- X
- X ctx->text.source = source;
- X ctx->text.lt.top = startPos;
- X ctx->text.s.left = ctx->text.s.right = 0;
- X ctx->text.insertPos = startPos;
- X ctx->text.lastPos = GETLASTPOS;
- X
- X ForceBuildLineTable(ctx);
- X if (XtIsRealized(w)) {
- X _XtTextPrepareToUpdate(ctx);
- X DisplayTextWindow(w);
- X _XtTextExecuteUpdate(ctx);
- X }
- X}
- X
- X/*
- X * This public routine deletes the text from startPos to endPos in a source and
- X * then inserts, at startPos, the text that was passed. As a side effect it
- X * "invalidates" that portion of the displayed text (if any), so that things
- X * will be repainted properly.
- X */
- Xint XtTextReplace(w, startPos, endPos, text)
- X Widget w;
- X XtTextPosition startPos, endPos;
- X XtTextBlock *text;
- X{
- X TextWidget ctx = (TextWidget) w;
- X int result;
- X
- X _XtTextPrepareToUpdate(ctx);
- X if (endPos > ctx->text.lastPos) endPos = ctx->text.lastPos;
- X if (startPos > ctx->text.lastPos) startPos = ctx->text.lastPos;
- X if ((result = ReplaceText(ctx, startPos, endPos, text)) == EditDone) {
- X if (ctx->text.insertPos >= endPos) {
- X int delta = text->length - (endPos - startPos);
- X XtTextScanDirection sd;
- X if (delta < 0) {
- X sd = XtsdLeft;
- X delta = -delta;
- X }
- X else
- X sd = XtsdRight;
- X
- X ctx->text.insertPos =
- X (*ctx->text.source->Scan)(ctx->text.source,
- X ctx->text.insertPos,
- X XtstPositions, sd,
- X delta, TRUE);
- X }
- X else if (ctx->text.insertPos > startPos)
- X ctx->text.insertPos =
- X (*ctx->text.source->Scan)(ctx->text.source, startPos,
- X XtstPositions, XtsdRight,
- X text->length, TRUE);
- X }
- X CheckResizeOrOverflow(ctx);
- X _XtTextExecuteUpdate(ctx);
- X
- X return result;
- X}
- X
- X
- XXtTextPosition XtTextTopPosition(w)
- X Widget w;
- X{
- X TextWidget ctx = (TextWidget) w;
- X
- X return ctx->text.lt.top;
- X}
- X
- X
- Xvoid XtTextSetInsertionPoint(w, position)
- X Widget w;
- X XtTextPosition position;
- X{
- X TextWidget ctx = (TextWidget) w;
- X
- X _XtTextPrepareToUpdate(ctx);
- X ctx->text.insertPos = (position > ctx->text.lastPos)
- X ? ctx->text.lastPos : position;
- X ctx->text.showposition = TRUE;
- X _XtTextExecuteUpdate(ctx);
- X}
- X
- X
- XXtTextPosition XtTextGetInsertionPoint(w)
- X Widget w;
- X{
- X TextWidget ctx = (TextWidget) w;
- X
- X return(ctx->text.insertPos);
- X}
- X
- X
- Xvoid XtTextUnsetSelection(w)
- X Widget w;
- X{
- X register TextWidget ctx = (TextWidget)w;
- X int i;
- X void (*nullProc)() = NULL;
- X
- X ctx->text.s.left = ctx->text.s.right = ctx->text.insertPos;
- X if (ctx->text.source->SetSelection != nullProc) {
- X (*ctx->text.source->SetSelection) (ctx->text.source, ctx->text.s.left,
- X ctx->text.s.right,
- X ctx->text.s.atom_count ?
- X ctx->text.s.selections[0] : NULL);
- X }
- X
- X for (i = ctx->text.s.atom_count; i;) {
- X Atom selection = ctx->text.s.selections[--i];
- X switch (selection) {
- 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: continue;
- X }
- X XtDisownSelection(w, selection);
- X LoseSelection(w, &selection); /* in case it wasn't just called */
- X }
- X}
- X
- X
- Xvoid XtTextChangeOptions(w, options)
- X Widget w;
- X int options;
- X{
- X TextWidget ctx = (TextWidget) w;
- X
- X ctx->text.options = options;
- X}
- X
- X
- Xint XtTextGetOptions(w)
- X Widget w;
- X{
- X TextWidget ctx = (TextWidget) w;
- X
- X return ctx->text.options;
- X}
- X
- Xvoid XtTextSetSelection (w, left, right)
- X Widget w;
- X XtTextPosition left, right;
- X{
- X TextWidget ctx = (TextWidget) w;
- X Atom selection = XA_PRIMARY;
- X
- X _XtTextPrepareToUpdate(ctx);
- X if (left == right)
- X XtTextUnsetSelection(w);
- X else
- X _XtTextSetNewSelection(ctx, left, right, &selection, ONE);
- X _XtTextExecuteUpdate(ctx);
- X}
- X
- Xvoid XtTextInvalidate(w, from, to)
- X Widget w;
- X XtTextPosition from,to;
- X{
- X TextWidget ctx = (TextWidget) w;
- X
- X ctx->text.lastPos = (*ctx->text.source->GetLastPos)(ctx->text.source);
- X _XtTextPrepareToUpdate(ctx);
- X _XtTextNeedsUpdating(ctx, from, to);
- X ForceBuildLineTable(ctx);
- X _XtTextExecuteUpdate(ctx);
- X}
- X
- X/*ARGSUSED*/
- Xvoid XtTextDisableRedisplay(w, d)
- X Widget w;
- X int d;
- X{
- X register TextWidget ctx = (TextWidget)w;
- X
- X ctx->text.update_disabled = True;
- X _XtTextPrepareToUpdate(ctx);
- X}
- X
- Xvoid XtTextEnableRedisplay(w)
- X Widget w;
- X{
- X register TextWidget ctx = (TextWidget)w;
- X register XtTextPosition lastPos;
- X
- X if (!ctx->text.update_disabled) return;
- X
- X ctx->text.update_disabled = False;
- X lastPos = ctx->text.lastPos = GETLASTPOS;
- X if (ctx->text.lt.top > lastPos) ctx->text.lt.top = ctx->text.lastPos;
- X if (ctx->text.insertPos > lastPos) ctx->text.insertPos = ctx->text.lastPos;
- X if (ctx->text.s.left > lastPos ||
- X ctx->text.s.right > lastPos) ctx->text.s.left = ctx->text.s.right = 0;
- X
- X ForceBuildLineTable(ctx);
- X if (XtIsRealized(w))
- X DisplayTextWindow(w);
- X _XtTextExecuteUpdate(ctx);
- X}
- X
- XXtTextSource XtTextGetSource(w)
- X Widget w;
- X{
- X return ((TextWidget)w)->text.source;
- X}
- X
- X
- END_OF_FILE
- if test 29444 -ne `wc -c <'xconf/Text.c.ab'`; then
- echo shar: \"'xconf/Text.c.ab'\" unpacked with wrong size!
- fi
- # end of 'xconf/Text.c.ab'
- fi
- echo shar: End of archive 2 \(of 5\).
- cp /dev/null ark2isdone
- 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
-