Add pancyrillic font
[platform/upstream/kbd.git] / src / setleds.c
1 /*
2  * setleds.c - aeb, 940130, 940909, 991008
3  *
4  * Call: setleds [-L] [-D] [-F] [{+|-}{num|caps|scroll}]*
5  * will set or clear the indicated flags on the stdin tty,
6  * and report the settings before and after.
7  * In particular, setleds without arguments will only report.
8  */
9
10 #include <stdio.h>
11 #include <fcntl.h>
12 #include <linux/kd.h>
13 #include <sys/ioctl.h>
14 #include "nls.h"
15 #include "version.h"
16
17 static void __attribute__ ((noreturn))
18 usage(void)
19 {
20     fprintf(stderr, _(
21 "Usage:\n"
22 "       setleds [-v] [-L] [-D] [-F] [[+|-][ num | caps | scroll %s]]\n"
23 "Thus,\n"
24 "       setleds +caps -num\n"
25 "will set CapsLock, clear NumLock and leave ScrollLock unchanged.\n"
26 "The settings before and after the change (if any) are reported\n"
27 "when the -v option is given or when no change is requested.\n"
28 "Normally, setleds influences the vt flag settings\n"
29 "(and these are usually reflected in the leds).\n"
30 "With -L, setleds only sets the leds, and leaves the flags alone.\n"
31 "With -D, setleds sets both the flags and the default flags, so\n"
32 "that a subsequent reset will not change the flags.\n"
33 ),
34 #ifdef __sparc__
35     "| compose "
36 #else
37     ""
38 #endif
39     );
40     exit(1);
41 }
42
43 #define onoff(a) ((a) ? _("on ") : _("off"))
44
45 /* report the bits, in the order seen on the (my) keyboard */
46 #define LED_NLOCK  1
47 #define LED_CMPOSE 2
48 #define LED_SCRLCK 4
49 #define LED_CLOCK  8
50
51 static void
52 sunreport(int leds) {
53         printf("NumLock %s   Compose %s   ScrollLock %s   CapsLock %s\n",
54                onoff(leds & LED_NLOCK),
55                onoff(leds & LED_CMPOSE),
56                onoff(leds & LED_SCRLCK),
57                onoff(leds & LED_CLOCK));
58 }
59
60 static void
61 report(int leds) {
62         printf("NumLock %s   CapsLock %s   ScrollLock %s\n",
63                onoff(leds & LED_NUM),
64                onoff(leds & LED_CAP),
65                onoff(leds & LED_SCR));
66 }
67
68 struct led {
69     char *name;
70     int bit;
71     int sunbit;
72 } leds[] = {
73     { "scroll", LED_SCR, LED_SCRLCK },
74     { "num",    LED_NUM, LED_NLOCK },
75     { "caps",   LED_CAP, LED_CLOCK },
76 #ifdef __sparc__
77     { "compose",   0,    LED_CMPOSE }
78 #endif
79 };
80
81 static void
82 getleds(char *cur_leds) {
83     if (ioctl(0, KDGETLED, cur_leds)) {
84         perror("KDGETLED");
85         fprintf(stderr,
86           _("Error reading current led setting. Maybe stdin is not a VT?\n"));
87         exit(1);
88     }
89 }
90
91 static int
92 setleds(char cur_leds) {
93     if (ioctl(0, KDSETLED, cur_leds)) {
94         perror("KDSETLED");
95         return -1;
96     }
97     return 0;
98 }
99
100 static void
101 getflags(char *flags) {
102     if (ioctl(0, KDGKBLED, flags)) {
103         perror("KDGKBLED");
104         fprintf(stderr,
105           _("Error reading current flags setting. "
106             "Maybe you are not on the console?\n"));
107         exit(1);
108     }
109 }
110
111 static int sunkbdfd = -1;
112
113 #ifndef KIOCGLED
114 #define arg_state __attribute__ ((unused))
115 #else
116 #define arg_state
117 #endif
118
119 static void __attribute__ ((noreturn))
120 sungetleds(arg_state char *cur_leds) {
121 #ifdef KIOCGLED
122     if (ioctl(sunkbdfd, KIOCGLED, cur_leds)) {
123         perror("KIOCGLED");
124         fprintf(stderr,
125           _("Error reading current led setting from /dev/kbd.\n"));
126         exit(1);
127     }
128 #else
129     fprintf(stderr, _("KIOCGLED unavailable?\n"));
130     exit(1);
131 #endif
132 }
133
134 #ifndef KIOCSLED
135 #define arg_state __attribute__ ((unused))
136 #else
137 #define arg_state
138 #endif
139
140 static void __attribute__ ((noreturn))
141 sunsetleds(arg_state char *cur_leds) {
142 #ifdef KIOCSLED
143     if (ioctl(sunkbdfd, KIOCSLED, cur_leds)) {
144         perror("KIOCSLED");
145         fprintf(stderr,
146           _("Error reading current led setting from /dev/kbd.\n"));
147         exit(1);
148     }
149 #else
150     fprintf(stderr, _("KIOCSLED unavailable?\n"));
151     exit(1);
152 #endif
153 }
154
155 int
156 main(int argc, char **argv) {
157     int optL = 0, optD = 0, optF = 0, verbose = 0;
158     char oleds, nleds, oflags, nflags, odefflags, ndefflags;
159     char nval, ndef, sign;
160     char osunleds = 0, nsunleds, nsunval, nsundef;
161     char *ap;
162     struct led *lp;
163
164     set_progname(argv[0]);
165
166     setlocale(LC_ALL, "");
167     bindtextdomain(PACKAGE_NAME, LOCALEDIR);
168     textdomain(PACKAGE_NAME);
169
170     if (argc == 2 && (!strcmp("-V", argv[1]) || !strcmp("--version", argv[1])))
171         print_version_and_exit();
172
173 #ifdef __sparc__
174     sunkbdfd = open("/dev/kbd", O_RDONLY);
175     if (sunkbdfd < 0) {
176         perror("/dev/kbd");
177         fprintf(stderr, _("Error opening /dev/kbd.\n"));
178         /* exit(1); */
179     }
180 #endif
181
182     getflags(&oflags);
183     getleds(&oleds);
184     if (sunkbdfd >= 0)
185             sungetleds(&osunleds);
186
187     while (argc > 1) {
188         if (!strcmp("-L", argv[1]))
189           optL = 1;
190         else if (!strcmp("-D", argv[1]))
191           optD = 1;
192         else if (!strcmp("-F", argv[1]))
193           optF = 1;
194         else if (!strcmp("-v", argv[1]))
195           verbose = 1;
196         else
197           break;
198         argc--;
199         argv++;
200     }
201
202     odefflags = ndefflags = ((oflags >> 4) & 7);
203     oflags = nflags = (oflags & 7);
204
205     if (argc <= 1) {
206         if (optL) {
207             nleds = 0xff;
208             if (setleds(nleds)) {
209                 fprintf(stderr, _("Error resetting ledmode\n"));
210                 exit(1);
211             }
212         }
213
214         /* If nothing to do, report, even if not verbose */
215         if (!optD && !optL && !optF)
216           optD = optL = optF = 1;
217         if (optD) {
218             printf(_("Current default flags:  "));
219             report(odefflags);
220         }
221         if (optF) {
222             printf(_("Current flags:          "));
223             report(oflags & 07);
224         }
225         if (optL) {
226             printf(_("Current leds:           "));
227             if (sunkbdfd >= 0)
228                 sunreport(osunleds);
229             else
230                 report(oleds);
231         }
232         exit(0);
233     }
234
235     if (!optL)
236       optF = 1;
237     nval = 0;
238     ndef = 0;
239     nsunval = 0;
240     nsundef = 0;
241
242     while(--argc) {
243         ap = *++argv;
244         sign = 1;               /* by default: set */
245         if(*ap == '+')
246           ap++;
247         else if(*ap == '-') {
248             sign = 0;
249             ap++;
250         }
251         for (lp = leds; (unsigned) (lp-leds) < sizeof(leds)/sizeof(leds[0]); lp++) {
252             if(!strcmp(ap, lp->name)) {
253                 if(sign) {
254                   nval |= lp->bit;
255                   nsunval |= lp->sunbit;
256                 }
257                 ndef |= lp->bit;
258                 nsundef |= lp->sunbit;
259                 goto nxtarg;
260             }
261         }
262         fprintf(stderr, _("unrecognized argument: _%s_\n\n"), ap);
263         usage();
264
265       nxtarg: ;
266     }
267
268     if (optD) {
269         ndefflags = (odefflags & ~ndef) | nval;
270         if (verbose) {
271             printf(_("Old default flags:    "));
272             report(odefflags);
273             printf(_("New default flags:    "));
274             report(ndefflags);
275         }
276     }
277     if (optF) {
278         nflags = ((oflags & ~ndef) | nval);
279         if (verbose) {
280             printf(_("Old flags:            "));
281             report(oflags & 07);
282             printf(_("New flags:            "));
283             report(nflags & 07);
284         }
285     }
286     if (optD || optF) {
287         if (ioctl(0, KDSKBLED, (ndefflags << 4) | nflags)) {
288             perror("KDSKBLED");
289             exit(1);
290         }
291     }
292     if (optL) {
293         if (sunkbdfd >= 0) {
294             nsunleds = (osunleds & ~nsundef) | nsunval;
295             if (verbose) {
296                 printf(_("Old leds:             "));
297                 sunreport(osunleds);
298                 printf(_("New leds:             "));
299                 sunreport(nsunleds);
300             }
301             sunsetleds(&nsunleds);
302         } else {
303             nleds = (oleds & ~ndef) | nval;
304             if (verbose) {
305                 printf(_("Old leds:             "));
306                 report(oleds);
307                 printf(_("New leds:             "));
308                 report(nleds);
309             }
310             if (setleds(nleds))
311                 exit(1);
312         }
313     }
314     exit(0);
315 }