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