1 /* 2 3 Copyright 1985, 1998 The Open Group 4 5 Permission to use, copy, modify, distribute, and sell this software and its 6 documentation for any purpose is hereby granted without fee, provided that 7 the above copyright notice appear in all copies and that both that 8 copyright notice and this permission notice appear in supporting 9 documentation. 10 11 The above copyright notice and this permission notice shall be included in 12 all copies or substantial portions of the Software. 13 14 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 18 AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 19 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 20 21 Except as contained in this notice, the name of The Open Group shall not be 22 used in advertising or otherwise to promote the sale, use or other dealings 23 in this Software without prior written authorization from The Open Group. 24 25 */ 26 /* Modified by Stephen so keyboard rate is set using XKB extensions */ 27 28 #ifdef HAVE_CONFIG_H 29 # include <config.h> 30 #endif 31 32 #ifdef HAVE_X11_EXTENSIONS_DPMS_H 33 # define DPMSExtension 34 #endif 35 36 #ifdef HAVE_X11_EXTENSIONS_MITMISC_H 37 # define MITMISC 38 #endif 39 40 #ifdef HAVE_X11_XKBLIB_H 41 # define XKB 42 #endif 43 44 #if defined(HAVE_X11_EXTENSIONS_XF86MISC_H) && defined(HAVE_X11_EXTENSIONS_XF86MSCSTR_H) 45 # define XF86MISC 46 #endif 47 48 #if defined(HAVE_X11_EXTENSIONS_FONTCACHE_H) && defined(HAVE_X11_EXTENSIONS_FONTCACHEP_H) 49 # define FONTCACHE 50 #endif 51 52 #include <stdio.h> 53 #include <ctype.h> 54 #include <stdarg.h> 55 #include <stdlib.h> 56 #ifdef HAVE_USLEEP 57 #include <unistd.h> 58 #endif 59 #include <X11/Xos.h> 60 #include <X11/Xfuncs.h> 61 #include <X11/Xlib.h> 62 #include <X11/keysym.h> 63 #include <X11/Xproto.h> 64 #include <X11/Xutil.h> 65 #include <X11/Xmu/Error.h> 66 #ifdef MITMISC 67 # include <X11/extensions/MITMisc.h> 68 #endif 69 #ifdef DPMSExtension 70 # include <X11/extensions/dpms.h> 71 #endif /* DPMSExtension */ 72 73 #ifdef XF86MISC 74 # include <X11/extensions/xf86misc.h> 75 # include <X11/extensions/xf86mscstr.h> 76 #endif 77 #ifdef XKB 78 # include <X11/XKBlib.h> 79 #endif 80 #ifdef FONTCACHE 81 # include <X11/extensions/fontcache.h> 82 # include <X11/extensions/fontcacheP.h> 83 84 static Status set_font_cache(Display *, long, long, long); 85 static void query_cache_status(Display *dpy); 86 #endif 87 88 #define ON 1 89 #define OFF 0 90 91 #define SERVER_DEFAULT (-1) 92 #define DONT_CHANGE -2 93 94 #define DEFAULT_ON (-50) 95 #define DEFAULT_TIMEOUT (-600) 96 97 #define ALL -1 98 #define TIMEOUT 1 99 #define INTERVAL 2 100 #define PREFER_BLANK 3 101 #define ALLOW_EXP 4 102 103 #ifdef XF86MISC 104 # define KBDDELAY_DEFAULT 500 105 # define KBDRATE_DEFAULT 30 106 #endif 107 #ifdef XKB 108 # define XKBDDELAY_DEFAULT 660 109 # define XKBDRATE_DEFAULT (1000/40) 110 #endif 111 112 #define nextarg(i, argv) \ 113 argv[i]; \ 114 if (i >= argc) \ 115 break; \ 116 117 static char *progName; 118 119 static int error_status = 0; 120 121 static int is_number(const char *arg, int maximum); 122 static void set_click(Display *dpy, int percent); 123 static void set_bell_vol(Display *dpy, int percent); 124 static void set_bell_pitch(Display *dpy, int pitch); 125 static void set_bell_dur(Display *dpy, int duration); 126 static void set_font_path(Display *dpy, const char *path, int special, 127 int before, int after); 128 static void set_led(Display *dpy, int led, int led_mode); 129 static void xkbset_led(Display *dpy, const char *led, int led_mode); 130 static void set_mouse(Display *dpy, int acc_num, int acc_denom, int threshold); 131 static void set_saver(Display *dpy, int mask, int value); 132 static void set_repeat(Display *dpy, int key, int auto_repeat_mode); 133 static void set_pixels(Display *dpy, const unsigned long *pixels, 134 caddr_t *colors, int numpixels); 135 static void set_lock(Display *dpy, Bool onoff); 136 static const char *on_or_off(int val, int onval, const char *onstr, 137 int offval, const char *offstr, 138 char buf[], size_t bufsize); 139 static void query(Display *dpy); 140 static void usage(const char *fmt, ...) _X_NORETURN _X_ATTRIBUTE_PRINTF(1,2); 141 static void error(const char *message) _X_NORETURN; 142 static int local_xerror(Display *dpy, XErrorEvent *rep); 143 144 #ifdef XF86MISC 145 static void set_repeatrate(Display *dpy, int delay, int rate); 146 #endif 147 #ifdef XKB 148 static void xkbset_repeatrate(Display *dpy, int delay, int rate); 149 #endif 150 151 int 152 main(int argc, char *argv[]) 153 { 154 const char *arg; 155 156 #define MAX_PIXEL_COUNT 512 157 unsigned long pixels[MAX_PIXEL_COUNT]; 158 caddr_t colors[MAX_PIXEL_COUNT]; 159 int numpixels = 0; 160 char *disp = NULL; 161 Display *dpy; 162 Bool hasargs = False; 163 164 progName = argv[0]; 165 for (int i = 1; i < argc; i++) { 166 arg = argv[i]; 167 if (strcmp(arg, "-display") == 0 || strcmp(arg, "-d") == 0) { 168 if (++i >= argc) 169 usage("missing argument to -display"); 170 disp = argv[i]; 171 } else { 172 /* accept single or double dash for -help & -version */ 173 if (arg[0] == '-' && arg[1] == '-') { 174 arg++; 175 } 176 177 if (strcmp(arg, "-help") == 0) { 178 usage(NULL); 179 } 180 else if (strcmp(arg, "-version") == 0) { 181 puts(PACKAGE_STRING); 182 exit(EXIT_SUCCESS); 183 } 184 else 185 hasargs = True; 186 } 187 } 188 if (!hasargs) { 189 usage(NULL); /* replace with window interface */ 190 } 191 192 dpy = XOpenDisplay(disp); /* Open display and check for success */ 193 if (dpy == NULL) { 194 fprintf(stderr, "%s: unable to open display \"%s\"\n", 195 argv[0], XDisplayName(disp)); 196 exit(EXIT_FAILURE); 197 } 198 XSetErrorHandler(local_xerror); 199 for (int i = 1; i < argc;) { 200 arg = argv[i++]; 201 if (strcmp(arg, "-display") == 0 || strcmp(arg, "-d") == 0) { 202 ++i; /* already dealt with */ 203 continue; 204 } else if (*arg == '-' && *(arg + 1) == 'c') { /* Does arg start 205 with "-c"? */ 206 set_click(dpy, 0); /* If so, turn click off */ 207 } else if (*arg == 'c') { /* Well, does it start 208 with "c", then? */ 209 int percent = SERVER_DEFAULT; /* Default click volume. */ 210 if (i >= argc) { 211 set_click(dpy, percent); /* set click to default */ 212 break; 213 } 214 arg = nextarg(i, argv); 215 if (strcmp(arg, "on") == 0) { /* Let click be default. */ 216 percent = DEFAULT_ON; 217 i++; 218 } else if (strcmp(arg, "off") == 0) { 219 percent = 0; /* Turn it off. */ 220 i++; 221 } else if (is_number(arg, 100)) { 222 percent = atoi(arg); /* Set to spec. volume */ 223 i++; 224 } 225 set_click(dpy, percent); 226 } else if (strcmp(arg, "-b") == 0) { 227 set_bell_vol(dpy, 0); /* Then turn off bell. */ 228 } else if (strcmp(arg, "b") == 0) { 229 int percent = SERVER_DEFAULT; /* Set bell to default. */ 230 if (i >= argc) { 231 set_bell_vol(dpy, percent); /* set bell to default */ 232 set_bell_pitch(dpy, percent); /* set pitch to default */ 233 set_bell_dur(dpy, percent); /* set duration to default */ 234 break; 235 } 236 arg = nextarg(i, argv); 237 if (strcmp(arg, "on") == 0) { /* Let it stay that way. */ 238 set_bell_vol(dpy, DEFAULT_ON); /* set bell on */ 239 set_bell_pitch(dpy, percent); /* set pitch to default */ 240 set_bell_dur(dpy, percent); /* set duration to default */ 241 i++; 242 } else if (strcmp(arg, "off") == 0) { 243 percent = 0; /* Turn the bell off. */ 244 set_bell_vol(dpy, percent); 245 i++; 246 } else if (is_number(arg, 100)) { /* If volume is given: */ 247 percent = atoi(arg); /* set bell appropriately. */ 248 set_bell_vol(dpy, percent); 249 i++; 250 arg = nextarg(i, argv); 251 252 if (is_number(arg, 32767)) { /* If pitch is given: */ 253 set_bell_pitch(dpy, atoi(arg)); /* set the bell. */ 254 i++; 255 256 arg = nextarg(i, argv); 257 if (is_number(arg, 32767)) { /* If duration is given: */ 258 set_bell_dur(dpy, atoi(arg)); /* set the bell. */ 259 i++; 260 } 261 } 262 } else 263 set_bell_vol(dpy, percent); /* set bell to default */ 264 } 265 #ifdef MITMISC 266 else if (strcmp(arg, "bc") == 0) { 267 int dummy; 268 269 if (XMITMiscQueryExtension(dpy, &dummy, &dummy)) 270 XMITMiscSetBugMode(dpy, True); 271 else 272 fprintf(stderr, 273 "server does not have extension for bc option\n"); 274 } else if (strcmp(arg, "-bc") == 0) { 275 int dummy; 276 277 if (XMITMiscQueryExtension(dpy, &dummy, &dummy)) 278 XMITMiscSetBugMode(dpy, False); 279 else 280 fprintf(stderr, 281 "server does not have extension for -bc option\n"); 282 } 283 #endif 284 #ifdef FONTCACHE 285 else if (strcmp(arg, "fc") == 0) { 286 int dummy; 287 FontCacheSettings cs; 288 289 if (FontCacheQueryExtension(dpy, &dummy, &dummy)) { 290 long himark, lowmark, balance; 291 292 FontCacheGetCacheSettings(dpy, &cs); 293 himark = cs.himark / 1024; 294 lowmark = cs.lowmark / 1024; 295 balance = cs.balance; 296 if (i >= argc) { 297 /* Set to server's values, and clear all cache 298 in side effect */ 299 set_font_cache(dpy, himark, lowmark, balance); 300 break; 301 } 302 arg = nextarg(i, argv); 303 if (is_number(arg, 32767)) { /* If hi-mark is given: */ 304 himark = atoi(arg); 305 i++; 306 if (himark <= 0) { 307 usage("hi-mark must be greater than 0"); 308 } 309 if (i >= argc) { 310 lowmark = (himark * 70) / 100; 311 set_font_cache(dpy, himark, lowmark, balance); 312 break; 313 } 314 arg = nextarg(i, argv); 315 if (is_number(arg, 32767)) { /* If low-mark is given: */ 316 lowmark = atoi(arg); 317 i++; 318 if (lowmark <= 0) { 319 usage("low-mark must be greater than 0"); 320 } 321 if (himark <= lowmark) { 322 usage("hi-mark must be greater than low-mark"); 323 } 324 if (i >= argc) { 325 set_font_cache(dpy, himark, lowmark, balance); 326 break; 327 } 328 arg = nextarg(i, argv); 329 if (is_number(arg, 90)) { 330 balance = atoi(arg); 331 i++; 332 if (!(10 <= balance && balance <= 90)) { 333 usage("balance must be 10 to 90\n"); 334 } 335 set_font_cache(dpy, himark, lowmark, balance); 336 } 337 } 338 } else if (strcmp(arg, "s") == 0 339 || strcmp(arg, "status") == 0) { 340 /* display cache status */ 341 query_cache_status(dpy); 342 } 343 } else { 344 fprintf(stderr, 345 "server does not have extension for fc option\n"); 346 } 347 } 348 #endif 349 else if (strcmp(arg, "fp") == 0) { /* set font path */ 350 if (i >= argc) { 351 arg = "default"; 352 } else { 353 arg = nextarg(i, argv); 354 } 355 set_font_path(dpy, arg, 1, 0, 0); /* special argument */ 356 i++; 357 } else if (strcmp(arg, "fp=") == 0) { /* unconditionally set */ 358 if (i >= argc) { 359 usage("missing fp= argument"); 360 } else { 361 arg = nextarg(i, argv); 362 } 363 set_font_path(dpy, arg, 0, 0, 0); /* not special, set */ 364 i++; 365 } else if (strcmp(arg, "+fp") == 0) { /* set font path */ 366 if (i >= argc) 367 usage("missing +fp argument"); 368 arg = nextarg(i, argv); 369 set_font_path(dpy, arg, 0, 1, 0); /* not special, prepend */ 370 i++; 371 } else if (strcmp(arg, "fp+") == 0) { /* set font path */ 372 if (i >= argc) 373 usage("missing fp+ argument"); 374 arg = nextarg(i, argv); 375 set_font_path(dpy, arg, 0, 0, 1); /* not special, append */ 376 i++; 377 } else if (strcmp(arg, "-fp") == 0) { /* set font path */ 378 if (i >= argc) 379 usage("missing -fp argument"); 380 arg = nextarg(i, argv); 381 set_font_path(dpy, arg, 0, -1, 0); /* not special, preremove */ 382 i++; 383 } else if (strcmp(arg, "fp-") == 0) { /* set font path */ 384 if (i >= argc) 385 usage("missing fp- argument"); 386 arg = nextarg(i, argv); 387 set_font_path(dpy, arg, 0, 0, -1); /* not special, postremove */ 388 i++; 389 } else if (strcmp(arg, "-led") == 0) { /* Turn off one or all LEDs */ 390 XKeyboardControl values = { 391 .led_mode = OFF, 392 .led = ALL /* None specified */ 393 }; 394 395 if (i >= argc) { 396 set_led(dpy, values.led, values.led_mode); 397 break; 398 } 399 arg = nextarg(i, argv); 400 if (strcmp(arg, "named") == 0) { 401 if (++i >= argc) { 402 usage("missing argument to led named"); 403 } else { 404 arg = nextarg(i, argv); 405 xkbset_led(dpy, arg, values.led_mode); 406 } 407 break; 408 } 409 if (is_number(arg, 32) && atoi(arg) > 0) { 410 values.led = atoi(arg); 411 i++; 412 } 413 set_led(dpy, values.led, values.led_mode); 414 } else if (strcmp(arg, "led") == 0) { /* Turn on one or all LEDs */ 415 XKeyboardControl values = { 416 .led_mode = ON, 417 .led = ALL 418 }; 419 420 if (i >= argc) { 421 set_led(dpy, values.led, 422 values.led_mode); /* set led to def */ 423 break; 424 } 425 arg = nextarg(i, argv); 426 if (strcmp(arg, "named") == 0) { 427 if (++i >= argc) { 428 usage("missing argument to -led named"); 429 } else { 430 arg = nextarg(i, argv); 431 xkbset_led(dpy, arg, values.led_mode); 432 } 433 break; 434 } 435 if (strcmp(arg, "on") == 0) { 436 i++; 437 } else if (strcmp(arg, "off") == 0) { /* ...except in this case. */ 438 values.led_mode = OFF; 439 i++; 440 } else if (is_number(arg, 32) && atoi(arg) > 0) { 441 values.led = atoi(arg); 442 i++; 443 } 444 set_led(dpy, values.led, values.led_mode); 445 } 446 /* Set pointer (mouse) settings: Acceleration and Threshold. */ 447 else if (strcmp(arg, "m") == 0 || strcmp(arg, "mouse") == 0) { 448 int acc_num = SERVER_DEFAULT; /* restore server defaults */ 449 int acc_denom = SERVER_DEFAULT; 450 int threshold = SERVER_DEFAULT; 451 452 if (i >= argc) { 453 set_mouse(dpy, acc_num, acc_denom, threshold); 454 break; 455 } 456 arg = argv[i]; 457 if (strcmp(arg, "default") == 0) { 458 i++; 459 } else if (*arg >= '0' && *arg <= '9') { 460 acc_denom = 1; 461 sscanf(arg, "%d/%d", &acc_num, &acc_denom); 462 i++; 463 if (i >= argc) { 464 set_mouse(dpy, acc_num, acc_denom, threshold); 465 break; 466 } 467 arg = argv[i]; 468 if (*arg >= '0' && *arg <= '9') { 469 threshold = atoi(arg); /* Set threshold as user specified. */ 470 i++; 471 } 472 } 473 set_mouse(dpy, acc_num, acc_denom, threshold); 474 } 475 #ifdef DPMSExtension 476 else if (strcmp(arg, "+dpms") == 0) { /* turn on DPMS */ 477 int dummy; 478 479 if (DPMSQueryExtension(dpy, &dummy, &dummy)) 480 DPMSEnable(dpy); 481 else 482 fprintf(stderr, 483 "server does not have extension for +dpms option\n"); 484 } else if (strcmp(arg, "-dpms") == 0) { /* shut off DPMS */ 485 int dummy; 486 487 if (DPMSQueryExtension(dpy, &dummy, &dummy)) 488 DPMSDisable(dpy); 489 else 490 fprintf(stderr, 491 "server does not have extension for -dpms option\n"); 492 493 } else if (strcmp(arg, "dpms") == 0) { /* tune DPMS */ 494 int dummy; 495 496 if (DPMSQueryExtension(dpy, &dummy, &dummy)) { 497 CARD16 standby_timeout, suspend_timeout, off_timeout; 498 499 DPMSGetTimeouts(dpy, &standby_timeout, &suspend_timeout, 500 &off_timeout); 501 if (i >= argc) { 502 DPMSEnable(dpy); 503 break; 504 } 505 arg = argv[i]; 506 if (*arg >= '0' && *arg <= '9') { 507 sscanf(arg, "%hu", &standby_timeout); 508 i++; 509 arg = argv[i]; 510 if ((arg) && (*arg >= '0' && *arg <= '9')) { 511 sscanf(arg, "%hu", &suspend_timeout); 512 i++; 513 arg = argv[i]; 514 if ((arg) && (*arg >= '0' && *arg <= '9')) { 515 sscanf(arg, "%hu", &off_timeout); 516 i++; 517 arg = argv[i]; 518 } 519 } 520 if ((suspend_timeout != 0) 521 && (standby_timeout > suspend_timeout)) { 522 fprintf(stderr, "illegal combination of values\n"); 523 fprintf(stderr, 524 " standby time of %d is greater than suspend time of %d\n", 525 standby_timeout, suspend_timeout); 526 exit(EXIT_FAILURE); 527 } 528 if ((off_timeout != 0) && (suspend_timeout > off_timeout)) { 529 fprintf(stderr, "illegal combination of values\n"); 530 fprintf(stderr, 531 " suspend time of %d is greater than off time of %d\n", 532 suspend_timeout, off_timeout); 533 exit(EXIT_FAILURE); 534 } 535 if ((suspend_timeout == 0) && (off_timeout != 0) && 536 (standby_timeout > off_timeout)) { 537 fprintf(stderr, "illegal combination of values\n"); 538 fprintf(stderr, 539 " standby time of %d is greater than off time of %d\n", 540 standby_timeout, off_timeout); 541 exit(EXIT_FAILURE); 542 } 543 DPMSEnable(dpy); 544 DPMSSetTimeouts(dpy, standby_timeout, suspend_timeout, 545 off_timeout); 546 } else if (strcmp(arg, "force") == 0) { 547 if (++i >= argc) 548 usage("missing argument to dpms force"); 549 arg = argv[i]; 550 /* 551 * The calls to usleep below are necessary to 552 * delay the actual DPMS mode setting briefly. 553 * Without them, it's likely that the mode will be 554 * set between the Down and Up key transitions, in 555 * which case the Up transition may immediately 556 * turn the display back on. 557 * 558 */ 559 560 #ifdef HAVE_USLEEP 561 # define Usleep(us) usleep((us)) 562 #elif defined(WIN32) 563 # define Usleep(us) Sleep(us) 564 #else 565 # define Usleep(us) sleep((us / 1000000 > 0) ? us / 1000000 : 1) 566 #endif /* HAVE_USLEEP */ 567 568 if (strcmp(arg, "on") == 0) { 569 DPMSEnable(dpy); 570 DPMSForceLevel(dpy, DPMSModeOn); 571 i++; 572 } else if (strcmp(arg, "standby") == 0) { 573 DPMSEnable(dpy); 574 Usleep(100000); 575 DPMSForceLevel(dpy, DPMSModeStandby); 576 i++; 577 } else if (strcmp(arg, "suspend") == 0) { 578 DPMSEnable(dpy); 579 Usleep(100000); 580 DPMSForceLevel(dpy, DPMSModeSuspend); 581 i++; 582 } else if (strcmp(arg, "off") == 0) { 583 DPMSEnable(dpy); 584 Usleep(100000); 585 DPMSForceLevel(dpy, DPMSModeOff); 586 i++; 587 } else { 588 fprintf(stderr, "bad parameter %s\n", arg); 589 i++; 590 } 591 } 592 } else { 593 fprintf(stderr, 594 "server does not have extension for dpms option\n"); 595 } 596 } 597 #endif /* DPMSExtension */ 598 else if (strcmp(arg, "s") == 0) { 599 if (i >= argc) { 600 set_saver(dpy, ALL, 0); /* Set everything to default */ 601 break; 602 } 603 arg = argv[i]; 604 if (strcmp(arg, "blank") == 0) { /* Alter blanking preference. */ 605 set_saver(dpy, PREFER_BLANK, PreferBlanking); 606 i++; 607 } else if (strcmp(arg, "noblank") == 0) { /* Ditto. */ 608 set_saver(dpy, PREFER_BLANK, DontPreferBlanking); 609 i++; 610 } else if (strcmp(arg, "expose") == 0) { /* Alter exposure preference. */ 611 set_saver(dpy, ALLOW_EXP, AllowExposures); 612 i++; 613 } else if (strcmp(arg, "noexpose") == 0) { /* Ditto. */ 614 set_saver(dpy, ALLOW_EXP, DontAllowExposures); 615 i++; 616 } else if (strcmp(arg, "off") == 0) { 617 set_saver(dpy, TIMEOUT, 0); /* Turn off screen saver. */ 618 i++; 619 if (i >= argc) 620 break; 621 arg = argv[i]; 622 if (strcmp(arg, "off") == 0) { 623 set_saver(dpy, INTERVAL, 0); 624 i++; 625 } 626 } else if (strcmp(arg, "default") == 0) { /* Leave as default. */ 627 set_saver(dpy, ALL, SERVER_DEFAULT); 628 i++; 629 } else if (strcmp(arg, "on") == 0) { /* Turn on. */ 630 set_saver(dpy, ALL, DEFAULT_TIMEOUT); 631 i++; 632 } else if (strcmp(arg, "activate") == 0) { /* force it active */ 633 XActivateScreenSaver(dpy); 634 i++; 635 } else if (strcmp(arg, "reset") == 0) { /* force it inactive */ 636 XResetScreenSaver(dpy); 637 i++; 638 } else if (*arg >= '0' && *arg <= '9') { /* Set as user wishes. */ 639 set_saver(dpy, TIMEOUT, atoi(arg)); 640 i++; 641 if (i >= argc) 642 break; 643 arg = argv[i]; 644 if (*arg >= '0' && *arg <= '9') { 645 set_saver(dpy, INTERVAL, atoi(arg)); 646 i++; 647 } 648 } 649 } else if (strcmp(arg, "-r") == 0) { /* Turn off one or 650 all autorepeats */ 651 int auto_repeat_mode = OFF; 652 int key = ALL; /* None specified */ 653 654 arg = argv[i]; 655 if (i < argc) 656 if (is_number(arg, 255)) { 657 key = atoi(arg); 658 i++; 659 } 660 set_repeat(dpy, key, auto_repeat_mode); 661 } else if (strcmp(arg, "r") == 0) { /* Turn on one or 662 all autorepeats */ 663 int auto_repeat_mode = ON; 664 int key = ALL; /* None specified */ 665 666 arg = argv[i]; 667 if (i < argc) { 668 if (strcmp(arg, "on") == 0) { 669 i++; 670 } else if (strcmp(arg, "off") == 0) { /* ...except in 671 this case */ 672 auto_repeat_mode = OFF; 673 i++; 674 } 675 #if defined(XF86MISC) || defined(XKB) 676 else if (strcmp(arg, "rate") == 0) { /* ...or this one. */ 677 int delay = 0, rate = 0; 678 int miscpresent = 0; 679 int xkbpresent = 0; 680 681 #ifdef XF86MISC 682 int rate_set = 0; 683 #endif 684 #ifdef XKB 685 int xkbmajor = XkbMajorVersion, xkbminor = XkbMinorVersion; 686 int xkbopcode, xkbevent, xkberror; 687 688 if (XkbQueryExtension(dpy, &xkbopcode, &xkbevent, 689 &xkberror, &xkbmajor, &xkbminor)) { 690 delay = XKBDDELAY_DEFAULT; 691 rate = XKBDRATE_DEFAULT; 692 xkbpresent = 1; 693 } 694 #endif 695 #ifdef XF86MISC 696 if (!xkbpresent) { 697 int dummy; 698 699 if (XF86MiscQueryExtension(dpy, &dummy, &dummy)) { 700 delay = KBDDELAY_DEFAULT; 701 rate = KBDRATE_DEFAULT; 702 miscpresent = 1; 703 } 704 } 705 #endif 706 if (!xkbpresent && !miscpresent) 707 fprintf(stderr, 708 "server does not have extension for \"r rate\" option\n"); 709 i++; 710 arg = argv[i]; 711 if (i < argc) { 712 if (is_number(arg, 10000) && atoi(arg) > 0) { 713 delay = atoi(arg); 714 i++; 715 arg = argv[i]; 716 if (i < argc) { 717 if (is_number(arg, 255) && atoi(arg) > 0) { 718 rate = atoi(arg); 719 i++; 720 } 721 } 722 } 723 } 724 #ifdef XKB 725 if (xkbpresent) { 726 xkbset_repeatrate(dpy, delay, 1000 / rate); 727 #ifdef XF86MISC 728 rate_set = 1; 729 #endif 730 } 731 #endif 732 #ifdef XF86MISC 733 if (miscpresent && !rate_set) { 734 set_repeatrate(dpy, delay, rate); 735 } 736 #endif 737 } 738 #endif 739 else if (is_number(arg, 255)) { 740 key = atoi(arg); 741 i++; 742 } 743 } 744 set_repeat(dpy, key, auto_repeat_mode); 745 } else if (strcmp(arg, "p") == 0) { 746 if (i + 1 >= argc) 747 usage("missing argument to p"); 748 arg = argv[i]; 749 if (numpixels >= MAX_PIXEL_COUNT) 750 usage("more than %d pixels specified", MAX_PIXEL_COUNT); 751 if (*arg >= '0' && *arg <= '9') 752 pixels[numpixels] = strtoul(arg, NULL, 10); 753 else 754 usage("invalid pixel number %s", arg); 755 i++; 756 colors[numpixels] = argv[i]; 757 i++; 758 numpixels++; 759 } else if (strcmp(arg, "-k") == 0) { 760 set_lock(dpy, OFF); 761 } else if (strcmp(arg, "k") == 0) { 762 set_lock(dpy, ON); 763 } else if (strcmp(arg, "q") == 0 || strcmp(arg, "-q") == 0) { 764 query(dpy); 765 } else 766 usage("unknown option %s", arg); 767 } 768 769 if (numpixels) 770 set_pixels(dpy, pixels, colors, numpixels); 771 772 XCloseDisplay(dpy); 773 774 exit(error_status); /* Done. We can go home now. */ 775 } 776 777 static int 778 is_number(const char *arg, int maximum) 779 { 780 const char *p; 781 782 if (arg[0] == '-' && arg[1] == '1' && arg[2] == '\0') 783 return (1); 784 for (p = arg; isdigit(*p); p++) ; 785 if (*p || atoi(arg) > maximum) 786 return (0); 787 return (1); 788 } 789 790 /* These next few functions do the real work (xsetting things). 791 */ 792 static void 793 set_click(Display *dpy, int percent) 794 { 795 XKeyboardControl values = { .key_click_percent = percent }; 796 797 if (percent == DEFAULT_ON) 798 values.key_click_percent = SERVER_DEFAULT; 799 XChangeKeyboardControl(dpy, KBKeyClickPercent, &values); 800 if (percent == DEFAULT_ON) { 801 XKeyboardState kbstate; 802 803 XGetKeyboardControl(dpy, &kbstate); 804 if (!kbstate.key_click_percent) { 805 values.key_click_percent = -percent; 806 XChangeKeyboardControl(dpy, KBKeyClickPercent, &values); 807 } 808 } 809 return; 810 } 811 812 static void 813 set_bell_vol(Display *dpy, int percent) 814 { 815 XKeyboardControl values = { .bell_percent = percent }; 816 817 if (percent == DEFAULT_ON) 818 values.bell_percent = SERVER_DEFAULT; 819 XChangeKeyboardControl(dpy, KBBellPercent, &values); 820 if (percent == DEFAULT_ON) { 821 XKeyboardState kbstate; 822 823 XGetKeyboardControl(dpy, &kbstate); 824 if (!kbstate.bell_percent) { 825 values.bell_percent = -percent; 826 XChangeKeyboardControl(dpy, KBBellPercent, &values); 827 } 828 } 829 return; 830 } 831 832 static void 833 set_bell_pitch(Display *dpy, int pitch) 834 { 835 XKeyboardControl values = { .bell_pitch = pitch }; 836 837 XChangeKeyboardControl(dpy, KBBellPitch, &values); 838 return; 839 } 840 841 static void 842 set_bell_dur(Display *dpy, int duration) 843 { 844 XKeyboardControl values = { .bell_duration = duration }; 845 846 XChangeKeyboardControl(dpy, KBBellDuration, &values); 847 return; 848 } 849 850 /* 851 * Set, add, or subtract the path according to before and after flags: 852 * 853 * before after action 854 * 855 * 0 0 FontPath := path 856 * -1 0 FontPath := current - path 857 * 0 -1 FontPath := current - path 858 * 1 0 FontPath := path + current 859 * 0 1 FontPath := current + path 860 */ 861 static void 862 set_font_path(Display *dpy, const char *path, int special, int before, int after) 863 { 864 char *directories = NULL; 865 char **directoryList = NULL; 866 unsigned int ndirs = 0; 867 char **currentList = NULL; 868 unsigned int ncurrent = 0; 869 870 if (special) { 871 if (strcmp(path, "default") == 0) { 872 XSetFontPath(dpy, NULL, 0); 873 return; 874 } 875 if (strcmp(path, "rehash") == 0) { 876 currentList = XGetFontPath(dpy, (int *) &ncurrent); 877 if (!currentList) { 878 fprintf(stderr, "%s: unable to get current font path.\n", 879 progName); 880 return; 881 } 882 XSetFontPath(dpy, currentList, (int) ncurrent); 883 XFreeFontPath(currentList); 884 return; 885 } 886 /* 887 * for now, fall though and process keyword and directory list for 888 * compatibility with previous versions. 889 */ 890 } 891 892 /* 893 * parse the path list. If before or after is non-zero, we'll need 894 * the current value. 895 */ 896 897 if (before != 0 || after != 0) { 898 currentList = XGetFontPath(dpy, (int *) &ncurrent); 899 if (!currentList) { 900 fprintf(stderr, "%s: unable to get old font path.\n", progName); 901 before = after = 0; 902 } 903 } 904 905 { 906 /* count the number of directories in path */ 907 const char *cp = path; 908 909 ndirs = 1; 910 while ((cp = strchr(cp, ',')) != NULL) { 911 ndirs++; 912 cp++; 913 } 914 } 915 916 directoryList = malloc(ndirs * sizeof(char *)); 917 if (!directoryList) 918 error("out of memory for font path directory list"); 919 920 directories = strdup(path); 921 if (!directories) 922 error("out of memory for font path directory string"); 923 else 924 { 925 /* mung the path and set directoryList pointers */ 926 unsigned int i = 0; 927 char *cp = directories; 928 929 directoryList[i++] = cp; 930 while ((cp = strchr(cp, ',')) != NULL) { 931 directoryList[i++] = cp + 1; 932 *cp++ = '\0'; 933 } 934 if (i != ndirs) { 935 fprintf(stderr, 936 "%s: internal error, only parsed %d of %d directories.\n", 937 progName, i, ndirs); 938 exit(EXIT_FAILURE); 939 } 940 } 941 942 /* 943 * now we have have parsed the input path, so we can set it 944 */ 945 946 if (before == 0 && after == 0) { 947 XSetFontPath(dpy, directoryList, (int) ndirs); 948 } 949 950 /* if adding to list, build a superset */ 951 if (before > 0 || after > 0) { 952 unsigned int nnew = ndirs + ncurrent; 953 char **newList = malloc(nnew * sizeof(char *)); 954 955 if (!newList) 956 error("out of memory"); 957 if (before > 0) { /* new + current */ 958 memmove(newList, directoryList, (ndirs * sizeof(char *))); 959 memmove((newList + ndirs), currentList, (ncurrent * sizeof(char *))); 960 XSetFontPath(dpy, newList, (int) nnew); 961 } else if (after > 0) { 962 memmove(newList, currentList, (ncurrent * sizeof(char *))); 963 memmove((newList + ncurrent), directoryList, 964 (ndirs * sizeof(char *))); 965 XSetFontPath(dpy, newList,(int) nnew); 966 } 967 free(newList); 968 } 969 970 /* if deleting from list, build one the same size */ 971 if (before < 0 || after < 0) { 972 unsigned int i, j; 973 unsigned int nnew = 0; 974 char **newList = malloc(ncurrent * sizeof(char *)); 975 976 if (!newList) 977 error("out of memory"); 978 for (i = 0; i < ncurrent; i++) { 979 for (j = 0; j < ndirs; j++) { 980 if (strcmp(currentList[i], directoryList[j]) == 0) 981 break; 982 } 983 /* if we ran out, then insert into new list */ 984 if (j == ndirs) 985 newList[nnew++] = currentList[i]; 986 } 987 if (nnew == ncurrent) { 988 fprintf(stderr, 989 "%s: warning, no entries deleted from font path.\n", 990 progName); 991 } 992 XSetFontPath(dpy, newList, (int) nnew); 993 free(newList); 994 } 995 996 free(directories); 997 free(directoryList); 998 if (currentList) 999 XFreeFontPath(currentList); 1000 1001 return; 1002 } 1003 1004 static void 1005 set_led(Display *dpy, int led, int led_mode) 1006 { 1007 XKeyboardControl values = { .led_mode = led_mode }; 1008 1009 if (led != ALL) { 1010 values.led = led; 1011 XChangeKeyboardControl(dpy, KBLed | KBLedMode, &values); 1012 } else { 1013 XChangeKeyboardControl(dpy, KBLedMode, &values); 1014 } 1015 return; 1016 } 1017 1018 static void 1019 xkbset_led(Display *dpy, const char *led, int led_mode) 1020 { 1021 #ifndef XKB 1022 error(" xset was not built with XKB Extension support\n"); 1023 #else 1024 int xkbmajor = XkbMajorVersion, xkbminor = XkbMinorVersion; 1025 int xkbopcode, xkbevent, xkberror; 1026 1027 if (XkbQueryExtension(dpy, &xkbopcode, &xkbevent, &xkberror, 1028 &xkbmajor, &xkbminor)) { 1029 Atom ledatom = XInternAtom(dpy, led, True); 1030 1031 if ((ledatom != None) && 1032 XkbGetNamedIndicator(dpy, ledatom, NULL, NULL, NULL, NULL)) { 1033 if (XkbSetNamedIndicator(dpy, ledatom, True, 1034 led_mode, False, NULL) == False) { 1035 printf("Failed to set led named %s %s\n", 1036 led, led_mode ? "on" : "off"); 1037 } 1038 } else { 1039 fprintf(stderr,"%s: Invalid led name: %s\n", progName, led); 1040 } 1041 } else { 1042 printf(" Server does not have the XKB Extension\n"); 1043 } 1044 #endif 1045 return; 1046 } 1047 1048 static void 1049 set_mouse(Display *dpy, int acc_num, int acc_denom, int threshold) 1050 { 1051 int do_accel = True, do_threshold = True; 1052 1053 if (acc_num == DONT_CHANGE) /* what an incredible crock... */ 1054 do_accel = False; 1055 if (threshold == DONT_CHANGE) 1056 do_threshold = False; 1057 if (acc_num < 0) /* shouldn't happen */ 1058 acc_num = SERVER_DEFAULT; 1059 if (acc_denom <= 0) /* prevent divide by zero */ 1060 acc_denom = SERVER_DEFAULT; 1061 if (threshold < 0) 1062 threshold = SERVER_DEFAULT; 1063 XChangePointerControl(dpy, do_accel, do_threshold, acc_num, 1064 acc_denom, threshold); 1065 return; 1066 } 1067 1068 static void 1069 set_saver(Display *dpy, int mask, int value) 1070 { 1071 int timeout, interval, prefer_blank, allow_exp; 1072 1073 XGetScreenSaver(dpy, &timeout, &interval, &prefer_blank, &allow_exp); 1074 if (mask == TIMEOUT) 1075 timeout = value; 1076 if (mask == INTERVAL) 1077 interval = value; 1078 if (mask == PREFER_BLANK) 1079 prefer_blank = value; 1080 if (mask == ALLOW_EXP) 1081 allow_exp = value; 1082 if (mask == ALL) { 1083 timeout = SERVER_DEFAULT; 1084 interval = SERVER_DEFAULT; 1085 prefer_blank = DefaultBlanking; 1086 allow_exp = DefaultExposures; 1087 } 1088 XSetScreenSaver(dpy, timeout, interval, prefer_blank, allow_exp); 1089 if (mask == ALL && value == DEFAULT_TIMEOUT) { 1090 XGetScreenSaver(dpy, &timeout, &interval, &prefer_blank, &allow_exp); 1091 if (!timeout) 1092 XSetScreenSaver(dpy, -DEFAULT_TIMEOUT, interval, prefer_blank, 1093 allow_exp); 1094 } 1095 return; 1096 } 1097 1098 static void 1099 set_repeat(Display *dpy, int key, int auto_repeat_mode) 1100 { 1101 XKeyboardControl values = { .auto_repeat_mode = auto_repeat_mode }; 1102 1103 if (key != ALL) { 1104 values.key = key; 1105 XChangeKeyboardControl(dpy, KBKey | KBAutoRepeatMode, &values); 1106 } else { 1107 XChangeKeyboardControl(dpy, KBAutoRepeatMode, &values); 1108 } 1109 return; 1110 } 1111 1112 #ifdef XF86MISC 1113 static void 1114 set_repeatrate(Display *dpy, int delay, int rate) 1115 { 1116 XF86MiscKbdSettings values; 1117 1118 XF86MiscGetKbdSettings(dpy, &values); 1119 values.delay = delay; 1120 values.rate = rate; 1121 XF86MiscSetKbdSettings(dpy, &values); 1122 return; 1123 } 1124 #endif 1125 1126 #ifdef XKB 1127 static void 1128 xkbset_repeatrate(Display *dpy, int delay, int interval) 1129 { 1130 XkbDescPtr xkb = XkbAllocKeyboard(); 1131 1132 if (!xkb) 1133 return; 1134 XkbGetControls(dpy, XkbRepeatKeysMask, xkb); 1135 xkb->ctrls->repeat_delay = delay; 1136 xkb->ctrls->repeat_interval = interval; 1137 XkbSetControls(dpy, XkbRepeatKeysMask, xkb); 1138 XkbFreeKeyboard(xkb, 0, True); 1139 } 1140 #endif 1141 1142 static void 1143 set_pixels(Display *dpy, const unsigned long *pixels, caddr_t * colors, 1144 int numpixels) 1145 { 1146 XColor def; 1147 int scr = DefaultScreen(dpy); 1148 Visual *visual = DefaultVisual(dpy, scr); 1149 Colormap cmap = DefaultColormap(dpy, scr); 1150 unsigned long max_cells = (unsigned long) DisplayCells(dpy, scr); 1151 XVisualInfo viproto, *vip; 1152 int nvisuals = 0; 1153 const char *visual_type = NULL; 1154 1155 viproto.visualid = XVisualIDFromVisual(visual); 1156 vip = XGetVisualInfo(dpy, VisualIDMask, &viproto, &nvisuals); 1157 if (!vip) { 1158 fprintf(stderr, "%s: Can't get visual for visualID 0x%x\n", 1159 progName, (unsigned int)viproto.visualid); 1160 return; 1161 } 1162 1163 switch (vip->class) { 1164 case GrayScale: 1165 case PseudoColor: 1166 break; 1167 case TrueColor: 1168 visual_type = "TrueColor"; 1169 /* fall through */ 1170 case DirectColor: 1171 max_cells *= max_cells * max_cells; 1172 break; 1173 case StaticGray: 1174 visual_type = "StaticGray"; 1175 break; 1176 case StaticColor: 1177 visual_type = "StaticColor"; 1178 break; 1179 default: 1180 fprintf(stderr, "%s: unknown visual class type %d\n", 1181 progName, vip->class); 1182 numpixels = 0; 1183 } 1184 1185 if (visual_type) { 1186 fprintf(stderr, 1187 "%s: cannot set pixel values in read-only %s visuals\n", 1188 progName, visual_type); 1189 } else { 1190 for (int i = 0; i < numpixels; i++) { 1191 def.pixel = pixels[i]; 1192 if (def.pixel >= max_cells) 1193 fprintf(stderr, 1194 "%s: pixel value %ld out of colormap range 0 through %ld\n", 1195 progName, def.pixel, max_cells - 1); 1196 else { 1197 if (XParseColor(dpy, cmap, colors[i], &def)) 1198 XStoreColor(dpy, cmap, &def); 1199 else 1200 fprintf(stderr, "%s: invalid color \"%s\"\n", progName, 1201 colors[i]); 1202 } 1203 } 1204 } 1205 1206 XFree(vip); 1207 1208 return; 1209 } 1210 1211 static void 1212 set_lock(Display *dpy, Bool onoff) 1213 { 1214 XModifierKeymap *mods; 1215 1216 mods = XGetModifierMapping(dpy); 1217 1218 if (onoff) 1219 mods = 1220 XInsertModifiermapEntry(mods, (KeyCode) XK_Caps_Lock, 1221 LockMapIndex); 1222 else 1223 mods = 1224 XDeleteModifiermapEntry(mods, (KeyCode) XK_Caps_Lock, 1225 LockMapIndex); 1226 XSetModifierMapping(dpy, mods); 1227 XFreeModifiermap(mods); 1228 return; 1229 } 1230 1231 #ifdef FONTCACHE 1232 static Status 1233 set_font_cache(Display *dpy, long himark, long lowmark, long balance) 1234 { 1235 FontCacheSettings cs = { 1236 .himark = himark * 1024, 1237 .lowmark = lowmark * 1024, 1238 .balance = balance 1239 }; 1240 1241 Status status = FontCacheChangeCacheSettings(dpy, &cs); 1242 1243 return status; 1244 } 1245 #endif 1246 1247 static const char * 1248 on_or_off(int val, int onval, const char *onstr, 1249 int offval, const char *offstr, char buf[], size_t bufsize) 1250 { 1251 if (val == onval) 1252 return onstr; 1253 else if (val == offval) 1254 return offstr; 1255 1256 buf[0] = '\0'; 1257 snprintf(buf, bufsize, "<%d>", val); 1258 return buf; 1259 } 1260 1261 /* This is the information-getting function for telling the user what the 1262 * current "xsettings" are. 1263 */ 1264 static void 1265 query(Display *dpy) 1266 { 1267 int scr = DefaultScreen(dpy); 1268 XKeyboardState values; 1269 int acc_num, acc_denom, threshold; 1270 int timeout, interval, prefer_blank, allow_exp; 1271 1272 #ifdef XKB 1273 XkbDescPtr xkb; 1274 int xkbmajor = XkbMajorVersion, xkbminor = XkbMinorVersion; 1275 int xkbopcode, xkbevent, xkberror; 1276 #endif 1277 char **font_path; 1278 int npaths; 1279 int i, j; 1280 char buf[20]; /* big enough for 16 bit number */ 1281 1282 XGetKeyboardControl(dpy, &values); 1283 XGetPointerControl(dpy, &acc_num, &acc_denom, &threshold); 1284 XGetScreenSaver(dpy, &timeout, &interval, &prefer_blank, &allow_exp); 1285 font_path = XGetFontPath(dpy, &npaths); 1286 1287 printf("Keyboard Control:\n"); 1288 printf 1289 (" auto repeat: %s key click percent: %d LED mask: %08lx\n", 1290 on_or_off(values.global_auto_repeat, AutoRepeatModeOn, "on", 1291 AutoRepeatModeOff, "off", buf, sizeof(buf)), 1292 values.key_click_percent, values.led_mask); 1293 #ifdef XKB 1294 if (XkbQueryExtension(dpy, &xkbopcode, &xkbevent, &xkberror, &xkbmajor, 1295 &xkbminor) 1296 && (xkb = XkbAllocKeyboard()) != NULL) { 1297 if (XkbGetNames(dpy, XkbIndicatorNamesMask, xkb) == Success) { 1298 Atom iatoms[XkbNumIndicators]; 1299 char *iatomnames[XkbNumIndicators]; 1300 Bool istates[XkbNumIndicators]; 1301 int inds[XkbNumIndicators]; 1302 int activecount = 0; 1303 int maxnamelen = 0; 1304 1305 printf(" XKB indicators:\n"); 1306 1307 for (i = 0, j = 0; i < XkbNumIndicators; i++) { 1308 if (xkb->names->indicators[i] != None) { 1309 iatoms[j++] = xkb->names->indicators[i]; 1310 } 1311 } 1312 1313 if (XGetAtomNames(dpy, iatoms, j, iatomnames)) { 1314 for (i = 0; i < j; i++) { 1315 if (XkbGetNamedIndicator(dpy, iatoms[i], &inds[i], 1316 &istates[i], NULL, NULL)) { 1317 int namelen = (int) strlen(iatomnames[i]); 1318 if (namelen > maxnamelen) { 1319 maxnamelen = namelen; 1320 } 1321 activecount++; 1322 } else { 1323 inds[i] = -1; 1324 } 1325 } 1326 } 1327 1328 if (activecount == 0) { 1329 printf(" None\n"); 1330 } else { 1331 int columnwidth; 1332 int linewidth; 1333 1334 #define XKB_IND_FORMAT_CHARS 13 /* size of other chars in ' DD: X: off' */ 1335 #define MAX_LINE_WIDTH 76 1336 1337 columnwidth = maxnamelen + XKB_IND_FORMAT_CHARS; 1338 if (columnwidth > MAX_LINE_WIDTH) { 1339 columnwidth = MAX_LINE_WIDTH; 1340 } 1341 1342 for (i = 0, linewidth = 0; i < activecount ; i++) { 1343 if (inds[i] != -1) { 1344 int spaces = columnwidth - XKB_IND_FORMAT_CHARS 1345 - (int) strlen(iatomnames[i]); 1346 1347 if (spaces < 0) 1348 spaces = 0; 1349 1350 linewidth += printf(" %02d: %s: %*s", 1351 inds[i], iatomnames[i], 1352 spaces + 3, 1353 on_or_off(istates[i], 1354 True, "on ", 1355 False, "off", 1356 buf, sizeof(buf))); 1357 } 1358 if (linewidth > (MAX_LINE_WIDTH - columnwidth)) { 1359 printf("\n"); 1360 linewidth = 0; 1361 } 1362 } 1363 if (linewidth > 0) { 1364 printf("\n"); 1365 } 1366 } 1367 } 1368 if (XkbGetControls(dpy, XkbRepeatKeysMask, xkb) == Success) { 1369 printf(" auto repeat delay: %d repeat rate: %d\n", 1370 xkb->ctrls->repeat_delay, 1371 1000 / xkb->ctrls->repeat_interval); 1372 } 1373 } 1374 #ifdef XF86MISC 1375 else 1376 #endif 1377 #endif 1378 #ifdef XF86MISC 1379 { 1380 int dummy; 1381 XF86MiscKbdSettings kbdinfo; 1382 1383 if (XF86MiscQueryExtension(dpy, &dummy, &dummy) && 1384 XF86MiscGetKbdSettings(dpy, &kbdinfo)) 1385 printf(" auto repeat delay: %d repeat rate: %d\n", 1386 kbdinfo.delay, kbdinfo.rate); 1387 } 1388 #endif 1389 printf(" auto repeating keys: "); 1390 for (i = 0; i < 4; i++) { 1391 if (i) 1392 printf(" "); 1393 for (j = 0; j < 8; j++) { 1394 printf("%02x", (unsigned char)values.auto_repeats[i * 8 + j]); 1395 } 1396 printf("\n"); 1397 } 1398 printf(" bell percent: %d bell pitch: %d bell duration: %d\n", 1399 values.bell_percent, values.bell_pitch, values.bell_duration); 1400 1401 printf("Pointer Control:\n"); 1402 printf(" acceleration: %d/%d threshold: %d\n", 1403 acc_num, acc_denom, threshold); 1404 1405 printf("Screen Saver:\n"); 1406 printf(" prefer blanking: %s ", 1407 on_or_off(prefer_blank, PreferBlanking, "yes", 1408 DontPreferBlanking, "no", buf, sizeof(buf))); 1409 printf("allow exposures: %s\n", 1410 on_or_off(allow_exp, AllowExposures, "yes", 1411 DontAllowExposures, "no", buf, sizeof(buf))); 1412 printf(" timeout: %d cycle: %d\n", timeout, interval); 1413 1414 printf("Colors:\n"); 1415 printf(" default colormap: 0x%lx BlackPixel: 0x%lx WhitePixel: 0x%lx\n", 1416 DefaultColormap(dpy, scr), BlackPixel(dpy, scr), WhitePixel(dpy, 1417 scr)); 1418 1419 printf("Font Path:\n"); 1420 if (npaths) { 1421 printf(" %s", *font_path++); 1422 for (--npaths; npaths; npaths--) 1423 printf(",%s", *font_path++); 1424 printf("\n"); 1425 } else { 1426 printf(" (empty)\n"); 1427 } 1428 1429 #ifdef MITMISC 1430 { 1431 int dummy; 1432 1433 if (XMITMiscQueryExtension(dpy, &dummy, &dummy)) { 1434 if (XMITMiscGetBugMode(dpy)) 1435 printf("Bug Mode: compatibility mode is enabled\n"); 1436 else 1437 printf("Bug Mode: compatibility mode is disabled\n"); 1438 } 1439 } 1440 #endif 1441 #ifdef DPMSExtension 1442 { 1443 1444 int dummy; 1445 CARD16 standby, suspend, off; 1446 BOOL onoff; 1447 CARD16 state; 1448 1449 printf("DPMS (Display Power Management Signaling):\n"); 1450 if (DPMSQueryExtension(dpy, &dummy, &dummy)) { 1451 if (DPMSCapable(dpy)) { 1452 DPMSGetTimeouts(dpy, &standby, &suspend, &off); 1453 printf(" Standby: %d Suspend: %d Off: %d\n", 1454 standby, suspend, off); 1455 DPMSInfo(dpy, &state, &onoff); 1456 if (onoff) { 1457 printf(" DPMS is Enabled\n"); 1458 switch (state) { 1459 case DPMSModeOn: 1460 printf(" Monitor is On\n"); 1461 break; 1462 case DPMSModeStandby: 1463 printf(" Monitor is in Standby\n"); 1464 break; 1465 case DPMSModeSuspend: 1466 printf(" Monitor is in Suspend\n"); 1467 break; 1468 case DPMSModeOff: 1469 printf(" Monitor is Off\n"); 1470 break; 1471 default: 1472 printf(" Unrecognized response from server\n"); 1473 } 1474 } else 1475 printf(" DPMS is Disabled\n"); 1476 } else 1477 printf(" Display is not capable of DPMS\n"); 1478 } else { 1479 printf(" Server does not have the DPMS Extension\n"); 1480 } 1481 } 1482 #endif 1483 #ifdef FONTCACHE 1484 { 1485 int dummy; 1486 1487 printf("Font cache:\n"); 1488 if (FontCacheQueryExtension(dpy, &dummy, &dummy)) { 1489 FontCacheSettings cs; 1490 1491 if (FontCacheGetCacheSettings(dpy, &cs)) { 1492 int himark = cs.himark / 1024; 1493 int lowmark = cs.lowmark / 1024; 1494 int balance = cs.balance; 1495 1496 printf(" hi-mark (KB): %d low-mark (KB): %d balance (%%): %d\n", 1497 himark, lowmark, balance); 1498 } 1499 } else { 1500 printf(" Server does not have the FontCache Extension\n"); 1501 } 1502 } 1503 #endif 1504 #ifdef XF86MISC 1505 { 1506 int dummy; 1507 int maj, min; 1508 XF86MiscFilePaths paths; 1509 1510 if (XF86MiscQueryExtension(dpy, &dummy, &dummy) && 1511 XF86MiscQueryVersion(dpy, &maj, &min) && 1512 ((maj > 0) || (maj == 0 && min >= 7)) && 1513 XF86MiscGetFilePaths(dpy, &paths)) { 1514 printf("File paths:\n"); 1515 printf(" Config file: %s\n", paths.configfile); 1516 printf(" Modules path: %s\n", paths.modulepath); 1517 printf(" Log file: %s\n", paths.logfile); 1518 } 1519 } 1520 #endif 1521 1522 return; 1523 } 1524 1525 #ifdef FONTCACHE 1526 /* 1527 * query_cache_status() 1528 * 1529 * This is the information-getting function for telling the user what the 1530 * current settings and statistics are. 1531 */ 1532 static void 1533 query_cache_status(Display *dpy) 1534 { 1535 int dummy; 1536 1537 if (FontCacheQueryExtension(dpy, &dummy, &dummy)) { 1538 FontCacheSettings cs; 1539 FontCacheStatistics cstats; 1540 1541 if (FontCacheGetCacheSettings(dpy, &cs)) { 1542 int himark = cs.himark / 1024; 1543 int lowmark = cs.lowmark / 1024; 1544 int balance = cs.balance; 1545 1546 printf("font cache settings:\n"); 1547 printf(" hi-mark (KB): %d low-mark (KB): %d balance (%%): %d\n", 1548 himark, lowmark, balance); 1549 } 1550 if (FontCacheGetCacheStatistics(dpy, &cstats)) { 1551 printf("font cache statistics:\n"); 1552 printf(" cache purged: %ld\n", cstats.purge_runs); 1553 printf(" cache status: %ld\n", cstats.purge_stat); 1554 printf(" cache balance: %ld\n", cstats.balance); 1555 printf("font cache entry statistics:\n"); 1556 printf(" hits: %ld\n", cstats.f.hits); 1557 printf(" misshits: %ld\n", cstats.f.misshits); 1558 printf(" purged: %ld\n", cstats.f.purged); 1559 printf(" usage: %ld\n", cstats.f.usage); 1560 printf("large bitmap cache entry statistics:\n"); 1561 printf(" hits: %ld\n", cstats.v.hits); 1562 printf(" misshits: %ld\n", cstats.v.misshits); 1563 printf(" purged: %ld\n", cstats.v.purged); 1564 printf(" usage: %ld\n", cstats.v.usage); 1565 } 1566 } else { 1567 printf("Server does not have the FontCache Extension\n"); 1568 } 1569 } 1570 #endif 1571 1572 /* This is the usage function */ 1573 1574 static void 1575 usage(const char *fmt, ...) 1576 { 1577 va_list ap; 1578 1579 if (fmt) { 1580 fprintf(stderr, "%s: ", progName); 1581 va_start(ap, fmt); 1582 vfprintf(stderr, fmt, ap); 1583 va_end(ap); 1584 fprintf(stderr, "\n\n"); 1585 1586 } 1587 1588 fprintf(stderr, "usage: %s [-display host:dpy] option ...\n%s", progName, 1589 " To turn bell off:\n" 1590 "\t-b b off b 0\n" 1591 " To set bell volume, pitch and duration:\n" 1592 "\t b [vol [pitch [dur]]] b on\n" 1593 #ifdef MITMISC 1594 " To disable bug compatibility mode:\n" 1595 "\t-bc\n" 1596 " To enable bug compatibility mode:\n" 1597 "\tbc\n" 1598 #endif 1599 " To turn keyclick off:\n" 1600 "\t-c c off c 0\n" 1601 " To set keyclick volume:\n" 1602 "\t c [0-100] c on\n" 1603 #ifdef DPMSExtension 1604 " To control Display Power Management Signaling (DPMS) features:\n" 1605 "\t-dpms DPMS features off\n" 1606 "\t+dpms DPMS features on\n" 1607 "\t dpms [standby [suspend [off]]] \n" 1608 "\t force standby \n" 1609 "\t force suspend \n" 1610 "\t force off \n" 1611 "\t force on \n" 1612 "\t (also implicitly enables DPMS features) \n" 1613 "\t a timeout value of zero disables the mode \n" 1614 #endif 1615 #ifdef FONTCACHE 1616 " To control font cache:\n" 1617 "\t fc [hi-mark [low-mark [balance]]]\n" 1618 "\t both mark values specified in KB\n" 1619 "\t balance value specified in percent (10 - 90)\n" 1620 " Show font cache statistics:\n" 1621 "\t fc s\n" 1622 #endif 1623 " To set the font path:\n" 1624 "\t fp= path[,path...]\n" 1625 " To restore the default font path:\n" 1626 "\t fp default\n" 1627 " To have the server reread font databases:\n" 1628 "\t fp rehash\n" 1629 " To remove elements from font path:\n" 1630 "\t-fp path[,path...] fp- path[,path...]\n" 1631 " To prepend or append elements to font path:\n" 1632 "\t+fp path[,path...] fp+ path[,path...]\n" 1633 " To set LED states off or on:\n" 1634 "\t-led [1-32] led off\n" 1635 "\t led [1-32] led on\n" 1636 #ifdef XKB 1637 "\t-led named 'name' led off\n" 1638 "\t led named 'name' led on\n" 1639 #endif 1640 " To set mouse acceleration and threshold:\n" 1641 "\t m [acc_mult[/acc_div] [thr]] m default\n" 1642 " To set pixel colors:\n" 1643 "\t p pixel_value color_name\n" 1644 " To turn auto-repeat off or on:\n" 1645 "\t-r [keycode] r off\n" 1646 "\t r [keycode] r on\n" 1647 #if defined(XF86MISC) || defined(XKB) 1648 "\t r rate [delay [rate]]\n" 1649 #endif 1650 " For screen-saver control:\n" 1651 "\t s [timeout [cycle]] s default s on\n" 1652 "\t s blank s noblank s off\n" 1653 "\t s expose s noexpose\n" 1654 "\t s activate s reset\n" 1655 " For status information: q\n" 1656 " To print version: -version\n" 1657 ); 1658 exit(EXIT_SUCCESS); 1659 } 1660 1661 static void 1662 error(const char *message) 1663 { 1664 fprintf(stderr, "%s: %s\n", progName, message); 1665 exit(EXIT_FAILURE); 1666 } 1667 1668 static int 1669 local_xerror(Display *dpy, XErrorEvent *rep) 1670 { 1671 if (rep->request_code == X_SetFontPath && rep->error_code == BadValue) { 1672 fprintf(stderr, 1673 "%s: bad font path element (#%ld), possible causes are:\n", 1674 progName, rep->resourceid); 1675 fprintf(stderr, 1676 " Directory does not exist or has wrong permissions\n" 1677 " Directory missing fonts.dir\n" 1678 " Incorrect font server address or syntax\n"); 1679 } else if (rep->request_code == X_StoreColors) { 1680 switch (rep->error_code) { 1681 case BadAccess: 1682 fprintf(stderr, 1683 "%s: pixel not allocated read/write\n", progName); 1684 break; 1685 case BadValue: 1686 fprintf(stderr, 1687 "%s: cannot store in pixel 0x%lx, invalid pixel number\n", 1688 progName, rep->resourceid); 1689 break; 1690 default: 1691 XmuPrintDefaultErrorMessage(dpy, rep, stderr); 1692 } 1693 } else 1694 XmuPrintDefaultErrorMessage(dpy, rep, stderr); 1695 1696 error_status = -1; 1697 1698 return (0); 1699 } 1700