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