Annotation of 43BSDTahoe/new/X/Xlib/XlibInternal.c, revision 1.1

1.1     ! root        1: #include <X/mit-copyright.h>
        !             2: 
        !             3: /* Copyright    Massachusetts Institute of Technology    1985  */
        !             4: 
        !             5: /*
        !             6:  *     XlibInternal.c - Internal support routines for the C subroutine
        !             7:  *     interface library (Xlib) to the X Window System Protocol V8.0.
        !             8:  */
        !             9: 
        !            10: #include "XlibInternal.h"
        !            11: #include <sys/uio.h>
        !            12: 
        !            13: /*
        !            14:  * The following routines are internal routines used by Xlib for protocol
        !            15:  * packet transmission and reception.
        !            16:  *
        !            17:  * XIOError(Display *) will be called if any sort of system call error occurs.
        !            18:  * This is assumed to be a fatal condition, i.e., XIOError should not return.
        !            19:  *
        !            20:  * XError(Display *, XErrorEvent *) will be called whenever an X_Error event is
        !            21:  * received.  This is not assumed to be a fatal condition, i.e., it is
        !            22:  * acceptable for this procedure to return.  However, XError should NOT
        !            23:  * perform any operations (directly or indirectly) on the DISPLAY.
        !            24:  *
        !            25:  * Routines declared with a return type of 'Status' return 0 on failure,
        !            26:  * and non 0 on success.  Routines with no declared return type don't 
        !            27:  * return anything.  Whenever possible routines that create objects return
        !            28:  * the object they have created.
        !            29:  */
        !            30: 
        !            31: #ifndef lint
        !            32: static char rcsid[] = "$Header: XlibInternal.c,v 10.13 86/04/22 15:30:52 jg Rel $";
        !            33: #endif
        !            34: 
        !            35: #ifdef titan
        !            36: #define iovbase iov_base.saddr
        !            37: #else
        !            38: #define iovbase iov_base
        !            39: #endif
        !            40: Display *_XlibCurrentDisplay = NULL;   /* default display to use in library */
        !            41: _QEvent *_qfree = NULL;                        /* NULL _QEvent. */
        !            42: 
        !            43: static int padlength[4] = {0, 3, 2, 1};
        !            44:     /* lookup table for adding padding bytes to data that is read from
        !            45:        or written to the X socket.  */
        !            46: 
        !            47: /*
        !            48:  * _XFlush - Flush the X request buffer.  If the buffer is empty, no
        !            49:  * action is taken.  This routine correctly handles incremental writes.
        !            50:  */
        !            51: _XFlush (dpy)
        !            52:        register Display *dpy;
        !            53: {
        !            54:        register int size;
        !            55:        register int write_stat;
        !            56:        register char *bufindex;
        !            57: 
        !            58:        size = dpy->bufptr - dpy->buffer;
        !            59:        bufindex = dpy->bufptr = dpy->buffer;
        !            60:        /*
        !            61:         * While write has not written the entire buffer, keep looping
        !            62:         * untill the entire buffer is written.  bufindex will be incremented
        !            63:         * and size decremented as buffer is written out.
        !            64:         */
        !            65:        while (size) {
        !            66:                if ((write_stat = write(dpy->fd, bufindex, size)) == -1) {
        !            67:                        /* Write failed! */
        !            68:                        /* errno set by write system call. */
        !            69:                        _XIOError(dpy);
        !            70:                }
        !            71:                size -= write_stat;
        !            72:                bufindex += write_stat;
        !            73:        }
        !            74:        dpy->lastdraw = NULL;
        !            75: }
        !            76: 
        !            77: 
        !            78: /* 
        !            79:  * _XRead - Read bytes from the socket taking into account incomplete
        !            80:  * reads.
        !            81:  */
        !            82: _XRead (dpy, data, size)
        !            83:        register Display *dpy;
        !            84:        register char *data;
        !            85:        register int size;
        !            86: {
        !            87:        register int bytes_read;
        !            88: 
        !            89:        while ((bytes_read = read(dpy->fd, data, size)) != size) {
        !            90: 
        !            91:                if (bytes_read > 0) {
        !            92:                    size -= bytes_read;
        !            93:                    data += bytes_read;
        !            94:                    }
        !            95: 
        !            96:                else if (bytes_read == 0) {
        !            97:                    /* Read failed because of end of file! */
        !            98:                    errno = EPIPE;
        !            99:                    _XIOError(dpy);
        !           100:                    }
        !           101: 
        !           102:                else  /* bytes_read is less than 0; presumably -1 */ {
        !           103:                    /* If it's a system call interrupt, it's not an error. */
        !           104:                    if (errno != EINTR)
        !           105:                        _XIOError(dpy);
        !           106:                    }
        !           107:                 }
        !           108: }
        !           109: 
        !           110: /*
        !           111:  * _XReadPad - Read bytes from the socket taking into account incomplete
        !           112:  * reads.  If the number of bytes is not 0 mod 32, read additional pad
        !           113:  * bytes.
        !           114:  */
        !           115: _XReadPad (dpy, data, size)
        !           116:        register Display *dpy;  
        !           117:        register char *data;
        !           118:        register int size;
        !           119: {
        !           120:        register int bytes_read;
        !           121:        struct iovec iov[2];
        !           122:        char pad[3];
        !           123: 
        !           124:        iov[0].iov_len = size;
        !           125:        iov[0].iovbase = data;
        !           126:        /* 
        !           127:         * The following hack is used to provide 32 bit long-word
        !           128:         * aligned padding.  The [1] vector is of length 0, 1, 2, or 3,
        !           129:         * whatever is needed.
        !           130:         */
        !           131: 
        !           132:        iov[1].iov_len = padlength[size & 3];
        !           133:        iov[1].iovbase = pad;
        !           134:        size += iov[1].iov_len;
        !           135: 
        !           136:        while ((bytes_read = readv (dpy->fd, iov, 2)) != size) {
        !           137: 
        !           138:            if (bytes_read > 0) {
        !           139:                size -= bytes_read;
        !           140:                if ((iov[0].iov_len -= bytes_read) < 0) {
        !           141:                    iov[1].iov_len += iov[0].iov_len;
        !           142:                    iov[1].iovbase -= iov[0].iov_len;
        !           143:                    iov[0].iov_len = 0;
        !           144:                    }
        !           145:                else
        !           146:                    iov[0].iovbase += bytes_read;
        !           147:                }
        !           148: 
        !           149:            else if (bytes_read == 0) {
        !           150:                /* Read failed because of end of file! */
        !           151:                errno = EPIPE;
        !           152:                _XIOError(dpy);
        !           153:                }
        !           154:            
        !           155:            else  /* bytes_read is less than 0; presumably -1 */ {
        !           156:                /* If it's a system call interrupt, it's not an error. */
        !           157:                if (errno != EINTR)
        !           158:                    _XIOError(dpy);
        !           159:                }
        !           160:            }
        !           161: 
        !           162: }
        !           163: 
        !           164: /*
        !           165:  * _XSend - Flush the buffer and send the client data. 32 bit word aligned
        !           166:  * transmission is used, if size is not 0 mod 4, extra bytes are transmitted.
        !           167:  */
        !           168: _XSend (dpy, data, size)
        !           169:        register Display *dpy;
        !           170:        char *data;
        !           171:        register int size;
        !           172: {
        !           173:        register int len;
        !           174:        struct iovec iov[3];
        !           175:        char pad[3];
        !           176: 
        !           177:        iov[0].iov_len = len = dpy->bufptr - dpy->buffer;
        !           178:        iov[0].iovbase = dpy->bufptr = dpy->buffer;
        !           179:        iov[1].iov_len = size;
        !           180:        iov[1].iovbase = data;
        !           181:        /* 
        !           182:         * The following hack is used to provide 32 bit long-word
        !           183:         * aligned padding.  The [2] vector is of length 0, 1, 2, or 3,
        !           184:         * whatever is needed.
        !           185:         */
        !           186:        iov[2].iov_len = padlength[size & 3];
        !           187:        iov[2].iovbase = pad;
        !           188:        len += (size + 3) & ~3;
        !           189:        /*
        !           190:         * Use while to allow for incremental writes.
        !           191:         */
        !           192:        while ((size = writev(dpy->fd, iov, 3)) != len) {
        !           193:                if (size < 0) _XIOError(dpy);
        !           194:                len -= size;
        !           195:                if ((iov[0].iov_len -= size) < 0) {
        !           196:                    iov[1].iov_len += iov[0].iov_len;
        !           197:                    iov[1].iovbase -= iov[0].iov_len;
        !           198:                    iov[0].iov_len = 0;
        !           199:                    if (iov[1].iov_len < 0) {
        !           200:                        iov[2].iov_len += iov[1].iov_len;
        !           201:                        iov[2].iovbase -= iov[1].iov_len;
        !           202:                        iov[1].iov_len = 0;
        !           203:                    }
        !           204:                }
        !           205:                else {
        !           206:                        iov[0].iovbase += size;
        !           207:                }
        !           208:        }
        !           209:        dpy->lastdraw = NULL;
        !           210: }
        !           211: 
        !           212: /*
        !           213:  * _XReply - Wait for a reply packet and copy its contents into the
        !           214:  * specified rep.  Mean while we must handle error and event packets that
        !           215:  * we may encounter.
        !           216:  */
        !           217: Status _XReply (dpy, rep)
        !           218:     register Display *dpy;
        !           219:     register XRep *rep;
        !           220: {
        !           221:     _XFlush(dpy);
        !           222:     while (1) {
        !           223:        _XRead(dpy, (char *)rep, sizeof(XRep));
        !           224:        switch ((int)rep->code) {
        !           225: 
        !           226:            case X_Reply:
        !           227:                /* Reply recieved. */
        !           228:                return(1);
        !           229:                 
        !           230:            case X_Error:
        !           231:                {
        !           232:                /* X_Error packet encountered! */
        !           233:                int current_request = dpy->request;
        !           234:                XErrorEvent *error = (XErrorEvent *) rep;
        !           235: 
        !           236:                if (error->serial == current_request)
        !           237:                        /* do not die on "no such font", "can't allocate",
        !           238:                           "can't grab" failures */
        !           239:                        switch (error->error_code) {
        !           240:                        case BadFont:
        !           241:                                if (error->request_code != X_GetFont)
        !           242:                                        break;
        !           243:                        case BadAlloc:
        !           244:                        case BadColor:
        !           245:                        case BadGrab:
        !           246:                                return (0);
        !           247:                        }
        !           248:                _XError(dpy, error);
        !           249:                if (error->serial == current_request)
        !           250:                    return(0);
        !           251:                }
        !           252:                break;
        !           253:            default:
        !           254:                _XEnq(dpy, (XEvent *) rep);
        !           255:                break;
        !           256:            }
        !           257:        }
        !           258: }   
        !           259: 
        !           260: 
        !           261: /*
        !           262:  * _XEnq - Place event packets on the display's queue.
        !           263:  */
        !           264: _XEnq (dpy, event)
        !           265:        register Display *dpy;
        !           266:        register XEvent *event;
        !           267: {
        !           268:        register _QEvent *qelt;
        !           269:        extern char *malloc();
        !           270: 
        !           271:        if (
        !           272:                /* If we are squishing MouseMoved events AND ... */
        !           273:                dpy->squish && 
        !           274:                /* the current event is a MouseMoved event AND ... */
        !           275:                (event->type == MouseMoved) &&
        !           276:                /* if there is a last event on the display queue AND ... */
        !           277:                (qelt = dpy->tail) && 
        !           278:                /* if that last event is also a MouseMoved event AND ... */
        !           279:                (qelt->event.type == MouseMoved) &&
        !           280:                /* it has the same event window as the current event ... */
        !           281:                (event->window == qelt->event.window)
        !           282:        ) {
        !           283:                /* then replace the last event with the current event! */
        !           284:                qelt->event = *event;
        !           285:                return;
        !           286:        }
        !           287:        if (qelt = _qfree) {
        !           288:                /* If _qfree is non-NULL do this, else malloc a new one. */
        !           289:                _qfree = qelt->next;
        !           290:        }
        !           291:        else if ((qelt = (_QEvent *) malloc((unsigned)sizeof(_QEvent))) == NULL) {
        !           292:                /* Malloc call failed! */
        !           293:                errno = ENOMEM;
        !           294:                _XIOError(dpy);
        !           295:        }
        !           296:        qelt->next = NULL;
        !           297:        qelt->event = *event;
        !           298:        if (dpy->tail) {
        !           299:                dpy->tail->next = qelt;
        !           300:        }
        !           301:        else {
        !           302:                dpy->head = qelt;
        !           303:        }
        !           304:        dpy->tail = qelt;
        !           305:        dpy->qlen++;
        !           306: }
        !           307: 
        !           308: 
        !           309: /*
        !           310:  * Undefine the routine pointers so we can define the following default
        !           311:  * routines.
        !           312:  */
        !           313: #undef _XError
        !           314: #undef _XIOError
        !           315: 
        !           316: 
        !           317: /*
        !           318:  * _XIOError - Default fatal system error reporting routine.  Called when
        !           319:  * an X internal system error is encountered.
        !           320:  */
        !           321: /*ARGSUSED*/
        !           322: _XIOError (dpy)
        !           323:        Display *dpy;
        !           324: {
        !           325:        perror("XIO");
        !           326:        exit(1);
        !           327: }
        !           328: 
        !           329: 
        !           330: /*
        !           331:  * _XError - Default non-fatal error reporting routine.  Called when an
        !           332:  * X_Error packet is encountered in the input stream.
        !           333:  */
        !           334: _XError (dpy, rep)
        !           335:     Display *dpy;
        !           336:     XErrorEvent *rep;
        !           337: {
        !           338:     fprintf(stderr, "X Error: %s\n", XErrDescrip (rep->error_code));
        !           339:     fprintf(stderr, "         Request code: %d\n", rep->request_code);
        !           340:     fprintf(stderr, "         Request function: %d\n", rep->func);
        !           341:     fprintf(stderr, "         Request window 0x%x\n", rep->window);
        !           342:     fprintf(stderr, "         Error Serial #%d\n", rep->serial);
        !           343:     fprintf(stderr, "         Current serial #%d\n", dpy->request);
        !           344:     exit(1);
        !           345: }
        !           346: 
        !           347: int (*_XIOErrorFunction)() = _XIOError;
        !           348: int (*_XErrorFunction)() = _XError;
        !           349: 
        !           350: #ifdef BIGSHORTS
        !           351: UnpackShorts(from, to, bytes)
        !           352:        ushort_p *from;
        !           353:        short *to;
        !           354:        unsigned bytes;
        !           355: {
        !           356:        unsigned i;
        !           357:        for (i = 0; i < (bytes/psizeof(short)); i++)
        !           358:                if (i&1)
        !           359:                        to[i] = from[i>>1].right;
        !           360:                else
        !           361:                        to[i] = from[i>>1].left;
        !           362: }
        !           363: 
        !           364: char packbuffer[1000];
        !           365: PackData(dpy, data, len)
        !           366:     register Display *dpy;
        !           367:     short *data;
        !           368:     unsigned len;
        !           369: {
        !           370:        if (dpy->bufptr + len < dpy->bufmax) {
        !           371:                PackShorts(data, dpy->bufptr, len);
        !           372:                dpy->bufptr += (len + 3) & ~3;
        !           373:        } else {
        !           374:                PackShorts(data, packbuffer, len);
        !           375:                _XSend(dpy, packbuffer, len);
        !           376:        }
        !           377: }
        !           378: 
        !           379: PackShorts(from, to, bytes)
        !           380:        short *from;
        !           381:        char *to;
        !           382:        unsigned bytes;
        !           383: {
        !           384:        unsigned i, n, offset;
        !           385:        ushort_p *uto;
        !           386: 
        !           387:        uto = (ushort_p *)to;
        !           388:        offset = ((int)to & 2) >> 1; /* lost 2 bits of pointer */
        !           389:        n = (bytes / 2) + offset;
        !           390:        for (i = offset; i < n; i++) {
        !           391:                if (i&1)
        !           392:                        uto[i>>1].right = from[i-offset];
        !           393:                else
        !           394:                        uto[i>>1].left = from[i-offset];
        !           395:        }
        !           396: }
        !           397: #endif

unix.superglobalmegacorp.com

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