summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--AUTHORS1
-rw-r--r--COPYING41
-rw-r--r--Makefile.am37
-rw-r--r--README5
-rwxr-xr-xautogen.sh12
-rw-r--r--configure.ac65
-rw-r--r--include/X11/extensions/Xpresent.h127
-rw-r--r--man/Makefile.am39
-rw-r--r--man/Xpresent.man70
-rw-r--r--src/Makefile.am14
-rw-r--r--src/Xpresent.c481
-rw-r--r--xpresent.pc.in12
12 files changed, 904 insertions, 0 deletions
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 <stdint.h>
+#include <X11/extensions/presenttokens.h>
+
+#include <X11/Xfuncproto.h>
+#include <X11/Xlib.h>
+#include <X11/extensions/Xfixes.h>
+
+/*
+ * 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 <X11/extensions/Xpresent.h>
+.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 <config.h>
+#endif
+
+#include <stdint.h>
+#include <stdio.h>
+#include <X11/Xlib.h>
+#include <X11/Xlibint.h>
+#include <X11/Xutil.h>
+
+#include <X11/extensions/extutil.h>
+#include <X11/extensions/geproto.h>
+#include <X11/extensions/ge.h>
+#include <X11/extensions/Xge.h>
+
+#include <X11/extensions/Xpresent.h>
+#include <X11/extensions/presentproto.h>
+
+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