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.
This commit is contained in:
Peter Hutterer 2008-04-26 17:38:55 +09:30
parent e251c9e75a
commit b304b0a65c
4 changed files with 63 additions and 4 deletions

View File

@ -31,6 +31,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#ifdef HAVE_DIX_CONFIG_H #ifdef HAVE_DIX_CONFIG_H
#include <dix-config.h> #include <dix-config.h>
#endif #endif
#include "privates.h"
#ifndef EXGLOBALS_H #ifndef EXGLOBALS_H
#define EXGLOBALS_H 1 #define EXGLOBALS_H 1
@ -75,4 +76,5 @@ extern int DeviceLeaveNotify;
extern int RT_INPUTCLIENT; extern int RT_INPUTCLIENT;
extern DevPrivateKey XIClientPrivateKey;
#endif /* EXGLOBALS_H */ #endif /* EXGLOBALS_H */

View File

@ -72,6 +72,7 @@ SOFTWARE.
#include "exglobals.h" #include "exglobals.h"
#include "swaprep.h" #include "swaprep.h"
#include "registry.h" #include "registry.h"
#include "privates.h"
/* modules local to Xi */ /* modules local to Xi */
#include "allowev.h" #include "allowev.h"
@ -324,19 +325,42 @@ int RT_INPUTCLIENT;
extern XExtensionVersion AllExtensionVersions[]; extern XExtensionVersion AllExtensionVersions[];
Mask PropagateMask[MAX_DEVICES]; Mask PropagateMask[MAX_DEVICES];
/*****************************************************************
*
* Versioning support
*
*/
DevPrivateKey XIClientPrivateKey = &XIClientPrivateKey;
static XExtensionVersion thisversion = { XI_Present,
XI_2_Major,
XI_2_Minor
};
/***************************************************************** /*****************************************************************
* *
* Declarations of local routines. * Declarations of local routines.
* *
*/ */
static XExtensionVersion thisversion = { XI_Present, static void
XI_2_Major, XIClientCallback(CallbackListPtr *list,
XI_2_Minor 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;
}
/************************************************************************* /*************************************************************************
* *
@ -1080,6 +1104,7 @@ XIGEEventFill(xGenericEvent* ev, DeviceIntPtr pDev,
* *
* This extension has several events and errors. * This extension has several events and errors.
* *
* XI is mandatory nowadays, so if we fail to init XI, we die.
*/ */
void void
@ -1087,6 +1112,12 @@ XInputExtensionInit(void)
{ {
ExtensionEntry *extEntry; 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, extEntry = AddExtension(INAME, IEVENTS, IERRORS, ProcIDispatch,
SProcIDispatch, IResetProc, StandardMinorOpcode); SProcIDispatch, IResetProc, StandardMinorOpcode);
if (extEntry) { if (extEntry) {

View File

@ -59,6 +59,7 @@ SOFTWARE.
#include "inputstr.h" /* DeviceIntPtr */ #include "inputstr.h" /* DeviceIntPtr */
#include <X11/extensions/XI.h> #include <X11/extensions/XI.h>
#include <X11/extensions/XIproto.h> #include <X11/extensions/XIproto.h>
#include "exevents.h"
#include "exglobals.h" #include "exglobals.h"
#include "getvers.h" #include "getvers.h"
@ -93,6 +94,7 @@ int
ProcXGetExtensionVersion(ClientPtr client) ProcXGetExtensionVersion(ClientPtr client)
{ {
xGetExtensionVersionReply rep; xGetExtensionVersionReply rep;
XIClientPtr pXIClient;
REQUEST(xGetExtensionVersionReq); REQUEST(xGetExtensionVersionReq);
REQUEST_AT_LEAST_SIZE(xGetExtensionVersionReq); REQUEST_AT_LEAST_SIZE(xGetExtensionVersionReq);
@ -101,6 +103,21 @@ ProcXGetExtensionVersion(ClientPtr client)
stuff->nbytes + 3) >> 2) stuff->nbytes + 3) >> 2)
return BadLength; 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_Reply;
rep.RepType = X_GetExtensionVersion; rep.RepType = X_GetExtensionVersion;
rep.length = 0; rep.length = 0;

View File

@ -32,6 +32,15 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#include <X11/extensions/XIproto.h> #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 ( extern void RegisterOtherDevice (
DeviceIntPtr /* device */); DeviceIntPtr /* device */);