Annotation of 43BSDTahoe/new/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.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.