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