Annotation of researchv9/X11/src/X.V11R1/lib/oldXtk/AsciiSink.c, revision 1.1

1.1     ! root        1: /* $Header: AsciiSink.c,v 1.2 87/08/06 14:35:30 toddb Exp $ */
        !             2: #ifndef lint
        !             3: static char *sccsid = "@(#)AsciiSink.c 1.9     2/24/87";
        !             4: #endif lint
        !             5: 
        !             6: /*
        !             7:  * Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
        !             8:  * 
        !             9:  *                         All Rights Reserved
        !            10:  * 
        !            11:  * Permission to use, copy, modify, and distribute this software and its 
        !            12:  * documentation for any purpose and without fee is hereby granted, 
        !            13:  * provided that the above copyright notice appear in all copies and that
        !            14:  * both that copyright notice and this permission notice appear in 
        !            15:  * supporting documentation, and that the name of Digital Equipment
        !            16:  * Corporation not be used in advertising or publicity pertaining to
        !            17:  * distribution of the software without specific, written prior permission.  
        !            18:  * 
        !            19:  * 
        !            20:  * DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
        !            21:  * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
        !            22:  * DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
        !            23:  * ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
        !            24:  * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
        !            25:  * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
        !            26:  * SOFTWARE.
        !            27:  */
        !            28: 
        !            29: #include "Xlib.h"
        !            30: #include "Xatom.h"
        !            31: #include "Intrinsic.h"
        !            32: #include "Text.h"
        !            33: #include "TextDisp.h"
        !            34: 
        !            35: #define GETLASTPOS (*(source->scan))(source, 0, XtstFile, XtsdRight, 1, TRUE)
        !            36: /* Private Ascii TextSink Definitions */
        !            37: 
        !            38: static unsigned bufferSize = 200;
        !            39: 
        !            40: typedef struct _AsciiSinkData {
        !            41:     GC normgc, invgc, xorgc;
        !            42:     XFontStruct *font;
        !            43:     int tabwidth;
        !            44:     Pixmap insertCursorOn;
        !            45:     Pixmap insertCursorOff;
        !            46:     InsertState laststate;
        !            47: } AsciiSinkData;
        !            48: 
        !            49: static char *buf;
        !            50: 
        !            51: /* Utilities */
        !            52: 
        !            53: static int CharWidth (data, x, c)
        !            54:   AsciiSinkData *data;
        !            55:   int x;
        !            56:   char c;
        !            57: {
        !            58:     int     width, nonPrinting;
        !            59:     XFontStruct *font = data->font;
        !            60: 
        !            61:     if (c == '\t')
        !            62:         /* This is totally bogus!! need to know tab settings etc.. */
        !            63:        return data->tabwidth - (x % data->tabwidth);
        !            64:     if (c == LF)
        !            65:        c = SP;
        !            66:     nonPrinting = (c < SP);
        !            67:     if (nonPrinting) c += '@';
        !            68: 
        !            69:     if (font->per_char &&
        !            70:            (c >= font->min_char_or_byte2 && c <= font->max_char_or_byte2))
        !            71:        width = font->per_char[c - font->min_char_or_byte2].width;
        !            72:     else
        !            73:        width = font->min_bounds.width;
        !            74: 
        !            75:     if (nonPrinting)
        !            76:        width += CharWidth(data, x, '^');
        !            77: 
        !            78:     return width;
        !            79: }
        !            80: 
        !            81: /* Sink Object Functions */
        !            82: 
        !            83: #define LBEARING(x) \
        !            84:     ((font->per_char != NULL && \
        !            85:       ((x) >= font->min_char_or_byte2 && (x) <= font->max_char_or_byte2)) \
        !            86:        ? font->per_char[(x) - font->min_char_or_byte2].lbearing \
        !            87:        : font->min_bounds.lbearing)
        !            88: 
        !            89: static int AsciiDisplayText (sink, source, w, x, y, pos1, pos2, highlight)
        !            90:   XtTextSink *sink;
        !            91:   XtTextSource *source;
        !            92:   Window w;
        !            93:   Position x, y;
        !            94:   int highlight;
        !            95:   XtTextPosition pos1, pos2;
        !            96: {
        !            97:     AsciiSinkData *data = (AsciiSinkData *) sink->data ;
        !            98:     XFontStruct *font = data->font;
        !            99:     int     j, k;
        !           100:     Dimension width;
        !           101:     XtTextBlock blk;
        !           102:     GC gc = highlight ? data->invgc : data->normgc;
        !           103:     GC invgc = highlight ? data->normgc : data->invgc;
        !           104: 
        !           105:     y += font->ascent;
        !           106:     j = 0;
        !           107:     while (pos1 < pos2) {
        !           108:        pos1 = (*(source->read))(source, pos1, &blk, pos2 - pos1);
        !           109:        for (k = 0; k < blk.length; k++) {
        !           110:            if (j >= bufferSize - 5) {
        !           111:                bufferSize *= 2;
        !           112:                buf = XtRealloc(buf, bufferSize);
        !           113:            }
        !           114:            buf[j] = blk.ptr[k];
        !           115:            if (buf[j] == LF)
        !           116:                buf[j] = ' ';
        !           117:            else if (buf[j] == '\t') {
        !           118:                XDrawImageString(sink->dpy, w, gc, x - LBEARING(*buf), y, buf, j);
        !           119:                buf[j] = 0;
        !           120:                x += XTextWidth(data->font, buf, j);
        !           121:                width = CharWidth(data, x, '\t');
        !           122:                XFillRectangle(sink->dpy, w, invgc, x,
        !           123:                               y - font->ascent, width,
        !           124:                               (Dimension) (data->font->ascent +
        !           125:                                            data->font->descent));
        !           126:                x += width;
        !           127:                j = -1;
        !           128:            }
        !           129:            else
        !           130:                if (buf[j] < ' ') {
        !           131:                    buf[j + 1] = buf[j] + '@';
        !           132:                    buf[j] = '^';
        !           133:                    j++;
        !           134:                }
        !           135:            j++;
        !           136:        }
        !           137:     }
        !           138:     XDrawImageString(sink->dpy, w, gc, x - LBEARING(*buf), y, buf, j);
        !           139: }
        !           140: 
        !           141: 
        !           142: static Pixmap CreateInsertCursor(dpy, d, gc, state)
        !           143: Display *dpy;
        !           144: Drawable d;
        !           145: GC gc;
        !           146: InsertState state;
        !           147: {
        !           148:     XImage image;
        !           149:     Pixmap insertCursor;
        !           150: 
        !           151:     /* stuff for the text insertion cursor */
        !           152: 
        !           153: #   define insertCursor_width 6
        !           154: #   define insertCursor_height 3
        !           155: 
        !           156:     static short insertCursor_bits[] = {0x000c, 0x001e, 0x0033};
        !           157: /*    static short insertCursor_bits[] = {0xfff3, 0xffe1, 0xffcc}; */
        !           158:     static short blank_bits[] = {0x0000, 0x0000, 0x0000};
        !           159: 
        !           160:     image.height = insertCursor_height;
        !           161:     image.width = insertCursor_width;
        !           162:     image.xoffset = 0;
        !           163:     image.format = XYBitmap;
        !           164:     image.data = (char *) ((state == XtisOn) ? insertCursor_bits : blank_bits);
        !           165: /*    image.data = (char *) insertCursor_bits;*/
        !           166:     image.byte_order = LSBFirst;
        !           167:     image.bitmap_unit = 16;
        !           168:     image.bitmap_bit_order = LSBFirst;
        !           169:     image.bitmap_pad = 16;
        !           170:     image.depth = 1;
        !           171:     image.bytes_per_line = ((insertCursor_width+15) / 16) * 2;
        !           172:     image.bits_per_pixel = 1;
        !           173:     image.obdata = NULL;
        !           174:     insertCursor = XCreatePixmap(dpy, d, (Dimension) image.width,
        !           175:                                 (Dimension) image.height,
        !           176:                                 DefaultDepth(dpy, DefaultScreen(dpy)));
        !           177:     /* !!! BOGUS -- should otherwise figure out the depth; this code may not
        !           178:        work on multiple screen displays. ||| */
        !           179:     XPutImage(dpy, insertCursor, gc, &image, 0, 0, 0, 0,
        !           180:              (Dimension)image.width, (Dimension)image.height);
        !           181:     return insertCursor;
        !           182: }
        !           183: 
        !           184: /*
        !           185:  * The following procedure manages the "insert" cursor.
        !           186:  */
        !           187: 
        !           188: static AsciiInsertCursor (sink, w, x, y, state)
        !           189:   XtTextSink *sink;
        !           190:   Window w;
        !           191:   Position x, y;
        !           192:   InsertState state;
        !           193: {
        !           194:     AsciiSinkData *data = (AsciiSinkData *) sink->data;
        !           195: 
        !           196: /*
        !           197:     XCopyArea(sink->dpy,
        !           198:              (state == XtisOn) ? data->insertCursorOn : data->insertCursorOff, w,
        !           199:              data->normgc, 0, 0, insertCursor_width, insertCursor_height,
        !           200:              x - (insertCursor_width >> 1), y - (insertCursor_height));
        !           201: */
        !           202:     if (state != data->laststate)
        !           203:        XCopyArea(sink->dpy,
        !           204:                  data->insertCursorOn, w,
        !           205:                  data->xorgc, 0, 0, insertCursor_width, insertCursor_height,
        !           206:                  x - (insertCursor_width >> 1), y - (insertCursor_height));
        !           207:     data->laststate = state;
        !           208: }
        !           209: 
        !           210: /*
        !           211:  * Clear the passed region to the background color.
        !           212:  */
        !           213: 
        !           214: static AsciiClearToBackground (sink, w, x, y, width, height)
        !           215:   XtTextSink *sink;
        !           216:   Window w;
        !           217:   Position x, y;
        !           218:   Dimension width, height;
        !           219: {
        !           220:     AsciiSinkData *data = (AsciiSinkData *) sink->data;
        !           221:     XFillRectangle(sink->dpy, w, data->invgc, x, y, width, height);
        !           222: }
        !           223: 
        !           224: /*
        !           225:  * Given two positions, find the distance between them.
        !           226:  */
        !           227: 
        !           228: static AsciiFindDistance (sink, source, fromPos, fromx, toPos,
        !           229:                          resWidth, resPos, resHeight)
        !           230:   XtTextSink *sink;
        !           231:   XtTextSource *source;
        !           232:   XtTextPosition fromPos;      /* First position. */
        !           233:   int fromx;                   /* Horizontal location of first position. */
        !           234:   XtTextPosition toPos;                /* Second position. */
        !           235:   int *resWidth;               /* Distance between fromPos and resPos. */
        !           236:   int *resPos;                 /* Actual second position used. */
        !           237:   int *resHeight;              /* Height required. */
        !           238: {
        !           239:     AsciiSinkData *data;
        !           240:     register    XtTextPosition index, lastPos;
        !           241:     register char   c;
        !           242:     XtTextBlock blk;
        !           243: 
        !           244:     data = (AsciiSinkData *) sink->data;
        !           245:     /* we may not need this */
        !           246:     lastPos = GETLASTPOS;
        !           247:     (*(source->read))(source, fromPos, &blk, toPos - fromPos);
        !           248:     *resWidth = 0;
        !           249:     for (index = fromPos; index != toPos && index < lastPos; index++) {
        !           250:        if (index - blk.firstPos >= blk.length)
        !           251:            (*(source->read))(source, index, &blk, toPos - fromPos);
        !           252:        c = blk.ptr[index - blk.firstPos];
        !           253:        if (c == LF) {
        !           254:            *resWidth += CharWidth(data, fromx + *resWidth, SP);
        !           255:            index++;
        !           256:            break;
        !           257:        }
        !           258:        *resWidth += CharWidth(data, fromx + *resWidth, c);
        !           259:     }
        !           260:     *resPos = index;
        !           261:     *resHeight = data->font->ascent + data->font->descent;
        !           262: }
        !           263: 
        !           264: 
        !           265: static AsciiFindPosition(sink, source, fromPos, fromx, width, stopAtWordBreak, 
        !           266:                         resPos, resWidth, resHeight)
        !           267:   XtTextSink *sink;    
        !           268:   XtTextSource *source;
        !           269:   XtTextPosition fromPos;      /* Starting position. */
        !           270:   int fromx;                   /* Horizontal location of starting position. */
        !           271:   int width;                   /* Desired width. */
        !           272:   int stopAtWordBreak;         /* Whether the resulting position should be at
        !           273:                                   a word break. */
        !           274:   XtTextPosition *resPos;      /* Resulting position. */
        !           275:   int *resWidth;               /* Actual width used. */
        !           276:   int *resHeight;              /* Height required. */
        !           277: {
        !           278:     AsciiSinkData *data;
        !           279:     XtTextPosition lastPos, index, whiteSpacePosition;
        !           280:     int     lastWidth, whiteSpaceWidth;
        !           281:     Boolean whiteSpaceSeen;
        !           282:     char    c;
        !           283:     XtTextBlock blk;
        !           284:     data = (AsciiSinkData *) sink->data;
        !           285:     lastPos = GETLASTPOS;
        !           286:     (*(source->read))(source, fromPos, &blk, bufferSize);
        !           287:     *resWidth = 0;
        !           288:     whiteSpaceSeen = FALSE;
        !           289:     c = 0;
        !           290:     for (index = fromPos; *resWidth <= width && index < lastPos; index++) {
        !           291:        lastWidth = *resWidth;
        !           292:        if (index - blk.firstPos >= blk.length)
        !           293:            (*(source->read))(source, index, &blk, bufferSize);
        !           294:        c = blk.ptr[index - blk.firstPos];
        !           295:        if (c == LF) {
        !           296:            *resWidth += CharWidth(data, fromx + *resWidth, SP);
        !           297:            index++;
        !           298:            break;
        !           299:        }
        !           300:        *resWidth += CharWidth(data, fromx + *resWidth, c);
        !           301:        if ((c == SP || c == TAB) && *resWidth <= width) {
        !           302:            whiteSpaceSeen = TRUE;
        !           303:            whiteSpacePosition = index;
        !           304:            whiteSpaceWidth = *resWidth;
        !           305:        }
        !           306:     }
        !           307:     if (*resWidth > width && index > fromPos) {
        !           308:        *resWidth = lastWidth;
        !           309:        index--;
        !           310:        if (stopAtWordBreak && whiteSpaceSeen) {
        !           311:            index = whiteSpacePosition + 1;
        !           312:            *resWidth = whiteSpaceWidth;
        !           313:        }
        !           314:     }
        !           315:     if (index == lastPos && c != LF) index = lastPos + 1;
        !           316:     *resPos = index;
        !           317:     *resHeight = data->font->ascent + data->font->descent;
        !           318: }
        !           319: 
        !           320: 
        !           321: static int AsciiResolveToPosition (sink, source, pos, fromx, width,
        !           322:                                   leftPos, rightPos)
        !           323:   XtTextSink *sink;
        !           324:   XtTextSource *source;
        !           325:   XtTextPosition pos;
        !           326:   int fromx,width;
        !           327:   XtTextPosition *leftPos, *rightPos;
        !           328: {
        !           329:     int     resWidth, resHeight;
        !           330: 
        !           331:     AsciiFindPosition(sink, source, pos, fromx, width, FALSE,
        !           332:            leftPos, &resWidth, &resHeight);
        !           333:     if (*leftPos > GETLASTPOS)
        !           334:        *leftPos = GETLASTPOS;
        !           335:     *rightPos = *leftPos;
        !           336: }
        !           337: 
        !           338: 
        !           339: static int AsciiMaxLinesForHeight (sink, height)
        !           340:   XtTextSink *sink;
        !           341:   int height;
        !           342: {
        !           343:     AsciiSinkData *data;
        !           344: 
        !           345:     data = (AsciiSinkData *) sink->data;
        !           346:     return(height / (data->font->ascent + data->font->descent));
        !           347: }
        !           348: 
        !           349: 
        !           350: static int AsciiMaxHeightForLines (sink, lines)
        !           351:   XtTextSink *sink;
        !           352:   int lines;
        !           353: {
        !           354:     AsciiSinkData *data;
        !           355: 
        !           356:     data = (AsciiSinkData *) sink->data;
        !           357:     return(lines * (data->font->ascent + data->font->descent));
        !           358: }
        !           359: 
        !           360: 
        !           361: /* Public routines */
        !           362: 
        !           363: static Boolean initialized = FALSE;
        !           364: static XContext asciiSinkContext;
        !           365: 
        !           366: AsciiSinkInitialize()
        !           367: {
        !           368:     if (initialized)
        !           369:        return;
        !           370:     initialized = TRUE;
        !           371: 
        !           372:     asciiSinkContext = XUniqueContext();
        !           373: 
        !           374:     buf = (char *) XtMalloc(bufferSize);
        !           375: }
        !           376: 
        !           377: 
        !           378: caddr_t XtAsciiSinkCreate (dpy, font, ink, background)
        !           379:     Display *dpy;
        !           380:     XFontStruct *font;
        !           381:     int        ink, background;
        !           382: {
        !           383:     Window window;
        !           384:     XtTextSink *sink;
        !           385:     AsciiSinkData *data;
        !           386:     unsigned long valuemask = (GCFont | GCGraphicsExposures |
        !           387:                               GCForeground | GCBackground | GCFunction);
        !           388:     XGCValues values;
        !           389:     unsigned long w;
        !           390: 
        !           391:     if (!initialized)
        !           392:        AsciiSinkInitialize();
        !           393: 
        !           394:     window = RootWindow(dpy, DefaultScreen(dpy));
        !           395:     sink = (XtTextSink *) XtMalloc(sizeof(XtTextSink));
        !           396:     sink->dpy = dpy;
        !           397:     sink->display = AsciiDisplayText;
        !           398:     sink->insertCursor = AsciiInsertCursor;
        !           399:     sink->clearToBackground = AsciiClearToBackground;
        !           400:     sink->findPosition = AsciiFindPosition;
        !           401:     sink->findDistance = AsciiFindDistance;
        !           402:     sink->resolve = AsciiResolveToPosition;
        !           403:     sink->maxLines = AsciiMaxLinesForHeight;
        !           404:     sink->maxHeight = AsciiMaxHeightForLines;
        !           405:     sink->data = (int *) XtMalloc(sizeof(AsciiSinkData));
        !           406:     data = (AsciiSinkData *) sink->data;
        !           407:     values.function = GXcopy;
        !           408:     values.font = font->fid;
        !           409:     values.graphics_exposures = (Bool) FALSE;
        !           410:     values.foreground = ink;
        !           411:     values.background = background;
        !           412:     data->normgc = XtGetGC(
        !           413:        dpy, (XContext)asciiSinkContext, window, valuemask, &values);
        !           414:     values.foreground = background;
        !           415:     values.background = ink;
        !           416:     data->invgc = XtGetGC(
        !           417:        dpy, (XContext)asciiSinkContext, window, valuemask, &values);
        !           418:     values.function = GXxor;
        !           419:     values.foreground = ink ^ background;
        !           420:     values.background = 0;
        !           421:     data->xorgc = XtGetGC(
        !           422:        dpy, (XContext)asciiSinkContext, window, valuemask, &values);
        !           423: 
        !           424:     w = -1;
        !           425:     if ((!XGetFontProperty(font, XA_QUAD_WIDTH, &w)) || w <= 0) {
        !           426:        if (font->per_char && font->min_char_or_byte2 <= '0' &&
        !           427:                              font->max_char_or_byte2 >= '0')
        !           428:            w = font->per_char['0' - font->min_char_or_byte2].width;
        !           429:        else
        !           430:            w = font->max_bounds.width;
        !           431:     }
        !           432:     if (w <= 0) w = 1;
        !           433:     data->tabwidth = 8 * w;
        !           434:     data->font = font;
        !           435: /*    data->insertCursorOn = CreateInsertCursor(dpy, window, data->normgc, XtisOn);*/
        !           436: /*    data->insertCursorOff = CreateInsertCursor(dpy, window, data->normgc, XtisOff);*/
        !           437:     data->insertCursorOn = CreateInsertCursor(dpy, window, data->xorgc, XtisOn);
        !           438:     data->laststate = XtisOff;
        !           439:     return(caddr_t) sink;
        !           440: }
        !           441: 
        !           442: void XtAsciiSinkDestroy (sink)
        !           443:     XtTextSink *sink;
        !           444: {
        !           445:     AsciiSinkData *data;
        !           446: 
        !           447:     data = (AsciiSinkData *) sink->data;
        !           448:     XtFree((char *) data);
        !           449:     XtFree((char *) sink);
        !           450: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.