chgfctl.c revision f7df2e56
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 feedback 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 61#include "exglobals.h" 62 63#include "chgfctl.h" 64 65#define DO_ALL (-1) 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 75SProcXChangeFeedbackControl(ClientPtr client) 76{ 77 REQUEST(xChangeFeedbackControlReq); 78 swaps(&stuff->length); 79 REQUEST_AT_LEAST_SIZE(xChangeFeedbackControlReq); 80 swapl(&stuff->mask); 81 return (ProcXChangeFeedbackControl(client)); 82} 83 84/****************************************************************************** 85 * 86 * This procedure changes KbdFeedbackClass data. 87 * 88 */ 89 90static int 91ChangeKbdFeedback(ClientPtr client, DeviceIntPtr dev, long unsigned int mask, 92 KbdFeedbackPtr k, xKbdFeedbackCtl * f) 93{ 94 KeybdCtrl kctrl; 95 int t; 96 int key = DO_ALL; 97 98 if (client->swapped) { 99 swaps(&f->length); 100 swaps(&f->pitch); 101 swaps(&f->duration); 102 swapl(&f->led_mask); 103 swapl(&f->led_values); 104 } 105 106 kctrl = k->ctrl; 107 if (mask & DvKeyClickPercent) { 108 t = f->click; 109 if (t == -1) 110 t = defaultKeyboardControl.click; 111 else if (t < 0 || t > 100) { 112 client->errorValue = t; 113 return BadValue; 114 } 115 kctrl.click = t; 116 } 117 118 if (mask & DvPercent) { 119 t = f->percent; 120 if (t == -1) 121 t = defaultKeyboardControl.bell; 122 else if (t < 0 || t > 100) { 123 client->errorValue = t; 124 return BadValue; 125 } 126 kctrl.bell = t; 127 } 128 129 if (mask & DvPitch) { 130 t = f->pitch; 131 if (t == -1) 132 t = defaultKeyboardControl.bell_pitch; 133 else if (t < 0) { 134 client->errorValue = t; 135 return BadValue; 136 } 137 kctrl.bell_pitch = t; 138 } 139 140 if (mask & DvDuration) { 141 t = f->duration; 142 if (t == -1) 143 t = defaultKeyboardControl.bell_duration; 144 else if (t < 0) { 145 client->errorValue = t; 146 return BadValue; 147 } 148 kctrl.bell_duration = t; 149 } 150 151 if (mask & DvLed) { 152 kctrl.leds &= ~(f->led_mask); 153 kctrl.leds |= (f->led_mask & f->led_values); 154 } 155 156 if (mask & DvKey) { 157 key = (KeyCode) f->key; 158 if (key < 8 || key > 255) { 159 client->errorValue = key; 160 return BadValue; 161 } 162 if (!(mask & DvAutoRepeatMode)) 163 return BadMatch; 164 } 165 166 if (mask & DvAutoRepeatMode) { 167 int inx = (key >> 3); 168 int kmask = (1 << (key & 7)); 169 170 t = (CARD8) f->auto_repeat_mode; 171 if (t == AutoRepeatModeOff) { 172 if (key == DO_ALL) 173 kctrl.autoRepeat = FALSE; 174 else 175 kctrl.autoRepeats[inx] &= ~kmask; 176 } 177 else if (t == AutoRepeatModeOn) { 178 if (key == DO_ALL) 179 kctrl.autoRepeat = TRUE; 180 else 181 kctrl.autoRepeats[inx] |= kmask; 182 } 183 else if (t == AutoRepeatModeDefault) { 184 if (key == DO_ALL) 185 kctrl.autoRepeat = defaultKeyboardControl.autoRepeat; 186 else 187 kctrl.autoRepeats[inx] &= ~kmask; 188 kctrl.autoRepeats[inx] = 189 (kctrl.autoRepeats[inx] & ~kmask) | 190 (defaultKeyboardControl.autoRepeats[inx] & kmask); 191 } 192 else { 193 client->errorValue = t; 194 return BadValue; 195 } 196 } 197 198 k->ctrl = kctrl; 199 (*k->CtrlProc) (dev, &k->ctrl); 200 return Success; 201} 202 203/****************************************************************************** 204 * 205 * This procedure changes PtrFeedbackClass data. 206 * 207 */ 208 209static int 210ChangePtrFeedback(ClientPtr client, DeviceIntPtr dev, long unsigned int mask, 211 PtrFeedbackPtr p, xPtrFeedbackCtl * f) 212{ 213 PtrCtrl pctrl; /* might get BadValue part way through */ 214 215 if (client->swapped) { 216 swaps(&f->length); 217 swaps(&f->num); 218 swaps(&f->denom); 219 swaps(&f->thresh); 220 } 221 222 pctrl = p->ctrl; 223 if (mask & DvAccelNum) { 224 int accelNum; 225 226 accelNum = f->num; 227 if (accelNum == -1) 228 pctrl.num = defaultPointerControl.num; 229 else if (accelNum < 0) { 230 client->errorValue = accelNum; 231 return BadValue; 232 } 233 else 234 pctrl.num = accelNum; 235 } 236 237 if (mask & DvAccelDenom) { 238 int accelDenom; 239 240 accelDenom = f->denom; 241 if (accelDenom == -1) 242 pctrl.den = defaultPointerControl.den; 243 else if (accelDenom <= 0) { 244 client->errorValue = accelDenom; 245 return BadValue; 246 } 247 else 248 pctrl.den = accelDenom; 249 } 250 251 if (mask & DvThreshold) { 252 int threshold; 253 254 threshold = f->thresh; 255 if (threshold == -1) 256 pctrl.threshold = defaultPointerControl.threshold; 257 else if (threshold < 0) { 258 client->errorValue = threshold; 259 return BadValue; 260 } 261 else 262 pctrl.threshold = threshold; 263 } 264 265 p->ctrl = pctrl; 266 (*p->CtrlProc) (dev, &p->ctrl); 267 return Success; 268} 269 270/****************************************************************************** 271 * 272 * This procedure changes IntegerFeedbackClass data. 273 * 274 */ 275 276static int 277ChangeIntegerFeedback(ClientPtr client, DeviceIntPtr dev, 278 long unsigned int mask, IntegerFeedbackPtr i, 279 xIntegerFeedbackCtl * f) 280{ 281 if (client->swapped) { 282 swaps(&f->length); 283 swapl(&f->int_to_display); 284 } 285 286 i->ctrl.integer_displayed = f->int_to_display; 287 (*i->CtrlProc) (dev, &i->ctrl); 288 return Success; 289} 290 291/****************************************************************************** 292 * 293 * This procedure changes StringFeedbackClass data. 294 * 295 */ 296 297static int 298ChangeStringFeedback(ClientPtr client, DeviceIntPtr dev, 299 long unsigned int mask, StringFeedbackPtr s, 300 xStringFeedbackCtl * f) 301{ 302 int i, j; 303 KeySym *syms, *sup_syms; 304 305 syms = (KeySym *) (f + 1); 306 if (client->swapped) { 307 swaps(&f->length); /* swapped num_keysyms in calling proc */ 308 SwapLongs((CARD32 *) syms, f->num_keysyms); 309 } 310 311 if (f->num_keysyms > s->ctrl.max_symbols) 312 return BadValue; 313 314 sup_syms = s->ctrl.symbols_supported; 315 for (i = 0; i < f->num_keysyms; i++) { 316 for (j = 0; j < s->ctrl.num_symbols_supported; j++) 317 if (*(syms + i) == *(sup_syms + j)) 318 break; 319 if (j == s->ctrl.num_symbols_supported) 320 return BadMatch; 321 } 322 323 s->ctrl.num_symbols_displayed = f->num_keysyms; 324 for (i = 0; i < f->num_keysyms; i++) 325 *(s->ctrl.symbols_displayed + i) = *(syms + i); 326 (*s->CtrlProc) (dev, &s->ctrl); 327 return Success; 328} 329 330/****************************************************************************** 331 * 332 * This procedure changes BellFeedbackClass data. 333 * 334 */ 335 336static int 337ChangeBellFeedback(ClientPtr client, DeviceIntPtr dev, 338 long unsigned int mask, BellFeedbackPtr b, 339 xBellFeedbackCtl * f) 340{ 341 int t; 342 BellCtrl bctrl; /* might get BadValue part way through */ 343 344 if (client->swapped) { 345 swaps(&f->length); 346 swaps(&f->pitch); 347 swaps(&f->duration); 348 } 349 350 bctrl = b->ctrl; 351 if (mask & DvPercent) { 352 t = f->percent; 353 if (t == -1) 354 t = defaultKeyboardControl.bell; 355 else if (t < 0 || t > 100) { 356 client->errorValue = t; 357 return BadValue; 358 } 359 bctrl.percent = t; 360 } 361 362 if (mask & DvPitch) { 363 t = f->pitch; 364 if (t == -1) 365 t = defaultKeyboardControl.bell_pitch; 366 else if (t < 0) { 367 client->errorValue = t; 368 return BadValue; 369 } 370 bctrl.pitch = t; 371 } 372 373 if (mask & DvDuration) { 374 t = f->duration; 375 if (t == -1) 376 t = defaultKeyboardControl.bell_duration; 377 else if (t < 0) { 378 client->errorValue = t; 379 return BadValue; 380 } 381 bctrl.duration = t; 382 } 383 b->ctrl = bctrl; 384 (*b->CtrlProc) (dev, &b->ctrl); 385 return Success; 386} 387 388/****************************************************************************** 389 * 390 * This procedure changes LedFeedbackClass data. 391 * 392 */ 393 394static int 395ChangeLedFeedback(ClientPtr client, DeviceIntPtr dev, long unsigned int mask, 396 LedFeedbackPtr l, xLedFeedbackCtl * f) 397{ 398 LedCtrl lctrl; /* might get BadValue part way through */ 399 400 if (client->swapped) { 401 swaps(&f->length); 402 swapl(&f->led_values); 403 swapl(&f->led_mask); 404 } 405 406 f->led_mask &= l->ctrl.led_mask; /* set only supported leds */ 407 f->led_values &= l->ctrl.led_mask; /* set only supported leds */ 408 if (mask & DvLed) { 409 lctrl.led_mask = f->led_mask; 410 lctrl.led_values = f->led_values; 411 (*l->CtrlProc) (dev, &lctrl); 412 l->ctrl.led_values &= ~(f->led_mask); /* zero changed leds */ 413 l->ctrl.led_values |= (f->led_mask & f->led_values); /* OR in set leds */ 414 } 415 416 return Success; 417} 418 419/*********************************************************************** 420 * 421 * Change the control attributes. 422 * 423 */ 424 425int 426ProcXChangeFeedbackControl(ClientPtr client) 427{ 428 unsigned len; 429 DeviceIntPtr dev; 430 KbdFeedbackPtr k; 431 PtrFeedbackPtr p; 432 IntegerFeedbackPtr i; 433 StringFeedbackPtr s; 434 BellFeedbackPtr b; 435 LedFeedbackPtr l; 436 int rc; 437 438 REQUEST(xChangeFeedbackControlReq); 439 REQUEST_AT_LEAST_SIZE(xChangeFeedbackControlReq); 440 441 len = stuff->length - bytes_to_int32(sizeof(xChangeFeedbackControlReq)); 442 rc = dixLookupDevice(&dev, stuff->deviceid, client, DixManageAccess); 443 if (rc != Success) 444 return rc; 445 446 switch (stuff->feedbackid) { 447 case KbdFeedbackClass: 448 if (len != bytes_to_int32(sizeof(xKbdFeedbackCtl))) 449 return BadLength; 450 451 for (k = dev->kbdfeed; k; k = k->next) 452 if (k->ctrl.id == ((xKbdFeedbackCtl *) &stuff[1])->id) 453 return ChangeKbdFeedback(client, dev, stuff->mask, k, 454 (xKbdFeedbackCtl *) &stuff[1]); 455 break; 456 case PtrFeedbackClass: 457 if (len != bytes_to_int32(sizeof(xPtrFeedbackCtl))) 458 return BadLength; 459 460 for (p = dev->ptrfeed; p; p = p->next) 461 if (p->ctrl.id == ((xPtrFeedbackCtl *) &stuff[1])->id) 462 return ChangePtrFeedback(client, dev, stuff->mask, p, 463 (xPtrFeedbackCtl *) &stuff[1]); 464 break; 465 case StringFeedbackClass: 466 { 467 xStringFeedbackCtl *f = ((xStringFeedbackCtl *) &stuff[1]); 468 469 if (client->swapped) { 470 if (len < bytes_to_int32(sizeof(xStringFeedbackCtl))) 471 return BadLength; 472 swaps(&f->num_keysyms); 473 } 474 if (len != 475 (bytes_to_int32(sizeof(xStringFeedbackCtl)) + f->num_keysyms)) 476 return BadLength; 477 478 for (s = dev->stringfeed; s; s = s->next) 479 if (s->ctrl.id == ((xStringFeedbackCtl *) &stuff[1])->id) 480 return ChangeStringFeedback(client, dev, stuff->mask, s, 481 (xStringFeedbackCtl *) &stuff[1]); 482 break; 483 } 484 case IntegerFeedbackClass: 485 if (len != bytes_to_int32(sizeof(xIntegerFeedbackCtl))) 486 return BadLength; 487 488 for (i = dev->intfeed; i; i = i->next) 489 if (i->ctrl.id == ((xIntegerFeedbackCtl *) &stuff[1])->id) 490 return ChangeIntegerFeedback(client, dev, stuff->mask, i, 491 (xIntegerFeedbackCtl *) & 492 stuff[1]); 493 break; 494 case LedFeedbackClass: 495 if (len != bytes_to_int32(sizeof(xLedFeedbackCtl))) 496 return BadLength; 497 498 for (l = dev->leds; l; l = l->next) 499 if (l->ctrl.id == ((xLedFeedbackCtl *) &stuff[1])->id) 500 return ChangeLedFeedback(client, dev, stuff->mask, l, 501 (xLedFeedbackCtl *) &stuff[1]); 502 break; 503 case BellFeedbackClass: 504 if (len != bytes_to_int32(sizeof(xBellFeedbackCtl))) 505 return BadLength; 506 507 for (b = dev->bell; b; b = b->next) 508 if (b->ctrl.id == ((xBellFeedbackCtl *) &stuff[1])->id) 509 return ChangeBellFeedback(client, dev, stuff->mask, b, 510 (xBellFeedbackCtl *) &stuff[1]); 511 break; 512 default: 513 break; 514 } 515 516 return BadMatch; 517} 518