blob: 253aaf66afb61c26bf09ef761ee086fa881f1508 [file] [log] [blame]
/*
* setmetamode.c - aeb, 940130
*
* Call: setmetamode { metabit | escprefix }
* and report the setting before and after.
* Without arguments setmetamode will only report.
*/
#include "config.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <fcntl.h>
#include <getopt.h>
#include <sysexits.h>
#include <linux/kd.h>
#include <sys/ioctl.h>
#include "libcommon.h"
static void __attribute__((noreturn))
usage(int rc, const struct kbd_help *options)
{
const struct kbd_help *h;
fprintf(stderr, _("Usage: %s [option...] [argument]\n"), get_progname());
fprintf(stderr, "\n");
fprintf(stderr, _(
"Arguments:\n"
" metabit the keysym marked with the high bit set.\n"
" escprefix specifies if pressing the meta (alt) key\n"
" generates an ESC (\\033) prefix followed by\n"
" the keysym.\n"
));
if (options) {
int max = 0;
fprintf(stderr, "\n");
fprintf(stderr, _("Options:"));
fprintf(stderr, "\n");
for (h = options; h && h->opts; h++) {
int len = (int) strlen(h->opts);
if (max < len)
max = len;
}
max += 2;
for (h = options; h && h->opts; h++)
fprintf(stderr, " %-*s %s\n", max, h->opts, h->desc);
}
fprintf(stderr, "\n");
fprintf(stderr, _("Report bugs to authors.\n"));
fprintf(stderr, "\n");
exit(rc);
}
static void
report(unsigned int meta)
{
const char *s;
switch (meta) {
case K_METABIT:
s = _("Meta key sets high order bit");
break;
case K_ESCPREFIX:
s = _("Meta key gives Esc prefix");
break;
default:
s = _("Strange mode for Meta key?");
}
printf("%s\n", s);
}
struct meta {
const char *name;
unsigned int val;
} metas[] = {
{ "metabit", K_METABIT },
{ "meta", K_METABIT },
{ "bit", K_METABIT },
{ "escprefix", K_ESCPREFIX },
{ "esc", K_ESCPREFIX },
{ "prefix", K_ESCPREFIX }
};
#define SIZE(a) (sizeof(a) / sizeof(a[0]))
int main(int argc, char **argv)
{
unsigned int ometa, nmeta;
struct meta *mp;
int c;
int fd = 0;
char *console = NULL;
set_progname(argv[0]);
setuplocale();
const char *short_opts = "C:hV";
const struct option long_opts[] = {
{ "console", required_argument, NULL, 'C' },
{ "help", no_argument, NULL, 'h' },
{ "version", no_argument, NULL, 'V' },
{ NULL, 0, NULL, 0 }
};
const struct kbd_help opthelp[] = {
{ "-C, --console=DEV", _("the console device to be used.") },
{ "-V, --version", _("print version number.") },
{ "-h, --help", _("print this usage message.") },
{ NULL, NULL }
};
while ((c = getopt_long(argc, argv, short_opts, long_opts, NULL)) != -1) {
switch (c) {
case 'C':
if (optarg == NULL || optarg[0] == '\0')
usage(EX_USAGE, opthelp);
console = optarg;
break;
case 'V':
print_version_and_exit();
break;
case 'h':
usage(EXIT_SUCCESS, opthelp);
break;
case '?':
usage(EX_USAGE, opthelp);
break;
}
}
if (console && (fd = getfd(console)) < 0)
kbd_error(EXIT_FAILURE, 0, _("Couldn't get a file descriptor referring to the console."));
if (ioctl(fd, KDGKBMETA, &ometa))
kbd_error(EXIT_FAILURE, errno, _("Unable to read meta key handling mode"));
if (optind == argc) {
report(ometa);
exit(EXIT_SUCCESS);
}
nmeta = 0; /* make gcc happy */
for (mp = metas; (unsigned)(mp - metas) < SIZE(metas); mp++) {
if (!strcmp(argv[1], mp->name)) {
nmeta = mp->val;
goto end;
}
}
fprintf(stderr, _("Unrecognized argument: %s"), argv[1]);
fprintf(stderr, "\n\n");
usage(EXIT_FAILURE, opthelp);
end:
printf(_("old state: "));
report(ometa);
if (ioctl(fd, KDSKBMETA, nmeta)) {
kbd_error(EXIT_FAILURE, errno, "ioctl KDSKBMETA");
}
printf(_("new state: "));
report(nmeta);
return EXIT_SUCCESS;
}