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