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