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