105b261ecSmrg/*
29ace9065Smrg * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved.
35a112b11Smrg * Copyright 2010, 2021 Red Hat, Inc.
405b261ecSmrg *
56747b715Smrg * Permission is hereby granted, free of charge, to any person obtaining a
66747b715Smrg * copy of this software and associated documentation files (the "Software"),
76747b715Smrg * to deal in the Software without restriction, including without limitation
86747b715Smrg * the rights to use, copy, modify, merge, publish, distribute, sublicense,
96747b715Smrg * and/or sell copies of the Software, and to permit persons to whom the
106747b715Smrg * Software is furnished to do so, subject to the following conditions:
1105b261ecSmrg *
126747b715Smrg * The above copyright notice and this permission notice (including the next
136747b715Smrg * paragraph) shall be included in all copies or substantial portions of the
146747b715Smrg * Software.
156747b715Smrg *
166747b715Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
176747b715Smrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
186747b715Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
196747b715Smrg * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
206747b715Smrg * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
216747b715Smrg * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
226747b715Smrg * DEALINGS IN THE SOFTWARE.
2305b261ecSmrg *
2405b261ecSmrg * Copyright © 2002 Keith Packard
2505b261ecSmrg *
2605b261ecSmrg * Permission to use, copy, modify, distribute, and sell this software and its
2705b261ecSmrg * documentation for any purpose is hereby granted without fee, provided that
2805b261ecSmrg * the above copyright notice appear in all copies and that both that
2905b261ecSmrg * copyright notice and this permission notice appear in supporting
3005b261ecSmrg * documentation, and that the name of Keith Packard not be used in
3105b261ecSmrg * advertising or publicity pertaining to distribution of the software without
3205b261ecSmrg * specific, written prior permission.  Keith Packard makes no
3305b261ecSmrg * representations about the suitability of this software for any purpose.  It
3405b261ecSmrg * is provided "as is" without express or implied warranty.
3505b261ecSmrg *
3605b261ecSmrg * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
3705b261ecSmrg * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
3805b261ecSmrg * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
3905b261ecSmrg * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
4005b261ecSmrg * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
4105b261ecSmrg * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
4205b261ecSmrg * PERFORMANCE OF THIS SOFTWARE.
4305b261ecSmrg */
4405b261ecSmrg
4505b261ecSmrg#ifdef HAVE_DIX_CONFIG_H
4605b261ecSmrg#include <dix-config.h>
4705b261ecSmrg#endif
4805b261ecSmrg
4905b261ecSmrg#include "xfixesint.h"
506747b715Smrg#include "protocol-versions.h"
5135c4bbdfSmrg#include "extinit.h"
5205b261ecSmrg
5335c4bbdfSmrgstatic unsigned char XFixesReqCode;
5435c4bbdfSmrgint XFixesEventBase;
5535c4bbdfSmrgint XFixesErrorBase;
564642e01fSmrg
576747b715Smrgstatic DevPrivateKeyRec XFixesClientPrivateKeyRec;
5835c4bbdfSmrg
596747b715Smrg#define XFixesClientPrivateKey (&XFixesClientPrivateKeyRec)
6005b261ecSmrg
6105b261ecSmrgstatic int
6205b261ecSmrgProcXFixesQueryVersion(ClientPtr client)
6305b261ecSmrg{
645a112b11Smrg    int major, minor;
6535c4bbdfSmrg    XFixesClientPtr pXFixesClient = GetXFixesClient(client);
6635c4bbdfSmrg    xXFixesQueryVersionReply rep = {
6735c4bbdfSmrg        .type = X_Reply,
6835c4bbdfSmrg        .sequenceNumber = client->sequence,
6935c4bbdfSmrg        .length = 0
7035c4bbdfSmrg    };
7135c4bbdfSmrg
7205b261ecSmrg    REQUEST(xXFixesQueryVersionReq);
7305b261ecSmrg
7405b261ecSmrg    REQUEST_SIZE_MATCH(xXFixesQueryVersionReq);
7535c4bbdfSmrg
7635c4bbdfSmrg    if (version_compare(stuff->majorVersion, stuff->minorVersion,
7735c4bbdfSmrg                        SERVER_XFIXES_MAJOR_VERSION,
7835c4bbdfSmrg                        SERVER_XFIXES_MINOR_VERSION) < 0) {
795a112b11Smrg        major = max(pXFixesClient->major_version, stuff->majorVersion);
805a112b11Smrg        minor = stuff->minorVersion;
8135c4bbdfSmrg    }
8235c4bbdfSmrg    else {
835a112b11Smrg        major = SERVER_XFIXES_MAJOR_VERSION;
845a112b11Smrg        minor = SERVER_XFIXES_MINOR_VERSION;
8505b261ecSmrg    }
8635c4bbdfSmrg
875a112b11Smrg    pXFixesClient->major_version = major;
885a112b11Smrg    rep.majorVersion = min(stuff->majorVersion, major);
895a112b11Smrg    rep.minorVersion = minor;
9005b261ecSmrg    if (client->swapped) {
9135c4bbdfSmrg        swaps(&rep.sequenceNumber);
9235c4bbdfSmrg        swapl(&rep.length);
9335c4bbdfSmrg        swapl(&rep.majorVersion);
9435c4bbdfSmrg        swapl(&rep.minorVersion);
9505b261ecSmrg    }
9635c4bbdfSmrg    WriteToClient(client, sizeof(xXFixesQueryVersionReply), &rep);
976747b715Smrg    return Success;
9805b261ecSmrg}
9905b261ecSmrg
10005b261ecSmrg/* Major version controls available requests */
10105b261ecSmrgstatic const int version_requests[] = {
10235c4bbdfSmrg    X_XFixesQueryVersion,       /* before client sends QueryVersion */
10335c4bbdfSmrg    X_XFixesGetCursorImage,     /* Version 1 */
10435c4bbdfSmrg    X_XFixesChangeCursorByName, /* Version 2 */
10535c4bbdfSmrg    X_XFixesExpandRegion,       /* Version 3 */
10635c4bbdfSmrg    X_XFixesShowCursor,         /* Version 4 */
10735c4bbdfSmrg    X_XFixesDestroyPointerBarrier,      /* Version 5 */
1085a112b11Smrg    X_XFixesGetClientDisconnectMode,    /* Version 6 */
10905b261ecSmrg};
11005b261ecSmrg
11135c4bbdfSmrgint (*ProcXFixesVector[XFixesNumberRequests]) (ClientPtr) = {
11205b261ecSmrg/*************** Version 1 ******************/
11305b261ecSmrg    ProcXFixesQueryVersion,
11435c4bbdfSmrg        ProcXFixesChangeSaveSet,
11535c4bbdfSmrg        ProcXFixesSelectSelectionInput,
11635c4bbdfSmrg        ProcXFixesSelectCursorInput, ProcXFixesGetCursorImage,
11705b261ecSmrg/*************** Version 2 ******************/
11835c4bbdfSmrg        ProcXFixesCreateRegion,
11935c4bbdfSmrg        ProcXFixesCreateRegionFromBitmap,
12035c4bbdfSmrg        ProcXFixesCreateRegionFromWindow,
12135c4bbdfSmrg        ProcXFixesCreateRegionFromGC,
12235c4bbdfSmrg        ProcXFixesCreateRegionFromPicture,
12335c4bbdfSmrg        ProcXFixesDestroyRegion,
12435c4bbdfSmrg        ProcXFixesSetRegion,
12535c4bbdfSmrg        ProcXFixesCopyRegion,
12635c4bbdfSmrg        ProcXFixesCombineRegion,
12735c4bbdfSmrg        ProcXFixesCombineRegion,
12835c4bbdfSmrg        ProcXFixesCombineRegion,
12935c4bbdfSmrg        ProcXFixesInvertRegion,
13035c4bbdfSmrg        ProcXFixesTranslateRegion,
13135c4bbdfSmrg        ProcXFixesRegionExtents,
13235c4bbdfSmrg        ProcXFixesFetchRegion,
13335c4bbdfSmrg        ProcXFixesSetGCClipRegion,
13435c4bbdfSmrg        ProcXFixesSetWindowShapeRegion,
13535c4bbdfSmrg        ProcXFixesSetPictureClipRegion,
13635c4bbdfSmrg        ProcXFixesSetCursorName,
13735c4bbdfSmrg        ProcXFixesGetCursorName,
13835c4bbdfSmrg        ProcXFixesGetCursorImageAndName,
13935c4bbdfSmrg        ProcXFixesChangeCursor, ProcXFixesChangeCursorByName,
14005b261ecSmrg/*************** Version 3 ******************/
14135c4bbdfSmrg        ProcXFixesExpandRegion,
14205b261ecSmrg/*************** Version 4 ****************/
14335c4bbdfSmrg        ProcXFixesHideCursor, ProcXFixesShowCursor,
14435c4bbdfSmrg/*************** Version 5 ****************/
1455a112b11Smrg        ProcXFixesCreatePointerBarrier, ProcXFixesDestroyPointerBarrier,
1465a112b11Smrg/*************** Version 6 ****************/
1475a112b11Smrg        ProcXFixesSetClientDisconnectMode, ProcXFixesGetClientDisconnectMode,
1485a112b11Smrg};
14905b261ecSmrg
15005b261ecSmrgstatic int
15135c4bbdfSmrgProcXFixesDispatch(ClientPtr client)
15205b261ecSmrg{
15305b261ecSmrg    REQUEST(xXFixesReq);
15435c4bbdfSmrg    XFixesClientPtr pXFixesClient = GetXFixesClient(client);
15505b261ecSmrg
1567e31ba66Smrg    if (pXFixesClient->major_version >= ARRAY_SIZE(version_requests))
15735c4bbdfSmrg        return BadRequest;
15805b261ecSmrg    if (stuff->xfixesReqType > version_requests[pXFixesClient->major_version])
15935c4bbdfSmrg        return BadRequest;
16005b261ecSmrg    return (*ProcXFixesVector[stuff->xfixesReqType]) (client);
16105b261ecSmrg}
16205b261ecSmrg
1637e31ba66Smrgstatic _X_COLD int
16405b261ecSmrgSProcXFixesQueryVersion(ClientPtr client)
16505b261ecSmrg{
16605b261ecSmrg    REQUEST(xXFixesQueryVersionReq);
1676e78d31fSmrg    REQUEST_SIZE_MATCH(xXFixesQueryVersionReq);
16805b261ecSmrg
16935c4bbdfSmrg    swaps(&stuff->length);
17035c4bbdfSmrg    swapl(&stuff->majorVersion);
17135c4bbdfSmrg    swapl(&stuff->minorVersion);
17205b261ecSmrg    return (*ProcXFixesVector[stuff->xfixesReqType]) (client);
17305b261ecSmrg}
17405b261ecSmrg
17535c4bbdfSmrgstatic int (*SProcXFixesVector[XFixesNumberRequests]) (ClientPtr) = {
17605b261ecSmrg/*************** Version 1 ******************/
17705b261ecSmrg    SProcXFixesQueryVersion,
17835c4bbdfSmrg        SProcXFixesChangeSaveSet,
17935c4bbdfSmrg        SProcXFixesSelectSelectionInput,
18035c4bbdfSmrg        SProcXFixesSelectCursorInput, SProcXFixesGetCursorImage,
18105b261ecSmrg/*************** Version 2 ******************/
18235c4bbdfSmrg        SProcXFixesCreateRegion,
18335c4bbdfSmrg        SProcXFixesCreateRegionFromBitmap,
18435c4bbdfSmrg        SProcXFixesCreateRegionFromWindow,
18535c4bbdfSmrg        SProcXFixesCreateRegionFromGC,
18635c4bbdfSmrg        SProcXFixesCreateRegionFromPicture,
18735c4bbdfSmrg        SProcXFixesDestroyRegion,
18835c4bbdfSmrg        SProcXFixesSetRegion,
18935c4bbdfSmrg        SProcXFixesCopyRegion,
19035c4bbdfSmrg        SProcXFixesCombineRegion,
19135c4bbdfSmrg        SProcXFixesCombineRegion,
19235c4bbdfSmrg        SProcXFixesCombineRegion,
19335c4bbdfSmrg        SProcXFixesInvertRegion,
19435c4bbdfSmrg        SProcXFixesTranslateRegion,
19535c4bbdfSmrg        SProcXFixesRegionExtents,
19635c4bbdfSmrg        SProcXFixesFetchRegion,
19735c4bbdfSmrg        SProcXFixesSetGCClipRegion,
19835c4bbdfSmrg        SProcXFixesSetWindowShapeRegion,
19935c4bbdfSmrg        SProcXFixesSetPictureClipRegion,
20035c4bbdfSmrg        SProcXFixesSetCursorName,
20135c4bbdfSmrg        SProcXFixesGetCursorName,
20235c4bbdfSmrg        SProcXFixesGetCursorImageAndName,
20335c4bbdfSmrg        SProcXFixesChangeCursor, SProcXFixesChangeCursorByName,
20405b261ecSmrg/*************** Version 3 ******************/
20535c4bbdfSmrg        SProcXFixesExpandRegion,
20605b261ecSmrg/*************** Version 4 ****************/
20735c4bbdfSmrg        SProcXFixesHideCursor, SProcXFixesShowCursor,
20835c4bbdfSmrg/*************** Version 5 ****************/
2095a112b11Smrg        SProcXFixesCreatePointerBarrier, SProcXFixesDestroyPointerBarrier,
2105a112b11Smrg/*************** Version 6 ****************/
2115a112b11Smrg        SProcXFixesSetClientDisconnectMode, SProcXFixesGetClientDisconnectMode,
2125a112b11Smrg};
21305b261ecSmrg
2147e31ba66Smrgstatic _X_COLD int
21535c4bbdfSmrgSProcXFixesDispatch(ClientPtr client)
21605b261ecSmrg{
21705b261ecSmrg    REQUEST(xXFixesReq);
2185a112b11Smrg    XFixesClientPtr pXFixesClient = GetXFixesClient(client);
2195a112b11Smrg
2205a112b11Smrg    if (pXFixesClient->major_version >= ARRAY_SIZE(version_requests))
2215a112b11Smrg        return BadRequest;
2225a112b11Smrg    if (stuff->xfixesReqType > version_requests[pXFixesClient->major_version])
22335c4bbdfSmrg        return BadRequest;
22405b261ecSmrg    return (*SProcXFixesVector[stuff->xfixesReqType]) (client);
22505b261ecSmrg}
22605b261ecSmrg
22705b261ecSmrgvoid
22805b261ecSmrgXFixesExtensionInit(void)
22905b261ecSmrg{
23005b261ecSmrg    ExtensionEntry *extEntry;
23105b261ecSmrg
23235c4bbdfSmrg    if (!dixRegisterPrivateKey
23335c4bbdfSmrg        (&XFixesClientPrivateKeyRec, PRIVATE_CLIENT, sizeof(XFixesClientRec)))
23435c4bbdfSmrg        return;
23535c4bbdfSmrg
2365a112b11Smrg    if (XFixesSelectionInit() &&
2375a112b11Smrg        XFixesCursorInit() &&
2385a112b11Smrg        XFixesRegionInit() &&
2395a112b11Smrg        XFixesClientDisconnectInit() &&
24035c4bbdfSmrg        (extEntry = AddExtension(XFIXES_NAME, XFixesNumberEvents,
24135c4bbdfSmrg                                 XFixesNumberErrors,
24235c4bbdfSmrg                                 ProcXFixesDispatch, SProcXFixesDispatch,
2437e31ba66Smrg                                 NULL, StandardMinorOpcode)) != 0) {
24435c4bbdfSmrg        XFixesReqCode = (unsigned char) extEntry->base;
24535c4bbdfSmrg        XFixesEventBase = extEntry->eventBase;
24635c4bbdfSmrg        XFixesErrorBase = extEntry->errorBase;
24735c4bbdfSmrg        EventSwapVector[XFixesEventBase + XFixesSelectionNotify] =
24835c4bbdfSmrg            (EventSwapPtr) SXFixesSelectionNotifyEvent;
24935c4bbdfSmrg        EventSwapVector[XFixesEventBase + XFixesCursorNotify] =
25035c4bbdfSmrg            (EventSwapPtr) SXFixesCursorNotifyEvent;
25135c4bbdfSmrg        SetResourceTypeErrorValue(RegionResType, XFixesErrorBase + BadRegion);
25235c4bbdfSmrg        SetResourceTypeErrorValue(PointerBarrierType,
25335c4bbdfSmrg                                  XFixesErrorBase + BadBarrier);
25405b261ecSmrg    }
25505b261ecSmrg}
2569ace9065Smrg
2579ace9065Smrg#ifdef PANORAMIX
2589ace9065Smrg
25935c4bbdfSmrgint (*PanoramiXSaveXFixesVector[XFixesNumberRequests]) (ClientPtr);
2609ace9065Smrg
2619ace9065Smrgvoid
26235c4bbdfSmrgPanoramiXFixesInit(void)
2639ace9065Smrg{
2649ace9065Smrg    int i;
2659ace9065Smrg
2669ace9065Smrg    for (i = 0; i < XFixesNumberRequests; i++)
26735c4bbdfSmrg        PanoramiXSaveXFixesVector[i] = ProcXFixesVector[i];
2689ace9065Smrg    /*
2699ace9065Smrg     * Stuff in Xinerama aware request processing hooks
2709ace9065Smrg     */
2719ace9065Smrg    ProcXFixesVector[X_XFixesSetGCClipRegion] = PanoramiXFixesSetGCClipRegion;
27235c4bbdfSmrg    ProcXFixesVector[X_XFixesSetWindowShapeRegion] =
27335c4bbdfSmrg        PanoramiXFixesSetWindowShapeRegion;
27435c4bbdfSmrg    ProcXFixesVector[X_XFixesSetPictureClipRegion] =
27535c4bbdfSmrg        PanoramiXFixesSetPictureClipRegion;
2769ace9065Smrg}
2779ace9065Smrg
2789ace9065Smrgvoid
27935c4bbdfSmrgPanoramiXFixesReset(void)
2809ace9065Smrg{
2819ace9065Smrg    int i;
2829ace9065Smrg
2839ace9065Smrg    for (i = 0; i < XFixesNumberRequests; i++)
28435c4bbdfSmrg        ProcXFixesVector[i] = PanoramiXSaveXFixesVector[i];
2859ace9065Smrg}
2869ace9065Smrg
2879ace9065Smrg#endif
288