16747b715Smrg/* 26747b715Smrg * Copyright © 2009 Red Hat, Inc. 36747b715Smrg * 46747b715Smrg * Permission is hereby granted, free of charge, to any person obtaining a 56747b715Smrg * copy of this software and associated documentation files (the "Software"), 66747b715Smrg * to deal in the Software without restriction, including without limitation 76747b715Smrg * the rights to use, copy, modify, merge, publish, distribute, sublicense, 86747b715Smrg * and/or sell copies of the Software, and to permit persons to whom the 96747b715Smrg * Software is furnished to do so, subject to the following conditions: 106747b715Smrg * 116747b715Smrg * The above copyright notice and this permission notice (including the next 126747b715Smrg * paragraph) shall be included in all copies or substantial portions of the 136747b715Smrg * Software. 146747b715Smrg * 156747b715Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 166747b715Smrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 176747b715Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 186747b715Smrg * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 196747b715Smrg * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 206747b715Smrg * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 216747b715Smrg * DEALINGS IN THE SOFTWARE. 226747b715Smrg * 236747b715Smrg * Authors: Peter Hutterer 246747b715Smrg * 256747b715Smrg */ 266747b715Smrg 276747b715Smrg/** 286747b715Smrg * @file xiqueryversion.c 296747b715Smrg * Protocol handling for the XIQueryVersion request/reply. 306747b715Smrg */ 316747b715Smrg 326747b715Smrg#ifdef HAVE_DIX_CONFIG_H 336747b715Smrg#include <dix-config.h> 346747b715Smrg#endif 356747b715Smrg 366747b715Smrg#include "inputstr.h" 376747b715Smrg 386747b715Smrg#include <X11/Xmd.h> 396747b715Smrg#include <X11/X.h> 406747b715Smrg#include <X11/extensions/XI2proto.h> 416747b715Smrg 426747b715Smrg#include "exglobals.h" 436747b715Smrg#include "exevents.h" 446747b715Smrg#include "xiqueryversion.h" 456747b715Smrg#include "misc.h" 466747b715Smrg 4735c4bbdfSmrgextern XExtensionVersion XIVersion; /* defined in getvers.c */ 4835c4bbdfSmrg 496747b715Smrg/** 506747b715Smrg * Return the supported XI version. 516747b715Smrg * 526747b715Smrg * Saves the version the client claims to support as well, for future 536747b715Smrg * reference. 546747b715Smrg */ 556747b715Smrgint 566747b715SmrgProcXIQueryVersion(ClientPtr client) 576747b715Smrg{ 586747b715Smrg xXIQueryVersionReply rep; 596747b715Smrg XIClientPtr pXIClient; 606747b715Smrg int major, minor; 616747b715Smrg 626747b715Smrg REQUEST(xXIQueryVersionReq); 636747b715Smrg REQUEST_SIZE_MATCH(xXIQueryVersionReq); 646747b715Smrg 656747b715Smrg /* This request only exists after XI2 */ 6635c4bbdfSmrg if (stuff->major_version < 2) { 676747b715Smrg client->errorValue = stuff->major_version; 686747b715Smrg return BadValue; 696747b715Smrg } 706747b715Smrg 716747b715Smrg pXIClient = dixLookupPrivate(&client->devPrivates, XIClientPrivateKey); 726747b715Smrg 7335c4bbdfSmrg if (version_compare(XIVersion.major_version, XIVersion.minor_version, 7435c4bbdfSmrg stuff->major_version, stuff->minor_version) > 0) { 756747b715Smrg major = stuff->major_version; 766747b715Smrg minor = stuff->minor_version; 7735c4bbdfSmrg } else { 786747b715Smrg major = XIVersion.major_version; 796747b715Smrg minor = XIVersion.minor_version; 806747b715Smrg } 816747b715Smrg 8235c4bbdfSmrg if (pXIClient->major_version) { 8335c4bbdfSmrg 8435c4bbdfSmrg /* Check to see if the client has only ever asked 8535c4bbdfSmrg * for version 2.2 or higher 8635c4bbdfSmrg */ 8735c4bbdfSmrg if (version_compare(major, minor, 2, 2) >= 0 && 8835c4bbdfSmrg version_compare(pXIClient->major_version, pXIClient->minor_version, 2, 2) >= 0) 8935c4bbdfSmrg { 9035c4bbdfSmrg 9135c4bbdfSmrg /* As of version 2.2, Peter promises to never again break 9235c4bbdfSmrg * backward compatibility, so we'll return the requested 9335c4bbdfSmrg * version to the client but leave the server internal 9435c4bbdfSmrg * version set to the highest requested value 9535c4bbdfSmrg */ 9635c4bbdfSmrg if (version_compare(major, minor, 9735c4bbdfSmrg pXIClient->major_version, pXIClient->minor_version) > 0) 9835c4bbdfSmrg { 9935c4bbdfSmrg pXIClient->major_version = major; 10035c4bbdfSmrg pXIClient->minor_version = minor; 10135c4bbdfSmrg } 10235c4bbdfSmrg } else { 10335c4bbdfSmrg if (version_compare(major, minor, 10435c4bbdfSmrg pXIClient->major_version, pXIClient->minor_version) < 0) { 10535c4bbdfSmrg 10635c4bbdfSmrg client->errorValue = stuff->major_version; 10735c4bbdfSmrg return BadValue; 10835c4bbdfSmrg } 10935c4bbdfSmrg major = pXIClient->major_version; 11035c4bbdfSmrg minor = pXIClient->minor_version; 11135c4bbdfSmrg } 11235c4bbdfSmrg } else { 11335c4bbdfSmrg pXIClient->major_version = major; 11435c4bbdfSmrg pXIClient->minor_version = minor; 11535c4bbdfSmrg } 1166747b715Smrg 11735c4bbdfSmrg rep = (xXIQueryVersionReply) { 11835c4bbdfSmrg .repType = X_Reply, 11935c4bbdfSmrg .RepType = X_XIQueryVersion, 12035c4bbdfSmrg .sequenceNumber = client->sequence, 12135c4bbdfSmrg .length = 0, 12235c4bbdfSmrg .major_version = major, 12335c4bbdfSmrg .minor_version = minor 12435c4bbdfSmrg }; 1256747b715Smrg 1266747b715Smrg WriteReplyToClient(client, sizeof(xXIQueryVersionReply), &rep); 1276747b715Smrg 1286747b715Smrg return Success; 1296747b715Smrg} 1306747b715Smrg 1316747b715Smrg/* Swapping routines */ 1326747b715Smrg 1331b5d61b8Smrgint _X_COLD 1346747b715SmrgSProcXIQueryVersion(ClientPtr client) 1356747b715Smrg{ 1366747b715Smrg REQUEST(xXIQueryVersionReq); 13735c4bbdfSmrg swaps(&stuff->length); 1386747b715Smrg REQUEST_AT_LEAST_SIZE(xXIQueryVersionReq); 13935c4bbdfSmrg swaps(&stuff->major_version); 14035c4bbdfSmrg swaps(&stuff->minor_version); 1416747b715Smrg return (ProcXIQueryVersion(client)); 1426747b715Smrg} 1436747b715Smrg 1441b5d61b8Smrgvoid _X_COLD 14535c4bbdfSmrgSRepXIQueryVersion(ClientPtr client, int size, xXIQueryVersionReply * rep) 1466747b715Smrg{ 14735c4bbdfSmrg swaps(&rep->sequenceNumber); 14835c4bbdfSmrg swapl(&rep->length); 14935c4bbdfSmrg swaps(&rep->major_version); 15035c4bbdfSmrg swaps(&rep->minor_version); 15135c4bbdfSmrg WriteToClient(client, size, rep); 1526747b715Smrg} 153