3 Copyright 1985, 1998 The Open Group
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
11 The above copyright notice and this permission notice shall be included in
12 all copies or substantial portions of the Software.
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.
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.
26 /* Modified by Stephen so keyboard rate is set using XKB extensions */
32 #ifdef HAVE_X11_EXTENSIONS_DPMS_H
33 # define DPMSExtension
36 #ifdef HAVE_X11_EXTENSIONS_MITMISC_H
40 #ifdef HAVE_X11_XKBLIB_H
44 #if defined(HAVE_X11_EXTENSIONS_XF86MISC_H) && defined(HAVE_X11_EXTENSIONS_XF86MSCSTR_H)
48 #if defined(HAVE_X11_EXTENSIONS_FONTCACHE_H) && defined(HAVE_X11_EXTENSIONS_FONTCACHEP_H)
57 #include <X11/Xfuncs.h>
59 #include <X11/keysym.h>
60 #include <X11/Xproto.h>
61 #include <X11/Xutil.h>
62 #include <X11/Xmu/Error.h>
64 # include <X11/extensions/MITMisc.h>
67 # include <X11/extensions/dpms.h>
72 # define Status wStatus
81 #endif /* DPMSExtension */
84 # include <X11/extensions/xf86misc.h>
85 # include <X11/extensions/xf86mscstr.h>
88 # include <X11/XKBlib.h>
91 # include <X11/extensions/fontcache.h>
92 # include <X11/extensions/fontcacheP.h>
94 static Status set_font_cache(Display *, long, long, long);
95 static void query_cache_status(Display *dpy);
101 #define SERVER_DEFAULT (-1)
102 #define DONT_CHANGE -2
104 #define DEFAULT_ON (-50)
105 #define DEFAULT_TIMEOUT (-600)
110 #define PREFER_BLANK 3
114 # define KBDDELAY_DEFAULT 500
115 # define KBDRATE_DEFAULT 30
118 # define XKBDDELAY_DEFAULT 660
119 # define XKBDRATE_DEFAULT (1000/40)
122 #define nextarg(i, argv) \
127 static char *progName;
129 static int error_status = 0;
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,
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);
154 static void set_repeatrate(Display *dpy, int delay, int rate);
157 static void xkbset_repeatrate(Display *dpy, int delay, int rate);
161 main(int argc, char *argv[])
166 int acc_num, acc_denom, threshold;
169 CARD16 standby_timeout, suspend_timeout, off_timeout;
171 int key, auto_repeat_mode;
172 XKeyboardControl values;
174 #define MAX_PIXEL_COUNT 512
175 unsigned long pixels[MAX_PIXEL_COUNT];
176 caddr_t colors[MAX_PIXEL_COUNT];
180 Bool hasargs = False;
186 int xkbmajor = XkbMajorVersion, xkbminor = XkbMinorVersion;
187 int xkbopcode, xkbevent, xkberror;
191 long himark, lowmark, balance;
195 for (i = 1; i < argc; i++) {
197 if (strcmp(arg, "-display") == 0 || strcmp(arg, "-d") == 0) {
199 usage("missing argument to -display", NULL);
206 usage(NULL, NULL); /* replace with window interface */
209 dpy = XOpenDisplay(disp); /* Open display and check for success */
211 fprintf(stderr, "%s: unable to open display \"%s\"\n",
212 argv[0], XDisplayName(disp));
215 XSetErrorHandler(local_xerror);
216 for (i = 1; i < argc;) {
218 if (strcmp(arg, "-display") == 0 || strcmp(arg, "-d") == 0) {
219 ++i; /* already dealt with */
221 } else if (*arg == '-' && *(arg + 1) == 'c') { /* Does arg start
223 set_click(dpy, 0); /* If so, turn click off */
224 } else if (*arg == 'c') { /* Well, does it start
226 percent = SERVER_DEFAULT; /* Default click volume. */
228 set_click(dpy, percent); /* set click to default */
231 arg = nextarg(i, argv);
232 if (strcmp(arg, "on") == 0) { /* Let click be default. */
233 percent = DEFAULT_ON;
235 } else if (strcmp(arg, "off") == 0) {
236 percent = 0; /* Turn it off. */
238 } else if (is_number(arg, 100)) {
239 percent = atoi(arg); /* Set to spec. volume */
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. */
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 */
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 */
259 } else if (strcmp(arg, "off") == 0) {
260 percent = 0; /* Turn the bell off. */
261 set_bell_vol(dpy, percent);
263 } else if (is_number(arg, 100)) { /* If volume is given: */
264 percent = atoi(arg); /* set bell appropriately. */
265 set_bell_vol(dpy, percent);
267 arg = nextarg(i, argv);
269 if (is_number(arg, 32767)) { /* If pitch is given: */
270 set_bell_pitch(dpy, atoi(arg)); /* set the bell. */
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. */
280 set_bell_vol(dpy, percent); /* set bell to default */
283 else if (strcmp(arg, "bc") == 0) {
286 if (XMITMiscQueryExtension(dpy, &dummy, &dummy))
287 XMITMiscSetBugMode(dpy, True);
290 "server does not have extension for bc option\n");
291 } else if (strcmp(arg, "-bc") == 0) {
294 if (XMITMiscQueryExtension(dpy, &dummy, &dummy))
295 XMITMiscSetBugMode(dpy, False);
298 "server does not have extension for -bc option\n");
302 else if (strcmp(arg, "fc") == 0) {
304 FontCacheSettings cs;
306 if (FontCacheQueryExtension(dpy, &dummy, &dummy)) {
307 FontCacheGetCacheSettings(dpy, &cs);
308 himark = cs.himark / 1024;
309 lowmark = cs.lowmark / 1024;
310 balance = cs.balance;
312 /* Set to server's values, and clear all cache
314 set_font_cache(dpy, himark, lowmark, balance);
317 arg = nextarg(i, argv);
318 if (is_number(arg, 32767)) { /* If hi-mark is given: */
322 usage("hi-mark must be greater than 0", NULL);
325 lowmark = (himark * 70) / 100;
326 set_font_cache(dpy, himark, lowmark, balance);
329 arg = nextarg(i, argv);
330 if (is_number(arg, 32767)) { /* If low-mark is given: */
334 usage("low-mark must be greater than 0", NULL);
336 if (himark <= lowmark) {
337 usage("hi-mark must be greater than low-mark",
341 set_font_cache(dpy, himark, lowmark, balance);
344 arg = nextarg(i, argv);
345 if (is_number(arg, 90)) {
348 if (!(10 <= balance && balance <= 90)) {
349 usage("balance must be 10 to 90\n");
351 set_font_cache(dpy, himark, lowmark, balance);
354 } else if (strcmp(arg, "s") == 0
355 || strcmp(arg, "status") == 0) {
356 /* display cache status */
357 query_cache_status(dpy);
361 "server does not have extension for fc option\n");
365 else if (strcmp(arg, "fp") == 0) { /* set font path */
369 arg = nextarg(i, argv);
371 set_font_path(dpy, arg, 1, 0, 0); /* special argument */
373 } else if (strcmp(arg, "fp=") == 0) { /* unconditionally set */
375 usage("missing fp= argument", NULL);
377 arg = nextarg(i, argv);
379 set_font_path(dpy, arg, 0, 0, 0); /* not special, set */
381 } else if (strcmp(arg, "+fp") == 0) { /* set font path */
383 usage("missing +fp argument", NULL);
384 arg = nextarg(i, argv);
385 set_font_path(dpy, arg, 0, 1, 0); /* not special, prepend */
387 } else if (strcmp(arg, "fp+") == 0) { /* set font path */
389 usage("missing fp+ argument", NULL);
390 arg = nextarg(i, argv);
391 set_font_path(dpy, arg, 0, 0, 1); /* not special, append */
393 } else if (strcmp(arg, "-fp") == 0) { /* set font path */
395 usage("missing -fp argument", NULL);
396 arg = nextarg(i, argv);
397 set_font_path(dpy, arg, 0, -1, 0); /* not special, preremove */
399 } else if (strcmp(arg, "fp-") == 0) { /* set font path */
401 usage("missing fp- argument", NULL);
402 arg = nextarg(i, argv);
403 set_font_path(dpy, arg, 0, 0, -1); /* not special, postremove */
405 } else if (strcmp(arg, "-led") == 0) { /* Turn off one or all LEDs */
406 values.led_mode = OFF;
407 values.led = ALL; /* None specified */
409 set_led(dpy, values.led, values.led_mode);
412 arg = nextarg(i, argv);
413 if (strcmp(arg, "named") == 0) {
415 usage("missing argument to led named", NULL);
417 arg = nextarg(i, argv);
418 xkbset_led(dpy, arg, values.led_mode);
422 if (is_number(arg, 32) && atoi(arg) > 0) {
423 values.led = atoi(arg);
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;
431 set_led(dpy, values.led,
432 values.led_mode); /* set led to def */
435 arg = nextarg(i, argv);
436 if (strcmp(arg, "named") == 0) {
438 usage("missing argument to -led named", NULL);
440 arg = nextarg(i, argv);
441 xkbset_led(dpy, arg, values.led_mode);
445 if (strcmp(arg, "on") == 0) {
447 } else if (strcmp(arg, "off") == 0) { /* ...except in this case. */
448 values.led_mode = OFF;
450 } else if (is_number(arg, 32) && atoi(arg) > 0) {
451 values.led = atoi(arg);
454 set_led(dpy, values.led, values.led_mode);
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;
462 set_mouse(dpy, acc_num, acc_denom, threshold);
466 if (strcmp(arg, "default") == 0) {
468 } else if (*arg >= '0' && *arg <= '9') {
470 sscanf(arg, "%d/%d", &acc_num, &acc_denom);
473 set_mouse(dpy, acc_num, acc_denom, threshold);
477 if (*arg >= '0' && *arg <= '9') {
478 threshold = atoi(arg); /* Set threshold as user specified. */
482 set_mouse(dpy, acc_num, acc_denom, threshold);
485 else if (strcmp(arg, "+dpms") == 0) { /* turn on DPMS */
488 if (DPMSQueryExtension(dpy, &dummy, &dummy))
492 "server does not have extension for +dpms option\n");
493 } else if (strcmp(arg, "-dpms") == 0) { /* shut off DPMS */
496 if (DPMSQueryExtension(dpy, &dummy, &dummy))
500 "server does not have extension for -dpms option\n");
502 } else if (strcmp(arg, "dpms") == 0) { /* tune DPMS */
505 if (DPMSQueryExtension(dpy, &dummy, &dummy)) {
506 DPMSGetTimeouts(dpy, &standby_timeout, &suspend_timeout,
513 if (*arg >= '0' && *arg <= '9') {
514 sscanf(arg, "%hu", &standby_timeout);
517 if ((arg) && (*arg >= '0' && *arg <= '9')) {
518 sscanf(arg, "%hu", &suspend_timeout);
521 if ((arg) && (*arg >= '0' && *arg <= '9')) {
522 sscanf(arg, "%hu", &off_timeout);
527 if ((suspend_timeout != 0)
528 && (standby_timeout > suspend_timeout)) {
529 fprintf(stderr, "illegal combination of values\n");
531 " standby time of %d is greater than suspend time of %d\n",
532 standby_timeout, suspend_timeout);
535 if ((off_timeout != 0) && (suspend_timeout > off_timeout)) {
536 fprintf(stderr, "illegal combination of values\n");
538 " suspend time of %d is greater than off time of %d\n",
539 suspend_timeout, off_timeout);
542 if ((suspend_timeout == 0) && (off_timeout != 0) &&
543 (standby_timeout > off_timeout)) {
544 fprintf(stderr, "illegal combination of values\n");
546 " standby time of %d is greater than off time of %d\n",
547 standby_timeout, off_timeout);
551 DPMSSetTimeouts(dpy, standby_timeout, suspend_timeout,
553 } else if (strcmp(arg, "force") == 0) {
555 usage("missing argument to dpms force", NULL);
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.
565 * On OS/2, use _sleep2()
569 # define Usleep(us) usleep((us))
573 # define Usleep(us) sginap((us) / 1000)
577 # ifdef _XPG4_EXTENDED
578 # define Usleep(us) usleep((us))
582 # define Usleep(us) _sleep2((us / 1000 > 0) ? us / 1000 : 1)
585 # define Usleep(us) Sleep(us)
588 # if defined(SYSV) || defined(SVR4)
589 # define Usleep(us) sleep((us / 1000000 > 0) ? us / 1000000 : 1)
591 # define Usleep(us) usleep((us))
594 #endif /* HAVE_USLEEP */
596 if (strcmp(arg, "on") == 0) {
598 DPMSForceLevel(dpy, DPMSModeOn);
600 } else if (strcmp(arg, "standby") == 0) {
603 DPMSForceLevel(dpy, DPMSModeStandby);
605 } else if (strcmp(arg, "suspend") == 0) {
608 DPMSForceLevel(dpy, DPMSModeSuspend);
610 } else if (strcmp(arg, "off") == 0) {
613 DPMSForceLevel(dpy, DPMSModeOff);
616 fprintf(stderr, "bad parameter %s\n", arg);
622 "server does not have extension for dpms option\n");
625 #endif /* DPMSExtension */
626 else if (strcmp(arg, "s") == 0) {
628 set_saver(dpy, ALL, 0); /* Set everything to default */
632 if (strcmp(arg, "blank") == 0) { /* Alter blanking preference. */
633 set_saver(dpy, PREFER_BLANK, PreferBlanking);
635 } else if (strcmp(arg, "noblank") == 0) { /* Ditto. */
636 set_saver(dpy, PREFER_BLANK, DontPreferBlanking);
638 } else if (strcmp(arg, "expose") == 0) { /* Alter exposure preference. */
639 set_saver(dpy, ALLOW_EXP, AllowExposures);
641 } else if (strcmp(arg, "noexpose") == 0) { /* Ditto. */
642 set_saver(dpy, ALLOW_EXP, DontAllowExposures);
644 } else if (strcmp(arg, "off") == 0) {
645 set_saver(dpy, TIMEOUT, 0); /* Turn off screen saver. */
650 if (strcmp(arg, "off") == 0) {
651 set_saver(dpy, INTERVAL, 0);
654 } else if (strcmp(arg, "default") == 0) { /* Leave as default. */
655 set_saver(dpy, ALL, SERVER_DEFAULT);
657 } else if (strcmp(arg, "on") == 0) { /* Turn on. */
658 set_saver(dpy, ALL, DEFAULT_TIMEOUT);
660 } else if (strcmp(arg, "activate") == 0) { /* force it active */
661 XActivateScreenSaver(dpy);
663 } else if (strcmp(arg, "reset") == 0) { /* force it inactive */
664 XResetScreenSaver(dpy);
666 } else if (*arg >= '0' && *arg <= '9') { /* Set as user wishes. */
667 set_saver(dpy, TIMEOUT, atoi(arg));
672 if (*arg >= '0' && *arg <= '9') {
673 set_saver(dpy, INTERVAL, atoi(arg));
677 } else if (strcmp(arg, "-r") == 0) { /* Turn off one or
679 auto_repeat_mode = OFF;
680 key = ALL; /* None specified */
683 if (is_number(arg, 255)) {
687 set_repeat(dpy, key, auto_repeat_mode);
688 } else if (strcmp(arg, "r") == 0) { /* Turn on one or
690 auto_repeat_mode = ON;
691 key = ALL; /* None specified */
694 if (strcmp(arg, "on") == 0) {
696 } else if (strcmp(arg, "off") == 0) { /* ...except in
698 auto_repeat_mode = OFF;
701 #if defined(XF86MISC) || defined(XKB)
702 else if (strcmp(arg, "rate") == 0) { /* ...or this one. */
703 int delay = 0, rate = 0;
710 if (XkbQueryExtension(dpy, &xkbopcode, &xkbevent,
711 &xkberror, &xkbmajor, &xkbminor)) {
712 delay = XKBDDELAY_DEFAULT;
713 rate = XKBDRATE_DEFAULT;
721 if (XF86MiscQueryExtension(dpy, &dummy, &dummy)) {
722 delay = KBDDELAY_DEFAULT;
723 rate = KBDRATE_DEFAULT;
728 if (!xkbpresent && !miscpresent)
730 "server does not have extension for \"r rate\" option\n");
734 if (is_number(arg, 10000) && atoi(arg) > 0) {
739 if (is_number(arg, 255) && atoi(arg) > 0) {
748 xkbset_repeatrate(dpy, delay, 1000 / rate);
755 if (miscpresent && !rate_set) {
756 set_repeatrate(dpy, delay, rate);
761 else if (is_number(arg, 255)) {
766 set_repeat(dpy, key, auto_repeat_mode);
767 } else if (strcmp(arg, "p") == 0) {
769 usage("missing argument to p", NULL);
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);
776 usage("invalid pixel number %s", arg);
778 colors[numpixels] = argv[i];
781 } else if (strcmp(arg, "-k") == 0) {
783 } else if (strcmp(arg, "k") == 0) {
785 } else if (strcmp(arg, "q") == 0 || strcmp(arg, "-q") == 0) {
788 usage("unknown option %s", arg);
792 set_pixels(dpy, pixels, colors, numpixels);
796 exit(error_status); /* Done. We can go home now. */
800 is_number(char *arg, int maximum)
804 if (arg[0] == '-' && arg[1] == '1' && arg[2] == '\0')
806 for (p = arg; isdigit(*p); p++) ;
807 if (*p || atoi(arg) > maximum)
812 /* These next few functions do the real work (xsetting things).
815 set_click(Display *dpy, int percent)
817 XKeyboardControl values;
818 XKeyboardState kbstate;
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);
835 set_bell_vol(Display *dpy, int percent)
837 XKeyboardControl values;
838 XKeyboardState kbstate;
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);
855 set_bell_pitch(Display *dpy, int pitch)
857 XKeyboardControl values;
859 values.bell_pitch = pitch;
860 XChangeKeyboardControl(dpy, KBBellPitch, &values);
865 set_bell_dur(Display *dpy, int duration)
867 XKeyboardControl values;
869 values.bell_duration = duration;
870 XChangeKeyboardControl(dpy, KBBellDuration, &values);
875 * Set, add, or subtract the path according to before and after flags:
877 * before after action
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
886 set_font_path(Display *dpy, char *path, int special, int before, int after)
888 char **directoryList = NULL;
890 char **currentList = NULL;
894 if (strcmp(path, "default") == 0) {
895 XSetFontPath(dpy, NULL, 0);
898 if (strcmp(path, "rehash") == 0) {
899 currentList = XGetFontPath(dpy, &ncurrent);
901 fprintf(stderr, "%s: unable to get current font path.\n",
905 XSetFontPath(dpy, currentList, ncurrent);
906 XFreeFontPath(currentList);
910 * for now, fall though and process keyword and directory list for
911 * compatibility with previous versions.
916 * parse the path list. If before or after is non-zero, we'll need
920 if (before != 0 || after != 0) {
921 currentList = XGetFontPath(dpy, &ncurrent);
923 fprintf(stderr, "%s: unable to get old font path.\n", progName);
929 /* count the number of directories in path */
930 register char *cp = path;
933 while ((cp = strchr(cp, ',')) != NULL) {
939 directoryList = (char **)malloc(ndirs * sizeof(char *));
941 error("out of memory for font path directory list");
944 /* mung the path and set directoryList pointers */
948 directoryList[i++] = cp;
949 while ((cp = strchr(cp, ',')) != NULL) {
950 directoryList[i++] = cp + 1;
955 "%s: internal error, only parsed %d of %d directories.\n",
962 * now we have have parsed the input path, so we can set it
965 if (before == 0 && after == 0) {
966 XSetFontPath(dpy, directoryList, ndirs);
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 *));
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);
989 free((char *)newList);
992 /* if deleting from list, build one the same size */
993 if (before < 0 || after < 0) {
996 char **newList = (char **)malloc(ncurrent * sizeof(char *));
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)
1005 /* if we ran out, then insert into new list */
1007 newList[nnew++] = currentList[i];
1009 if (nnew == ncurrent) {
1011 "%s: warning, no entries deleted from font path.\n",
1014 XSetFontPath(dpy, newList, nnew);
1015 free((char *)newList);
1019 free((char *)directoryList);
1021 XFreeFontPath(currentList);
1027 set_led(Display *dpy, int led, int led_mode)
1029 XKeyboardControl values;
1031 values.led_mode = led_mode;
1034 XChangeKeyboardControl(dpy, KBLed | KBLedMode, &values);
1036 XChangeKeyboardControl(dpy, KBLedMode, &values);
1042 xkbset_led(Display *dpy, const char *led, int led_mode)
1045 error(" xset was not built with XKB Extension support\n");
1047 int xkbmajor = XkbMajorVersion, xkbminor = XkbMinorVersion;
1048 int xkbopcode, xkbevent, xkberror;
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");
1062 fprintf(stderr,"%s: Invalid led name: %s\n", progName, led);
1065 printf(" Server does not have the XKB Extension\n");
1072 set_mouse(Display *dpy, int acc_num, int acc_denom, int threshold)
1074 int do_accel = True, do_threshold = True;
1076 if (acc_num == DONT_CHANGE) /* what an incredible crock... */
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;
1085 threshold = SERVER_DEFAULT;
1086 XChangePointerControl(dpy, do_accel, do_threshold, acc_num,
1087 acc_denom, threshold);
1092 set_saver(Display *dpy, int mask, int value)
1094 int timeout, interval, prefer_blank, allow_exp;
1096 XGetScreenSaver(dpy, &timeout, &interval, &prefer_blank, &allow_exp);
1097 if (mask == TIMEOUT)
1099 if (mask == INTERVAL)
1101 if (mask == PREFER_BLANK)
1102 prefer_blank = value;
1103 if (mask == ALLOW_EXP)
1106 timeout = SERVER_DEFAULT;
1107 interval = SERVER_DEFAULT;
1108 prefer_blank = DefaultBlanking;
1109 allow_exp = DefaultExposures;
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);
1115 XSetScreenSaver(dpy, -DEFAULT_TIMEOUT, interval, prefer_blank,
1122 set_repeat(Display *dpy, int key, int auto_repeat_mode)
1124 XKeyboardControl values;
1126 values.auto_repeat_mode = auto_repeat_mode;
1129 XChangeKeyboardControl(dpy, KBKey | KBAutoRepeatMode, &values);
1131 XChangeKeyboardControl(dpy, KBAutoRepeatMode, &values);
1138 set_repeatrate(Display *dpy, int delay, int rate)
1140 XF86MiscKbdSettings values;
1142 XF86MiscGetKbdSettings(dpy, &values);
1143 values.delay = delay;
1145 XF86MiscSetKbdSettings(dpy, &values);
1152 xkbset_repeatrate(Display *dpy, int delay, int interval)
1154 XkbDescPtr xkb = XkbAllocKeyboard();
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);
1167 set_pixels(Display *dpy, unsigned long *pixels, caddr_t * colors,
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;
1177 char *visual_type = NULL;
1180 viproto.visualid = XVisualIDFromVisual(visual);
1181 vip = XGetVisualInfo(dpy, VisualIDMask, &viproto, &nvisuals);
1183 fprintf(stderr, "%s: Can't get visual for visualID 0x%x\n",
1184 progName, (unsigned int)viproto.visualid);
1188 switch (vip->class) {
1193 visual_type = "TrueColor";
1196 max_cells *= max_cells * max_cells;
1199 visual_type = "StaticGray";
1202 visual_type = "StaticColor";
1205 fprintf(stderr, "%s: unknown visual class type %d\n",
1206 progName, vip->class);
1212 "%s: cannot set pixel values in read-only %s visuals\n",
1213 progName, visual_type);
1215 for (i = 0; i < numpixels; i++) {
1216 def.pixel = pixels[i];
1217 if (def.pixel >= max_cells)
1219 "%s: pixel value %ld out of colormap range 0 through %ld\n",
1220 progName, def.pixel, max_cells - 1);
1222 if (XParseColor(dpy, cmap, colors[i], &def))
1223 XStoreColor(dpy, cmap, &def);
1225 fprintf(stderr, "%s: invalid color \"%s\"\n", progName,
1237 set_lock(Display *dpy, Bool onoff)
1239 XModifierKeymap *mods;
1241 mods = XGetModifierMapping(dpy);
1245 XInsertModifiermapEntry(mods, (KeyCode) XK_Caps_Lock,
1249 XDeleteModifiermapEntry(mods, (KeyCode) XK_Caps_Lock,
1251 XSetModifierMapping(dpy, mods);
1252 XFreeModifiermap(mods);
1258 set_font_cache(Display *dpy, long himark, long lowmark, long balance)
1260 FontCacheSettings cs;
1263 cs.himark = himark * 1024;
1264 cs.lowmark = lowmark * 1024;
1265 cs.balance = balance;
1266 status = FontCacheChangeCacheSettings(dpy, &cs);
1273 on_or_off(int val, int onval, char *onstr,
1274 int offval, char *offstr, char buf[])
1278 else if (val == offval)
1282 sprintf(buf, "<%d>", val);
1286 /* This is the information-getting function for telling the user what the
1287 * current "xsettings" are.
1292 int scr = DefaultScreen(dpy);
1293 XKeyboardState values;
1294 int acc_num, acc_denom, threshold;
1295 int timeout, interval, prefer_blank, allow_exp;
1298 XF86MiscKbdSettings kbdinfo;
1302 int xkbmajor = XkbMajorVersion, xkbminor = XkbMinorVersion;
1303 int xkbopcode, xkbevent, xkberror;
1308 char buf[20]; /* big enough for 16 bit number */
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);
1315 printf("Keyboard Control:\n");
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,
1322 if (XkbQueryExtension(dpy, &xkbopcode, &xkbevent, &xkberror, &xkbmajor,
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;
1335 printf(" XKB indicators:\n");
1337 for (i = 0, j = 0; i < XkbNumIndicators; i++) {
1338 if (xkb->names->indicators[i] != None) {
1339 iatoms[j++] = xkb->names->indicators[i];
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;
1358 if (activecount == 0) {
1362 #define XKB_IND_FORMAT_CHARS 13 /* size of other chars in ' DD: X: off' */
1363 #define MAX_LINE_WIDTH 76
1365 columnwidth = maxnamelen + XKB_IND_FORMAT_CHARS;
1366 if (columnwidth > MAX_LINE_WIDTH) {
1367 columnwidth = MAX_LINE_WIDTH;
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]);
1378 linewidth += printf(" %02d: %s: %*s",
1379 inds[i], iatomnames[i],
1381 on_or_off(istates[i],
1383 False, "off", buf));
1385 if (linewidth > (MAX_LINE_WIDTH - columnwidth)) {
1390 if (linewidth > 0) {
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);
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);
1415 printf(" auto repeating keys: ");
1416 for (i = 0; i < 4; i++) {
1419 for (j = 0; j < 8; j++) {
1420 printf("%02x", (unsigned char)values.auto_repeats[i * 8 + j]);
1424 printf(" bell percent: %d bell pitch: %d bell duration: %d\n",
1425 values.bell_percent, values.bell_pitch, values.bell_duration);
1427 printf("Pointer Control:\n");
1428 printf(" acceleration: %d/%d threshold: %d\n",
1429 acc_num, acc_denom, threshold);
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);
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,
1445 printf("Font Path:\n");
1447 printf(" %s", *font_path++);
1448 for (--npaths; npaths; npaths--)
1449 printf(",%s", *font_path++);
1452 printf(" (empty)\n");
1459 if (XMITMiscQueryExtension(dpy, &dummy, &dummy)) {
1460 if (XMITMiscGetBugMode(dpy))
1461 printf("Bug Mode: compatibility mode is enabled\n");
1463 printf("Bug Mode: compatibility mode is disabled\n");
1467 #ifdef DPMSExtension
1471 CARD16 standby, suspend, off;
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);
1483 printf(" DPMS is Enabled\n");
1486 printf(" Monitor is On\n");
1488 case DPMSModeStandby:
1489 printf(" Monitor is in Standby\n");
1491 case DPMSModeSuspend:
1492 printf(" Monitor is in Suspend\n");
1495 printf(" Monitor is Off\n");
1498 printf(" Unrecognized response from server\n");
1501 printf(" DPMS is Disabled\n");
1503 printf(" Display is not capable of DPMS\n");
1505 printf(" Server does not have the DPMS Extension\n");
1512 FontCacheSettings cs;
1513 int himark, lowmark, balance;
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);
1525 printf(" Server does not have the FontCache Extension\n");
1533 XF86MiscFilePaths paths;
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);
1552 * query_cache_status()
1554 * This is the information-getting function for telling the user what the
1555 * current settings and statistics are.
1558 query_cache_status(Display *dpy)
1561 FontCacheSettings cs;
1562 FontCacheStatistics cstats;
1563 int himark, lowmark, balance;
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);
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);
1591 printf("Server does not have the FontCache Extension\n");
1596 /* This is the usage function */
1599 usage(char *fmt, ...)
1604 fprintf(stderr, "%s: ", progName);
1606 vfprintf(stderr, fmt, ap);
1608 fprintf(stderr, "\n\n");
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");
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");
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");
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");
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");
1661 fprintf(stderr, "\t-led named 'name' led off\n");
1662 fprintf(stderr, "\t led named 'name' led on\n");
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");
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");
1684 error(char *message)
1686 fprintf(stderr, "%s: %s\n", progName, message);
1691 local_xerror(Display *dpy, XErrorEvent *rep)
1693 if (rep->request_code == X_SetFontPath && rep->error_code == BadValue) {
1695 "%s: bad font path element (#%ld), possible causes are:\n",
1696 progName, rep->resourceid);
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) {
1705 "%s: pixel not allocated read/write\n", progName);
1709 "%s: cannot store in pixel 0x%lx, invalid pixel number\n",
1710 progName, rep->resourceid);
1713 XmuPrintDefaultErrorMessage(dpy, rep, stderr);
1716 XmuPrintDefaultErrorMessage(dpy, rep, stderr);