xfixes.c revision 5a112b11
1/* 2 * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved. 3 * Copyright 2010, 2021 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 53static unsigned char XFixesReqCode; 54int XFixesEventBase; 55int XFixesErrorBase; 56 57static DevPrivateKeyRec XFixesClientPrivateKeyRec; 58 59#define XFixesClientPrivateKey (&XFixesClientPrivateKeyRec) 60 61static int 62ProcXFixesQueryVersion(ClientPtr client) 63{ 64 int major, minor; 65 XFixesClientPtr pXFixesClient = GetXFixesClient(client); 66 xXFixesQueryVersionReply rep = { 67 .type = X_Reply, 68 .sequenceNumber = client->sequence, 69 .length = 0 70 }; 71 72 REQUEST(xXFixesQueryVersionReq); 73 74 REQUEST_SIZE_MATCH(xXFixesQueryVersionReq); 75 76 if (version_compare(stuff->majorVersion, stuff->minorVersion, 77 SERVER_XFIXES_MAJOR_VERSION, 78 SERVER_XFIXES_MINOR_VERSION) < 0) { 79 major = max(pXFixesClient->major_version, stuff->majorVersion); 80 minor = stuff->minorVersion; 81 } 82 else { 83 major = SERVER_XFIXES_MAJOR_VERSION; 84 minor = SERVER_XFIXES_MINOR_VERSION; 85 } 86 87 pXFixesClient->major_version = major; 88 rep.majorVersion = min(stuff->majorVersion, major); 89 rep.minorVersion = minor; 90 if (client->swapped) { 91 swaps(&rep.sequenceNumber); 92 swapl(&rep.length); 93 swapl(&rep.majorVersion); 94 swapl(&rep.minorVersion); 95 } 96 WriteToClient(client, sizeof(xXFixesQueryVersionReply), &rep); 97 return Success; 98} 99 100/* Major version controls available requests */ 101static const int version_requests[] = { 102 X_XFixesQueryVersion, /* before client sends QueryVersion */ 103 X_XFixesGetCursorImage, /* Version 1 */ 104 X_XFixesChangeCursorByName, /* Version 2 */ 105 X_XFixesExpandRegion, /* Version 3 */ 106 X_XFixesShowCursor, /* Version 4 */ 107 X_XFixesDestroyPointerBarrier, /* Version 5 */ 108 X_XFixesGetClientDisconnectMode, /* Version 6 */ 109}; 110 111int (*ProcXFixesVector[XFixesNumberRequests]) (ClientPtr) = { 112/*************** Version 1 ******************/ 113 ProcXFixesQueryVersion, 114 ProcXFixesChangeSaveSet, 115 ProcXFixesSelectSelectionInput, 116 ProcXFixesSelectCursorInput, ProcXFixesGetCursorImage, 117/*************** Version 2 ******************/ 118 ProcXFixesCreateRegion, 119 ProcXFixesCreateRegionFromBitmap, 120 ProcXFixesCreateRegionFromWindow, 121 ProcXFixesCreateRegionFromGC, 122 ProcXFixesCreateRegionFromPicture, 123 ProcXFixesDestroyRegion, 124 ProcXFixesSetRegion, 125 ProcXFixesCopyRegion, 126 ProcXFixesCombineRegion, 127 ProcXFixesCombineRegion, 128 ProcXFixesCombineRegion, 129 ProcXFixesInvertRegion, 130 ProcXFixesTranslateRegion, 131 ProcXFixesRegionExtents, 132 ProcXFixesFetchRegion, 133 ProcXFixesSetGCClipRegion, 134 ProcXFixesSetWindowShapeRegion, 135 ProcXFixesSetPictureClipRegion, 136 ProcXFixesSetCursorName, 137 ProcXFixesGetCursorName, 138 ProcXFixesGetCursorImageAndName, 139 ProcXFixesChangeCursor, ProcXFixesChangeCursorByName, 140/*************** Version 3 ******************/ 141 ProcXFixesExpandRegion, 142/*************** Version 4 ****************/ 143 ProcXFixesHideCursor, ProcXFixesShowCursor, 144/*************** Version 5 ****************/ 145 ProcXFixesCreatePointerBarrier, ProcXFixesDestroyPointerBarrier, 146/*************** Version 6 ****************/ 147 ProcXFixesSetClientDisconnectMode, ProcXFixesGetClientDisconnectMode, 148}; 149 150static int 151ProcXFixesDispatch(ClientPtr client) 152{ 153 REQUEST(xXFixesReq); 154 XFixesClientPtr pXFixesClient = GetXFixesClient(client); 155 156 if (pXFixesClient->major_version >= ARRAY_SIZE(version_requests)) 157 return BadRequest; 158 if (stuff->xfixesReqType > version_requests[pXFixesClient->major_version]) 159 return BadRequest; 160 return (*ProcXFixesVector[stuff->xfixesReqType]) (client); 161} 162 163static _X_COLD int 164SProcXFixesQueryVersion(ClientPtr client) 165{ 166 REQUEST(xXFixesQueryVersionReq); 167 REQUEST_SIZE_MATCH(xXFixesQueryVersionReq); 168 169 swaps(&stuff->length); 170 swapl(&stuff->majorVersion); 171 swapl(&stuff->minorVersion); 172 return (*ProcXFixesVector[stuff->xfixesReqType]) (client); 173} 174 175static int (*SProcXFixesVector[XFixesNumberRequests]) (ClientPtr) = { 176/*************** Version 1 ******************/ 177 SProcXFixesQueryVersion, 178 SProcXFixesChangeSaveSet, 179 SProcXFixesSelectSelectionInput, 180 SProcXFixesSelectCursorInput, SProcXFixesGetCursorImage, 181/*************** Version 2 ******************/ 182 SProcXFixesCreateRegion, 183 SProcXFixesCreateRegionFromBitmap, 184 SProcXFixesCreateRegionFromWindow, 185 SProcXFixesCreateRegionFromGC, 186 SProcXFixesCreateRegionFromPicture, 187 SProcXFixesDestroyRegion, 188 SProcXFixesSetRegion, 189 SProcXFixesCopyRegion, 190 SProcXFixesCombineRegion, 191 SProcXFixesCombineRegion, 192 SProcXFixesCombineRegion, 193 SProcXFixesInvertRegion, 194 SProcXFixesTranslateRegion, 195 SProcXFixesRegionExtents, 196 SProcXFixesFetchRegion, 197 SProcXFixesSetGCClipRegion, 198 SProcXFixesSetWindowShapeRegion, 199 SProcXFixesSetPictureClipRegion, 200 SProcXFixesSetCursorName, 201 SProcXFixesGetCursorName, 202 SProcXFixesGetCursorImageAndName, 203 SProcXFixesChangeCursor, SProcXFixesChangeCursorByName, 204/*************** Version 3 ******************/ 205 SProcXFixesExpandRegion, 206/*************** Version 4 ****************/ 207 SProcXFixesHideCursor, SProcXFixesShowCursor, 208/*************** Version 5 ****************/ 209 SProcXFixesCreatePointerBarrier, SProcXFixesDestroyPointerBarrier, 210/*************** Version 6 ****************/ 211 SProcXFixesSetClientDisconnectMode, SProcXFixesGetClientDisconnectMode, 212}; 213 214static _X_COLD int 215SProcXFixesDispatch(ClientPtr client) 216{ 217 REQUEST(xXFixesReq); 218 XFixesClientPtr pXFixesClient = GetXFixesClient(client); 219 220 if (pXFixesClient->major_version >= ARRAY_SIZE(version_requests)) 221 return BadRequest; 222 if (stuff->xfixesReqType > version_requests[pXFixesClient->major_version]) 223 return BadRequest; 224 return (*SProcXFixesVector[stuff->xfixesReqType]) (client); 225} 226 227void 228XFixesExtensionInit(void) 229{ 230 ExtensionEntry *extEntry; 231 232 if (!dixRegisterPrivateKey 233 (&XFixesClientPrivateKeyRec, PRIVATE_CLIENT, sizeof(XFixesClientRec))) 234 return; 235 236 if (XFixesSelectionInit() && 237 XFixesCursorInit() && 238 XFixesRegionInit() && 239 XFixesClientDisconnectInit() && 240 (extEntry = AddExtension(XFIXES_NAME, XFixesNumberEvents, 241 XFixesNumberErrors, 242 ProcXFixesDispatch, SProcXFixesDispatch, 243 NULL, StandardMinorOpcode)) != 0) { 244 XFixesReqCode = (unsigned char) extEntry->base; 245 XFixesEventBase = extEntry->eventBase; 246 XFixesErrorBase = extEntry->errorBase; 247 EventSwapVector[XFixesEventBase + XFixesSelectionNotify] = 248 (EventSwapPtr) SXFixesSelectionNotifyEvent; 249 EventSwapVector[XFixesEventBase + XFixesCursorNotify] = 250 (EventSwapPtr) SXFixesCursorNotifyEvent; 251 SetResourceTypeErrorValue(RegionResType, XFixesErrorBase + BadRegion); 252 SetResourceTypeErrorValue(PointerBarrierType, 253 XFixesErrorBase + BadBarrier); 254 } 255} 256 257#ifdef PANORAMIX 258 259int (*PanoramiXSaveXFixesVector[XFixesNumberRequests]) (ClientPtr); 260 261void 262PanoramiXFixesInit(void) 263{ 264 int i; 265 266 for (i = 0; i < XFixesNumberRequests; i++) 267 PanoramiXSaveXFixesVector[i] = ProcXFixesVector[i]; 268 /* 269 * Stuff in Xinerama aware request processing hooks 270 */ 271 ProcXFixesVector[X_XFixesSetGCClipRegion] = PanoramiXFixesSetGCClipRegion; 272 ProcXFixesVector[X_XFixesSetWindowShapeRegion] = 273 PanoramiXFixesSetWindowShapeRegion; 274 ProcXFixesVector[X_XFixesSetPictureClipRegion] = 275 PanoramiXFixesSetPictureClipRegion; 276} 277 278void 279PanoramiXFixesReset(void) 280{ 281 int i; 282 283 for (i = 0; i < XFixesNumberRequests; i++) 284 ProcXFixesVector[i] = PanoramiXSaveXFixesVector[i]; 285} 286 287#endif 288