Annotation of 43BSD/contrib/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.12 86/02/01 15:42:11 tony Rel $";
        !            33: #endif
        !            34: 
        !            35: Display *_XlibCurrentDisplay = NULL;   /* default display to use in library */
        !            36: _QEvent *_qfree = NULL;                        /* NULL _QEvent. */
        !            37: 
        !            38: static int padlength[4] = {0, 3, 2, 1};
        !            39:     /* lookup table for adding padding bytes to data that is read from
        !            40:        or written to the X socket.  */
        !            41: 
        !            42: /*
        !            43:  * _XFlush - Flush the X request buffer.  If the buffer is empty, no
        !            44:  * action is taken.  This routine correctly handles incremental writes.
        !            45:  */
        !            46: _XFlush (dpy)
        !            47:        register Display *dpy;
        !            48: {
        !            49:        register int size;
        !            50:        register int write_stat;
        !            51:        register char *bufindex;
        !            52: 
        !            53:        size = dpy->bufptr - dpy->buffer;
        !            54:        bufindex = dpy->bufptr = dpy->buffer;
        !            55:        /*
        !            56:         * While write has not written the entire buffer, keep looping
        !            57:         * untill the entire buffer is written.  bufindex will be incremented
        !            58:         * and size decremented as buffer is written out.
        !            59:         */
        !            60:        while (size) {
        !            61:                if ((write_stat = write(dpy->fd, bufindex, size)) == -1) {
        !            62:                        /* Write failed! */
        !            63:                        /* errno set by write system call. */
        !            64:                        _XIOError(dpy);
        !            65:                }
        !            66:                size -= write_stat;
        !            67:                bufindex += write_stat;
        !            68:        }
        !            69:        dpy->lastdraw = NULL;
        !            70: }
        !            71: 
        !            72: 
        !            73: /* 
        !            74:  * _XRead - Read bytes from the socket taking into account incomplete
        !            75:  * reads.
        !            76:  */
        !            77: _XRead (dpy, data, size)
        !            78:        register Display *dpy;
        !            79:        register char *data;
        !            80:        register int size;
        !            81: {
        !            82:        register int bytes_read;
        !            83: 
        !            84:        while ((bytes_read = read(dpy->fd, data, size)) != size) {
        !            85: 
        !            86:                if (bytes_read > 0) {
        !            87:                    size -= bytes_read;
        !            88:                    data += bytes_read;
        !            89:                    }
        !            90: 
        !            91:                else if (bytes_read == 0) {
        !            92:                    /* Read failed because of end of file! */
        !            93:                    errno = EPIPE;
        !            94:                    _XIOError(dpy);
        !            95:                    }
        !            96: 
        !            97:                else  /* bytes_read is less than 0; presumably -1 */ {
        !            98:                    /* If it's a system call interrupt, it's not an error. */
        !            99:                    if (errno != EINTR)
        !           100:                        _XIOError(dpy);
        !           101:                    }
        !           102:                 }
        !           103: }
        !           104: 
        !           105: /*
        !           106:  * _XReadPad - Read bytes from the socket taking into account incomplete
        !           107:  * reads.  If the number of bytes is not 0 mod 32, read additional pad
        !           108:  * bytes.
        !           109:  */
        !           110: _XReadPad (dpy, data, size)
        !           111:        register Display *dpy;  
        !           112:        register char *data;
        !           113:        register int size;
        !           114: {
        !           115:        register int bytes_read;
        !           116:        struct iovec iov[2];
        !           117:        char pad[3];
        !           118: 
        !           119:        iov[0].iov_len = size;
        !           120:        iov[0].iov_base = data;
        !           121:        /* 
        !           122:         * The following hack is used to provide 32 bit long-word
        !           123:         * aligned padding.  The [1] vector is of length 0, 1, 2, or 3,
        !           124:         * whatever is needed.
        !           125:         */
        !           126: 
        !           127:        iov[1].iov_len = padlength[size & 3];
        !           128:        iov[1].iov_base = pad;
        !           129:        size += iov[1].iov_len;
        !           130: 
        !           131:        while ((bytes_read = readv (dpy->fd, iov, 2)) != size) {
        !           132: 
        !           133:            if (bytes_read > 0) {
        !           134:                size -= bytes_read;
        !           135:                if ((iov[0].iov_len -= bytes_read) < 0) {
        !           136:                    iov[1].iov_len += iov[0].iov_len;
        !           137:                    iov[1].iov_base -= iov[0].iov_len;
        !           138:                    iov[0].iov_len = 0;
        !           139:                    }
        !           140:                else
        !           141:                    iov[0].iov_base += bytes_read;
        !           142:                }
        !           143: 
        !           144:            else if (bytes_read == 0) {
        !           145:                /* Read failed because of end of file! */
        !           146:                errno = EPIPE;
        !           147:                _XIOError(dpy);
        !           148:                }
        !           149:            
        !           150:            else  /* bytes_read is less than 0; presumably -1 */ {
        !           151:                /* If it's a system call interrupt, it's not an error. */
        !           152:                if (errno != EINTR)
        !           153:                    _XIOError(dpy);
        !           154:                }
        !           155:            }
        !           156: 
        !           157: }
        !           158: 
        !           159: /*
        !           160:  * _XSend - Flush the buffer and send the client data. 32 bit word aligned
        !           161:  * transmission is used, if size is not 0 mod 4, extra bytes are transmitted.
        !           162:  */
        !           163: _XSend (dpy, data, size)
        !           164:        register Display *dpy;
        !           165:        char *data;
        !           166:        register int size;
        !           167: {
        !           168:        register int len;
        !           169:        struct iovec iov[3];
        !           170:        char pad[3];
        !           171: 
        !           172:        iov[0].iov_len = len = dpy->bufptr - dpy->buffer;
        !           173:        iov[0].iov_base = dpy->bufptr = dpy->buffer;
        !           174:        iov[1].iov_len = size;
        !           175:        iov[1].iov_base = data;
        !           176:        /* 
        !           177:         * The following hack is used to provide 32 bit long-word
        !           178:         * aligned padding.  The [2] vector is of length 0, 1, 2, or 3,
        !           179:         * whatever is needed.
        !           180:         */
        !           181:        iov[2].iov_len = padlength[size & 3];
        !           182:        iov[2].iov_base = pad;
        !           183:        len += (size + 3) & ~3;
        !           184:        /*
        !           185:         * Use while to allow for incremental writes.
        !           186:         */
        !           187:        while ((size = writev(dpy->fd, iov, 3)) != len) {
        !           188:                if (size < 0) _XIOError(dpy);
        !           189:                len -= size;
        !           190:                if ((iov[0].iov_len -= size) < 0) {
        !           191:                    iov[1].iov_len += iov[0].iov_len;
        !           192:                    iov[1].iov_base -= iov[0].iov_len;
        !           193:                    iov[0].iov_len = 0;
        !           194:                    if (iov[1].iov_len < 0) {
        !           195:                        iov[2].iov_len += iov[1].iov_len;
        !           196:                        iov[2].iov_base -= iov[1].iov_len;
        !           197:                        iov[1].iov_len = 0;
        !           198:                    }
        !           199:                }
        !           200:                else {
        !           201:                        iov[0].iov_base += size;
        !           202:                }
        !           203:        }
        !           204:        dpy->lastdraw = NULL;
        !           205: }
        !           206: 
        !           207: /*
        !           208:  * _XReply - Wait for a reply packet and copy its contents into the
        !           209:  * specified rep.  Mean while we must handle error and event packets that
        !           210:  * we may encounter.
        !           211:  */
        !           212: Status _XReply (dpy, rep)
        !           213:     register Display *dpy;
        !           214:     register XRep *rep;
        !           215: {
        !           216:     _XFlush(dpy);
        !           217:     while (1) {
        !           218:        _XRead(dpy, (char *)rep, sizeof(XRep));
        !           219:        switch ((int)rep->code) {
        !           220: 
        !           221:            case X_Reply:
        !           222:                /* Reply recieved. */
        !           223:                return(1);
        !           224:                 
        !           225:            case X_Error:
        !           226:                {
        !           227:                /* X_Error packet encountered! */
        !           228:                int current_request = dpy->request;
        !           229:                XErrorEvent *error = (XErrorEvent *) rep;
        !           230: 
        !           231:                if (error->serial == current_request)
        !           232:                        /* do not die on "no such font", "can't allocate",
        !           233:                           "can't grab" failures */
        !           234:                        switch (error->error_code) {
        !           235:                        case BadFont:
        !           236:                                if (error->request_code != X_GetFont)
        !           237:                                        break;
        !           238:                        case BadAlloc:
        !           239:                        case BadColor:
        !           240:                        case BadGrab:
        !           241:                                return (0);
        !           242:                        }
        !           243:                _XError(dpy, error);
        !           244:                if (error->serial == current_request)
        !           245:                    return(0);
        !           246:                }
        !           247:                break;
        !           248:            default:
        !           249:                _XEnq(dpy, (XEvent *) rep);
        !           250:                break;
        !           251:            }
        !           252:        }
        !           253: }   
        !           254: 
        !           255: 
        !           256: /*
        !           257:  * _XEnq - Place event packets on the display's queue.
        !           258:  */
        !           259: _XEnq (dpy, event)
        !           260:        register Display *dpy;
        !           261:        register XEvent *event;
        !           262: {
        !           263:        register _QEvent *qelt;
        !           264:        extern char *malloc();
        !           265: 
        !           266:        if (
        !           267:                /* If we are squishing MouseMoved events AND ... */
        !           268:                dpy->squish && 
        !           269:                /* the current event is a MouseMoved event AND ... */
        !           270:                (event->type == MouseMoved) &&
        !           271:                /* if there is a last event on the display queue AND ... */
        !           272:                (qelt = dpy->tail) && 
        !           273:                /* if that last event is also a MouseMoved event AND ... */
        !           274:                (qelt->event.type == MouseMoved) &&
        !           275:                /* it has the same event window as the current event ... */
        !           276:                (event->window == qelt->event.window)
        !           277:        ) {
        !           278:                /* then replace the last event with the current event! */
        !           279:                qelt->event = *event;
        !           280:                return;
        !           281:        }
        !           282:        if (qelt = _qfree) {
        !           283:                /* If _qfree is non-NULL do this, else malloc a new one. */
        !           284:                _qfree = qelt->next;
        !           285:        }
        !           286:        else if ((qelt = (_QEvent *) malloc((unsigned)sizeof(_QEvent))) == NULL) {
        !           287:                /* Malloc call failed! */
        !           288:                errno = ENOMEM;
        !           289:                _XIOError(dpy);
        !           290:        }
        !           291:        qelt->next = NULL;
        !           292:        qelt->event = *event;
        !           293:        if (dpy->tail) {
        !           294:                dpy->tail->next = qelt;
        !           295:        }
        !           296:        else {
        !           297:                dpy->head = qelt;
        !           298:        }
        !           299:        dpy->tail = qelt;
        !           300:        dpy->qlen++;
        !           301: }
        !           302: 
        !           303: 
        !           304: /*
        !           305:  * Undefine the routine pointers so we can define the following default
        !           306:  * routines.
        !           307:  */
        !           308: #undef _XError
        !           309: #undef _XIOError
        !           310: 
        !           311: 
        !           312: /*
        !           313:  * _XIOError - Default fatal system error reporting routine.  Called when
        !           314:  * an X internal system error is encountered.
        !           315:  */
        !           316: /*ARGSUSED*/
        !           317: _XIOError (dpy)
        !           318:        Display *dpy;
        !           319: {
        !           320:        perror("XIO");
        !           321:        exit(1);
        !           322: }
        !           323: 
        !           324: 
        !           325: /*
        !           326:  * _XError - Default non-fatal error reporting routine.  Called when an
        !           327:  * X_Error packet is encountered in the input stream.
        !           328:  */
        !           329: _XError (dpy, rep)
        !           330:     Display *dpy;
        !           331:     XErrorEvent *rep;
        !           332: {
        !           333:     fprintf(stderr, "X Error: %s\n", XErrDescrip (rep->error_code));
        !           334:     fprintf(stderr, "         Request code: %d\n", rep->request_code);
        !           335:     fprintf(stderr, "         Request function: %d\n", rep->func);
        !           336:     fprintf(stderr, "         Request window 0x%x\n", rep->window);
        !           337:     fprintf(stderr, "         Error Serial #%d\n", rep->serial);
        !           338:     fprintf(stderr, "         Current serial #%d\n", dpy->request);
        !           339:     exit(1);
        !           340: }
        !           341: 
        !           342: int (*_XIOErrorFunction)() = _XIOError;
        !           343: int (*_XErrorFunction)() = _XError;

unix.superglobalmegacorp.com

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