Reviewed-by: Jeremy Huddleston <[email protected]> (for the man page update also)
On Apr 22, 2012, at 8:29 PM, Peter Hutterer <[email protected]> wrote: > Clients that use plugin systems may require multiple calls to > XIQueryVersion from different plugins. The current error handling requires > client-side synchronisation of version numbers. > > The first call to XIQueryVersion defines the server behaviour. Once cached, > always return that version number to any clients. Unless a client requests a > version lower than the first defined one, then a BadValue must be returned > to be protocol-compatible. > > Introduced in 2c23ef83b0e03e163aeeb06133538606886f4e9c > > Signed-off-by: Peter Hutterer <[email protected]> > --- > Xi/xiqueryversion.c | 41 ++++++------- > test/xi2/protocol-xiqueryversion.c | 113 ++++++++++++++++++++++++++++++++++++ > 2 files changed, 134 insertions(+), 20 deletions(-) > > diff --git a/Xi/xiqueryversion.c b/Xi/xiqueryversion.c > index fc0ca75..6081c41 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 2552307..1347e86 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; > } > -- > 1.7.10 > > _______________________________________________ > [email protected]: X.Org development > Archives: http://lists.x.org/archives/xorg-devel > Info: http://lists.x.org/mailman/listinfo/xorg-devel > _______________________________________________ [email protected]: X.Org development Archives: http://lists.x.org/archives/xorg-devel Info: http://lists.x.org/mailman/listinfo/xorg-devel
