1/************************************************************ 2 3Copyright 1989, 1998 The Open Group 4 5Permission to use, copy, modify, distribute, and sell this software and its 6documentation for any purpose is hereby granted without fee, provided that 7the above copyright notice appear in all copies and that both that 8copyright notice and this permission notice appear in supporting 9documentation. 10 11The above copyright notice and this permission notice shall be included in 12all copies or substantial portions of the Software. 13 14THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 18AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 19CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 20 21Except as contained in this notice, the name of The Open Group shall not be 22used in advertising or otherwise to promote the sale, use or other dealings 23in this Software without prior written authorization from The Open Group. 24 25Copyright 1989 by Hewlett-Packard Company, Palo Alto, California. 26 27 All Rights Reserved 28 29Permission to use, copy, modify, and distribute this software and its 30documentation for any purpose and without fee is hereby granted, 31provided that the above copyright notice appear in all copies and that 32both that copyright notice and this permission notice appear in 33supporting documentation, and that the name of Hewlett-Packard not be 34used in advertising or publicity pertaining to distribution of the 35software without specific, written prior permission. 36 37HEWLETT-PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING 38ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL 39HEWLETT-PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR 40ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, 41WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, 42ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS 43SOFTWARE. 44 45********************************************************/ 46 47/******************************************************************** 48 * 49 * Change Device control attributes for an extension device. 50 * 51 */ 52 53#ifdef HAVE_DIX_CONFIG_H 54#include <dix-config.h> 55#endif 56 57#include "inputstr.h" /* DeviceIntPtr */ 58#include <X11/extensions/XI.h> 59#include <X11/extensions/XIproto.h> /* control constants */ 60#include "XIstubs.h" 61 62#include "exglobals.h" 63#include "exevents.h" 64 65#include "chgdctl.h" 66 67/*********************************************************************** 68 * 69 * This procedure changes the control attributes for an extension device, 70 * for clients on machines with a different byte ordering than the server. 71 * 72 */ 73 74int _X_COLD 75SProcXChangeDeviceControl(ClientPtr client) 76{ 77 xDeviceCtl *ctl; 78 79 REQUEST(xChangeDeviceControlReq); 80 swaps(&stuff->length); 81 REQUEST_AT_LEAST_EXTRA_SIZE(xChangeDeviceControlReq, sizeof(xDeviceCtl)); 82 swaps(&stuff->control); 83 ctl = (xDeviceCtl *) &stuff[1]; 84 swaps(&ctl->control); 85 swaps(&ctl->length); 86 switch (stuff->control) { 87 case DEVICE_ABS_CALIB: 88#if 0 89 calib = (xDeviceAbsCalibCtl*)ctl; 90 swaps(&calib->length, n); 91 swapl(&calib->min_x, n); 92 swapl(&calib->max_x, n); 93 swapl(&calib->min_y, n); 94 swapl(&calib->max_y, n); 95 swapl(&calib->flip_x, n); 96 swapl(&calib->flip_y, n); 97 swapl(&calib->rotation, n); 98 swapl(&calib->button_threshold, n); 99 break; 100#endif 101 case DEVICE_ABS_AREA: 102#if 0 103 area = (xDeviceAbsAreaCtl*)ctl; 104 swapl(&area->offset_x, n); 105 swapl(&area->offset_y, n); 106 swapl(&area->width, n); 107 swapl(&area->height, n); 108 swapl(&area->screen, n); 109 swapl(&area->following, n); 110 break; 111#endif 112 case DEVICE_CORE: 113 case DEVICE_ENABLE: 114 case DEVICE_RESOLUTION: 115 /* hmm. beer. *drool* */ 116 break; 117 118 } 119 return (ProcXChangeDeviceControl(client)); 120} 121 122/*********************************************************************** 123 * 124 * Change the control attributes. 125 * 126 */ 127 128int 129ProcXChangeDeviceControl(ClientPtr client) 130{ 131 unsigned len; 132 int i, status, ret = BadValue; 133 DeviceIntPtr dev; 134 xDeviceResolutionCtl *r; 135 xChangeDeviceControlReply rep; 136 AxisInfoPtr a; 137 CARD32 *resolution; 138 xDeviceEnableCtl *e; 139 140 REQUEST(xChangeDeviceControlReq); 141 REQUEST_AT_LEAST_EXTRA_SIZE(xChangeDeviceControlReq, sizeof(xDeviceCtl)); 142 143 len = stuff->length - bytes_to_int32(sizeof(xChangeDeviceControlReq)); 144 ret = dixLookupDevice(&dev, stuff->deviceid, client, DixManageAccess); 145 if (ret != Success) 146 goto out; 147 148 /* XTest devices are special, none of the below apply to them anyway */ 149 if (IsXTestDevice(dev, NULL)) { 150 ret = BadMatch; 151 goto out; 152 } 153 154 rep = (xChangeDeviceControlReply) { 155 .repType = X_Reply, 156 .RepType = X_ChangeDeviceControl, 157 .sequenceNumber = client->sequence, 158 .length = 0, 159 .status = Success, 160 }; 161 162 switch (stuff->control) { 163 case DEVICE_RESOLUTION: 164 r = (xDeviceResolutionCtl *) &stuff[1]; 165 if ((len < bytes_to_int32(sizeof(xDeviceResolutionCtl))) || 166 (len != 167 bytes_to_int32(sizeof(xDeviceResolutionCtl)) + r->num_valuators)) { 168 ret = BadLength; 169 goto out; 170 } 171 if (!dev->valuator) { 172 ret = BadMatch; 173 goto out; 174 } 175 if ((dev->deviceGrab.grab) && !SameClient(dev->deviceGrab.grab, client)) { 176 rep.status = AlreadyGrabbed; 177 ret = Success; 178 goto out; 179 } 180 resolution = (CARD32 *) (r + 1); 181 if (r->first_valuator + r->num_valuators > dev->valuator->numAxes) { 182 ret = BadValue; 183 goto out; 184 } 185 status = ChangeDeviceControl(client, dev, (xDeviceCtl *) r); 186 if (status == Success) { 187 a = &dev->valuator->axes[r->first_valuator]; 188 for (i = 0; i < r->num_valuators; i++) 189 if (*(resolution + i) < (a + i)->min_resolution || 190 *(resolution + i) > (a + i)->max_resolution) 191 return BadValue; 192 for (i = 0; i < r->num_valuators; i++) 193 (a++)->resolution = *resolution++; 194 195 ret = Success; 196 } 197 else if (status == DeviceBusy) { 198 rep.status = DeviceBusy; 199 ret = Success; 200 } 201 else { 202 ret = BadMatch; 203 } 204 break; 205 case DEVICE_ABS_CALIB: 206 case DEVICE_ABS_AREA: 207 /* Calibration is now done through properties, and never had any effect 208 * on anything (in the open-source world). Thus, be honest. */ 209 ret = BadMatch; 210 break; 211 case DEVICE_CORE: 212 /* Sorry, no device core switching no more. If you want a device to 213 * send core events, attach it to a master device */ 214 ret = BadMatch; 215 break; 216 case DEVICE_ENABLE: 217 e = (xDeviceEnableCtl *) &stuff[1]; 218 if ((len != bytes_to_int32(sizeof(xDeviceEnableCtl)))) { 219 ret = BadLength; 220 goto out; 221 } 222 223 if (IsXTestDevice(dev, NULL)) 224 status = !Success; 225 else 226 status = ChangeDeviceControl(client, dev, (xDeviceCtl *) e); 227 228 if (status == Success) { 229 if (e->enable) 230 EnableDevice(dev, TRUE); 231 else 232 DisableDevice(dev, TRUE); 233 ret = Success; 234 } 235 else if (status == DeviceBusy) { 236 rep.status = DeviceBusy; 237 ret = Success; 238 } 239 else { 240 ret = BadMatch; 241 } 242 243 break; 244 default: 245 ret = BadValue; 246 } 247 248 out: 249 if (ret == Success) { 250 devicePresenceNotify dpn = { 251 .type = DevicePresenceNotify, 252 .time = currentTime.milliseconds, 253 .devchange = DeviceControlChanged, 254 .deviceid = dev->id, 255 .control = stuff->control 256 }; 257 SendEventToAllWindows(dev, DevicePresenceNotifyMask, 258 (xEvent *) &dpn, 1); 259 260 WriteReplyToClient(client, sizeof(xChangeDeviceControlReply), &rep); 261 } 262 263 return ret; 264} 265 266/*********************************************************************** 267 * 268 * This procedure writes the reply for the xChangeDeviceControl function, 269 * if the client and server have a different byte ordering. 270 * 271 */ 272 273void _X_COLD 274SRepXChangeDeviceControl(ClientPtr client, int size, 275 xChangeDeviceControlReply * rep) 276{ 277 swaps(&rep->sequenceNumber); 278 swapl(&rep->length); 279 WriteToClient(client, size, rep); 280} 281