summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Xi/xiqueryversion.c41
-rw-r--r--test/xi2/protocol-xiqueryversion.c113
2 files changed, 134 insertions, 20 deletions
diff --git a/Xi/xiqueryversion.c b/Xi/xiqueryversion.c
index fc0ca751b..6081c413d 100644
--- a/Xi/xiqueryversion.c
+++ b/Xi/xiqueryversion.c
@@ -70,28 +70,29 @@ ProcXIQueryVersion(ClientPtr client)
pXIClient = dixLookupPrivate(&client->devPrivates, XIClientPrivateKey);
- if (pXIClient->major_version &&
- (stuff->major_version != pXIClient->major_version ||
- stuff->minor_version != pXIClient->minor_version))
- {
- client->errorValue = stuff->major_version;
- return BadValue;
+ if (pXIClient->major_version) {
+ if (version_compare(stuff->major_version, stuff->minor_version,
+ pXIClient->major_version, pXIClient->minor_version) < 0) {
+ client->errorValue = stuff->major_version;
+ return BadValue;
+ }
+ major = pXIClient->major_version;
+ minor = pXIClient->minor_version;
+ } else {
+ if (version_compare(XIVersion.major_version, XIVersion.minor_version,
+ stuff->major_version, stuff->minor_version) > 0) {
+ major = stuff->major_version;
+ minor = stuff->minor_version;
+ }
+ else {
+ major = XIVersion.major_version;
+ minor = XIVersion.minor_version;
+ }
+
+ pXIClient->major_version = major;
+ pXIClient->minor_version = minor;
}
-
- if (version_compare(XIVersion.major_version, XIVersion.minor_version,
- stuff->major_version, stuff->minor_version) > 0) {
- major = stuff->major_version;
- minor = stuff->minor_version;
- }
- else {
- major = XIVersion.major_version;
- minor = XIVersion.minor_version;
- }
-
- pXIClient->major_version = major;
- pXIClient->minor_version = minor;
-
memset(&rep, 0, sizeof(xXIQueryVersionReply));
rep.repType = X_Reply;
rep.RepType = X_XIQueryVersion;
diff --git a/test/xi2/protocol-xiqueryversion.c b/test/xi2/protocol-xiqueryversion.c
index 2552307f2..1347e866c 100644
--- a/test/xi2/protocol-xiqueryversion.c
+++ b/test/xi2/protocol-xiqueryversion.c
@@ -54,6 +54,8 @@ struct test_data {
int minor_client;
int major_server;
int minor_server;
+ int major_cached;
+ int minor_cached;
};
static void
@@ -82,6 +84,24 @@ reply_XIQueryVersion(ClientPtr client, int len, char *data, void *userdata)
assert((sver > cver) ? ver == cver : ver == sver);
}
+static void
+reply_XIQueryVersion_multiple(ClientPtr client, int len, char *data, void *userdata)
+{
+ xXIQueryVersionReply *rep = (xXIQueryVersionReply *) data;
+ struct test_data *versions = (struct test_data *) userdata;
+
+ reply_check_defaults(rep, len, XIQueryVersion);
+ assert(rep->length == 0);
+
+ if (versions->major_cached == -1) {
+ versions->major_cached = rep->major_version;
+ versions->minor_cached = rep->minor_version;
+ }
+
+ assert(versions->major_cached == rep->major_version);
+ assert(versions->minor_cached == rep->minor_version);
+}
+
/**
* Run a single test with server version smaj.smin and client
* version cmaj.cmin. Verify that return code is equal to 'error'.
@@ -173,12 +193,105 @@ test_XIQueryVersion(void)
reply_handler = NULL;
}
+
+static void
+test_XIQueryVersion_multiple(void)
+{
+ xXIQueryVersionReq request;
+ ClientRec client;
+ struct test_data versions;
+ int rc;
+
+ request_init(&request, XIQueryVersion);
+ client = init_client(request.length, &request);
+
+ /* Change the server to support 2.2 */
+ XIVersion.major_version = 2;
+ XIVersion.minor_version = 2;
+
+ reply_handler = reply_XIQueryVersion_multiple;
+ userdata = (void *) &versions;
+
+ /* run 1 */
+ versions.major_cached = -1;
+ versions.minor_cached = -1;
+
+ /* client is lower than server, noncached */
+ request.major_version = 2;
+ request.minor_version = 1;
+ rc = ProcXIQueryVersion(&client);
+ assert(rc == Success);
+
+ /* client is higher than server, cached */
+ request.major_version = 2;
+ request.minor_version = 3;
+ rc = ProcXIQueryVersion(&client);
+ assert(rc == Success);
+
+ /* client is equal, cached */
+ request.major_version = 2;
+ request.minor_version = 2;
+ rc = ProcXIQueryVersion(&client);
+ assert(rc == Success);
+
+ /* client is low than cached */
+ request.major_version = 2;
+ request.minor_version = 0;
+ rc = ProcXIQueryVersion(&client);
+ assert(rc == BadValue);
+
+ /* run 2 */
+ client = init_client(request.length, &request);
+ XIVersion.major_version = 2;
+ XIVersion.minor_version = 2;
+ versions.major_cached = -1;
+ versions.minor_cached = -1;
+
+ request.major_version = 2;
+ request.minor_version = 2;
+ rc = ProcXIQueryVersion(&client);
+ assert(rc == Success);
+
+ request.major_version = 2;
+ request.minor_version = 3;
+ rc = ProcXIQueryVersion(&client);
+ assert(rc == Success);
+
+ request.major_version = 2;
+ request.minor_version = 1;
+ rc = ProcXIQueryVersion(&client);
+ assert(rc == BadValue);
+
+ /* run 3 */
+ client = init_client(request.length, &request);
+ XIVersion.major_version = 2;
+ XIVersion.minor_version = 2;
+ versions.major_cached = -1;
+ versions.minor_cached = -1;
+
+ request.major_version = 2;
+ request.minor_version = 3;
+ rc = ProcXIQueryVersion(&client);
+ assert(rc == Success);
+
+ request.major_version = 2;
+ request.minor_version = 2;
+ rc = ProcXIQueryVersion(&client);
+ assert(rc == Success);
+
+ request.major_version = 2;
+ request.minor_version = 1;
+ rc = ProcXIQueryVersion(&client);
+ assert(rc == BadValue);
+}
+
int
main(int argc, char **argv)
{
init_simple();
test_XIQueryVersion();
+ test_XIQueryVersion_multiple();
return 0;
}