Annotation of 43BSDReno/contrib/isode-beta/others/X/client/XlibInt.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  * $XConsortium: XlibInt.c,v 11.90 88/09/30 17:25:18 jim Exp $
                      3:  */
                      4: 
                      5: #include "copyright.h"
                      6: /* Copyright    Massachusetts Institute of Technology    1985, 1986, 1987 */
                      7: 
                      8: /*
                      9:  *     XlibInternal.c - Internal support routines for the C subroutine
                     10:  *     interface library (Xlib) to the X Window System Protocol V11.0.
                     11:  */
                     12: #define NEED_EVENTS
                     13: #define NEED_REPLIES
                     14: 
                     15: #include <stdio.h>
                     16: #include "Xlibint.h"
                     17: 
                     18: #ifdef ISOCONN
                     19: #include <isode/psap.h>
                     20: #include <isode/tsap.h>
                     21: #include <isode/isoservent.h>
                     22: 
                     23: #endif /* ISOCONN */
                     24: 
                     25: #ifdef CRAY
                     26: 
                     27: /*
                     28:  * Cray UniCOS does not have readv and writev so we emulate
                     29:  */
                     30: #include <sys/socket.h>
                     31: 
                     32: static int readv (fd, iov, iovcnt)
                     33: int fd;
                     34: struct iovec *iov;
                     35: int iovcnt;
                     36: {
                     37:        struct msghdr hdr;
                     38: 
                     39:        hdr.msg_iov = iov;
                     40:        hdr.msg_iovlen = iovcnt;
                     41:        hdr.msg_accrights = 0;
                     42:        hdr.msg_accrightslen = 0;
                     43:        hdr.msg_name = 0;
                     44:        hdr.msg_namelen = 0;
                     45: 
                     46:        return (recvmsg (fd, &hdr, 0));
                     47: }
                     48: 
                     49: static int writev (fd, iov, iovcnt)
                     50: int fd;
                     51: struct iovec *iov;
                     52: int iovcnt;
                     53: {
                     54:        struct msghdr hdr;
                     55: 
                     56:        hdr.msg_iov = iov;
                     57:        hdr.msg_iovlen = iovcnt;
                     58:        hdr.msg_accrights = 0;
                     59:        hdr.msg_accrightslen = 0;
                     60:        hdr.msg_name = 0;
                     61:        hdr.msg_namelen = 0;
                     62: 
                     63:        return (sendmsg (fd, &hdr, 0));
                     64: }
                     65: 
                     66: #endif /* CRAY */
                     67: 
                     68: #ifdef ISOCONN
                     69: /*
                     70:  * Need these Convenience routines to map IO to T-service 
                     71:  * XXX
                     72:  * Should map error returns in td->td_reason into
                     73:  * errno's appropriately...
                     74:  */
                     75: 
                     76: /*
                     77:  * Check if any bytes queued that could be read...
                     78:  */
                     79: TBytesReadable(fd, ptr)
                     80: int fd;
                     81: long *ptr;
                     82: {
                     83:        struct TSAPdisconnect tds;
                     84:         struct TSAPdisconnect *td = &tds;
                     85:        int ret = TSelectOctets (fd, ptr, td);
                     86:        if (ret == NOTOK) {
                     87:                    fprintf(stderr, "Client TBytesReadable: %s\n", 
                     88:                        TErrString(td->td_reason));
                     89:        }
                     90:        return ret;
                     91: }
                     92: 
                     93: /*
                     94:  * need followinf for arg mismatch
                     95:  */
                     96: UBytesReadable(fd, ptr)
                     97: int fd;
                     98: long *ptr;
                     99: {
                    100:        return ioctl(fd, FIONREAD, ptr);
                    101: }
                    102: 
                    103: /* 
                    104:  * Simple read from transport cx, client
                    105:  */
                    106: TReadFromServer(fd, data, size)
                    107: int fd;
                    108: unsigned size;
                    109: char *data;
                    110: {
                    111:        char *aptr = data;
                    112:        struct TSAPdisconnect tds;
                    113:        struct TSAPdisconnect *td = &tds;
                    114: static struct TSAPdata txs;
                    115: static struct TSAPdata *tx = &txs;
                    116: static struct qbuf *qb;
                    117: static char *qptr;
                    118: static int ingot, qcpy, result = 0;
                    119:        int q2data, ret;
                    120: 
                    121: #ifdef ISODEBUG
                    122:        if (isodexbug) {
                    123:                fprintf(stderr, "TReadFromServer %d want %d (%d buffered)\n", 
                    124:                        fd, size, result);
                    125:        }
                    126: #endif /* ISODEBUG */
                    127:        if (result == 0) {
                    128:                if ((ret = TReadRequest(fd, tx, OK, td)) == NOTOK) {
                    129: #ifdef ISODEBUG
                    130:                    if (errno == EWOULDBLOCK) {
                    131:                        fprintf(stderr, "Client TReadReq would block: %s\n", 
                    132:                                TErrString(td->td_reason));
                    133:                        if (!DR_FATAL(td->td_reason))
                    134:                                errno = EWOULDBLOCK;
                    135:                        else
                    136:                                errno = EBADF;
                    137:                        return ret;
                    138:                    }
                    139:                    if (isodexbug)
                    140:                            fprintf(stderr, "Client TReadReq: %s\n", 
                    141:                                TErrString(td->td_reason));
                    142: #endif /* ISODEBUG */
                    143: /*
                    144:  * map problems here - eg fTimeOut...
                    145:  */
                    146:                    if (td->td_reason == DR_TIMER)
                    147:                        errno = EWOULDBLOCK;
                    148:                    return ret;
                    149:                }
                    150:                result = tx->tx_cc;
                    151:                qb = &(tx->tx_qbuf);
                    152:                qptr = qb->qb_data;
                    153: #ifdef ISODEBUG
                    154:                if (isodexbug)
                    155:                        fprintf(stderr, "TReadRequest want %d got %d\n", 
                    156:                                size, result);
                    157: #endif
                    158:        } 
                    159: #ifdef ISODEBUG
                    160:        else {
                    161:                if (isodexbug)
                    162:                        fprintf(stderr, "TReadFromServer want %d buffered %d\n",
                    163:                                 size, result);
                    164:        }
                    165: #endif
                    166: /*
                    167:  * Buffer it
                    168:  */
                    169:         ingot = 0;
                    170:         aptr = data;
                    171:        for(ingot = 0, aptr = data, q2data = min(size, result); 
                    172:                ingot<q2data;
                    173:                aptr += qcpy, ingot+= qcpy) {
                    174:            int aleft = q2data - ingot;
                    175:            if (qb->qb_len > aleft) {
                    176:                    qcpy = aleft;
                    177:                    bcopy(qptr, aptr, qcpy);
                    178:                    qptr += aleft;
                    179:            } else {
                    180:                    qcpy = qb->qb_len;
                    181:                    bcopy(qb->qb_data, aptr, qcpy);
                    182:                    if ((qb = qb->qb_forw) == NULL)
                    183:                        break;
                    184:                    qptr = qb->qb_data;
                    185:            }
                    186:         }
                    187:        if ((result -= ingot) <= 0) {
                    188:                result = 0;
                    189:                TXFREE(tx);
                    190:        }
                    191:        return ingot;
                    192: 
                    193: }
                    194: 
                    195: /*
                    196:  * Simple write on transport descriptor client
                    197:  */
                    198: TWriteToServer(fd, data, size)
                    199: int fd;
                    200: unsigned size;
                    201: char *data;
                    202: {
                    203:        struct TSAPdisconnect tds;
                    204:         struct TSAPdisconnect *td = &tds;
                    205: 
                    206: #ifdef ISODEBUG
                    207:        if (isodexbug)
                    208:                fprintf(stderr, "TWriteToServer %d: %d\n", fd, size);
                    209: #endif
                    210:        if (TDataRequest(fd, data, size, td) == NOTOK) {
                    211:                if (errno != EWOULDBLOCK)
                    212:                        fprintf(stderr, "Client TDataReq: %s\n", 
                    213:                                TErrString(td->td_reason));
                    214:                return -1;
                    215:        } else
                    216:                return size;
                    217: }
                    218: 
                    219: /*
                    220:  * This is really disgusting, as we do 2 copies - one qbuf into data,
                    221:  * one data into iovecs...should really do something utterly neater or
                    222:  * ask mtr to provide another T-Service interface for pre-alloced
                    223:  * bufs - ideally iovec style
                    224:  *
                    225:  * or change the structure of X to do async...
                    226:  */
                    227: TReadvFromServer(fd, iov, iovcnt)
                    228: int fd, iovcnt;
                    229: struct iovec *iov;
                    230: {
                    231:        int i, size, result, left, bcp; 
                    232:        char *data, *dp;
                    233:        struct iovec *iovp;
                    234: 
                    235:        for(i=0, size = 0, iovp = iov; i < iovcnt; i++, iovp++)
                    236:                size += iovp->iov_len;
                    237: 
                    238: #ifdef ISODEBUG
                    239:        if (isodexbug)
                    240:                fprintf(stderr, "TReadvFromServer %d, want %d\n", fd, size);
                    241: #endif
                    242:        if ((data = Xmalloc(size)) == NULL) {
                    243: #ifdef ISODEBUG
                    244:            if (isodexbug)
                    245:                    fprintf(stderr, "TReadvFromServer, malloc failed\n");
                    246: #endif
                    247: /*
                    248:  * Could map to EWOULDBLOCK...?
                    249:  */
                    250:            return(-1);
                    251:        }
                    252: 
                    253: /*
                    254:  * Note, TReadFromServer is written to *NOT* return more than size
                    255:  */
                    256:        if ((result = TReadFromServer(fd, data, size)) == NOTOK) {
                    257:            if (errno != EWOULDBLOCK)
                    258:                    fprintf(stderr, "TReadvReq err\n");
                    259:            return(-1);
                    260:        }
                    261: 
                    262:        left = result;
                    263:        dp = data;
                    264:        while (left > 0) {
                    265:            bcp = iov->iov_len;
                    266:            if (bcp > left )
                    267:                bcp = left;
                    268:            bcopy(dp, iov->iov_base, bcp);
                    269:            if (bcp < left)
                    270:                iov++;
                    271:            dp += bcp;
                    272:            left -= bcp;
                    273:        }
                    274:        Xfree(data);
                    275:        return result;
                    276: }
                    277: 
                    278: /*
                    279:  * scatter gather write to transport descriptor
                    280:  */
                    281: TWritevToServer(fd, iov, iovcnt)
                    282: int fd, iovcnt;
                    283: struct iovec *iov;
                    284: {
                    285:        struct TSAPdisconnect tds;
                    286:        struct TSAPdisconnect *td = &tds;
                    287:        struct udvec uv[64], *uvp;
                    288:        int i, ret, tot = 0;
                    289: 
                    290: /*
                    291:  * Yuck needs dynamicising, or else rely on
                    292:  * iov's being same as uv's
                    293:  */
                    294:        if (iovcnt >= 64) {
                    295:                fprintf(stderr, "Very Bad News i am afraid\n");
                    296:                return -99;
                    297:        }
                    298:        for (i=0, uvp = uv; i<iovcnt; uvp++, iov++, i++) {
                    299:                uvp->uv_base = iov->iov_base;
                    300:                uvp->uv_len = iov->iov_len;
                    301:                tot += uvp->uv_len;
                    302:        }
                    303: #ifdef ISODEBUG
                    304:        if (isodexbug)
                    305:                fprintf(stderr, "TWritevToServer %d: %d\n",fd, tot);
                    306: #endif
                    307:        uv[iovcnt].uv_base = NULLCP;
                    308:        uv[iovcnt].uv_len = 0;
                    309:        if ((ret = TWriteRequest(fd, uv, td)) == NOTOK) {
                    310:            if (errno != EWOULDBLOCK)
                    311:                    fprintf(stderr, "Client TReadReq: %s\n", TErrString(td->td_reason));
                    312:            return -1;  
                    313:        }
                    314:        return tot;
                    315: }
                    316: 
                    317: TDiscFromServer(fd)
                    318: int fd;
                    319: {
                    320:        struct TSAPdisconnect tds;
                    321:         struct TSAPdisconnect *td = &tds;
                    322: 
                    323:         if (TDiscRequest(fd, NULLCP, 0, td) == NOTOK)
                    324:                 fprintf(stderr, "TDR failed %s\n", TErrString(td->td_reason));
                    325: }
                    326: 
                    327: #endif /* ISOCONN */
                    328: 
                    329: /*
                    330:  * The following routines are internal routines used by Xlib for protocol
                    331:  * packet transmission and reception.
                    332:  *
                    333:  * XIOError(Display *) will be called if any sort of system call error occurs.
                    334:  * This is assumed to be a fatal condition, i.e., XIOError should not return.
                    335:  *
                    336:  * XError(Display *, XErrorEvent *) will be called whenever an X_Error event is
                    337:  * received.  This is not assumed to be a fatal condition, i.e., it is
                    338:  * acceptable for this procedure to return.  However, XError should NOT
                    339:  * perform any operations (directly or indirectly) on the DISPLAY.
                    340:  *
                    341:  * Routines declared with a return type of 'Status' return 0 on failure,
                    342:  * and non 0 on success.  Routines with no declared return type don't 
                    343:  * return anything.  Whenever possible routines that create objects return
                    344:  * the object they have created.
                    345:  */
                    346: 
                    347: _XQEvent *_qfree = NULL;                       /* NULL _XQEvent. */
                    348: 
                    349: static int padlength[4] = {0, 3, 2, 1};
                    350:     /* lookup table for adding padding bytes to data that is read from
                    351:        or written to the X socket.  */
                    352: 
                    353: static xReq _dummy_request = {
                    354:        0, 0, 0
                    355: };
                    356: /*
                    357:  * _XFlush - Flush the X request buffer.  If the buffer is empty, no
                    358:  * action is taken.  This routine correctly handles incremental writes.
                    359:  * This routine may have to be reworked if int < long.
                    360:  */
                    361: _XFlush (dpy)
                    362:        register Display *dpy;
                    363: {
                    364:        register long size, todo;
                    365:        register int write_stat;
                    366:        register char *bufindex;
                    367: 
                    368:        size = todo = dpy->bufptr - dpy->buffer;
                    369:        bufindex = dpy->bufptr = dpy->buffer;
                    370:        /*
                    371:         * While write has not written the entire buffer, keep looping
                    372:         * until the entire buffer is written.  bufindex will be incremented
                    373:         * and size decremented as buffer is written out.
                    374:         */
                    375:        while (size) {
                    376:            errno = 0;
                    377:            write_stat = WriteToServer(dpy->fd, bufindex, (int) todo);
                    378:            if (write_stat >= 0) {
                    379:                size -= write_stat;
                    380:                todo = size;
                    381:                bufindex += write_stat;
                    382: #ifdef EWOULDBLOCK
                    383:            } else if (errno == EWOULDBLOCK) {
                    384:                _XWaitForWritable(dpy);
                    385: #endif
                    386: #ifdef SUNSYSV
                    387:            } else if (errno == 0) {
                    388:                _XWaitForWritable(dpy);
                    389: #endif
                    390: #ifdef EMSGSIZE
                    391:            } else if (errno == EMSGSIZE) {
                    392:                todo >>= 1;
                    393: #endif
                    394:            } else {
                    395:                /* Write failed! */
                    396:                /* errno set by write system call. */
                    397:                (*_XIOErrorFunction)(dpy);
                    398:            }
                    399:        }
                    400:        dpy->last_req = (char *)&_dummy_request;
                    401: }
                    402: 
                    403: int
                    404: _XEventsQueued (dpy, mode)
                    405:     register Display *dpy;
                    406:     int mode;
                    407: {
                    408:        register int len;
                    409:        int pend;
                    410:        char buf[BUFSIZE];
                    411:        register xReply *rep;
                    412:        
                    413:        if (mode == QueuedAfterFlush)
                    414:            _XFlush(dpy);
                    415:        if (BytesReadable(dpy->fd, (char *) &pend) < 0)
                    416:            (*_XIOErrorFunction)(dpy);
                    417:        if ((len = pend) < SIZEOF(xReply))
                    418:            return(dpy->qlen);  /* _XFlush can enqueue events */
                    419:        else if (len > BUFSIZE)
                    420:            len = BUFSIZE;
                    421:        len /= SIZEOF(xReply);
                    422:        pend = len * SIZEOF(xReply);
                    423:        _XRead (dpy, buf, (long) pend);
                    424: 
                    425:        /* no space between comma and type or else macro will die */
                    426:        STARTITERATE (rep,xReply, buf, (len > 0), len--) {
                    427:            if (rep->generic.type == X_Error)
                    428:                _XError(dpy, (xError *)rep);
                    429:            else   /* must be an event packet */
                    430:                _XEnq(dpy, (xEvent *) rep);
                    431:        }
                    432:        ENDITERATE
                    433:        return(dpy->qlen);
                    434: }
                    435: 
                    436: /* _XReadEvents - Flush the output queue,
                    437:  * then read as many events as possible (but at least 1) and enqueue them
                    438:  */
                    439: _XReadEvents(dpy)
                    440:        register Display *dpy;
                    441: {
                    442:        char buf[BUFSIZE];
                    443:        long pend_not_register; /* because can't "&" a register variable */
                    444:        register long pend;
                    445:        register xEvent *ev;
                    446:        Bool not_yet_flushed = True;
                    447: 
                    448:        do {
                    449:            /* find out how much data can be read */
                    450:            if (BytesReadable(dpy->fd, (char *) &pend_not_register) < 0)
                    451:                (*_XIOErrorFunction)(dpy);
                    452:            pend = pend_not_register;
                    453: 
                    454:            /* must read at least one xEvent; if none is pending, then
                    455:               we'll just flush and block waiting for it */
                    456:            if (pend < SIZEOF(xEvent)) {
                    457:                pend = SIZEOF(xEvent);
                    458:                /* don't flush until we block the first time */
                    459:                if (not_yet_flushed) {
                    460:                    int qlen = dpy->qlen;
                    461:                    _XFlush (dpy);
                    462:                    if (qlen != dpy->qlen) return;
                    463:                    not_yet_flushed = False;
                    464:                }
                    465:            }
                    466:                
                    467:            /* but we won't read more than the max buffer size */
                    468:            if (pend > BUFSIZE)
                    469:                pend = BUFSIZE;
                    470: 
                    471:            /* round down to an integral number of XReps */
                    472:            pend = (pend / SIZEOF(xEvent)) * SIZEOF(xEvent);
                    473: 
                    474:            _XRead (dpy, buf, pend);
                    475: 
                    476:            /* no space between comma and type or else macro will die */
                    477:            STARTITERATE (ev,xEvent, buf, (pend > 0),
                    478:                          pend -= SIZEOF(xEvent)) {
                    479:                if (ev->u.u.type == X_Error)
                    480:                    _XError (dpy, (xError *) ev);
                    481:                else  /* it's an event packet; enqueue it */
                    482:                    _XEnq (dpy, ev);
                    483:            }
                    484:            ENDITERATE
                    485:        } while (dpy->head == NULL);
                    486: }
                    487: 
                    488: /* 
                    489:  * _XRead - Read bytes from the socket taking into account incomplete
                    490:  * reads.  This routine may have to be reworked if int < long.
                    491:  */
                    492: _XRead (dpy, data, size)
                    493:        register Display *dpy;
                    494:        register char *data;
                    495:        register long size;
                    496: {
                    497:        register long bytes_read;
                    498: 
                    499:        if (size == 0) return;
                    500:        errno = 0;
                    501:        while ((bytes_read = ReadFromServer(dpy->fd, data, (int)size))
                    502:                != size) {
                    503: 
                    504:                if (bytes_read > 0) {
                    505:                    size -= bytes_read;
                    506:                    data += bytes_read;
                    507:                    }
                    508: #ifdef EWOULDBLOCK
                    509:                else if (errno == EWOULDBLOCK) {
                    510:                    _XWaitForReadable(dpy);
                    511:                    errno = 0;
                    512:                }
                    513: #endif         
                    514: #ifdef SUNSYSV
                    515:                else if (errno == 0) {
                    516:                    _XWaitForReadable(dpy);
                    517:                }
                    518: #endif
                    519:                else if (bytes_read == 0) {
                    520:                    /* Read failed because of end of file! */
                    521:                    errno = EPIPE;
                    522:                    (*_XIOErrorFunction)(dpy);
                    523:                    }
                    524: 
                    525:                else  /* bytes_read is less than 0; presumably -1 */ {
                    526:                    /* If it's a system call interrupt, it's not an error. */
                    527:                    if (errno != EINTR)
                    528:                        (*_XIOErrorFunction)(dpy);
                    529:                    }
                    530:                 }
                    531: }
                    532: 
                    533: #ifdef WORD64
                    534: 
                    535: /*
                    536:  * XXX This is a *really* stupid way of doing this....
                    537:  */
                    538: 
                    539: #define PACKBUFFERSIZE 4096
                    540: 
                    541: 
                    542: /*
                    543:  * _XRead32 - Read bytes from the socket unpacking each 32 bits
                    544:  *            into a long (64 bits on a CRAY computer).
                    545:  * 
                    546:  */
                    547: static _doXRead32 (dpy, data, size, packbuffer)
                    548:         register Display *dpy;
                    549:         register long *data;
                    550:         register long size;
                    551:        register char *packbuffer;
                    552: {
                    553:  long *lpack,*lp;
                    554:  long mask32 = 0x00000000ffffffff;
                    555:  long maskw, nwords, i, bits;
                    556: 
                    557:         _XReadPad (dpy, packbuffer, size);
                    558: 
                    559:         lp = data;
                    560:         lpack = (long *) packbuffer;
                    561:         nwords = size >> 2;
                    562:         bits = 32;
                    563: 
                    564:         for(i=0;i<nwords;i++){
                    565:             maskw = mask32 << bits;
                    566:            *lp++ = ( *lpack & maskw ) >> bits;
                    567:             bits = bits ^32;
                    568:             if(bits){
                    569:                lpack++;
                    570:             }
                    571:         }
                    572: }
                    573: 
                    574: _XRead32 (dpy, data, len)
                    575:     Display *dpy;
                    576:     long *data;
                    577:     long len;
                    578: {
                    579:     char packbuffer[PACKBUFFERSIZE];
                    580:     unsigned nwords = (PACKBUFFERSIZE >> 2);   /* bytes to CARD32 */
                    581: 
                    582:     for (; len > nwords; len -= nwords, data += nwords) {
                    583:        _doXRead32 (dpy, data, nwords, packbuffer);
                    584:     }
                    585:     _doXRead32 (dpy, data, len, packbuffer);
                    586: }
                    587: 
                    588: 
                    589: 
                    590: /*
                    591:  * _XRead16 - Read bytes from the socket unpacking each 16 bits
                    592:  *            into a long (64 bits on a CRAY computer).
                    593:  *
                    594:  */
                    595: static _doXRead16 (dpy, data, size, packbuffer)
                    596:         register Display *dpy;
                    597:         register short *data;
                    598:         register long size;
                    599:        char *packbuffer;
                    600: {
                    601:        long *lpack,*lp;
                    602:        long mask16 = 0x000000000000ffff;
                    603:        long maskw, nwords, i, bits;
                    604: 
                    605:         _XRead(dpy,packbuffer,size);   /* don't do a padded read... */
                    606: 
                    607:         lp = (long *) data;
                    608:         lpack = (long *) packbuffer;
                    609:         nwords = size >> 1;  /* number of 16 bit words to be unpacked */
                    610:         bits = 48;
                    611:         for(i=0;i<nwords;i++){
                    612:             maskw = mask16 << bits;
                    613:            *lp++ = ( *lpack & maskw ) >> bits;
                    614:             bits -= 16;
                    615:             if(bits < 0){
                    616:                lpack++;
                    617:                bits = 48;
                    618:             }
                    619:         }
                    620: }
                    621: 
                    622: _XRead16 (dpy, data, len)
                    623:     Display *dpy;
                    624:     short *data;
                    625:     long len;
                    626: {
                    627:     char packbuffer[PACKBUFFERSIZE];
                    628:     unsigned nwords = (PACKBUFFERSIZE >> 1);   /* bytes to CARD16 */
                    629: 
                    630:     for (; len > nwords; len -= nwords, data += nwords) {
                    631:        _doXRead16 (dpy, data, nwords, packbuffer);
                    632:     }
                    633:     _doXRead16 (dpy, data, len, packbuffer);
                    634: }
                    635: 
                    636: _XRead16Pad (dpy, data, size)
                    637:     Display *dpy;
                    638:     short *data;
                    639:     long size;
                    640: {
                    641:     int slop = (size & 3);
                    642:     short slopbuf[3];
                    643: 
                    644:     _XRead16 (dpy, data, size);
                    645:     if (slop > 0) {
                    646:        _XRead16 (dpy, slopbuf, 4 - slop);
                    647:     }
                    648: }
                    649: #endif /* WORD64 */
                    650: 
                    651: 
                    652: /*
                    653:  * _XReadPad - Read bytes from the socket taking into account incomplete
                    654:  * reads.  If the number of bytes is not 0 mod 32, read additional pad
                    655:  * bytes. This routine may have to be reworked if int < long.
                    656:  */
                    657: _XReadPad (dpy, data, size)
                    658:        register Display *dpy;  
                    659:        register char *data;
                    660:        register long size;
                    661: {
                    662:        register long bytes_read;
                    663:        struct iovec iov[2];
                    664:        char pad[3];
                    665: 
                    666:        if (size == 0) return;
                    667:        iov[0].iov_len = (int)size;
                    668:        iov[0].iov_base = data;
                    669:        /* 
                    670:         * The following hack is used to provide 32 bit long-word
                    671:         * aligned padding.  The [1] vector is of length 0, 1, 2, or 3,
                    672:         * whatever is needed.
                    673:         */
                    674: 
                    675:        iov[1].iov_len = padlength[size & 3];
                    676:        iov[1].iov_base = pad;
                    677:        size += iov[1].iov_len;
                    678: 
                    679:        errno = 0;
                    680:        while ((bytes_read = ReadvFromServer (dpy->fd, iov, 2)) != size) {
                    681: 
                    682:            if (bytes_read > 0) {
                    683:                size -= bytes_read;
                    684:                if ((iov[0].iov_len -= bytes_read) < 0) {
                    685:                    iov[1].iov_len += iov[0].iov_len;
                    686:                    iov[1].iov_base -= iov[0].iov_len;
                    687:                    iov[0].iov_len = 0;
                    688:                    }
                    689:                else
                    690:                    iov[0].iov_base += bytes_read;
                    691:                }
                    692: #ifdef EWOULDBLOCK
                    693:            else if (errno == EWOULDBLOCK) {
                    694:                _XWaitForReadable(dpy);
                    695:                errno = 0;
                    696:            }
                    697: #endif
                    698: #ifdef SUNSYSV
                    699:            else if (errno == 0) {
                    700:                _XWaitForReadable(dpy);
                    701:            }
                    702: #endif
                    703:            else if (bytes_read == 0) {
                    704:                /* Read failed because of end of file! */
                    705:                errno = EPIPE;
                    706:                (*_XIOErrorFunction)(dpy);
                    707:                }
                    708:            
                    709:            else  /* bytes_read is less than 0; presumably -1 */ {
                    710:                /* If it's a system call interrupt, it's not an error. */
                    711:                if (errno != EINTR)
                    712:                    (*_XIOErrorFunction)(dpy);
                    713:                }
                    714:            }
                    715: 
                    716: }
                    717: 
                    718: /*
                    719:  * _XSend - Flush the buffer and send the client data. 32 bit word aligned
                    720:  * transmission is used, if size is not 0 mod 4, extra bytes are transmitted.
                    721:  * This routine may have to be reworked if int < long;
                    722:  */
                    723: _XSend (dpy, data, size)
                    724:        register Display *dpy;
                    725:        char *data;
                    726:        register long size;
                    727: {
                    728:        struct iovec iov[3];
                    729:        static char pad[3] = {0, 0, 0};
                    730:            /* XText8 and XText16 require that the padding bytes be zero! */
                    731: 
                    732:        long skip = 0;
                    733:        long total = (dpy->bufptr - dpy->buffer) + ((size + 3) & ~3);
                    734:        long todo = total;
                    735: 
                    736:        while (total) {
                    737:            long before = skip;
                    738:            long remain = todo;
                    739:            int i = 0;
                    740:            long len;
                    741: 
                    742:        /* You could be very general here and have "in" and "out" iovecs
                    743:         * and write a loop without using a macro, but what the heck
                    744:         */
                    745: 
                    746: #define InsertIOV(pointer, length) \
                    747:            len = (length) - before; \
                    748:            if (len > remain) \
                    749:                len = remain; \
                    750:            if (len <= 0) { \
                    751:                before = -len; \
                    752:            } else { \
                    753:                iov[i].iov_len = len; \
                    754:                iov[i].iov_base = (pointer) + before; \
                    755:                i++; \
                    756:                remain -= len; \
                    757:                before = 0; \
                    758:            }
                    759: 
                    760:            InsertIOV(dpy->buffer, dpy->bufptr - dpy->buffer)
                    761:            InsertIOV(data, size)
                    762:            /* Provide 32-bit aligned padding as necessary */
                    763:            InsertIOV(pad, padlength[size & 3])
                    764:     
                    765:            errno = 0;
                    766:            if ((len = WritevToServer(dpy->fd, iov, i)) >= 0) {
                    767:                skip += len;
                    768:                total -= len;
                    769:                todo = total;
                    770: #ifdef EWOULDBLOCK
                    771:            } else if (errno == EWOULDBLOCK) {
                    772:                _XWaitForWritable(dpy);
                    773: #endif
                    774: #ifdef SUNSYSV
                    775:            } else if (errno == 0) {
                    776:                _XWaitForWritable(dpy);
                    777: #endif
                    778: #ifdef EMSGSIZE
                    779:            } else if (errno == EMSGSIZE) {
                    780:                todo = todo >> 1;
                    781: #endif
                    782:            } else {
                    783:                (*_XIOErrorFunction)(dpy);
                    784:            }
                    785:        }
                    786: 
                    787:        dpy->bufptr = dpy->buffer;
                    788:        dpy->last_req = (char *) & _dummy_request;
                    789: }
                    790: 
                    791: /*
                    792:  * _XAllocID - normal resource ID allocation routine.  A client
                    793:  * can roll his own and instatantiate it if he wants, but must
                    794:  * follow the rules.
                    795:  */
                    796: XID _XAllocID(dpy)
                    797: register Display *dpy;
                    798: {
                    799:    return (dpy->resource_base + (dpy->resource_id++ << dpy->resource_shift));
                    800: }
                    801: 
                    802: /*
                    803:  * The hard part about this is that we only get 16 bits from a reply.  Well,
                    804:  * then, we have three values that will march along, with the following
                    805:  * invariant:
                    806:  *     dpy->last_request_read <= rep->sequenceNumber <= dpy->request
                    807:  * The right choice for rep->sequenceNumber is the largest that
                    808:  * still meets these constraints.
                    809:  */
                    810: static unsigned long
                    811: _SetLastRequestRead(dpy, rep)
                    812:     register Display *dpy;
                    813:     register xGenericReply *rep;
                    814: {
                    815:     register unsigned long     newseq, lastseq;
                    816: 
                    817:     /*
                    818:      * KeymapNotify has no sequence number, but is always guaranteed
                    819:      * to immediately follow another event, except when generated via
                    820:      * SendEvent (hmmm).
                    821:      */
                    822:     if ((rep->type & 0x7f) == KeymapNotify)
                    823:        return(dpy->last_request_read);
                    824: 
                    825:     newseq = (dpy->last_request_read & ~((unsigned long)0xffff)) |
                    826:             rep->sequenceNumber;
                    827:     lastseq = dpy->last_request_read;
                    828:     while (newseq < lastseq) {
                    829:        newseq += 0x10000;
                    830:        if (newseq > dpy->request) {
                    831:            (void) fprintf (stderr, 
                    832:            "Xlib:  sequence lost (0x%lx > 0x%lx) in reply type 0x%x!\n",
                    833:                                   newseq, dpy->request, 
                    834:                                   (unsigned int) rep->type);
                    835:            newseq -= 0x10000;
                    836:            break;
                    837:        }
                    838:     }
                    839: 
                    840:     dpy->last_request_read = newseq;
                    841:     return(newseq);
                    842: }
                    843: 
                    844: /*
                    845:  * _XReply - Wait for a reply packet and copy its contents into the
                    846:  * specified rep.  Mean while we must handle error and event packets that
                    847:  * we may encounter.
                    848:  */
                    849: Status _XReply (dpy, rep, extra, discard)
                    850:     register Display *dpy;
                    851:     register xReply *rep;
                    852:     int extra;         /* number of 32-bit words expected after the reply */
                    853:     Bool discard;      /* should I discard data followind "extra" words? */
                    854: {
                    855:     /* Pull out the serial number now, so that (currently illegal) requests
                    856:      * generated by an error handler don't confuse us.
                    857:      */
                    858:     unsigned long cur_request = dpy->request;
                    859: 
                    860:     _XFlush(dpy);
                    861:     while (1) {
                    862:        _XRead(dpy, (char *)rep, (long)SIZEOF(xReply));
                    863:        switch ((int)rep->generic.type) {
                    864: 
                    865:            case X_Reply:
                    866:                /* Reply received.  Fast update for synchronous replies,
                    867:                 * but deal with multiple outstanding replies.
                    868:                 */
                    869:                if (rep->generic.sequenceNumber == (cur_request & 0xffff))
                    870:                    dpy->last_request_read = cur_request;
                    871:                else
                    872:                    (void) _SetLastRequestRead(dpy, &rep->generic);
                    873:                if (extra == 0) {
                    874:                    if (discard && (rep->generic.length > 0))
                    875:                       /* unexpectedly long reply! */
                    876:                       _EatData (dpy, rep->generic.length);
                    877:                    return (1);
                    878:                    }
                    879:                if (extra == rep->generic.length) {
                    880:                    /* 
                    881:                     * Read the extra data into storage immediately following
                    882:                     * the GenericReply structure. 
                    883:                     */
                    884:                    _XRead (dpy, NEXTPTR(rep,xReply), ((long)extra) << 2);
                    885:                    return (1);
                    886:                    }
                    887:                if (extra < rep->generic.length) {
                    888:                    /* Actual reply is longer than "extra" */
                    889:                    _XRead (dpy, NEXTPTR(rep,xReply), ((long)extra) << 2);
                    890:                    if (discard)
                    891:                        _EatData (dpy, rep->generic.length - extra);
                    892:                    return (1);
                    893:                    }
                    894:                /* 
                    895:                 *if we get here, then extra > rep->generic.length--meaning we
                    896:                 * read a reply that's shorter than we expected.  This is an 
                    897:                 * error,  but we still need to figure out how to handle it...
                    898:                 */
                    899:                _XRead (dpy, NEXTPTR(rep,xReply),
                    900:                        ((long) rep->generic.length) << 2);
                    901:                (*_XIOErrorFunction) (dpy);
                    902:                return (0);
                    903: 
                    904:            case X_Error:
                    905:                {
                    906:                register _XExtension *ext;
                    907:                register Bool ret = False;
                    908:                int ret_code;
                    909:                xError *err = (xError *) rep;
                    910:                unsigned long serial;
                    911: 
                    912:                serial = _SetLastRequestRead(dpy, (xGenericReply *)rep);
                    913:                if (serial == cur_request)
                    914:                        /* do not die on "no such font", "can't allocate",
                    915:                           "can't grab" failures */
                    916:                        switch ((int)err->errorCode) {
                    917:                        case BadName:
                    918:                            switch (err->majorCode) {
                    919:                                case X_OpenFont:
                    920:                                case X_LookupColor:
                    921:                                case X_AllocNamedColor:
                    922:                                    return(0);
                    923:                            }
                    924:                            break;
                    925:                        case BadFont:
                    926:                            if (err->majorCode == X_QueryFont)
                    927:                                return (0);
                    928:                            break;
                    929:                        case BadAlloc:
                    930:                        case BadAccess:
                    931:                                return (0);
                    932:                        /* 
                    933:                         * we better see if there is an extension who may
                    934:                         * want to suppress the error.
                    935:                         */
                    936:                        default:
                    937:                            ext = dpy->ext_procs;
                    938:                            while (ext) {
                    939:                                if (ext->error != NULL) 
                    940:                                   ret = (*ext->error)
                    941:                                        (dpy, err, &ext->codes, &ret_code);
                    942:                                ext = ext->next;
                    943:                                }
                    944:                            if (ret) return (ret_code);
                    945:                            break;
                    946:                        }
                    947:                _XError(dpy, err);
                    948:                if (serial == cur_request)
                    949:                    return(0);
                    950:                }
                    951:                break;
                    952:            default:
                    953:                _XEnq(dpy, (xEvent *) rep);
                    954:                break;
                    955:            }
                    956:        }
                    957: }   
                    958: 
                    959: 
                    960: /* Read and discard "n" 32-bit words. */
                    961: 
                    962: static _EatData (dpy, n)
                    963:     Display *dpy;
                    964:     unsigned long n;
                    965:     {
                    966:     unsigned int bufsize;
                    967:     char *buf;
                    968:     n <<= 2;  /* convert to number of bytes */
                    969:     buf = Xmalloc (bufsize = (n > 2048) ? 2048 : n);
                    970:     while (n) {
                    971:        long bytes_read = (n > bufsize) ? bufsize : n;
                    972:        _XRead (dpy, buf, bytes_read);
                    973:        n -= bytes_read;
                    974:        }
                    975:     Xfree (buf);
                    976:     }
                    977: 
                    978: /*
                    979:  * _XEnq - Place event packets on the display's queue.
                    980:  * note that no squishing of move events in V11, since there
                    981:  * is pointer motion hints....
                    982:  */
                    983: _XEnq (dpy, event)
                    984:        register Display *dpy;
                    985:        register xEvent *event;
                    986: {
                    987:        register _XQEvent *qelt;
                    988: 
                    989: /*NOSTRICT*/
                    990:        if (qelt = _qfree) {
                    991:                /* If _qfree is non-NULL do this, else malloc a new one. */
                    992:                _qfree = qelt->next;
                    993:        }
                    994:        else if ((qelt = 
                    995:            (_XQEvent *) Xmalloc((unsigned)sizeof(_XQEvent))) == NULL) {
                    996:                /* Malloc call failed! */
                    997:                errno = ENOMEM;
                    998:                (*_XIOErrorFunction)(dpy);
                    999:        }
                   1000:        qelt->next = NULL;
                   1001:        /* go call through display to find proper event reformatter */
                   1002:        if ((*dpy->event_vec[event->u.u.type & 0177])(dpy, &qelt->event, event)) {
                   1003:            if (dpy->tail)      dpy->tail->next = qelt;
                   1004:            else                dpy->head = qelt;
                   1005:     
                   1006:            dpy->tail = qelt;
                   1007:            dpy->qlen++;
                   1008:        } else {
                   1009:            /* ignored, or stashed away for many-to-one compression */
                   1010:            qelt->next = _qfree;
                   1011:            _qfree = qelt;
                   1012:        }
                   1013: }
                   1014: /*
                   1015:  * EventToWire in seperate file in that often not needed.
                   1016:  */
                   1017: 
                   1018: /*ARGSUSED*/
                   1019: Bool
                   1020: _XUnknownWireEvent(dpy, re, event)
                   1021: register Display *dpy; /* pointer to display structure */
                   1022: register XEvent *re;   /* pointer to where event should be reformatted */
                   1023: register xEvent *event;        /* wire protocol event */
                   1024: {
                   1025: #ifdef notdef
                   1026:        (void) fprintf(stderr, 
                   1027:            "Xlib: unhandled wire event! event number = %d, display = %x\n.",
                   1028:                        event->u.u.type, dpy);
                   1029: #endif
                   1030:        return(False);
                   1031: }
                   1032: 
                   1033: /*ARGSUSED*/
                   1034: Status
                   1035: _XUnknownNativeEvent(dpy, re, event)
                   1036: register Display *dpy; /* pointer to display structure */
                   1037: register XEvent *re;   /* pointer to where event should be reformatted */
                   1038: register xEvent *event;        /* wire protocol event */
                   1039: {
                   1040: #ifdef notdef
                   1041:        (void) fprintf(stderr, 
                   1042:           "Xlib: unhandled native event! event number = %d, display = %x\n.",
                   1043:                        re->type, dpy);
                   1044: #endif
                   1045:        return(0);
                   1046: }
                   1047: /*
                   1048:  * reformat a wire event into an XEvent structure of the right type.
                   1049:  */
                   1050: Bool
                   1051: _XWireToEvent(dpy, re, event)
                   1052: register Display *dpy; /* pointer to display structure */
                   1053: register XEvent *re;   /* pointer to where event should be reformatted */
                   1054: register xEvent *event;        /* wire protocol event */
                   1055: {
                   1056: 
                   1057:        re->type = event->u.u.type & 0x7f;
                   1058:        ((XAnyEvent *)re)->serial = _SetLastRequestRead(dpy,
                   1059:                                        (xGenericReply *)event);
                   1060:        ((XAnyEvent *)re)->send_event = ((event->u.u.type & 0x80) != 0);
                   1061:        ((XAnyEvent *)re)->display = dpy;
                   1062:        
                   1063:        /* Ignore the leading bit of the event type since it is set when a
                   1064:                client sends an event rather than the server. */
                   1065: 
                   1066:        switch (event-> u.u.type & 0177) {
                   1067:              case KeyPress:
                   1068:              case KeyRelease:
                   1069:                {
                   1070:                        register XKeyEvent *ev = (XKeyEvent*) re;
                   1071:                        ev->root        = event->u.keyButtonPointer.root;
                   1072:                        ev->window      = event->u.keyButtonPointer.event;
                   1073:                        ev->subwindow   = event->u.keyButtonPointer.child;
                   1074:                        ev->time        = event->u.keyButtonPointer.time;
                   1075:                        ev->x           = event->u.keyButtonPointer.eventX;
                   1076:                        ev->y           = event->u.keyButtonPointer.eventY;
                   1077:                        ev->x_root      = event->u.keyButtonPointer.rootX;
                   1078:                        ev->y_root      = event->u.keyButtonPointer.rootY;
                   1079:                        ev->state       = event->u.keyButtonPointer.state;
                   1080:                        ev->same_screen = event->u.keyButtonPointer.sameScreen;
                   1081:                        ev->keycode     = event->u.u.detail;
                   1082:                }
                   1083:                break;
                   1084:              case ButtonPress:
                   1085:              case ButtonRelease:
                   1086:                {
                   1087:                        register XButtonEvent *ev =  (XButtonEvent *) re;
                   1088:                        ev->root        = event->u.keyButtonPointer.root;
                   1089:                        ev->window      = event->u.keyButtonPointer.event;
                   1090:                        ev->subwindow   = event->u.keyButtonPointer.child;
                   1091:                        ev->time        = event->u.keyButtonPointer.time;
                   1092:                        ev->x           = event->u.keyButtonPointer.eventX;
                   1093:                        ev->y           = event->u.keyButtonPointer.eventY;
                   1094:                        ev->x_root      = event->u.keyButtonPointer.rootX;
                   1095:                        ev->y_root      = event->u.keyButtonPointer.rootY;
                   1096:                        ev->state       = event->u.keyButtonPointer.state;
                   1097:                        ev->same_screen = event->u.keyButtonPointer.sameScreen;
                   1098:                        ev->button      = event->u.u.detail;
                   1099:                }
                   1100:                break;
                   1101:              case MotionNotify:
                   1102:                {
                   1103:                        register XMotionEvent *ev =   (XMotionEvent *)re;
                   1104:                        ev->root        = event->u.keyButtonPointer.root;
                   1105:                        ev->window      = event->u.keyButtonPointer.event;
                   1106:                        ev->subwindow   = event->u.keyButtonPointer.child;
                   1107:                        ev->time        = event->u.keyButtonPointer.time;
                   1108:                        ev->x           = event->u.keyButtonPointer.eventX;
                   1109:                        ev->y           = event->u.keyButtonPointer.eventY;
                   1110:                        ev->x_root      = event->u.keyButtonPointer.rootX;
                   1111:                        ev->y_root      = event->u.keyButtonPointer.rootY;
                   1112:                        ev->state       = event->u.keyButtonPointer.state;
                   1113:                        ev->same_screen = event->u.keyButtonPointer.sameScreen;
                   1114:                        ev->is_hint     = event->u.u.detail;
                   1115:                }
                   1116:                break;
                   1117:              case EnterNotify:
                   1118:              case LeaveNotify:
                   1119:                {
                   1120:                        register XCrossingEvent *ev   = (XCrossingEvent *) re;
                   1121:                        ev->root        = event->u.enterLeave.root;
                   1122:                        ev->window      = event->u.enterLeave.event;
                   1123:                        ev->subwindow   = event->u.enterLeave.child;
                   1124:                        ev->time        = event->u.enterLeave.time;
                   1125:                        ev->x           = event->u.enterLeave.eventX;
                   1126:                        ev->y           = event->u.enterLeave.eventY;
                   1127:                        ev->x_root      = event->u.enterLeave.rootX;
                   1128:                        ev->y_root      = event->u.enterLeave.rootY;
                   1129:                        ev->state       = event->u.enterLeave.state;
                   1130:                        ev->mode        = event->u.enterLeave.mode;
                   1131:                        ev->same_screen = (event->u.enterLeave.flags & 
                   1132:                                ELFlagSameScreen) && True;
                   1133:                        ev->focus       = (event->u.enterLeave.flags &
                   1134:                                ELFlagFocus) && True;
                   1135:                        ev->detail      = event->u.u.detail;
                   1136:                }
                   1137:                  break;
                   1138:              case FocusIn:
                   1139:              case FocusOut:
                   1140:                {
                   1141:                        register XFocusChangeEvent *ev = (XFocusChangeEvent *) re;
                   1142:                        ev->window      = event->u.focus.window;
                   1143:                        ev->mode        = event->u.focus.mode;
                   1144:                        ev->detail      = event->u.u.detail;
                   1145:                }
                   1146:                  break;
                   1147:              case KeymapNotify:
                   1148:                {
                   1149:                        register XKeymapEvent *ev = (XKeymapEvent *) re;
                   1150:                        ev->window      = dpy->current;
                   1151:                        bcopy ((char *)((xKeymapEvent *) event)->map,
                   1152:                               &ev->key_vector[1], 
                   1153:                               sizeof (((xKeymapEvent *) event)->map));
                   1154:                }
                   1155:                break;
                   1156:              case Expose:
                   1157:                {
                   1158:                        register XExposeEvent *ev = (XExposeEvent *) re;
                   1159:                        ev->window      = event->u.expose.window;
                   1160:                        ev->x           = event->u.expose.x;
                   1161:                        ev->y           = event->u.expose.y;
                   1162:                        ev->width       = event->u.expose.width;
                   1163:                        ev->height      = event->u.expose.height;
                   1164:                        ev->count       = event->u.expose.count;
                   1165:                }
                   1166:                break;
                   1167:              case GraphicsExpose:
                   1168:                {
                   1169:                    register XGraphicsExposeEvent *ev =
                   1170:                        (XGraphicsExposeEvent *) re;
                   1171:                    ev->drawable        = event->u.graphicsExposure.drawable;
                   1172:                    ev->x               = event->u.graphicsExposure.x;
                   1173:                    ev->y               = event->u.graphicsExposure.y;
                   1174:                    ev->width           = event->u.graphicsExposure.width;
                   1175:                    ev->height          = event->u.graphicsExposure.height;
                   1176:                    ev->count           = event->u.graphicsExposure.count;
                   1177:                    ev->major_code      = event->u.graphicsExposure.majorEvent;
                   1178:                    ev->minor_code      = event->u.graphicsExposure.minorEvent;
                   1179:                }
                   1180:                break;
                   1181:              case NoExpose:
                   1182:                {
                   1183:                    register XNoExposeEvent *ev = (XNoExposeEvent *) re;
                   1184:                    ev->drawable        = event->u.noExposure.drawable;
                   1185:                    ev->major_code      = event->u.noExposure.majorEvent;
                   1186:                    ev->minor_code      = event->u.noExposure.minorEvent;
                   1187:                }
                   1188:                break;
                   1189:              case VisibilityNotify:
                   1190:                {
                   1191:                    register XVisibilityEvent *ev = (XVisibilityEvent *) re;
                   1192:                    ev->window          = event->u.visibility.window;
                   1193:                    ev->state           = event->u.visibility.state;
                   1194:                }
                   1195:                break;
                   1196:              case CreateNotify:
                   1197:                {
                   1198:                    register XCreateWindowEvent *ev =
                   1199:                         (XCreateWindowEvent *) re;
                   1200:                    ev->window          = event->u.createNotify.window;
                   1201:                    ev->parent          = event->u.createNotify.parent;
                   1202:                    ev->x               = event->u.createNotify.x;
                   1203:                    ev->y               = event->u.createNotify.y;
                   1204:                    ev->width           = event->u.createNotify.width;
                   1205:                    ev->height          = event->u.createNotify.height;
                   1206:                    ev->border_width    = event->u.createNotify.borderWidth;
                   1207:                    ev->override_redirect       = event->u.createNotify.override;
                   1208:                }
                   1209:                break;
                   1210:              case DestroyNotify:
                   1211:                {
                   1212:                    register XDestroyWindowEvent *ev =
                   1213:                                (XDestroyWindowEvent *) re;
                   1214:                    ev->window          = event->u.destroyNotify.window;
                   1215:                    ev->event           = event->u.destroyNotify.event;
                   1216:                }
                   1217:                break;
                   1218:              case UnmapNotify:
                   1219:                {
                   1220:                    register XUnmapEvent *ev = (XUnmapEvent *) re;
                   1221:                    ev->window          = event->u.unmapNotify.window;
                   1222:                    ev->event           = event->u.unmapNotify.event;
                   1223:                    ev->from_configure  = event->u.unmapNotify.fromConfigure;
                   1224:                }
                   1225:                break;
                   1226:              case MapNotify:
                   1227:                {
                   1228:                    register XMapEvent *ev = (XMapEvent *) re;
                   1229:                    ev->window          = event->u.mapNotify.window;
                   1230:                    ev->event           = event->u.mapNotify.event;
                   1231:                    ev->override_redirect       = event->u.mapNotify.override;
                   1232:                }
                   1233:                break;
                   1234:              case MapRequest:
                   1235:                {
                   1236:                    register XMapRequestEvent *ev = (XMapRequestEvent *) re;
                   1237:                    ev->window          = event->u.mapRequest.window;
                   1238:                    ev->parent          = event->u.mapRequest.parent;
                   1239:                }
                   1240:                break;
                   1241:              case ReparentNotify:
                   1242:                {
                   1243:                    register XReparentEvent *ev = (XReparentEvent *) re;
                   1244:                    ev->event           = event->u.reparent.event;
                   1245:                    ev->window          = event->u.reparent.window;
                   1246:                    ev->parent          = event->u.reparent.parent;
                   1247:                    ev->x               = event->u.reparent.x;
                   1248:                    ev->y               = event->u.reparent.y;
                   1249:                    ev->override_redirect       = event->u.reparent.override;
                   1250:                }
                   1251:                break;
                   1252:              case ConfigureNotify:
                   1253:                {
                   1254:                    register XConfigureEvent *ev = (XConfigureEvent *) re;
                   1255:                    ev->event   = event->u.configureNotify.event;
                   1256:                    ev->window  = event->u.configureNotify.window;
                   1257:                    ev->above   = event->u.configureNotify.aboveSibling;
                   1258:                    ev->x       = event->u.configureNotify.x;
                   1259:                    ev->y       = event->u.configureNotify.y;
                   1260:                    ev->width   = event->u.configureNotify.width;
                   1261:                    ev->height  = event->u.configureNotify.height;
                   1262:                    ev->border_width  = event->u.configureNotify.borderWidth;
                   1263:                    ev->override_redirect = event->u.configureNotify.override;
                   1264:                }
                   1265:                break;
                   1266:              case ConfigureRequest:
                   1267:                {
                   1268:                    register XConfigureRequestEvent *ev =
                   1269:                        (XConfigureRequestEvent *) re;
                   1270:                    ev->window          = event->u.configureRequest.window;
                   1271:                    ev->parent          = event->u.configureRequest.parent;
                   1272:                    ev->above           = event->u.configureRequest.sibling;
                   1273:                    ev->x               = event->u.configureRequest.x;
                   1274:                    ev->y               = event->u.configureRequest.y;
                   1275:                    ev->width           = event->u.configureRequest.width;
                   1276:                    ev->height          = event->u.configureRequest.height;
                   1277:                    ev->border_width    = event->u.configureRequest.borderWidth;
                   1278:                    ev->value_mask      = event->u.configureRequest.valueMask;
                   1279:                    ev->detail          = event->u.u.detail;
                   1280:                }
                   1281:                break;
                   1282:              case GravityNotify:
                   1283:                {
                   1284:                    register XGravityEvent *ev = (XGravityEvent *) re;
                   1285:                    ev->window          = event->u.gravity.window;
                   1286:                    ev->event           = event->u.gravity.event;
                   1287:                    ev->x               = event->u.gravity.x;
                   1288:                    ev->y               = event->u.gravity.y;
                   1289:                }
                   1290:                break;
                   1291:              case ResizeRequest:
                   1292:                {
                   1293:                    register XResizeRequestEvent *ev =
                   1294:                        (XResizeRequestEvent *) re;
                   1295:                    ev->window          = event->u.resizeRequest.window;
                   1296:                    ev->width           = event->u.resizeRequest.width;
                   1297:                    ev->height          = event->u.resizeRequest.height;
                   1298:                }
                   1299:                break;
                   1300:              case CirculateNotify:
                   1301:                {
                   1302:                    register XCirculateEvent *ev = (XCirculateEvent *) re;
                   1303:                    ev->window          = event->u.circulate.window;
                   1304:                    ev->event           = event->u.circulate.event;
                   1305:                    ev->place           = event->u.circulate.place;
                   1306:                }
                   1307:                break;
                   1308:              case CirculateRequest:
                   1309:                {
                   1310:                    register XCirculateRequestEvent *ev =
                   1311:                        (XCirculateRequestEvent *) re;
                   1312:                    ev->window          = event->u.circulate.window;
                   1313:                    ev->parent          = event->u.circulate.event;
                   1314:                    ev->place           = event->u.circulate.place;
                   1315:                }
                   1316:                break;
                   1317:              case PropertyNotify:
                   1318:                {
                   1319:                    register XPropertyEvent *ev = (XPropertyEvent *) re;
                   1320:                    ev->window          = event->u.property.window;
                   1321:                    ev->atom            = event->u.property.atom;
                   1322:                    ev->time            = event->u.property.time;
                   1323:                    ev->state           = event->u.property.state;
                   1324:                }
                   1325:                break;
                   1326:              case SelectionClear:
                   1327:                {
                   1328:                    register XSelectionClearEvent *ev =
                   1329:                         (XSelectionClearEvent *) re;
                   1330:                    ev->window          = event->u.selectionClear.window;
                   1331:                    ev->selection       = event->u.selectionClear.atom;
                   1332:                    ev->time            = event->u.selectionClear.time;
                   1333:                }
                   1334:                break;
                   1335:              case SelectionRequest:
                   1336:                {
                   1337:                    register XSelectionRequestEvent *ev =
                   1338:                        (XSelectionRequestEvent *) re;
                   1339:                    ev->owner           = event->u.selectionRequest.owner;
                   1340:                    ev->requestor       = event->u.selectionRequest.requestor;
                   1341:                    ev->selection       = event->u.selectionRequest.selection;
                   1342:                    ev->target          = event->u.selectionRequest.target;
                   1343:                    ev->property        = event->u.selectionRequest.property;
                   1344:                    ev->time            = event->u.selectionRequest.time;
                   1345:                }
                   1346:                break;
                   1347:              case SelectionNotify:
                   1348:                {
                   1349:                    register XSelectionEvent *ev = (XSelectionEvent *) re;
                   1350:                    ev->requestor       = event->u.selectionNotify.requestor;
                   1351:                    ev->selection       = event->u.selectionNotify.selection;
                   1352:                    ev->target          = event->u.selectionNotify.target;
                   1353:                    ev->property        = event->u.selectionNotify.property;
                   1354:                    ev->time            = event->u.selectionNotify.time;
                   1355:                }
                   1356:                break;
                   1357:              case ColormapNotify:
                   1358:                {
                   1359:                    register XColormapEvent *ev = (XColormapEvent *) re;
                   1360:                    ev->window          = event->u.colormap.window;
                   1361:                    ev->colormap        = event->u.colormap.colormap;
                   1362:                    ev->new             = event->u.colormap.new;
                   1363:                    ev->state           = event->u.colormap.state;
                   1364:                }
                   1365:                break;
                   1366:              case ClientMessage:
                   1367:                {
                   1368:                   register int i;
                   1369:                   register XClientMessageEvent *ev 
                   1370:                                        = (XClientMessageEvent *) re;
                   1371:                   ev->window           = event->u.clientMessage.window;
                   1372:                   ev->format           = event->u.u.detail;
                   1373:                   switch (ev->format) {
                   1374:                        case 8: 
                   1375:                           ev->message_type = event->u.clientMessage.u.b.type;
                   1376:                           for (i = 0; i < 20; i++)     
                   1377:                             ev->data.b[i] = event->u.clientMessage.u.b.bytes[i];
                   1378:                           break;
                   1379:                        case 16:
                   1380:                           ev->message_type = event->u.clientMessage.u.s.type;
                   1381:                           ev->data.s[0] = event->u.clientMessage.u.s.shorts0;
                   1382:                           ev->data.s[1] = event->u.clientMessage.u.s.shorts1;
                   1383:                           ev->data.s[2] = event->u.clientMessage.u.s.shorts2;
                   1384:                           ev->data.s[3] = event->u.clientMessage.u.s.shorts3;
                   1385:                           ev->data.s[4] = event->u.clientMessage.u.s.shorts4;
                   1386:                           ev->data.s[5] = event->u.clientMessage.u.s.shorts5;
                   1387:                           ev->data.s[6] = event->u.clientMessage.u.s.shorts6;
                   1388:                           ev->data.s[7] = event->u.clientMessage.u.s.shorts7;
                   1389:                           ev->data.s[8] = event->u.clientMessage.u.s.shorts8;
                   1390:                           ev->data.s[9] = event->u.clientMessage.u.s.shorts9;
                   1391:                           break;
                   1392:                        case 32:
                   1393:                           ev->message_type = event->u.clientMessage.u.l.type;
                   1394:                           ev->data.l[0] = event->u.clientMessage.u.l.longs0;
                   1395:                           ev->data.l[1] = event->u.clientMessage.u.l.longs1;
                   1396:                           ev->data.l[2] = event->u.clientMessage.u.l.longs2;
                   1397:                           ev->data.l[3] = event->u.clientMessage.u.l.longs3;
                   1398:                           ev->data.l[4] = event->u.clientMessage.u.l.longs4;
                   1399:                           break;
                   1400:                        default: /* XXX should never occur */
                   1401:                                break;
                   1402:                    }
                   1403:                }
                   1404:                break;
                   1405:              case MappingNotify:
                   1406:                {
                   1407:                   register XMappingEvent *ev = (XMappingEvent *)re;
                   1408:                   ev->first_keycode    = event->u.mappingNotify.firstKeyCode;
                   1409:                   ev->request          = event->u.mappingNotify.request;
                   1410:                   ev->count            = event->u.mappingNotify.count;
                   1411:                }
                   1412:                break;
                   1413:              default:
                   1414:                return(_XUnknownWireEvent(dpy, re, event));
                   1415:        }
                   1416:        return(True);
                   1417: }
                   1418: 
                   1419: 
                   1420: static char *_SysErrorMsg (n)
                   1421:     int n;
                   1422: {
                   1423:     extern char *sys_errlist[];
                   1424:     extern int sys_nerr;
                   1425:     char *s = ((n >= 0 && n < sys_nerr) ? sys_errlist[n] : "unknown error");
                   1426: 
                   1427:     return (s ? s : "no such error");
                   1428: }
                   1429: 
                   1430: /*
                   1431:  * _XIOError - Default fatal system error reporting routine.  Called when
                   1432:  * an X internal system error is encountered.
                   1433:  */
                   1434: _XIOError (dpy)
                   1435:        Display *dpy;
                   1436: {
                   1437:        (void) fprintf (stderr, 
                   1438:         "XIO:  fatal IO error %d (%s) on X server \"%s\"\r\n",
                   1439:                        errno, _SysErrorMsg (errno), DisplayString (dpy));
                   1440:        (void) fprintf (stderr, 
                   1441:         "      after %lu requests (%lu known processed) with %d events remaining.\r\n",
                   1442:                        NextRequest(dpy) - 1, LastKnownRequestProcessed(dpy),
                   1443:                        QLength(dpy));
                   1444: 
                   1445:        if (errno == EPIPE) {
                   1446:            (void) fprintf (stderr,
                   1447:         "      The connection was probably broken by a server shutdown or KillClient.\r\n");
                   1448:        }
                   1449: 
                   1450:        exit (1);
                   1451: }
                   1452: 
                   1453: /*
                   1454:  * _XError - Default non-fatal error reporting routine.  Called when an
                   1455:  * X_Error packet is encountered in the input stream.
                   1456:  */
                   1457: int _XError (dpy, rep)
                   1458:     Display *dpy;
                   1459:     xError *rep;
                   1460: {
                   1461:     XErrorEvent event;
                   1462:     /* 
                   1463:      * X_Error packet encountered!  We need to unpack the error before
                   1464:      * giving it to the user.
                   1465:      */
                   1466: 
                   1467:     event.display = dpy;
                   1468:     event.type = X_Error;
                   1469:     event.serial = _SetLastRequestRead(dpy, (xGenericReply *)rep);
                   1470:     event.resourceid = rep->resourceID;
                   1471:     event.error_code = rep->errorCode;
                   1472:     event.request_code = rep->majorCode;
                   1473:     event.minor_code = rep->minorCode;
                   1474:     if (_XErrorFunction != NULL) {
                   1475:        return ((*_XErrorFunction)(dpy, &event));
                   1476:       }
                   1477:     exit(1);
                   1478:     /*NOTREACHED*/
                   1479: }
                   1480:     
                   1481: int _XPrintDefaultError (dpy, event, fp)
                   1482:     Display *dpy;
                   1483:     XErrorEvent *event;
                   1484:     FILE *fp;
                   1485: {
                   1486:     char buffer[BUFSIZ];
                   1487:     char mesg[BUFSIZ];
                   1488:     char number[32];
                   1489:     char *mtype = "XlibMessage";
                   1490:     XGetErrorText(dpy, event->error_code, buffer, BUFSIZ);
                   1491:     XGetErrorDatabaseText(dpy, mtype, "XError", "X Error", mesg, BUFSIZ);
                   1492:     (void) fprintf(fp, "%s:  %s\n  ", mesg, buffer);
                   1493:     XGetErrorDatabaseText(dpy, mtype, "MajorCode", "Request Major code %d", 
                   1494:        mesg, BUFSIZ);
                   1495:     (void) fprintf(fp, mesg, event->request_code);
                   1496:     sprintf(number, "%d", event->request_code);
                   1497:     XGetErrorDatabaseText(dpy, "XRequest", number, "",         buffer, BUFSIZ);
                   1498:     (void) fprintf(fp, " (%s)", buffer);
                   1499:     fputs("\n  ", fp);
                   1500:     XGetErrorDatabaseText(dpy, mtype, "MinorCode", "Request Minor code", 
                   1501:        mesg, BUFSIZ);
                   1502:     (void) fprintf(fp, mesg, event->minor_code);
                   1503:     fputs("\n  ", fp);
                   1504:     XGetErrorDatabaseText(dpy, mtype, "ResourceID", "ResourceID 0x%x",
                   1505:        mesg, BUFSIZ);
                   1506:     (void) fprintf(fp, mesg, event->resourceid);
                   1507:     fputs("\n  ", fp);
                   1508:     XGetErrorDatabaseText(dpy, mtype, "ErrorSerial", "Error Serial #%d", 
                   1509:        mesg, BUFSIZ);
                   1510:     (void) fprintf(fp, mesg, event->serial);
                   1511:     fputs("\n  ", fp);
                   1512:     XGetErrorDatabaseText(dpy, mtype, "CurrentSerial", "Current Serial #%d",
                   1513:        mesg, BUFSIZ);
                   1514:     (void) fprintf(fp, mesg, dpy->request);
                   1515:     fputs("\n", fp);
                   1516:     if (event->error_code == BadImplementation) return 0;
                   1517:     return 1;
                   1518: }
                   1519: 
                   1520: int _XDefaultError(dpy, event)
                   1521:        Display *dpy;
                   1522:        XErrorEvent *event;
                   1523: {
                   1524:     if (_XPrintDefaultError (dpy, event, stderr) == 0) return 0;
                   1525:     exit(1);
                   1526:     /*NOTREACHED*/
                   1527: }
                   1528: 
                   1529: int (*_XIOErrorFunction)() = _XIOError;
                   1530: int (*_XErrorFunction)() = _XDefaultError;
                   1531: 
                   1532: /*
                   1533:  * This routine can be used to (cheaply) get some memory within a single
                   1534:  * Xlib routine for scratch space.  It is reallocated from the same place
                   1535:  * each time, unless the library needs a large scratch space.
                   1536:  */
                   1537: char *_XAllocScratch (dpy, nbytes)
                   1538:        register Display *dpy;
                   1539:        unsigned long nbytes;
                   1540: {
                   1541:        if (nbytes > dpy->scratch_length) {
                   1542:            if (dpy->scratch_buffer != NULL) Xfree (dpy->scratch_buffer);
                   1543:            return( dpy->scratch_length = nbytes, 
                   1544:            dpy->scratch_buffer = Xmalloc ((unsigned)nbytes) );
                   1545:        }
                   1546:        return (dpy->scratch_buffer);
                   1547: }
                   1548: 
                   1549: /*
                   1550:  * Given a visual id, find the visual structure for this id on this display.
                   1551:  */
                   1552: Visual *_XVIDtoVisual (dpy, id)
                   1553:        Display *dpy;
                   1554:        VisualID id;
                   1555: {
                   1556:        register int i, j, k;
                   1557:        register Screen *sp;
                   1558:        register Depth *dp;
                   1559:        register Visual *vp;
                   1560:        for (i = 0; i < dpy->nscreens; i++) {
                   1561:                sp = &dpy->screens[i];
                   1562:                for (j = 0; j < sp->ndepths; j++) {
                   1563:                        dp = &sp->depths[j];
                   1564:                        for (k = 0; k < dp->nvisuals; k++) {
                   1565:                                vp = &dp->visuals[k];
                   1566:                                if (vp->visualid == id) return (vp);
                   1567:                        }
                   1568:                }
                   1569:        }
                   1570:        return (NULL);
                   1571: }
                   1572: 
                   1573: XFree (data)
                   1574:        char *data;
                   1575: {
                   1576:        Xfree (data);
                   1577: }
                   1578: 
                   1579: #ifdef DataRoutineIsProcedure
                   1580: void Data (dpy, data, len)
                   1581:        Display *dpy;
                   1582:        char *data;
                   1583:        long len;
                   1584: {
                   1585:        if (dpy->bufptr + (len) <= dpy->bufmax) {
                   1586:                bcopy(data, dpy->bufptr, (int)len);
                   1587:                dpy->bufptr += ((len) + 3) & ~3;
                   1588:        } else {
                   1589:                _XSend(dpy, data, len);
                   1590:        }
                   1591: }
                   1592: #endif /* DataRoutineIsProcedure */
                   1593: 
                   1594: 
                   1595: #ifdef WORD64
                   1596: 
                   1597: /*
                   1598:  * XXX This is a *really* stupid way of doing this.  It should just use 
                   1599:  * dpy->bufptr directly, taking into account where in the word it is.
                   1600:  */
                   1601: 
                   1602: /*
                   1603:  * Data16 - Place 16 bit data in the buffer.
                   1604:  *
                   1605:  * "dpy" is a pointer to a Display.
                   1606:  * "data" is a pointer to the data.
                   1607:  * "len" is the length in bytes of the data.
                   1608:  */
                   1609: 
                   1610: static doData16(dpy, data, len, packbuffer)
                   1611:     register Display *dpy;
                   1612:     short *data;
                   1613:     unsigned len;
                   1614:     char *packbuffer;
                   1615: {
                   1616:     long *lp,*lpack;
                   1617:     long i, nwords,bits;
                   1618:     long mask16 = 0x000000000000ffff;
                   1619: 
                   1620:         lp = (long *)data;
                   1621:         lpack = (long *)packbuffer;
                   1622:         *lpack = 0;
                   1623: 
                   1624: /*  nwords is the number of 16 bit values to be packed,
                   1625:  *  the low order 16 bits of each word will be packed
                   1626:  *  into 64 bit words
                   1627:  */
                   1628:         nwords = len >> 1;
                   1629:         bits = 48;
                   1630: 
                   1631:         for(i=0;i<nwords;i++){
                   1632:            *lpack ^= (*lp & mask16) << bits;
                   1633:            bits -= 16 ;
                   1634:            lp++;
                   1635:            if(bits < 0){
                   1636:                lpack++;
                   1637:                *lpack = 0;
                   1638:                bits = 48;
                   1639:            }
                   1640:         }
                   1641:         Data(dpy, packbuffer, len);
                   1642: }
                   1643: 
                   1644: Data16 (dpy, data, len)
                   1645:     Display *dpy;
                   1646:     short *data;
                   1647:     unsigned len;
                   1648: {
                   1649:     char packbuffer[PACKBUFFERSIZE];
                   1650:     unsigned nwords = (PACKBUFFERSIZE >> 1);   /* bytes to CARD16 */
                   1651: 
                   1652:     for (; len > nwords; len -= nwords, data += nwords) {
                   1653:        doData16 (dpy, data, nwords, packbuffer);
                   1654:     }
                   1655:     doData16 (dpy, data, len, packbuffer);
                   1656: }
                   1657: 
                   1658: /*
                   1659:  * Data32 - Place 32 bit data in the buffer.
                   1660:  *
                   1661:  * "dpy" is a pointer to a Display.
                   1662:  * "data" is a pointer to the data.
                   1663:  * "len" is the length in bytes of the data.
                   1664:  */
                   1665: 
                   1666: static doData32 (dpy, data, len, packbuffer)
                   1667:     register Display *dpy;
                   1668:     long *data;
                   1669:     unsigned len;
                   1670:     char *packbuffer;
                   1671: {
                   1672:     long *lp,*lpack;
                   1673:     long i,bits,nwords;
                   1674:     long mask32 = 0x00000000ffffffff;
                   1675: 
                   1676:         lpack = (long *) packbuffer;
                   1677:         lp = data;
                   1678: 
                   1679:         *lpack = 0;
                   1680: 
                   1681: /*  nwords is the number of 32 bit values to be packed
                   1682:  *  the low order 32 bits of each word will be packed
                   1683:  *  into 64 bit words
                   1684:  */
                   1685:         nwords = len >> 2;
                   1686:         bits = 32;
                   1687: 
                   1688:         for(i=0;i<nwords;i++){
                   1689:            *lpack ^= (*lp & mask32) << bits;
                   1690:            bits = bits ^32;
                   1691:            lp++;
                   1692:            if(bits){
                   1693:               lpack++;
                   1694:               *lpack = 0;
                   1695:            }
                   1696:         }
                   1697:         Data(dpy, packbuffer, len);
                   1698: }
                   1699: 
                   1700: Data32 (dpy, data, len)
                   1701:     Display *dpy;
                   1702:     short *data;
                   1703:     unsigned len;
                   1704: {
                   1705:     char packbuffer[PACKBUFFERSIZE];
                   1706:     unsigned nwords = (PACKBUFFERSIZE >> 2);   /* bytes to CARD32 */
                   1707: 
                   1708:     for (; len > nwords; len -= nwords, data += nwords) {
                   1709:        doData32 (dpy, data, nwords, packbuffer);
                   1710:     }
                   1711:     doData32 (dpy, data, len, packbuffer);
                   1712: }
                   1713: 
                   1714: #endif /* WORD64 */
                   1715: 
                   1716: 
                   1717: 
                   1718: /*
                   1719:  * _XFreeQ - free the queue of events, called by XCloseDisplay when there are
                   1720:  * no more displays left on the display list
                   1721:  */
                   1722: 
                   1723: void _XFreeQ ()
                   1724: {
                   1725:     register _XQEvent *qelt = _qfree;
                   1726:   
                   1727:     while (qelt) {
                   1728:        register _XQEvent *qnext = qelt->next;
                   1729:        Xfree (qelt);
                   1730:        qelt = qnext;
                   1731:     }
                   1732:     _qfree = NULL;
                   1733:     return;
                   1734: }
                   1735: 
                   1736: 

unix.superglobalmegacorp.com

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