Annotation of 43BSDReno/contrib/isode-beta/others/X/client/XlibInt.c, revision 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.