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:
parent
e251c9e75a
commit
b304b0a65c
|
@ -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 */
|
||||
|
|
39
Xi/extinit.c
39
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,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) {
|
||||
|
|
17
Xi/getvers.c
17
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;
|
||||
|
|
|
@ -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 */);
|
||||
|
||||
|
|
Loading…
Reference in New Issue