summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Hutterer <peter@cs.unisa.edu.au>2008-04-26 17:38:55 +0930
committerPeter Hutterer <peter@cs.unisa.edu.au>2008-04-26 17:47:15 +0930
commitb304b0a65cc57127cdea103f2c5114e4ea79af41 (patch)
tree54464e7dccf3bc9994af12eeaffb842de416bf52
parente251c9e75afdc5e32f2bc9801712272358934266 (diff)
Xi: add versioning support.
Remember the version the client sent to us, so we can adjust our replies accordingly. This requires the client to use the {major|minor}Version fields in the GetExtensionVersion request. However, they were padding before, so we must assume they are garbage if nbytes is non-zero. If nbytes is zero, the client is probably a new client and we can handle it correctly.
-rw-r--r--Xi/exglobals.h2
-rw-r--r--Xi/extinit.c33
-rw-r--r--Xi/getvers.c17
-rw-r--r--include/exevents.h9
4 files changed, 60 insertions, 1 deletions
diff --git a/Xi/exglobals.h b/Xi/exglobals.h
index 8cbccf294..4c23d84b4 100644
--- a/Xi/exglobals.h
+++ b/Xi/exglobals.h
@@ -31,6 +31,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#ifdef HAVE_DIX_CONFIG_H
#include <dix-config.h>
#endif
+#include "privates.h"
#ifndef EXGLOBALS_H
#define EXGLOBALS_H 1
@@ -75,4 +76,5 @@ extern int DeviceLeaveNotify;
extern int RT_INPUTCLIENT;
+extern DevPrivateKey XIClientPrivateKey;
#endif /* EXGLOBALS_H */
diff --git a/Xi/extinit.c b/Xi/extinit.c
index 838efdd1c..a647b9e18 100644
--- a/Xi/extinit.c
+++ b/Xi/extinit.c
@@ -72,6 +72,7 @@ SOFTWARE.
#include "exglobals.h"
#include "swaprep.h"
#include "registry.h"
+#include "privates.h"
/* modules local to Xi */
#include "allowev.h"
@@ -324,20 +325,43 @@ int RT_INPUTCLIENT;
extern XExtensionVersion AllExtensionVersions[];
+
Mask PropagateMask[MAX_DEVICES];
/*****************************************************************
*
- * Declarations of local routines.
+ * Versioning support
*
*/
+DevPrivateKey XIClientPrivateKey = &XIClientPrivateKey;
+
static XExtensionVersion thisversion = { XI_Present,
XI_2_Major,
XI_2_Minor
};
+/*****************************************************************
+ *
+ * Declarations of local routines.
+ *
+ */
+
+static void
+XIClientCallback(CallbackListPtr *list,
+ pointer closure,
+ pointer data)
+{
+ NewClientInfoRec *clientinfo = (NewClientInfoRec*)data;
+ ClientPtr pClient = clientinfo->client;
+ XIClientPtr pXIClient;
+
+ pXIClient = dixLookupPrivate(&pClient->devPrivates, XIClientPrivateKey);
+ pXIClient->major_version = 0;
+ pXIClient->minor_version = 0;
+}
+
/*************************************************************************
*
* ProcIDispatch - main dispatch routine for requests to this extension.
@@ -1080,6 +1104,7 @@ XIGEEventFill(xGenericEvent* ev, DeviceIntPtr pDev,
*
* This extension has several events and errors.
*
+ * XI is mandatory nowadays, so if we fail to init XI, we die.
*/
void
@@ -1087,6 +1112,12 @@ XInputExtensionInit(void)
{
ExtensionEntry *extEntry;
+ if (!dixRequestPrivate(XIClientPrivateKey, sizeof(XIClientRec)))
+ FatalError("Cannot request private for XI.\n");
+
+ if (!AddCallback(&ClientStateCallback, XIClientCallback, 0))
+ FatalError("Failed to add callback to XI.\n");
+
extEntry = AddExtension(INAME, IEVENTS, IERRORS, ProcIDispatch,
SProcIDispatch, IResetProc, StandardMinorOpcode);
if (extEntry) {
diff --git a/Xi/getvers.c b/Xi/getvers.c
index 1e17eea5a..43a1a4d26 100644
--- a/Xi/getvers.c
+++ b/Xi/getvers.c
@@ -59,6 +59,7 @@ SOFTWARE.
#include "inputstr.h" /* DeviceIntPtr */
#include <X11/extensions/XI.h>
#include <X11/extensions/XIproto.h>
+#include "exevents.h"
#include "exglobals.h"
#include "getvers.h"
@@ -93,6 +94,7 @@ int
ProcXGetExtensionVersion(ClientPtr client)
{
xGetExtensionVersionReply rep;
+ XIClientPtr pXIClient;
REQUEST(xGetExtensionVersionReq);
REQUEST_AT_LEAST_SIZE(xGetExtensionVersionReq);
@@ -101,6 +103,21 @@ ProcXGetExtensionVersion(ClientPtr client)
stuff->nbytes + 3) >> 2)
return BadLength;
+ pXIClient = dixLookupPrivate(&client->devPrivates, XIClientPrivateKey);
+
+ /* GetExtensionVersionReq before XI 2 didn't supply the client's
+ * major/minor. So we don't actually have a clue what they support.
+ * {major|minor}Version was added as part of XI, so if they are set, we
+ * know we can trust it. In this case the client must set nbytes to 0
+ * though, otherwise we have to assume that the version are padding
+ * garbage.
+ */
+ if (!stuff->nbytes) /* Client using XQueryInputVersion(). */
+ {
+ pXIClient->major_version = stuff->majorVersion;
+ pXIClient->minor_version = stuff->minorVersion;
+ } /* else version unknown, leave it at 0.0 */
+
rep.repType = X_Reply;
rep.RepType = X_GetExtensionVersion;
rep.length = 0;
diff --git a/include/exevents.h b/include/exevents.h
index 0892f4d0a..8d5d5dd49 100644
--- a/include/exevents.h
+++ b/include/exevents.h
@@ -32,6 +32,15 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#include <X11/extensions/XIproto.h>
+/**
+ * Attached to the devPrivates of each client. Specifies the version number as
+ * supported by the client.
+ */
+typedef struct _XIClientRec {
+ int major_version;
+ int minor_version;
+} XIClientRec, *XIClientPtr;
+
extern void RegisterOtherDevice (
DeviceIntPtr /* device */);