xfixes.c revision 6747b715
105b261ecSmrg/*
26747b715Smrg * Copyright © 2006 Sun Microsystems, Inc.  All rights reserved.
305b261ecSmrg *
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:
1005b261ecSmrg *
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.
2205b261ecSmrg *
2305b261ecSmrg * Copyright © 2002 Keith Packard
2405b261ecSmrg *
2505b261ecSmrg * Permission to use, copy, modify, distribute, and sell this software and its
2605b261ecSmrg * documentation for any purpose is hereby granted without fee, provided that
2705b261ecSmrg * the above copyright notice appear in all copies and that both that
2805b261ecSmrg * copyright notice and this permission notice appear in supporting
2905b261ecSmrg * documentation, and that the name of Keith Packard not be used in
3005b261ecSmrg * advertising or publicity pertaining to distribution of the software without
3105b261ecSmrg * specific, written prior permission.  Keith Packard makes no
3205b261ecSmrg * representations about the suitability of this software for any purpose.  It
3305b261ecSmrg * is provided "as is" without express or implied warranty.
3405b261ecSmrg *
3505b261ecSmrg * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
3605b261ecSmrg * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
3705b261ecSmrg * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
3805b261ecSmrg * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
3905b261ecSmrg * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
4005b261ecSmrg * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
4105b261ecSmrg * PERFORMANCE OF THIS SOFTWARE.
4205b261ecSmrg */
4305b261ecSmrg
4405b261ecSmrg#ifdef HAVE_DIX_CONFIG_H
4505b261ecSmrg#include <dix-config.h>
4605b261ecSmrg#endif
4705b261ecSmrg
4805b261ecSmrg#include "xfixesint.h"
496747b715Smrg#include "protocol-versions.h"
5005b261ecSmrg/*
5105b261ecSmrg * Must use these instead of the constants from xfixeswire.h.  They advertise
5205b261ecSmrg * what we implement, not what the protocol headers define.
5305b261ecSmrg */
5405b261ecSmrg
5505b261ecSmrgstatic unsigned char	XFixesReqCode;
5605b261ecSmrgint		XFixesEventBase;
5705b261ecSmrgint		XFixesErrorBase;
584642e01fSmrg
596747b715Smrgstatic DevPrivateKeyRec XFixesClientPrivateKeyRec;
606747b715Smrg#define XFixesClientPrivateKey (&XFixesClientPrivateKeyRec)
6105b261ecSmrg
6205b261ecSmrgstatic int
6305b261ecSmrgProcXFixesQueryVersion(ClientPtr client)
6405b261ecSmrg{
6505b261ecSmrg    XFixesClientPtr pXFixesClient = GetXFixesClient (client);
6605b261ecSmrg    xXFixesQueryVersionReply rep;
6705b261ecSmrg    register int n;
6805b261ecSmrg    REQUEST(xXFixesQueryVersionReq);
6905b261ecSmrg
7005b261ecSmrg    REQUEST_SIZE_MATCH(xXFixesQueryVersionReq);
716747b715Smrg    memset(&rep, 0, sizeof(xXFixesQueryVersionReply));
7205b261ecSmrg    rep.type = X_Reply;
7305b261ecSmrg    rep.length = 0;
7405b261ecSmrg    rep.sequenceNumber = client->sequence;
756747b715Smrg    if (stuff->majorVersion < SERVER_XFIXES_MAJOR_VERSION) {
7605b261ecSmrg	rep.majorVersion = stuff->majorVersion;
7705b261ecSmrg	rep.minorVersion = stuff->minorVersion;
7805b261ecSmrg    } else {
796747b715Smrg	rep.majorVersion = SERVER_XFIXES_MAJOR_VERSION;
806747b715Smrg	if (stuff->majorVersion == SERVER_XFIXES_MAJOR_VERSION &&
816747b715Smrg	    stuff->minorVersion < SERVER_XFIXES_MINOR_VERSION)
8205b261ecSmrg	    rep.minorVersion = stuff->minorVersion;
8305b261ecSmrg	else
846747b715Smrg	    rep.minorVersion = SERVER_XFIXES_MINOR_VERSION;
8505b261ecSmrg    }
8605b261ecSmrg    pXFixesClient->major_version = rep.majorVersion;
8705b261ecSmrg    pXFixesClient->minor_version = rep.minorVersion;
8805b261ecSmrg    if (client->swapped) {
8905b261ecSmrg    	swaps(&rep.sequenceNumber, n);
9005b261ecSmrg    	swapl(&rep.length, n);
9105b261ecSmrg	swapl(&rep.majorVersion, n);
9205b261ecSmrg	swapl(&rep.minorVersion, n);
9305b261ecSmrg    }
9405b261ecSmrg    WriteToClient(client, sizeof(xXFixesQueryVersionReply), (char *)&rep);
956747b715Smrg    return Success;
9605b261ecSmrg}
9705b261ecSmrg
9805b261ecSmrg/* Major version controls available requests */
9905b261ecSmrgstatic const int version_requests[] = {
10005b261ecSmrg    X_XFixesQueryVersion,	/* before client sends QueryVersion */
10105b261ecSmrg    X_XFixesGetCursorImage,	/* Version 1 */
10205b261ecSmrg    X_XFixesChangeCursorByName,	/* Version 2 */
10305b261ecSmrg    X_XFixesExpandRegion,	/* Version 3 */
10405b261ecSmrg    X_XFixesShowCursor,	        /* Version 4 */
10505b261ecSmrg};
10605b261ecSmrg
10705b261ecSmrg#define NUM_VERSION_REQUESTS	(sizeof (version_requests) / sizeof (version_requests[0]))
10805b261ecSmrg
10905b261ecSmrgint	(*ProcXFixesVector[XFixesNumberRequests])(ClientPtr) = {
11005b261ecSmrg/*************** Version 1 ******************/
11105b261ecSmrg    ProcXFixesQueryVersion,
11205b261ecSmrg    ProcXFixesChangeSaveSet,
11305b261ecSmrg    ProcXFixesSelectSelectionInput,
11405b261ecSmrg    ProcXFixesSelectCursorInput,
11505b261ecSmrg    ProcXFixesGetCursorImage,
11605b261ecSmrg/*************** Version 2 ******************/
11705b261ecSmrg    ProcXFixesCreateRegion,
11805b261ecSmrg    ProcXFixesCreateRegionFromBitmap,
11905b261ecSmrg    ProcXFixesCreateRegionFromWindow,
12005b261ecSmrg    ProcXFixesCreateRegionFromGC,
12105b261ecSmrg    ProcXFixesCreateRegionFromPicture,
12205b261ecSmrg    ProcXFixesDestroyRegion,
12305b261ecSmrg    ProcXFixesSetRegion,
12405b261ecSmrg    ProcXFixesCopyRegion,
12505b261ecSmrg    ProcXFixesCombineRegion,
12605b261ecSmrg    ProcXFixesCombineRegion,
12705b261ecSmrg    ProcXFixesCombineRegion,
12805b261ecSmrg    ProcXFixesInvertRegion,
12905b261ecSmrg    ProcXFixesTranslateRegion,
13005b261ecSmrg    ProcXFixesRegionExtents,
13105b261ecSmrg    ProcXFixesFetchRegion,
13205b261ecSmrg    ProcXFixesSetGCClipRegion,
13305b261ecSmrg    ProcXFixesSetWindowShapeRegion,
13405b261ecSmrg    ProcXFixesSetPictureClipRegion,
13505b261ecSmrg    ProcXFixesSetCursorName,
13605b261ecSmrg    ProcXFixesGetCursorName,
13705b261ecSmrg    ProcXFixesGetCursorImageAndName,
13805b261ecSmrg    ProcXFixesChangeCursor,
13905b261ecSmrg    ProcXFixesChangeCursorByName,
14005b261ecSmrg/*************** Version 3 ******************/
14105b261ecSmrg    ProcXFixesExpandRegion,
14205b261ecSmrg/*************** Version 4 ****************/
14305b261ecSmrg    ProcXFixesHideCursor,
14405b261ecSmrg    ProcXFixesShowCursor,
14505b261ecSmrg};
14605b261ecSmrg
14705b261ecSmrgstatic int
14805b261ecSmrgProcXFixesDispatch (ClientPtr client)
14905b261ecSmrg{
15005b261ecSmrg    REQUEST(xXFixesReq);
15105b261ecSmrg    XFixesClientPtr pXFixesClient = GetXFixesClient (client);
15205b261ecSmrg
15305b261ecSmrg    if (pXFixesClient->major_version >= NUM_VERSION_REQUESTS)
15405b261ecSmrg	return BadRequest;
15505b261ecSmrg    if (stuff->xfixesReqType > version_requests[pXFixesClient->major_version])
15605b261ecSmrg	return BadRequest;
15705b261ecSmrg    return (*ProcXFixesVector[stuff->xfixesReqType]) (client);
15805b261ecSmrg}
15905b261ecSmrg
16005b261ecSmrgstatic int
16105b261ecSmrgSProcXFixesQueryVersion(ClientPtr client)
16205b261ecSmrg{
16305b261ecSmrg    register int n;
16405b261ecSmrg    REQUEST(xXFixesQueryVersionReq);
16505b261ecSmrg
16605b261ecSmrg    swaps(&stuff->length, n);
16705b261ecSmrg    swapl(&stuff->majorVersion, n);
16805b261ecSmrg    swapl(&stuff->minorVersion, n);
16905b261ecSmrg    return (*ProcXFixesVector[stuff->xfixesReqType]) (client);
17005b261ecSmrg}
17105b261ecSmrg
17205b261ecSmrgstatic int (*SProcXFixesVector[XFixesNumberRequests])(ClientPtr) = {
17305b261ecSmrg/*************** Version 1 ******************/
17405b261ecSmrg    SProcXFixesQueryVersion,
17505b261ecSmrg    SProcXFixesChangeSaveSet,
17605b261ecSmrg    SProcXFixesSelectSelectionInput,
17705b261ecSmrg    SProcXFixesSelectCursorInput,
17805b261ecSmrg    SProcXFixesGetCursorImage,
17905b261ecSmrg/*************** Version 2 ******************/
18005b261ecSmrg    SProcXFixesCreateRegion,
18105b261ecSmrg    SProcXFixesCreateRegionFromBitmap,
18205b261ecSmrg    SProcXFixesCreateRegionFromWindow,
18305b261ecSmrg    SProcXFixesCreateRegionFromGC,
18405b261ecSmrg    SProcXFixesCreateRegionFromPicture,
18505b261ecSmrg    SProcXFixesDestroyRegion,
18605b261ecSmrg    SProcXFixesSetRegion,
18705b261ecSmrg    SProcXFixesCopyRegion,
18805b261ecSmrg    SProcXFixesCombineRegion,
18905b261ecSmrg    SProcXFixesCombineRegion,
19005b261ecSmrg    SProcXFixesCombineRegion,
19105b261ecSmrg    SProcXFixesInvertRegion,
19205b261ecSmrg    SProcXFixesTranslateRegion,
19305b261ecSmrg    SProcXFixesRegionExtents,
19405b261ecSmrg    SProcXFixesFetchRegion,
19505b261ecSmrg    SProcXFixesSetGCClipRegion,
19605b261ecSmrg    SProcXFixesSetWindowShapeRegion,
19705b261ecSmrg    SProcXFixesSetPictureClipRegion,
19805b261ecSmrg    SProcXFixesSetCursorName,
19905b261ecSmrg    SProcXFixesGetCursorName,
20005b261ecSmrg    SProcXFixesGetCursorImageAndName,
20105b261ecSmrg    SProcXFixesChangeCursor,
20205b261ecSmrg    SProcXFixesChangeCursorByName,
20305b261ecSmrg/*************** Version 3 ******************/
20405b261ecSmrg    SProcXFixesExpandRegion,
20505b261ecSmrg/*************** Version 4 ****************/
20605b261ecSmrg    SProcXFixesHideCursor,
20705b261ecSmrg    SProcXFixesShowCursor,
20805b261ecSmrg};
20905b261ecSmrg
21005b261ecSmrgstatic int
21105b261ecSmrgSProcXFixesDispatch (ClientPtr client)
21205b261ecSmrg{
21305b261ecSmrg    REQUEST(xXFixesReq);
21405b261ecSmrg    if (stuff->xfixesReqType >= XFixesNumberRequests)
21505b261ecSmrg	return BadRequest;
21605b261ecSmrg    return (*SProcXFixesVector[stuff->xfixesReqType]) (client);
21705b261ecSmrg}
21805b261ecSmrg
21905b261ecSmrgstatic void
22005b261ecSmrgXFixesClientCallback (CallbackListPtr	*list,
22105b261ecSmrg		      pointer		closure,
22205b261ecSmrg		      pointer		data)
22305b261ecSmrg{
22405b261ecSmrg    NewClientInfoRec	*clientinfo = (NewClientInfoRec *) data;
22505b261ecSmrg    ClientPtr		pClient = clientinfo->client;
22605b261ecSmrg    XFixesClientPtr	pXFixesClient = GetXFixesClient (pClient);
22705b261ecSmrg
22805b261ecSmrg    pXFixesClient->major_version = 0;
22905b261ecSmrg    pXFixesClient->minor_version = 0;
23005b261ecSmrg}
23105b261ecSmrg
23205b261ecSmrg/*ARGSUSED*/
23305b261ecSmrgstatic void
23405b261ecSmrgXFixesResetProc (ExtensionEntry *extEntry)
23505b261ecSmrg{
23605b261ecSmrg    DeleteCallback (&ClientStateCallback, XFixesClientCallback, 0);
23705b261ecSmrg}
23805b261ecSmrg
23905b261ecSmrgvoid
24005b261ecSmrgXFixesExtensionInit(void)
24105b261ecSmrg{
24205b261ecSmrg    ExtensionEntry *extEntry;
24305b261ecSmrg
2446747b715Smrg    if (!dixRegisterPrivateKey(&XFixesClientPrivateKeyRec, PRIVATE_CLIENT, sizeof (XFixesClientRec)))
24505b261ecSmrg	return;
24605b261ecSmrg    if (!AddCallback (&ClientStateCallback, XFixesClientCallback, 0))
24705b261ecSmrg	return;
24805b261ecSmrg
24905b261ecSmrg    if (XFixesSelectionInit() && XFixesCursorInit () && XFixesRegionInit () &&
25005b261ecSmrg	(extEntry = AddExtension(XFIXES_NAME, XFixesNumberEvents,
25105b261ecSmrg				 XFixesNumberErrors,
25205b261ecSmrg				 ProcXFixesDispatch, SProcXFixesDispatch,
25305b261ecSmrg				 XFixesResetProc, StandardMinorOpcode)) != 0)
25405b261ecSmrg    {
25505b261ecSmrg	XFixesReqCode = (unsigned char)extEntry->base;
25605b261ecSmrg	XFixesEventBase = extEntry->eventBase;
25705b261ecSmrg	XFixesErrorBase = extEntry->errorBase;
25805b261ecSmrg	EventSwapVector[XFixesEventBase + XFixesSelectionNotify] =
25905b261ecSmrg	    (EventSwapPtr) SXFixesSelectionNotifyEvent;
26005b261ecSmrg	EventSwapVector[XFixesEventBase + XFixesCursorNotify] =
26105b261ecSmrg	    (EventSwapPtr) SXFixesCursorNotifyEvent;
2626747b715Smrg	SetResourceTypeErrorValue(RegionResType, XFixesErrorBase + BadRegion);
26305b261ecSmrg    }
26405b261ecSmrg}
265