Annotation of 43BSD/contrib/X/Xlib/XlibInternal.c, revision 1.1.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.