diff options
Diffstat (limited to 'libX11/src/xcb_lock.c')
-rw-r--r-- | libX11/src/xcb_lock.c | 235 |
1 files changed, 0 insertions, 235 deletions
diff --git a/libX11/src/xcb_lock.c b/libX11/src/xcb_lock.c deleted file mode 100644 index 71b238354..000000000 --- a/libX11/src/xcb_lock.c +++ /dev/null @@ -1,235 +0,0 @@ -/* Copyright (C) 2003-2006 Jamey Sharp, Josh Triplett - * This file is licensed under the MIT license. See the file COPYING. */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include "Xlibint.h" -#include "locking.h" -#include "Xxcbint.h" -#include <xcb/xcbext.h> -#include <xcb/xcbxlib.h> - -#include <pthread.h> - -static void _XCBLockDisplay(Display *dpy) -{ - if(dpy->xcb->lock_fns.lock_display) - dpy->xcb->lock_fns.lock_display(dpy); - if(!dpy->lock || dpy->lock->locking_level == 0) - xcb_xlib_lock(dpy->xcb->connection); - if(!(dpy->flags & XlibDisplayIOError)) - _XGetXCBBuffer(dpy); -} - -/* XXX: If you change this function, update _XReply's copy of its guts! */ -static void _XCBUnlockDisplay(Display *dpy) -{ - if(!(dpy->flags & XlibDisplayIOError)) - { - _XPutXCBBuffer(dpy); - assert(dpy->xcb->partial_request == 0); - assert(xcb_get_request_sent(dpy->xcb->connection) == dpy->request); - - /* Traditional Xlib does this in _XSend; see the Xlib/XCB version - * of that function for why we do it here instead. */ - _XSetSeqSyncFunction(dpy); - } - - if(!dpy->lock || dpy->lock->locking_level == 0) - xcb_xlib_unlock(dpy->xcb->connection); - if(dpy->xcb->lock_fns.unlock_display) - dpy->xcb->lock_fns.unlock_display(dpy); -} - -int _XCBInitDisplayLock(Display *dpy) -{ - if(!dpy->lock_fns && !(dpy->lock_fns = Xcalloc(1, sizeof(*dpy->lock_fns)))) - return 0; - dpy->xcb->lock_fns.lock_display = dpy->lock_fns->lock_display; - dpy->lock_fns->lock_display = _XCBLockDisplay; - dpy->xcb->lock_fns.unlock_display = dpy->lock_fns->unlock_display; - dpy->lock_fns->unlock_display = _XCBUnlockDisplay; - return 1; -} - -void _XCBShutdownDisplayLock(Display *dpy) -{ - if(dpy->lock_fns) { - Xfree((char *)dpy->lock_fns); - dpy->lock_fns = NULL; - } -} - -void _XGetXCBBuffer(Display *dpy) -{ - static const xReq dummy_request; - unsigned int xcb_req = xcb_get_request_sent(dpy->xcb->connection); - if(xcb_connection_has_error(dpy->xcb->connection)) - _XIOError(dpy); - - /* if Xlib has a partial request pending then XCB doesn't know about - * the current request yet */ - if(dpy->xcb->partial_request) - ++xcb_req; - - assert(XCB_SEQUENCE_COMPARE(xcb_req, >=, dpy->request)); - dpy->request = xcb_req; - - dpy->last_req = (char *) &dummy_request; -} - -static size_t request_length(struct iovec *vec) -{ - /* we have at least part of a request. dig out the length field. - * note that length fields are always in vec[0]: Xlib doesn't split - * fixed-length request parts. */ - size_t len; - assert(vec[0].iov_len >= 4); - len = ((uint16_t *) vec[0].iov_base)[1]; - if(len == 0) - { - /* it's a bigrequest. dig out the *real* length field. */ - assert(vec[0].iov_len >= 8); - len = ((uint32_t *) vec[0].iov_base)[1]; - } - return len << 2; -} - -static inline int issue_complete_request(Display *dpy, int veclen, struct iovec *vec) -{ - xcb_protocol_request_t xcb_req = { 0 }; - unsigned int sequence; - int flags = XCB_REQUEST_RAW; - int i; - size_t len; - - /* skip empty iovecs. if no iovecs remain, we're done. */ - assert(veclen >= 0); - while(veclen > 0 && vec[0].iov_len == 0) - --veclen, ++vec; - if(!veclen) - return 0; - - len = request_length(vec); - - /* do we have enough data for a complete request? how many iovec - * elements does it span? */ - for(i = 0; i < veclen; ++i) - { - size_t oldlen = len; - len -= vec[i].iov_len; - /* if len is now 0 or has wrapped, we have enough data. */ - if((len - 1) > oldlen) - break; - } - if(i == veclen) - return 0; - - /* we have enough data to issue one complete request. the remaining - * code can't fail. */ - - /* len says how far we overshot our data needs. (it's "negative" if - * we actually overshot, or 0 if we're right on.) */ - vec[i].iov_len += len; - xcb_req.count = i + 1; - xcb_req.opcode = ((uint8_t *) vec[0].iov_base)[0]; - - /* if we don't own the event queue, we have to ask XCB to set our - * errors aside for us. */ - if(dpy->xcb->event_owner != XlibOwnsEventQueue) - flags |= XCB_REQUEST_CHECKED; - - /* XCB will always skip request 0; account for that in the Xlib count */ - if (xcb_get_request_sent(dpy->xcb->connection) == 0xffffffff) - dpy->request++; - /* send the accumulated request. */ - sequence = xcb_send_request(dpy->xcb->connection, flags, vec, &xcb_req); - if(!sequence) - _XIOError(dpy); - - /* update the iovecs to refer only to data not yet sent. */ - vec[i].iov_len = -len; - - /* iff we asked XCB to set aside errors, we must pick those up - * eventually. iff there are async handlers, we may have just - * issued requests that will generate replies. in either case, - * we need to remember to check later. */ - if(flags & XCB_REQUEST_CHECKED || dpy->async_handlers) - { - PendingRequest *req = malloc(sizeof(PendingRequest)); - assert(req); - req->next = 0; - req->waiters = -1; - req->sequence = sequence; - *dpy->xcb->pending_requests_tail = req; - dpy->xcb->pending_requests_tail = &req->next; - } - return 1; -} - -void _XPutXCBBuffer(Display *dpy) -{ - static char const pad[3]; - const int padsize = -dpy->xcb->request_extra_size & 3; - xcb_connection_t *c = dpy->xcb->connection; - _XExtension *ext; - struct iovec iov[6]; - - assert_sequence_less(dpy->last_request_read, dpy->request); - assert_sequence_less(xcb_get_request_sent(c), dpy->request); - - for(ext = dpy->flushes; ext; ext = ext->next_flush) - { - ext->before_flush(dpy, &ext->codes, dpy->buffer, dpy->bufptr - dpy->buffer); - if(dpy->xcb->request_extra) - { - ext->before_flush(dpy, &ext->codes, dpy->xcb->request_extra, dpy->xcb->request_extra_size); - if(padsize) - ext->before_flush(dpy, &ext->codes, pad, padsize); - } - } - - iov[2].iov_base = dpy->xcb->partial_request; - iov[2].iov_len = dpy->xcb->partial_request_offset; - iov[3].iov_base = dpy->buffer; - iov[3].iov_len = dpy->bufptr - dpy->buffer; - iov[4].iov_base = (caddr_t) dpy->xcb->request_extra; - iov[4].iov_len = dpy->xcb->request_extra_size; - iov[5].iov_base = (caddr_t) pad; - iov[5].iov_len = padsize; - - while(issue_complete_request(dpy, 4, iov + 2)) - /* empty */; - - /* first discard any completed partial_request. */ - if(iov[2].iov_len == 0 && dpy->xcb->partial_request) - { - free(dpy->xcb->partial_request); - dpy->xcb->partial_request = 0; - dpy->xcb->partial_request_offset = 0; - } - - /* is there anything to copy into partial_request? */ - if(iov[3].iov_len != 0 || iov[4].iov_len != 0 || iov[5].iov_len != 0) - { - int i; - if(!dpy->xcb->partial_request) - { - size_t len = request_length(iov + 3); - assert(!dpy->xcb->partial_request_offset); - dpy->xcb->partial_request = malloc(len); - assert(dpy->xcb->partial_request); - } - for(i = 3; i < sizeof(iov) / sizeof(*iov); ++i) - { - memcpy(dpy->xcb->partial_request + dpy->xcb->partial_request_offset, iov[i].iov_base, iov[i].iov_len); - dpy->xcb->partial_request_offset += iov[i].iov_len; - } - } - - dpy->xcb->request_extra = 0; - dpy->xcb->request_extra_size = 0; - dpy->bufptr = dpy->buffer; -} |