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
#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 */

View File

@ -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,19 +325,42 @@ int RT_INPUTCLIENT;
extern XExtensionVersion AllExtensionVersions[];
Mask PropagateMask[MAX_DEVICES];
/*****************************************************************
*
* Versioning support
*
*/
DevPrivateKey XIClientPrivateKey = &XIClientPrivateKey;
static XExtensionVersion thisversion = { XI_Present,
XI_2_Major,
XI_2_Minor
};
/*****************************************************************
*
* Declarations of local routines.
*
*/
static XExtensionVersion thisversion = { XI_Present,
XI_2_Major,
XI_2_Minor
};
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;
}
/*************************************************************************
*
@ -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) {

View File

@ -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;

View File

@ -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 */);