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