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