Annotation of researchv9/X11/src/X.V11R1/lib/oldXtk/AsciiSink.c, revision 1.1.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.