Commit | Line | Data |
---|---|---|
a09e091a JB |
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 | |
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 | #define NUM_VERSION_REQUESTS (sizeof (version_requests) / sizeof (version_requests[0])) | |
109 | ||
110 | int (*ProcXFixesVector[XFixesNumberRequests]) (ClientPtr) = { | |
111 | /*************** Version 1 ******************/ | |
112 | ProcXFixesQueryVersion, | |
113 | ProcXFixesChangeSaveSet, | |
114 | ProcXFixesSelectSelectionInput, | |
115 | ProcXFixesSelectCursorInput, ProcXFixesGetCursorImage, | |
116 | /*************** Version 2 ******************/ | |
117 | ProcXFixesCreateRegion, | |
118 | ProcXFixesCreateRegionFromBitmap, | |
119 | ProcXFixesCreateRegionFromWindow, | |
120 | ProcXFixesCreateRegionFromGC, | |
121 | ProcXFixesCreateRegionFromPicture, | |
122 | ProcXFixesDestroyRegion, | |
123 | ProcXFixesSetRegion, | |
124 | ProcXFixesCopyRegion, | |
125 | ProcXFixesCombineRegion, | |
126 | ProcXFixesCombineRegion, | |
127 | ProcXFixesCombineRegion, | |
128 | ProcXFixesInvertRegion, | |
129 | ProcXFixesTranslateRegion, | |
130 | ProcXFixesRegionExtents, | |
131 | ProcXFixesFetchRegion, | |
132 | ProcXFixesSetGCClipRegion, | |
133 | ProcXFixesSetWindowShapeRegion, | |
134 | ProcXFixesSetPictureClipRegion, | |
135 | ProcXFixesSetCursorName, | |
136 | ProcXFixesGetCursorName, | |
137 | ProcXFixesGetCursorImageAndName, | |
138 | ProcXFixesChangeCursor, ProcXFixesChangeCursorByName, | |
139 | /*************** Version 3 ******************/ | |
140 | ProcXFixesExpandRegion, | |
141 | /*************** Version 4 ****************/ | |
142 | ProcXFixesHideCursor, ProcXFixesShowCursor, | |
143 | /*************** Version 5 ****************/ | |
144 | ProcXFixesCreatePointerBarrier, ProcXFixesDestroyPointerBarrier,}; | |
145 | ||
146 | static int | |
147 | ProcXFixesDispatch(ClientPtr client) | |
148 | { | |
149 | REQUEST(xXFixesReq); | |
150 | XFixesClientPtr pXFixesClient = GetXFixesClient(client); | |
151 | ||
152 | if (pXFixesClient->major_version >= NUM_VERSION_REQUESTS) | |
153 | return BadRequest; | |
154 | if (stuff->xfixesReqType > version_requests[pXFixesClient->major_version]) | |
155 | return BadRequest; | |
156 | return (*ProcXFixesVector[stuff->xfixesReqType]) (client); | |
157 | } | |
158 | ||
159 | static int | |
160 | SProcXFixesQueryVersion(ClientPtr client) | |
161 | { | |
162 | REQUEST(xXFixesQueryVersionReq); | |
163 | ||
164 | swaps(&stuff->length); | |
165 | swapl(&stuff->majorVersion); | |
166 | swapl(&stuff->minorVersion); | |
167 | return (*ProcXFixesVector[stuff->xfixesReqType]) (client); | |
168 | } | |
169 | ||
170 | static int (*SProcXFixesVector[XFixesNumberRequests]) (ClientPtr) = { | |
171 | /*************** Version 1 ******************/ | |
172 | SProcXFixesQueryVersion, | |
173 | SProcXFixesChangeSaveSet, | |
174 | SProcXFixesSelectSelectionInput, | |
175 | SProcXFixesSelectCursorInput, SProcXFixesGetCursorImage, | |
176 | /*************** Version 2 ******************/ | |
177 | SProcXFixesCreateRegion, | |
178 | SProcXFixesCreateRegionFromBitmap, | |
179 | SProcXFixesCreateRegionFromWindow, | |
180 | SProcXFixesCreateRegionFromGC, | |
181 | SProcXFixesCreateRegionFromPicture, | |
182 | SProcXFixesDestroyRegion, | |
183 | SProcXFixesSetRegion, | |
184 | SProcXFixesCopyRegion, | |
185 | SProcXFixesCombineRegion, | |
186 | SProcXFixesCombineRegion, | |
187 | SProcXFixesCombineRegion, | |
188 | SProcXFixesInvertRegion, | |
189 | SProcXFixesTranslateRegion, | |
190 | SProcXFixesRegionExtents, | |
191 | SProcXFixesFetchRegion, | |
192 | SProcXFixesSetGCClipRegion, | |
193 | SProcXFixesSetWindowShapeRegion, | |
194 | SProcXFixesSetPictureClipRegion, | |
195 | SProcXFixesSetCursorName, | |
196 | SProcXFixesGetCursorName, | |
197 | SProcXFixesGetCursorImageAndName, | |
198 | SProcXFixesChangeCursor, SProcXFixesChangeCursorByName, | |
199 | /*************** Version 3 ******************/ | |
200 | SProcXFixesExpandRegion, | |
201 | /*************** Version 4 ****************/ | |
202 | SProcXFixesHideCursor, SProcXFixesShowCursor, | |
203 | /*************** Version 5 ****************/ | |
204 | SProcXFixesCreatePointerBarrier, SProcXFixesDestroyPointerBarrier,}; | |
205 | ||
206 | static int | |
207 | SProcXFixesDispatch(ClientPtr client) | |
208 | { | |
209 | REQUEST(xXFixesReq); | |
210 | if (stuff->xfixesReqType >= XFixesNumberRequests) | |
211 | return BadRequest; | |
212 | return (*SProcXFixesVector[stuff->xfixesReqType]) (client); | |
213 | } | |
214 | ||
215 | static void | |
216 | XFixesClientCallback(CallbackListPtr *list, pointer closure, pointer data) | |
217 | { | |
218 | NewClientInfoRec *clientinfo = (NewClientInfoRec *) data; | |
219 | ClientPtr pClient = clientinfo->client; | |
220 | XFixesClientPtr pXFixesClient = GetXFixesClient(pClient); | |
221 | ||
222 | pXFixesClient->major_version = 0; | |
223 | pXFixesClient->minor_version = 0; | |
224 | } | |
225 | ||
226 | /*ARGSUSED*/ static void | |
227 | XFixesResetProc(ExtensionEntry * extEntry) | |
228 | { | |
229 | DeleteCallback(&ClientStateCallback, XFixesClientCallback, 0); | |
230 | } | |
231 | ||
232 | void | |
233 | XFixesExtensionInit(void) | |
234 | { | |
235 | ExtensionEntry *extEntry; | |
236 | ||
237 | if (!dixRegisterPrivateKey | |
238 | (&XFixesClientPrivateKeyRec, PRIVATE_CLIENT, sizeof(XFixesClientRec))) | |
239 | return; | |
240 | if (!AddCallback(&ClientStateCallback, XFixesClientCallback, 0)) | |
241 | return; | |
242 | ||
243 | if (XFixesSelectionInit() && XFixesCursorInit() && XFixesRegionInit() && | |
244 | (extEntry = AddExtension(XFIXES_NAME, XFixesNumberEvents, | |
245 | XFixesNumberErrors, | |
246 | ProcXFixesDispatch, SProcXFixesDispatch, | |
247 | XFixesResetProc, StandardMinorOpcode)) != 0) { | |
248 | XFixesReqCode = (unsigned char) extEntry->base; | |
249 | XFixesEventBase = extEntry->eventBase; | |
250 | XFixesErrorBase = extEntry->errorBase; | |
251 | EventSwapVector[XFixesEventBase + XFixesSelectionNotify] = | |
252 | (EventSwapPtr) SXFixesSelectionNotifyEvent; | |
253 | EventSwapVector[XFixesEventBase + XFixesCursorNotify] = | |
254 | (EventSwapPtr) SXFixesCursorNotifyEvent; | |
255 | SetResourceTypeErrorValue(RegionResType, XFixesErrorBase + BadRegion); | |
256 | SetResourceTypeErrorValue(PointerBarrierType, | |
257 | XFixesErrorBase + BadBarrier); | |
258 | } | |
259 | } | |
260 | ||
261 | #ifdef PANORAMIX | |
262 | ||
263 | int (*PanoramiXSaveXFixesVector[XFixesNumberRequests]) (ClientPtr); | |
264 | ||
265 | void | |
266 | PanoramiXFixesInit(void) | |
267 | { | |
268 | int i; | |
269 | ||
270 | for (i = 0; i < XFixesNumberRequests; i++) | |
271 | PanoramiXSaveXFixesVector[i] = ProcXFixesVector[i]; | |
272 | /* | |
273 | * Stuff in Xinerama aware request processing hooks | |
274 | */ | |
275 | ProcXFixesVector[X_XFixesSetGCClipRegion] = PanoramiXFixesSetGCClipRegion; | |
276 | ProcXFixesVector[X_XFixesSetWindowShapeRegion] = | |
277 | PanoramiXFixesSetWindowShapeRegion; | |
278 | ProcXFixesVector[X_XFixesSetPictureClipRegion] = | |
279 | PanoramiXFixesSetPictureClipRegion; | |
280 | } | |
281 | ||
282 | void | |
283 | PanoramiXFixesReset(void) | |
284 | { | |
285 | int i; | |
286 | ||
287 | for (i = 0; i < XFixesNumberRequests; i++) | |
288 | ProcXFixesVector[i] = PanoramiXSaveXFixesVector[i]; | |
289 | } | |
290 | ||
291 | #endif |