xref: /OK3568_Linux_fs/external/xserver/xfixes/xfixes.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1 /*
2  * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved.
3  * Copyright 2010 Red Hat, Inc.
4  *
5  * Permission is hereby granted, free of charge, to any person obtaining a
6  * copy of this software and associated documentation files (the "Software"),
7  * to deal in the Software without restriction, including without limitation
8  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9  * and/or sell copies of the Software, and to permit persons to whom the
10  * Software is furnished to do so, subject to the following conditions:
11  *
12  * The above copyright notice and this permission notice (including the next
13  * paragraph) shall be included in all copies or substantial portions of the
14  * Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
19  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22  * DEALINGS IN THE SOFTWARE.
23  *
24  * Copyright © 2002 Keith Packard
25  *
26  * Permission to use, copy, modify, distribute, and sell this software and its
27  * documentation for any purpose is hereby granted without fee, provided that
28  * the above copyright notice appear in all copies and that both that
29  * copyright notice and this permission notice appear in supporting
30  * documentation, and that the name of Keith Packard not be used in
31  * advertising or publicity pertaining to distribution of the software without
32  * specific, written prior permission.  Keith Packard makes no
33  * representations about the suitability of this software for any purpose.  It
34  * is provided "as is" without express or implied warranty.
35  *
36  * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
37  * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
38  * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
39  * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
40  * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
41  * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
42  * PERFORMANCE OF THIS SOFTWARE.
43  */
44 
45 #ifdef HAVE_DIX_CONFIG_H
46 #include <dix-config.h>
47 #endif
48 
49 #include "xfixesint.h"
50 #include "protocol-versions.h"
51 #include "extinit.h"
52 
53 static unsigned char XFixesReqCode;
54 int XFixesEventBase;
55 int XFixesErrorBase;
56 
57 static DevPrivateKeyRec XFixesClientPrivateKeyRec;
58 
59 #define XFixesClientPrivateKey (&XFixesClientPrivateKeyRec)
60 
61 static int
ProcXFixesQueryVersion(ClientPtr client)62 ProcXFixesQueryVersion(ClientPtr client)
63 {
64     XFixesClientPtr pXFixesClient = GetXFixesClient(client);
65     xXFixesQueryVersionReply rep = {
66         .type = X_Reply,
67         .sequenceNumber = client->sequence,
68         .length = 0
69     };
70 
71     REQUEST(xXFixesQueryVersionReq);
72 
73     REQUEST_SIZE_MATCH(xXFixesQueryVersionReq);
74 
75     if (version_compare(stuff->majorVersion, stuff->minorVersion,
76                         SERVER_XFIXES_MAJOR_VERSION,
77                         SERVER_XFIXES_MINOR_VERSION) < 0) {
78         rep.majorVersion = stuff->majorVersion;
79         rep.minorVersion = stuff->minorVersion;
80     }
81     else {
82         rep.majorVersion = SERVER_XFIXES_MAJOR_VERSION;
83         rep.minorVersion = SERVER_XFIXES_MINOR_VERSION;
84     }
85 
86     pXFixesClient->major_version = rep.majorVersion;
87     pXFixesClient->minor_version = rep.minorVersion;
88     if (client->swapped) {
89         swaps(&rep.sequenceNumber);
90         swapl(&rep.length);
91         swapl(&rep.majorVersion);
92         swapl(&rep.minorVersion);
93     }
94     WriteToClient(client, sizeof(xXFixesQueryVersionReply), &rep);
95     return Success;
96 }
97 
98 /* Major version controls available requests */
99 static const int version_requests[] = {
100     X_XFixesQueryVersion,       /* before client sends QueryVersion */
101     X_XFixesGetCursorImage,     /* Version 1 */
102     X_XFixesChangeCursorByName, /* Version 2 */
103     X_XFixesExpandRegion,       /* Version 3 */
104     X_XFixesShowCursor,         /* Version 4 */
105     X_XFixesDestroyPointerBarrier,      /* Version 5 */
106 };
107 
108 int (*ProcXFixesVector[XFixesNumberRequests]) (ClientPtr) = {
109 /*************** Version 1 ******************/
110     ProcXFixesQueryVersion,
111         ProcXFixesChangeSaveSet,
112         ProcXFixesSelectSelectionInput,
113         ProcXFixesSelectCursorInput, ProcXFixesGetCursorImage,
114 /*************** Version 2 ******************/
115         ProcXFixesCreateRegion,
116         ProcXFixesCreateRegionFromBitmap,
117         ProcXFixesCreateRegionFromWindow,
118         ProcXFixesCreateRegionFromGC,
119         ProcXFixesCreateRegionFromPicture,
120         ProcXFixesDestroyRegion,
121         ProcXFixesSetRegion,
122         ProcXFixesCopyRegion,
123         ProcXFixesCombineRegion,
124         ProcXFixesCombineRegion,
125         ProcXFixesCombineRegion,
126         ProcXFixesInvertRegion,
127         ProcXFixesTranslateRegion,
128         ProcXFixesRegionExtents,
129         ProcXFixesFetchRegion,
130         ProcXFixesSetGCClipRegion,
131         ProcXFixesSetWindowShapeRegion,
132         ProcXFixesSetPictureClipRegion,
133         ProcXFixesSetCursorName,
134         ProcXFixesGetCursorName,
135         ProcXFixesGetCursorImageAndName,
136         ProcXFixesChangeCursor, ProcXFixesChangeCursorByName,
137 /*************** Version 3 ******************/
138         ProcXFixesExpandRegion,
139 /*************** Version 4 ****************/
140         ProcXFixesHideCursor, ProcXFixesShowCursor,
141 /*************** Version 5 ****************/
142 ProcXFixesCreatePointerBarrier, ProcXFixesDestroyPointerBarrier,};
143 
144 static int
ProcXFixesDispatch(ClientPtr client)145 ProcXFixesDispatch(ClientPtr client)
146 {
147     REQUEST(xXFixesReq);
148     XFixesClientPtr pXFixesClient = GetXFixesClient(client);
149 
150     if (pXFixesClient->major_version >= ARRAY_SIZE(version_requests))
151         return BadRequest;
152     if (stuff->xfixesReqType > version_requests[pXFixesClient->major_version])
153         return BadRequest;
154     return (*ProcXFixesVector[stuff->xfixesReqType]) (client);
155 }
156 
157 static _X_COLD int
SProcXFixesQueryVersion(ClientPtr client)158 SProcXFixesQueryVersion(ClientPtr client)
159 {
160     REQUEST(xXFixesQueryVersionReq);
161     REQUEST_SIZE_MATCH(xXFixesQueryVersionReq);
162 
163     swaps(&stuff->length);
164     swapl(&stuff->majorVersion);
165     swapl(&stuff->minorVersion);
166     return (*ProcXFixesVector[stuff->xfixesReqType]) (client);
167 }
168 
169 static int (*SProcXFixesVector[XFixesNumberRequests]) (ClientPtr) = {
170 /*************** Version 1 ******************/
171     SProcXFixesQueryVersion,
172         SProcXFixesChangeSaveSet,
173         SProcXFixesSelectSelectionInput,
174         SProcXFixesSelectCursorInput, SProcXFixesGetCursorImage,
175 /*************** Version 2 ******************/
176         SProcXFixesCreateRegion,
177         SProcXFixesCreateRegionFromBitmap,
178         SProcXFixesCreateRegionFromWindow,
179         SProcXFixesCreateRegionFromGC,
180         SProcXFixesCreateRegionFromPicture,
181         SProcXFixesDestroyRegion,
182         SProcXFixesSetRegion,
183         SProcXFixesCopyRegion,
184         SProcXFixesCombineRegion,
185         SProcXFixesCombineRegion,
186         SProcXFixesCombineRegion,
187         SProcXFixesInvertRegion,
188         SProcXFixesTranslateRegion,
189         SProcXFixesRegionExtents,
190         SProcXFixesFetchRegion,
191         SProcXFixesSetGCClipRegion,
192         SProcXFixesSetWindowShapeRegion,
193         SProcXFixesSetPictureClipRegion,
194         SProcXFixesSetCursorName,
195         SProcXFixesGetCursorName,
196         SProcXFixesGetCursorImageAndName,
197         SProcXFixesChangeCursor, SProcXFixesChangeCursorByName,
198 /*************** Version 3 ******************/
199         SProcXFixesExpandRegion,
200 /*************** Version 4 ****************/
201         SProcXFixesHideCursor, SProcXFixesShowCursor,
202 /*************** Version 5 ****************/
203 SProcXFixesCreatePointerBarrier, SProcXFixesDestroyPointerBarrier,};
204 
205 static _X_COLD int
SProcXFixesDispatch(ClientPtr client)206 SProcXFixesDispatch(ClientPtr client)
207 {
208     REQUEST(xXFixesReq);
209     if (stuff->xfixesReqType >= XFixesNumberRequests)
210         return BadRequest;
211     return (*SProcXFixesVector[stuff->xfixesReqType]) (client);
212 }
213 
214 void
XFixesExtensionInit(void)215 XFixesExtensionInit(void)
216 {
217     ExtensionEntry *extEntry;
218 
219     if (!dixRegisterPrivateKey
220         (&XFixesClientPrivateKeyRec, PRIVATE_CLIENT, sizeof(XFixesClientRec)))
221         return;
222 
223     if (XFixesSelectionInit() && XFixesCursorInit() && XFixesRegionInit() &&
224         (extEntry = AddExtension(XFIXES_NAME, XFixesNumberEvents,
225                                  XFixesNumberErrors,
226                                  ProcXFixesDispatch, SProcXFixesDispatch,
227                                  NULL, StandardMinorOpcode)) != 0) {
228         XFixesReqCode = (unsigned char) extEntry->base;
229         XFixesEventBase = extEntry->eventBase;
230         XFixesErrorBase = extEntry->errorBase;
231         EventSwapVector[XFixesEventBase + XFixesSelectionNotify] =
232             (EventSwapPtr) SXFixesSelectionNotifyEvent;
233         EventSwapVector[XFixesEventBase + XFixesCursorNotify] =
234             (EventSwapPtr) SXFixesCursorNotifyEvent;
235         SetResourceTypeErrorValue(RegionResType, XFixesErrorBase + BadRegion);
236         SetResourceTypeErrorValue(PointerBarrierType,
237                                   XFixesErrorBase + BadBarrier);
238     }
239 }
240 
241 #ifdef PANORAMIX
242 
243 int (*PanoramiXSaveXFixesVector[XFixesNumberRequests]) (ClientPtr);
244 
245 void
PanoramiXFixesInit(void)246 PanoramiXFixesInit(void)
247 {
248     int i;
249 
250     for (i = 0; i < XFixesNumberRequests; i++)
251         PanoramiXSaveXFixesVector[i] = ProcXFixesVector[i];
252     /*
253      * Stuff in Xinerama aware request processing hooks
254      */
255     ProcXFixesVector[X_XFixesSetGCClipRegion] = PanoramiXFixesSetGCClipRegion;
256     ProcXFixesVector[X_XFixesSetWindowShapeRegion] =
257         PanoramiXFixesSetWindowShapeRegion;
258     ProcXFixesVector[X_XFixesSetPictureClipRegion] =
259         PanoramiXFixesSetPictureClipRegion;
260 }
261 
262 void
PanoramiXFixesReset(void)263 PanoramiXFixesReset(void)
264 {
265     int i;
266 
267     for (i = 0; i < XFixesNumberRequests; i++)
268         ProcXFixesVector[i] = PanoramiXSaveXFixesVector[i];
269 }
270 
271 #endif
272