From 0c90a6e5f8e127d179d870a7fdad660acb9299c7 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Thu, 12 Sep 2013 17:15:33 -0700 Subject: Initial import of Xlib Present binding Signed-off-by: Keith Packard --- AUTHORS | 1 + COPYING | 41 ++++ Makefile.am | 37 +++ README | 5 + autogen.sh | 12 + configure.ac | 65 ++++++ include/X11/extensions/Xpresent.h | 127 ++++++++++ man/Makefile.am | 39 ++++ man/Xpresent.man | 70 ++++++ src/Makefile.am | 14 ++ src/Xpresent.c | 481 ++++++++++++++++++++++++++++++++++++++ xpresent.pc.in | 12 + 12 files changed, 904 insertions(+) create mode 100644 AUTHORS create mode 100644 COPYING create mode 100644 Makefile.am create mode 100644 README create mode 100755 autogen.sh create mode 100644 configure.ac create mode 100644 include/X11/extensions/Xpresent.h create mode 100644 man/Makefile.am create mode 100644 man/Xpresent.man create mode 100644 src/Makefile.am create mode 100644 src/Xpresent.c create mode 100644 xpresent.pc.in diff --git a/AUTHORS b/AUTHORS new file mode 100644 index 0000000..744c0d9 --- /dev/null +++ b/AUTHORS @@ -0,0 +1 @@ +Keith Packard, Intel diff --git a/COPYING b/COPYING new file mode 100644 index 0000000..66012a9 --- /dev/null +++ b/COPYING @@ -0,0 +1,41 @@ + +Copyright © 2001,2003 Keith Packard + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation, and that the name of Keith Packard not be used in +advertising or publicity pertaining to distribution of the software without +specific, written prior permission. Keith Packard makes no +representations about the suitability of this software for any purpose. It +is provided "as is" without express or implied warranty. + +KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, +INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO +EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR +CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, +DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER +TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +PERFORMANCE OF THIS SOFTWARE. + +Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved. + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the "Software"), +to deal in the Software without restriction, including without limitation +the rights to use, copy, modify, merge, publish, distribute, sublicense, +and/or sell copies of the Software, and to permit persons to whom the +Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice (including the next +paragraph) shall be included in all copies or substantial portions of the +Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. diff --git a/Makefile.am b/Makefile.am new file mode 100644 index 0000000..3972ddb --- /dev/null +++ b/Makefile.am @@ -0,0 +1,37 @@ +# +# Copyright © 2013 Keith Packard +# +# Permission to use, copy, modify, distribute, and sell this software and its +# documentation for any purpose is hereby granted without fee, provided that +# the above copyright notice appear in all copies and that both that +# copyright notice and this permission notice appear in supporting +# documentation, and that the name of Keith Packard not be used in +# advertising or publicity pertaining to distribution of the software without +# specific, written prior permission. Keith Packard makes no +# representations about the suitability of this software for any purpose. It +# is provided "as is" without express or implied warranty. +# +# KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, +# INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO +# EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR +# CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, +# DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER +# TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +# PERFORMANCE OF THIS SOFTWARE. + +SUBDIRS = src man + +pkgconfigdir = $(libdir)/pkgconfig +pkgconfig_DATA = xpresent.pc + +MAINTAINERCLEANFILES = ChangeLog INSTALL + +.PHONY: ChangeLog INSTALL + +INSTALL: + $(INSTALL_CMD) + +ChangeLog: + $(CHANGELOG_CMD) + +dist-hook: ChangeLog INSTALL diff --git a/README b/README new file mode 100644 index 0000000..bb3e0b2 --- /dev/null +++ b/README @@ -0,0 +1,5 @@ +This package contains header files and documentation for the Present +extension. Library and server implementations are separate. + +Keith Packard +keithp@keithp.com diff --git a/autogen.sh b/autogen.sh new file mode 100755 index 0000000..904cd67 --- /dev/null +++ b/autogen.sh @@ -0,0 +1,12 @@ +#! /bin/sh + +srcdir=`dirname $0` +test -z "$srcdir" && srcdir=. + +ORIGDIR=`pwd` +cd $srcdir + +autoreconf -v --install || exit 1 +cd $ORIGDIR || exit $? + +$srcdir/configure --enable-maintainer-mode "$@" diff --git a/configure.ac b/configure.ac new file mode 100644 index 0000000..51d3f96 --- /dev/null +++ b/configure.ac @@ -0,0 +1,65 @@ +# +# Copyright © 2012 Keith Packard +# +# Permission to use, copy, modify, distribute, and sell this software and its +# documentation for any purpose is hereby granted without fee, provided that +# the above copyright notice appear in all copies and that both that +# copyright notice and this permission notice appear in supporting +# documentation, and that the name of Keith Packard not be used in +# advertising or publicity pertaining to distribution of the software without +# specific, written prior permission. Keith Packard makes no +# representations about the suitability of this software for any purpose. It +# is provided "as is" without express or implied warranty. +# +# KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, +# INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO +# EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR +# CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, +# DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER +# TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +# PERFORMANCE OF THIS SOFTWARE. +# + +# Initialize Autoconf +AC_PREREQ([2.60]) + +# +# Version should match the current XPresent version. XPresentQueryVersion +# returns the version from xpresentwire.h, NOT the version we set here. But we +# try to keep these the same. Note that the library has an extra +# digit in the version number to track changes which don't affect the +# protocol, so Xpresent version l.n.m corresponds to protocol version l.n, +# that 'revision' number appears in Xpresent.h and has to be manually +# synchronized. +# +AC_INIT(libXpresent, [1.0.0], + [https://bugs.freedesktop.org/enter_bug.cgi?product=xorg], [libXpresent]) +AC_CONFIG_SRCDIR([Makefile.am]) +AC_CONFIG_HEADERS([config.h]) + +# Initialize Automake +AM_INIT_AUTOMAKE([foreign dist-bzip2]) +AM_MAINTAINER_MODE + +# Initialize libtool +AC_PROG_LIBTOOL + +# Require xorg-macros 1.8 or later for MAN_SUBSTS set by XORG_MANPAGE_SECTIONS +m4_ifndef([XORG_MACROS_VERSION], + [m4_fatal([must install xorg-macros 1.8 or later before running autoconf/autogen])]) +XORG_MACROS_VERSION(1.8) +XORG_DEFAULT_OPTIONS + +# Check presentext configuration, strip extra digits from package version to +# find the required protocol version +PRESENTEXT_VERSION=[`echo $VERSION | sed 's/^\([0-9][0-9]*\.[0-9][0-9]*\).*$/\1/'`] +AC_SUBST(PRESENTEXT_VERSION) + +# Obtain compiler/linker options for depedencies +PKG_CHECK_MODULES(PRESENTEXT, xproto [presentproto >= $PRESENTEXT_VERSION] xextproto x11) + +AC_CONFIG_FILES([Makefile + src/Makefile + man/Makefile + xpresent.pc]) +AC_OUTPUT diff --git a/include/X11/extensions/Xpresent.h b/include/X11/extensions/Xpresent.h new file mode 100644 index 0000000..b253870 --- /dev/null +++ b/include/X11/extensions/Xpresent.h @@ -0,0 +1,127 @@ +/* + * Copyright © 2013 Keith Packard + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that copyright + * notice and this permission notice appear in supporting documentation, and + * that the name of the copyright holders not be used in advertising or + * publicity pertaining to distribution of the software without specific, + * written prior permission. The copyright holders make no representations + * about the suitability of this software for any purpose. It is provided "as + * is" without express or implied warranty. + * + * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * OF THIS SOFTWARE. + */ + +#ifndef _XPRESENT_H_ +#define _XPRESENT_H_ + +#include +#include + +#include +#include +#include + +/* + * This revision number also appears in configure.ac, they have + * to be manually synchronized + */ +#define PRESENT_REVISION 0 +#define PRESENT_VERSION ((PRESENT_MAJOR * 10000) + (PRESENT_MINOR * 100) + (PRESENT_REVISION)) + +/** + * Generic Present event. All Present events have the same header. + */ + +typedef struct { + int type; /* event base */ + unsigned long serial; + Bool send_event; + Display *display; + int extension; + int evtype; +} XPresentEvent; + +typedef struct { + int type; /* event base */ + unsigned long serial; + Bool send_event; + Display *display; + int extension; + int evtype; + + uint32_t eid; + Window window; + int x,y; + unsigned width, height; + int off_x, off_y; + int pixmap_width, pixmap_height; + long pixmap_flags; +} XPresentConfigureNotifyEvent; + +typedef struct { + int type; /* event base */ + unsigned long serial; + Bool send_event; + Display *display; + int extension; + int evtype; + + uint32_t eid; + Window window; + uint32_t serial_number; + uint64_t ust; + uint64_t msc; +} XPresentCompleteNotifyEvent; + +_XFUNCPROTOBEGIN + +Bool XPresentQueryExtension (Display *dpy, + int *major_opcode_return, + int *event_base_return, + int *error_base_return); + +Status XPresentQueryVersion (Display *dpy, + int *major_version_return, + int *minor_version_return); + +int XPresentVersion (void); + +void +XPresentRegion(Display *dpy, + Window window, + Pixmap pixmap, + uint32_t serial, + XserverRegion valid, + XserverRegion update, + int x_off, + int y_off, + XID idle_fence, + uint64_t target_msc, + uint64_t divisor, + uint64_t remainder); + +void +XPresentNotifyMSC(Display *dpy, + Window window, + uint32_t serial, + uint64_t target_msc, + uint64_t divisor, + uint64_t remainder); + +XID +XPresentSelectInput(Display *dpy, + Window window, + unsigned event_mask); + +_XFUNCPROTOEND + +#endif /* _XPRESENT_H_ */ diff --git a/man/Makefile.am b/man/Makefile.am new file mode 100644 index 0000000..0e9f4a4 --- /dev/null +++ b/man/Makefile.am @@ -0,0 +1,39 @@ +# +# Copyright (c) 2005, Oracle and/or its affiliates. All rights reserved. +# +# Permission is hereby granted, free of charge, to any person obtaining a +# copy of this software and associated documentation files (the "Software"), +# to deal in the Software without restriction, including without limitation +# the rights to use, copy, modify, merge, publish, distribute, sublicense, +# and/or sell copies of the Software, and to permit persons to whom the +# Software is furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice (including the next +# paragraph) shall be included in all copies or substantial portions of the +# Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +# DEALINGS IN THE SOFTWARE. +# + +libmandir = $(LIB_MAN_DIR) + +libman_PRE = Xpresent.man + +libman_DATA = $(libman_PRE:man=@LIB_MAN_SUFFIX@) + +EXTRA_DIST = $(libman_PRE) + +CLEANFILES = $(libman_DATA) + +# String replacements for man pages now come from xorg-macros.m4 via configure + +SUFFIXES = .$(LIB_MAN_SUFFIX) .man + +.man.$(LIB_MAN_SUFFIX): + $(AM_V_GEN)$(SED) $(MAN_SUBSTS) < $< > $@ diff --git a/man/Xpresent.man b/man/Xpresent.man new file mode 100644 index 0000000..f615d69 --- /dev/null +++ b/man/Xpresent.man @@ -0,0 +1,70 @@ +.\" +.\" +.\" Copyright © 2013 Keith Packard +.\" +.\" Permission to use, copy, modify, distribute, and sell this software and its +.\" documentation for any purpose is hereby granted without fee, provided that +.\" the above copyright notice appear in all copies and that both that copyright +.\" notice and this permission notice appear in supporting documentation, and +.\" that the name of the copyright holders not be used in advertising or +.\" publicity pertaining to distribution of the software without specific, +.\" written prior permission. The copyright holders make no representations +.\" about the suitability of this software for any purpose. It is provided "as +.\" is" without express or implied warranty. +.\" +.\" THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, +.\" INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO +.\" EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR +.\" CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, +.\" DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER +.\" TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE +.\" OF THIS SOFTWARE. +.\" +.de TQ +.br +.ns +.TP \\$1 +.. +.TH XPRESENT __libmansuffix__ __xorgversion__ + +.SH NAME +Xpresent \- X Present Extension +.SH SYNTAX +\&#include +.nf +.sp +Bool XPresentQueryExtension \^(\^Display *\fIdpy\fP, + int *\fIevent_base_return\fP, int *\fIerror_base_return\fP\^); +.sp +Status XPresentQueryVersion \^(\^Display *\fIdpy\fP, + int *\fImajor_version_return\fP, + int *\fIminor_version_return\fP\^); +.sp +void XPresentRegion \^(\^Display *dpy, + Window \fIwindow\fP, + Pixmap \fIpixmap\fP, + uint32_t serial, + XserverRegion valid, + XserverRegion update, + int x_off, + int y_off, + XID idle_fence, + XID target_crtc, + uint64_t target_msc, + uint64_t divisor, + uint64_t remainder); +.fi +.SH ARGUMENTS +.IP \fIdisplay\fP 1i +Specifies the connection to the X server. +.IP \fIwindow\fP 1i +Specifies which window. +.SH DESCRIPTION +.B Xpresent +is a library designed to interface the X Present +Extension. +.SH RESTRICTIONS +.B Xpresent +will remain upward compatible after the 1.0 release. +.SH AUTHORS +Keith Packard, Intel diff --git a/src/Makefile.am b/src/Makefile.am new file mode 100644 index 0000000..925d224 --- /dev/null +++ b/src/Makefile.am @@ -0,0 +1,14 @@ +lib_LTLIBRARIES = libXpresent.la + +libXpresent_la_SOURCES = Xpresent.c + +libXpresent_la_LIBADD = @PRESENTEXT_LIBS@ +AM_CFLAGS = $(CWARNFLAGS) @PRESENTEXT_CFLAGS@ + +AM_CPPFLAGS = -I$(top_srcdir)/include + +libXpresent_la_LDFLAGS = -version-number 1:0:0 -no-undefined + +libXpresentincludedir = $(includedir)/X11/extensions +libXpresentinclude_HEADERS = $(top_srcdir)/include/X11/extensions/Xpresent.h + diff --git a/src/Xpresent.c b/src/Xpresent.c new file mode 100644 index 0000000..ffe82d7 --- /dev/null +++ b/src/Xpresent.c @@ -0,0 +1,481 @@ +/* + * Copyright © 2013 Keith Packard + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that copyright + * notice and this permission notice appear in supporting documentation, and + * that the name of the copyright holders not be used in advertising or + * publicity pertaining to distribution of the software without specific, + * written prior permission. The copyright holders make no representations + * about the suitability of this software for any purpose. It is provided "as + * is" without express or implied warranty. + * + * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * OF THIS SOFTWARE. + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include + +typedef struct _XPresentExtDisplayInfo { + struct _XPresentExtDisplayInfo *next; /* keep a linked list */ + Display *display; /* which display this is */ + XExtCodes *codes; /* the extension protocol codes */ + int major_version; /* -1 means we don't know */ + int minor_version; /* -1 means we don't know */ +} XPresentExtDisplayInfo; + +/* replaces XExtensionInfo */ +typedef struct _XPresentExtInfo { + XPresentExtDisplayInfo *head; /* start of the list */ + XPresentExtDisplayInfo *cur; /* most recently used */ + int ndisplays; /* number of displays */ +} XPresentExtInfo; + +extern XPresentExtInfo XPresentExtensionInfo; +extern char XPresentExtensionName[]; + +XPresentExtDisplayInfo * +XPresentFindDisplay (Display *dpy); + +#define XPresentHasExtension(i) ((i) && ((i)->codes)) + +#define XPresentCheckExtension(dpy,i,val) \ + if (!XPresentHasExtension(i)) { return val; } + +#define XPresentSimpleCheckExtension(dpy,i) \ + if (!XPresentHasExtension(i)) { return; } + +XPresentExtInfo XPresentExtensionInfo; +char XPresentExtensionName[] = PRESENT_NAME; + +static int +XPresentCloseDisplay (Display *dpy, XExtCodes *codes); + +static Bool +XPresentCopyCookie(Display *dpy, + XGenericEventCookie *in, + XGenericEventCookie *out) +{ + int ret = True; + XPresentExtDisplayInfo *info = XPresentFindDisplay(dpy); + + if (in->extension != info->codes->major_opcode) + { + printf("XFixesCopyCookie: wrong extension opcode %d\n", + in->extension); + return False; + } + + *out = *in; + out->data = NULL; + out->cookie = 0; + + switch(in->evtype) { + case PresentConfigureNotify: + case PresentCompleteNotify: + case PresentRedirectNotify: + break; + default: + printf("XPresentCopyCookie: unknown evtype %d\n", in->evtype); + ret = False; + } + + if (!ret) + printf("XPresentCopyCookie: Failed to copy evtype %d", in->evtype); + return ret; +} + +static Bool +XPresentWireToCookie(Display *dpy, + XGenericEventCookie *cookie, + xEvent *wire_event) +{ + XPresentExtDisplayInfo *info = XPresentFindDisplay(dpy); + xGenericEvent *ge = (xGenericEvent*)wire_event; + + if (ge->extension != info->codes->major_opcode) + { + printf("XInputWireToCookie: wrong extension opcode %d\n", + ge->extension); + return False; + } + + cookie->type = ge->type & 0x7f; + cookie->serial = _XSetLastRequestRead(dpy, (xGenericReply *) ge); + cookie->send_event = ((ge->type & 0x80) != 0); + cookie->display = dpy; + cookie->extension = ge->extension; + cookie->evtype = ge->evtype; + + switch(ge->evtype) { + case PresentConfigureNotify: { + xPresentConfigureNotify *proto = (xPresentConfigureNotify *) ge; + XPresentConfigureNotifyEvent *ce = malloc (sizeof (XPresentConfigureNotifyEvent)); + cookie->data = ce; + + ce->type = cookie->type; + ce->serial = cookie->serial; + ce->send_event = cookie->send_event; + ce->display = cookie->display; + ce->extension = cookie->extension; + ce->evtype = cookie->evtype; + + ce->eid = proto->eid; + ce->window = proto->window; + ce->x = proto->x; + ce->y = proto->y; + ce->width = proto->width; + ce->height = proto->height; + ce->off_x = proto->off_x; + ce->off_y = proto->off_y; + ce->pixmap_width = proto->pixmap_width; + ce->pixmap_height = proto->pixmap_height; + ce->pixmap_flags = proto->pixmap_flags; + + break; + } + case PresentCompleteNotify: { + xPresentCompleteNotify *proto = (xPresentCompleteNotify *) ge; + XPresentCompleteNotifyEvent *ce = malloc (sizeof (XPresentCompleteNotifyEvent)); + cookie->data = ce; + + ce->type = cookie->type; + ce->serial = cookie->serial; + ce->send_event = cookie->send_event; + ce->display = cookie->display; + ce->extension = cookie->extension; + ce->evtype = cookie->evtype; + + ce->eid = proto->eid; + ce->window = proto->window; + ce->serial_number = proto->serial; + ce->ust = proto->ust; + ce->msc = proto->msc; + + break; + } + case PresentRedirectNotify: + break; + default: + printf("XPresentWireToCookie: Unknown generic event. type %d\n", ge->evtype); + + } + return False; +} + +/* + * XPresentExtAddDisplay - add a display to this extension. (Replaces + * XextAddDisplay) + */ +static XPresentExtDisplayInfo * +XPresentExtAddDisplay (XPresentExtInfo *extinfo, + Display *dpy, + char *ext_name) +{ + XPresentExtDisplayInfo *info; + + info = (XPresentExtDisplayInfo *) Xmalloc (sizeof (XPresentExtDisplayInfo)); + if (!info) return NULL; + info->display = dpy; + + info->codes = XInitExtension (dpy, ext_name); + + /* + * if the server has the extension, then we can initialize the + * appropriate function vectors + */ + if (info->codes) { + xPresentQueryVersionReply rep; + xPresentQueryVersionReq *req; + + XESetCloseDisplay (dpy, info->codes->extension, XPresentCloseDisplay); + + XESetWireToEventCookie(dpy, info->codes->major_opcode, XPresentWireToCookie); + XESetCopyEventCookie(dpy, info->codes->major_opcode, XPresentCopyCookie); + + /* + * Get the version info + */ + LockDisplay (dpy); + GetReq (PresentQueryVersion, req); + req->reqType = info->codes->major_opcode; + req->presentReqType = X_PresentQueryVersion; + req->majorVersion = PRESENT_MAJOR; + req->minorVersion = PRESENT_MINOR; + if (!_XReply (dpy, (xReply *) &rep, 0, xTrue)) + { + UnlockDisplay (dpy); + SyncHandle (); + Xfree(info); + return NULL; + } + info->major_version = rep.majorVersion; + info->minor_version = rep.minorVersion; + UnlockDisplay (dpy); + SyncHandle (); + } else { + /* The server doesn't have this extension. + * Use a private Xlib-internal extension to hang the close_display + * hook on so that the "cache" (extinfo->cur) is properly cleaned. + * (XBUG 7955) + */ + XExtCodes *codes = XAddExtension(dpy); + if (!codes) { + XFree(info); + return NULL; + } + XESetCloseDisplay (dpy, codes->extension, XPresentCloseDisplay); + } + + /* + * now, chain it onto the list + */ + _XLockMutex(_Xglobal_lock); + info->next = extinfo->head; + extinfo->head = info; + extinfo->cur = info; + extinfo->ndisplays++; + _XUnlockMutex(_Xglobal_lock); + return info; +} + + +/* + * XPresentExtRemoveDisplay - remove the indicated display from the + * extension object. (Replaces XextRemoveDisplay.) + */ +static int +XPresentExtRemoveDisplay (XPresentExtInfo *extinfo, Display *dpy) +{ + XPresentExtDisplayInfo *info, *prev; + + /* + * locate this display and its back link so that it can be removed + */ + _XLockMutex(_Xglobal_lock); + prev = NULL; + for (info = extinfo->head; info; info = info->next) { + if (info->display == dpy) break; + prev = info; + } + if (!info) { + _XUnlockMutex(_Xglobal_lock); + return 0; /* hmm, actually an error */ + } + + /* + * remove the display from the list; handles going to zero + */ + if (prev) + prev->next = info->next; + else + extinfo->head = info->next; + + extinfo->ndisplays--; + if (info == extinfo->cur) extinfo->cur = NULL; /* flush cache */ + _XUnlockMutex(_Xglobal_lock); + + Xfree ((char *) info); + return 1; +} + +/* + * XPresentExtFindDisplay - look for a display in this extension; keeps a + * cache of the most-recently used for efficiency. (Replaces + * XextFindDisplay.) + */ +static XPresentExtDisplayInfo * +XPresentExtFindDisplay (XPresentExtInfo *extinfo, + Display *dpy) +{ + XPresentExtDisplayInfo *info; + + /* + * see if this was the most recently accessed display + */ + if ((info = extinfo->cur) && info->display == dpy) + return info; + + /* + * look for display in list + */ + _XLockMutex(_Xglobal_lock); + for (info = extinfo->head; info; info = info->next) { + if (info->display == dpy) { + extinfo->cur = info; /* cache most recently used */ + _XUnlockMutex(_Xglobal_lock); + return info; + } + } + _XUnlockMutex(_Xglobal_lock); + + return NULL; +} + +XPresentExtDisplayInfo * +XPresentFindDisplay (Display *dpy) +{ + XPresentExtDisplayInfo *info; + + info = XPresentExtFindDisplay (&XPresentExtensionInfo, dpy); + if (!info) + info = XPresentExtAddDisplay (&XPresentExtensionInfo, dpy, + XPresentExtensionName); + return info; +} + +static int +XPresentCloseDisplay (Display *dpy, XExtCodes *codes) +{ + return XPresentExtRemoveDisplay (&XPresentExtensionInfo, dpy); +} + +Bool +XPresentQueryExtension (Display *dpy, + int *major_opcode_return, + int *event_base_return, + int *error_base_return) +{ + XPresentExtDisplayInfo *info = XPresentFindDisplay (dpy); + + if (XPresentHasExtension(info)) + { + if (major_opcode_return) + *major_opcode_return = info->codes->major_opcode; + if (event_base_return) + *event_base_return = info->codes->first_event; + if (error_base_return) + *error_base_return = info->codes->first_error; + return True; + } + else + return False; +} + +Status +XPresentQueryVersion (Display *dpy, + int *major_version_return, + int *minor_version_return) +{ + XPresentExtDisplayInfo *info = XPresentFindDisplay (dpy); + + XPresentCheckExtension (dpy, info, 0); + + *major_version_return = info->major_version; + *minor_version_return = info->minor_version; + return 1; +} + +int +XPresentVersion (void) +{ + return PRESENT_VERSION; +} + +void +XPresentRegion(Display *dpy, + Window window, + Pixmap pixmap, + uint32_t serial, + XserverRegion valid, + XserverRegion update, + int x_off, + int y_off, + XID idle_fence, + uint64_t target_msc, + uint64_t divisor, + uint64_t remainder) +{ + XPresentExtDisplayInfo *info = XPresentFindDisplay (dpy); + xPresentRegionReq *req; + + XPresentSimpleCheckExtension (dpy, info); + + LockDisplay (dpy); + GetReq(PresentRegion, req); + req->reqType = info->codes->major_opcode; + req->presentReqType = X_PresentRegion; + req->window = window; + req->pixmap = pixmap; + req->serial = serial; + req->valid = valid; + req->update = update; + req->x_off = x_off; + req->y_off = y_off; + req->idle_fence = idle_fence; + req->target_msc = target_msc; + req->divisor = divisor; + req->remainder = remainder; + UnlockDisplay (dpy); + SyncHandle(); +} + +void +XPresentNotifyMSC(Display *dpy, + Window window, + uint32_t serial, + uint64_t target_msc, + uint64_t divisor, + uint64_t remainder) +{ + XPresentExtDisplayInfo *info = XPresentFindDisplay (dpy); + xPresentNotifyMSCReq *req; + + XPresentSimpleCheckExtension (dpy, info); + + LockDisplay (dpy); + GetReq(PresentNotifyMSC, req); + req->reqType = info->codes->major_opcode; + req->presentReqType = X_PresentNotifyMSC; + req->window = window; + req->serial = serial; + req->target_msc = target_msc; + req->divisor = divisor; + req->remainder = remainder; + UnlockDisplay (dpy); + SyncHandle(); +} + +XID +XPresentSelectInput(Display *dpy, + Window window, + unsigned event_mask) +{ + XPresentExtDisplayInfo *info = XPresentFindDisplay (dpy); + XID eid; + xPresentSelectInputReq *req; + + XPresentCheckExtension (dpy, info, 0); + LockDisplay (dpy); + GetReq(PresentSelectInput, req); + req->reqType = info->codes->major_opcode; + req->presentReqType = X_PresentSelectInput; + req->eid = eid = XAllocID(dpy); + req->window = window; + req->eventMask = event_mask; + UnlockDisplay (dpy); + SyncHandle(); + return eid; +} diff --git a/xpresent.pc.in b/xpresent.pc.in new file mode 100644 index 0000000..d5d0d38 --- /dev/null +++ b/xpresent.pc.in @@ -0,0 +1,12 @@ +prefix=@prefix@ +exec_prefix=@exec_prefix@ +libdir=@libdir@ +includedir=@includedir@ + +Name: Xpresent +Description: X Present Library +Version: @PACKAGE_VERSION@ +Requires: xproto presentproto >= @PRESENTEXT_VERSION@ +Requires.private: x11 +Cflags: -I${includedir} +Libs: -L${libdir} -lXpresent -- cgit v1.2.3