summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/Xcomposite.c333
-rw-r--r--src/xcompositeint.h66
2 files changed, 399 insertions, 0 deletions
diff --git a/src/Xcomposite.c b/src/Xcomposite.c
new file mode 100644
index 0000000..e056edd
--- /dev/null
+++ b/src/Xcomposite.c
@@ -0,0 +1,333 @@
+/*
+ * $Id$
+ *
+ * Copyright © 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.
+ */
+
+#include "xcompositeint.h"
+
+XCompositeExtInfo XCompositeExtensionInfo;
+
+const char XCompositeExtensionName[] = COMPOSITE_NAME;
+
+/*
+ * XCompositeExtRemoveDisplay - remove the indicated display from the
+ * extension object. (Replaces XextRemoveDisplay.)
+ */
+static int
+XCompositeExtRemoveDisplay (XCompositeExtInfo *extinfo, Display *dpy)
+{
+ XCompositeExtDisplayInfo *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;
+}
+
+static int
+XCompositeCloseDisplay (Display *dpy, XExtCodes *codes)
+{
+ return XCompositeExtRemoveDisplay (&XCompositeExtensionInfo, dpy);
+}
+
+/*
+ * XCompositeExtAddDisplay - add a display to this extension. (Replaces
+ * XextAddDisplay)
+ */
+static XCompositeExtDisplayInfo *
+XCompositeExtAddDisplay (XCompositeExtInfo *extinfo,
+ Display *dpy,
+ const char *ext_name)
+{
+ XCompositeExtDisplayInfo *info;
+ int ev;
+
+ info = (XCompositeExtDisplayInfo *) Xmalloc (sizeof (XCompositeExtDisplayInfo));
+ 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) {
+ xCompositeQueryVersionReply rep;
+ xCompositeQueryVersionReq *req;
+ XESetCloseDisplay (dpy, info->codes->extension,
+ XCompositeCloseDisplay);
+ /*
+ * Get the version info
+ */
+ LockDisplay (dpy);
+ GetReq (CompositeQueryVersion, req);
+ req->reqType = info->codes->major_opcode;
+ req->compositeReqType = X_CompositeQueryVersion;
+ req->majorVersion = COMPOSITE_MAJOR;
+ req->minorVersion = COMPOSITE_MINOR;
+ if (!_XReply (dpy, (xReply *) &rep, 0, xTrue))
+ {
+ UnlockDisplay (dpy);
+ SyncHandle ();
+ return 0;
+ }
+ info->major_version = rep.majorVersion;
+ info->minor_version = rep.minorVersion;
+ UnlockDisplay (dpy);
+ } 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, XCompositeCloseDisplay);
+ }
+
+ /*
+ * 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;
+}
+
+/*
+ * XCompositeExtFindDisplay - look for a display in this extension; keeps a
+ * cache of the most-recently used for efficiency. (Replaces
+ * XextFindDisplay.)
+ */
+static XCompositeExtDisplayInfo *
+XCompositeExtFindDisplay (XCompositeExtInfo *extinfo,
+ Display *dpy)
+{
+ XCompositeExtDisplayInfo *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;
+}
+
+XCompositeExtDisplayInfo *
+XCompositeFindDisplay (Display *dpy)
+{
+ XCompositeExtDisplayInfo *info;
+
+ info = XCompositeExtFindDisplay (&XCompositeExtensionInfo, dpy);
+ if (!info)
+ info = XCompositeExtAddDisplay (&XCompositeExtensionInfo, dpy,
+ XCompositeExtensionName);
+ return info;
+}
+
+
+Bool
+XCompositeQueryExtension (Display *dpy, int *event_basep, int *error_basep)
+{
+ XCompositeExtDisplayInfo *info = XCompositeFindDisplay (dpy);
+
+ if (XCompositeHasExtension(info))
+ {
+ *event_basep = info->codes->first_event;
+ *error_basep = info->codes->first_error;
+ return True;
+ }
+ else
+ return False;
+}
+
+Status
+XCompositeQueryVersion (Display *dpy,
+ int *major_versionp,
+ int *minor_versionp)
+{
+ XCompositeExtDisplayInfo *info = XCompositeFindDisplay (dpy);
+
+ XCompositeCheckExtension (dpy, info, 0);
+ *major_versionp = info->major_version;
+ *minor_versionp = info->minor_version;
+ UnlockDisplay (dpy);
+ SyncHandle ();
+ return 1;
+}
+
+int
+XCompositeVersion (void)
+{
+ return XCOMPOSITE_VERSION;
+}
+
+void
+XCompositeRedirectWindow (Display *dpy, Window window, int update)
+{
+ XCompositeExtDisplayInfo *info = XCompositeFindDisplay (dpy);
+ xCompositeRedirectWindowReq *req;
+
+ XCompositeSimpleCheckExtension (dpy, info);
+ LockDisplay (dpy);
+ GetReq (CompositeRedirectWindow, req);
+ req->reqType = info->codes->major_opcode;
+ req->compositeReqType = X_CompositeRedirectWindow;
+ req->window = window;
+ req->update = update;
+ UnlockDisplay (dpy);
+ SyncHandle ();
+}
+
+void
+XCompositeRedirectSubwindows (Display *dpy, Window window, int update)
+{
+ XCompositeExtDisplayInfo *info = XCompositeFindDisplay (dpy);
+ xCompositeRedirectSubwindowsReq *req;
+
+ XCompositeSimpleCheckExtension (dpy, info);
+ LockDisplay (dpy);
+ GetReq (CompositeRedirectSubwindows, req);
+ req->reqType = info->codes->major_opcode;
+ req->compositeReqType = X_CompositeRedirectSubwindows;
+ req->window = window;
+ req->update = update;
+ UnlockDisplay (dpy);
+ SyncHandle ();
+}
+
+void
+XCompositeUnredirectWindow (Display *dpy, Window window, int update)
+{
+ XCompositeExtDisplayInfo *info = XCompositeFindDisplay (dpy);
+ xCompositeUnredirectWindowReq *req;
+
+ XCompositeSimpleCheckExtension (dpy, info);
+ LockDisplay (dpy);
+ GetReq (CompositeUnredirectWindow, req);
+ req->reqType = info->codes->major_opcode;
+ req->compositeReqType = X_CompositeUnredirectWindow;
+ req->window = window;
+ req->update = update;
+ UnlockDisplay (dpy);
+ SyncHandle ();
+}
+
+void
+XCompositeUnredirectSubwindows (Display *dpy, Window window, int update)
+{
+ XCompositeExtDisplayInfo *info = XCompositeFindDisplay (dpy);
+ xCompositeUnredirectSubwindowsReq *req;
+
+ XCompositeSimpleCheckExtension (dpy, info);
+ LockDisplay (dpy);
+ GetReq (CompositeUnredirectSubwindows, req);
+ req->reqType = info->codes->major_opcode;
+ req->compositeReqType = X_CompositeUnredirectSubwindows;
+ req->window = window;
+ req->update = update;
+ UnlockDisplay (dpy);
+ SyncHandle ();
+}
+
+XserverRegion
+XCompositeCreateRegionFromBorderClip (Display *dpy, Window window)
+{
+ XCompositeExtDisplayInfo *info = XCompositeFindDisplay (dpy);
+ xCompositeCreateRegionFromBorderClipReq *req;
+ XserverRegion region;
+
+ XCompositeCheckExtension (dpy, info, 0);
+ LockDisplay (dpy);
+ GetReq (CompositeCreateRegionFromBorderClip, req);
+ req->reqType = info->codes->major_opcode;
+ req->compositeReqType = X_CompositeCreateRegionFromBorderClip;
+ req->window = window;
+ region = req->region = XAllocID (dpy);
+ UnlockDisplay (dpy);
+ SyncHandle ();
+ return region;
+}
+
+Pixmap
+XCompositeNameWindowPixmap (Display *dpy, Window window)
+{
+ XCompositeExtDisplayInfo *info = XCompositeFindDisplay (dpy);
+ xCompositeNameWindowPixmapReq *req;
+ Pixmap pixmap;
+
+ XCompositeCheckExtension (dpy, info, 0);
+ LockDisplay (dpy);
+ GetReq (CompositeNameWindowPixmap, req);
+ req->reqType = info->codes->major_opcode;
+ req->compositeReqType = X_CompositeNameWindowPixmap;
+ req->window = window;
+ pixmap = req->pixmap = XAllocID (dpy);
+ UnlockDisplay (dpy);
+ SyncHandle ();
+ return pixmap;
+}
diff --git a/src/xcompositeint.h b/src/xcompositeint.h
new file mode 100644
index 0000000..31554f0
--- /dev/null
+++ b/src/xcompositeint.h
@@ -0,0 +1,66 @@
+/*
+ * $Id$
+ *
+ * Copyright © 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.
+ */
+
+#ifndef _XDAMAGEINT_H_
+#define _XDAMAGEINT_H_
+
+#define NEED_EVENTS
+#define NEED_REPLIES
+#include <stdio.h>
+#include <X11/Xlib.h>
+#include <X11/Xlibint.h>
+#include <X11/Xutil.h>
+#include <X11/extensions/compositeproto.h>
+#include "Xcomposite.h"
+
+typedef struct _XCompositeExtDisplayInfo {
+ struct _XCompositeExtDisplayInfo *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 */
+} XCompositeExtDisplayInfo;
+
+/* replaces XExtensionInfo */
+typedef struct _XCompositeExtInfo {
+ XCompositeExtDisplayInfo *head; /* start of the list */
+ XCompositeExtDisplayInfo *cur; /* most recently used */
+ int ndisplays; /* number of displays */
+} XCompositeExtInfo;
+
+extern XCompositeExtInfo XCompositeExtensionInfo;
+extern const char XCompositeExtensionName[];
+
+XCompositeExtDisplayInfo *
+XCompositeFindDisplay (Display *dpy);
+
+#define XCompositeHasExtension(i) ((i) && ((i)->codes))
+
+#define XCompositeCheckExtension(dpy,i,val) \
+ if (!XCompositeHasExtension(i)) { return val; }
+
+#define XCompositeSimpleCheckExtension(dpy,i) \
+ if (!XCompositeHasExtension(i)) { return; }
+
+#endif /* _XDAMAGEINT_H_ */