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