|
Packit Service |
50ad14 |
/*
|
|
Packit Service |
50ad14 |
* mapscrn.c
|
|
Packit Service |
50ad14 |
*/
|
|
Packit Service |
50ad14 |
#include "config.h"
|
|
Packit Service |
50ad14 |
|
|
Packit Service |
50ad14 |
#include <stdio.h>
|
|
Packit Service |
50ad14 |
#include <stdlib.h>
|
|
Packit Service |
50ad14 |
#include <memory.h>
|
|
Packit Service |
50ad14 |
#include <string.h>
|
|
Packit Service |
50ad14 |
#include <fcntl.h>
|
|
Packit Service |
50ad14 |
#include <sys/types.h>
|
|
Packit Service |
50ad14 |
#include <sys/stat.h>
|
|
Packit Service |
50ad14 |
#include <sys/ioctl.h>
|
|
Packit Service |
50ad14 |
#include <linux/kd.h>
|
|
Packit Service |
50ad14 |
#include "kbd.h"
|
|
Packit Service |
50ad14 |
#include "paths.h"
|
|
Packit Service |
50ad14 |
#include "findfile.h"
|
|
Packit Service |
50ad14 |
#include "kdmapop.h"
|
|
Packit Service |
50ad14 |
#include "utf8.h"
|
|
Packit Service |
50ad14 |
#include "nls.h"
|
|
Packit Service |
50ad14 |
#include "kbd_error.h"
|
|
Packit Service |
50ad14 |
|
|
Packit Service |
50ad14 |
/* the two exported functions */
|
|
Packit Service |
50ad14 |
void saveoldmap(int fd, char *omfil);
|
|
Packit Service |
50ad14 |
void loadnewmap(int fd, char *mfil);
|
|
Packit Service |
50ad14 |
|
|
Packit Service |
50ad14 |
static int ctoi(char *);
|
|
Packit Service |
50ad14 |
|
|
Packit Service |
50ad14 |
/* search for the map file in these directories (with trailing /) */
|
|
Packit Service |
50ad14 |
static const char *const mapdirpath[] = { "", DATADIR "/" TRANSDIR "/", 0 };
|
|
Packit Service |
50ad14 |
static const char *const mapsuffixes[] = { "", ".trans", "_to_uni.trans", ".acm", 0 };
|
|
Packit Service |
50ad14 |
|
|
Packit Service |
50ad14 |
#ifdef MAIN
|
|
Packit Service |
50ad14 |
#include "getfd.h"
|
|
Packit Service |
50ad14 |
#include "version.h"
|
|
Packit Service |
50ad14 |
|
|
Packit Service |
50ad14 |
int verbose = 0;
|
|
Packit Service |
50ad14 |
int debug = 0;
|
|
Packit Service |
50ad14 |
|
|
Packit Service |
50ad14 |
int main(int argc, char *argv[])
|
|
Packit Service |
50ad14 |
{
|
|
Packit Service |
50ad14 |
int fd;
|
|
Packit Service |
50ad14 |
|
|
Packit Service |
50ad14 |
set_progname(argv[0]);
|
|
Packit Service |
50ad14 |
|
|
Packit Service |
50ad14 |
setlocale(LC_ALL, "");
|
|
Packit Service |
50ad14 |
bindtextdomain(PACKAGE_NAME, LOCALEDIR);
|
|
Packit Service |
50ad14 |
textdomain(PACKAGE_NAME);
|
|
Packit Service |
50ad14 |
|
|
Packit Service |
50ad14 |
if (argc == 2 && !strcmp(argv[1], "-V"))
|
|
Packit Service |
50ad14 |
print_version_and_exit();
|
|
Packit Service |
50ad14 |
|
|
Packit Service |
50ad14 |
if (argc > 1 && !strcmp(argv[1], "-v")) {
|
|
Packit Service |
50ad14 |
verbose = 1;
|
|
Packit Service |
50ad14 |
argc--;
|
|
Packit Service |
50ad14 |
argv++;
|
|
Packit Service |
50ad14 |
}
|
|
Packit Service |
50ad14 |
|
|
Packit Service |
50ad14 |
if ((fd = getfd(NULL)) < 0)
|
|
Packit Service |
50ad14 |
kbd_error(EXIT_FAILURE, 0, _("Couldn't get a file descriptor referring to the console"));
|
|
Packit Service |
50ad14 |
|
|
Packit Service |
50ad14 |
if (argc >= 3 && !strcmp(argv[1], "-o")) {
|
|
Packit Service |
50ad14 |
saveoldmap(fd, argv[2]);
|
|
Packit Service |
50ad14 |
argc -= 2;
|
|
Packit Service |
50ad14 |
argv += 2;
|
|
Packit Service |
50ad14 |
if (argc == 1)
|
|
Packit Service |
50ad14 |
exit(EXIT_SUCCESS);
|
|
Packit Service |
50ad14 |
}
|
|
Packit Service |
50ad14 |
|
|
Packit Service |
50ad14 |
if (argc != 2) {
|
|
Packit Service |
50ad14 |
fprintf(stderr, _("usage: %s [-V] [-v] [-o map.orig] map-file\n"),
|
|
Packit Service |
50ad14 |
progname);
|
|
Packit Service |
50ad14 |
exit(EXIT_FAILURE);
|
|
Packit Service |
50ad14 |
}
|
|
Packit Service |
50ad14 |
loadnewmap(fd, argv[1]);
|
|
Packit Service |
50ad14 |
exit(EXIT_SUCCESS);
|
|
Packit Service |
50ad14 |
}
|
|
Packit Service |
50ad14 |
#endif
|
|
Packit Service |
50ad14 |
|
|
Packit Service |
50ad14 |
/*
|
|
Packit Service |
50ad14 |
* Read two-column file (index, value) with index in 0-255
|
|
Packit Service |
50ad14 |
* and value in 0-65535. Acceptable representations:
|
|
Packit Service |
50ad14 |
* decimal (nnn), octal (0nnn), hexadecimal (0xnnn), Unicode (U+xxxx),
|
|
Packit Service |
50ad14 |
* character ('x').
|
|
Packit Service |
50ad14 |
* In the character encoding, x may be a single byte binary value
|
|
Packit Service |
50ad14 |
* (but not space, tab, comma, #) or a single Unicode value coded
|
|
Packit Service |
50ad14 |
* as a UTF-8 sequence.
|
|
Packit Service |
50ad14 |
*
|
|
Packit Service |
50ad14 |
* Store values in ubuf[], and small values also in buf[].
|
|
Packit Service |
50ad14 |
* Set u to 1 in case a value above 255 or a U+ occurs.
|
|
Packit Service |
50ad14 |
* Set lineno to line number of first error.
|
|
Packit Service |
50ad14 |
*/
|
|
Packit Service |
50ad14 |
static int
|
|
Packit Service |
50ad14 |
parsemap(FILE *fp, char *buf, unsigned short *ubuf, int *u, int *lineno)
|
|
Packit Service |
50ad14 |
{
|
|
Packit Service |
50ad14 |
char buffer[256];
|
|
Packit Service |
50ad14 |
int in, on, ln, ret = 0;
|
|
Packit Service |
50ad14 |
char *p, *q;
|
|
Packit Service |
50ad14 |
|
|
Packit Service |
50ad14 |
ln = 0;
|
|
Packit Service |
50ad14 |
while (fgets(buffer, sizeof(buffer) - 1, fp)) {
|
|
Packit Service |
50ad14 |
ln++;
|
|
Packit Service |
50ad14 |
if (!*u && strstr(buffer, "U+"))
|
|
Packit Service |
50ad14 |
*u = 1;
|
|
Packit Service |
50ad14 |
p = strtok(buffer, " \t\n");
|
|
Packit Service |
50ad14 |
if (p && *p != '#') {
|
|
Packit Service |
50ad14 |
q = strtok(NULL, " \t\n#");
|
|
Packit Service |
50ad14 |
if (q) {
|
|
Packit Service |
50ad14 |
in = ctoi(p);
|
|
Packit Service |
50ad14 |
on = ctoi(q);
|
|
Packit Service |
50ad14 |
if (in >= 0 && in < 256 &&
|
|
Packit Service |
50ad14 |
on >= 0 && on < 65536) {
|
|
Packit Service |
50ad14 |
ubuf[in] = on;
|
|
Packit Service |
50ad14 |
if (on < 256)
|
|
Packit Service |
50ad14 |
buf[in] = on;
|
|
Packit Service |
50ad14 |
else
|
|
Packit Service |
50ad14 |
*u = 1;
|
|
Packit Service |
50ad14 |
} else {
|
|
Packit Service |
50ad14 |
if (!ret)
|
|
Packit Service |
50ad14 |
*lineno = ln;
|
|
Packit Service |
50ad14 |
ret = -1;
|
|
Packit Service |
50ad14 |
}
|
|
Packit Service |
50ad14 |
}
|
|
Packit Service |
50ad14 |
}
|
|
Packit Service |
50ad14 |
}
|
|
Packit Service |
50ad14 |
return ret;
|
|
Packit Service |
50ad14 |
}
|
|
Packit Service |
50ad14 |
|
|
Packit Service |
50ad14 |
static int
|
|
Packit Service |
50ad14 |
readnewmapfromfile(char *mfil, char *buf, unsigned short *ubuf)
|
|
Packit Service |
50ad14 |
{
|
|
Packit Service |
50ad14 |
struct stat stbuf;
|
|
Packit Service |
50ad14 |
int u = 0;
|
|
Packit Service |
50ad14 |
int lineno = 0;
|
|
Packit Service |
50ad14 |
lkfile_t fp;
|
|
Packit Service |
50ad14 |
|
|
Packit Service |
50ad14 |
if (lk_findfile(mfil, mapdirpath, mapsuffixes, &fp)) {
|
|
Packit Service |
50ad14 |
fprintf(stderr, _("mapscrn: cannot open map file _%s_\n"),
|
|
Packit Service |
50ad14 |
mfil);
|
|
Packit Service |
50ad14 |
exit(1);
|
|
Packit Service |
50ad14 |
}
|
|
Packit Service |
50ad14 |
if (stat(fp.pathname, &stbuf)) {
|
|
Packit Service |
50ad14 |
perror(fp.pathname);
|
|
Packit Service |
50ad14 |
fprintf(stderr, _("Cannot stat map file"));
|
|
Packit Service |
50ad14 |
exit(1);
|
|
Packit Service |
50ad14 |
}
|
|
Packit Service |
50ad14 |
if (stbuf.st_size == E_TABSZ) {
|
|
Packit Service |
50ad14 |
if (verbose)
|
|
Packit Service |
50ad14 |
printf(_("Loading binary direct-to-font screen map "
|
|
Packit Service |
50ad14 |
"from file %s\n"),
|
|
Packit Service |
50ad14 |
fp.pathname);
|
|
Packit Service |
50ad14 |
if (fread(buf, E_TABSZ, 1, fp.fd) != 1) {
|
|
Packit Service |
50ad14 |
fprintf(stderr,
|
|
Packit Service |
50ad14 |
_("Error reading map from file `%s'\n"),
|
|
Packit Service |
50ad14 |
fp.pathname);
|
|
Packit Service |
50ad14 |
exit(1);
|
|
Packit Service |
50ad14 |
}
|
|
Packit Service |
50ad14 |
} else if (stbuf.st_size == 2 * E_TABSZ) {
|
|
Packit Service |
50ad14 |
if (verbose)
|
|
Packit Service |
50ad14 |
printf(_("Loading binary unicode screen map "
|
|
Packit Service |
50ad14 |
"from file %s\n"),
|
|
Packit Service |
50ad14 |
fp.pathname);
|
|
Packit Service |
50ad14 |
if (fread(ubuf, 2 * E_TABSZ, 1, fp.fd) != 1) {
|
|
Packit Service |
50ad14 |
fprintf(stderr,
|
|
Packit Service |
50ad14 |
_("Error reading map from file `%s'\n"),
|
|
Packit Service |
50ad14 |
fp.pathname);
|
|
Packit Service |
50ad14 |
exit(1);
|
|
Packit Service |
50ad14 |
}
|
|
Packit Service |
50ad14 |
u = 1;
|
|
Packit Service |
50ad14 |
} else {
|
|
Packit Service |
50ad14 |
if (verbose)
|
|
Packit Service |
50ad14 |
printf(_("Loading symbolic screen map from file %s\n"),
|
|
Packit Service |
50ad14 |
fp.pathname);
|
|
Packit Service |
50ad14 |
if (parsemap(fp.fd, buf, ubuf, &u, &lineno)) {
|
|
Packit Service |
50ad14 |
fprintf(stderr,
|
|
Packit Service |
50ad14 |
_("Error parsing symbolic map "
|
|
Packit Service |
50ad14 |
"from `%s', line %d\n"),
|
|
Packit Service |
50ad14 |
fp.pathname, lineno);
|
|
Packit Service |
50ad14 |
exit(1);
|
|
Packit Service |
50ad14 |
}
|
|
Packit Service |
50ad14 |
}
|
|
Packit Service |
50ad14 |
lk_fpclose(&fp);
|
|
Packit Service |
50ad14 |
return u;
|
|
Packit Service |
50ad14 |
}
|
|
Packit Service |
50ad14 |
|
|
Packit Service |
50ad14 |
void loadnewmap(int fd, char *mfil)
|
|
Packit Service |
50ad14 |
{
|
|
Packit Service |
50ad14 |
unsigned short ubuf[E_TABSZ];
|
|
Packit Service |
50ad14 |
char buf[E_TABSZ];
|
|
Packit Service |
50ad14 |
int i, u;
|
|
Packit Service |
50ad14 |
|
|
Packit Service |
50ad14 |
/* default: trivial straight-to-font */
|
|
Packit Service |
50ad14 |
for (i = 0; i < E_TABSZ; i++) {
|
|
Packit Service |
50ad14 |
buf[i] = i;
|
|
Packit Service |
50ad14 |
ubuf[i] = (0xf000 + i);
|
|
Packit Service |
50ad14 |
}
|
|
Packit Service |
50ad14 |
|
|
Packit Service |
50ad14 |
u = 0;
|
|
Packit Service |
50ad14 |
if (mfil)
|
|
Packit Service |
50ad14 |
u = readnewmapfromfile(mfil, buf, ubuf);
|
|
Packit Service |
50ad14 |
|
|
Packit Service |
50ad14 |
/* do we need to use loaduniscrnmap() ? */
|
|
Packit Service |
50ad14 |
if (u) {
|
|
Packit Service |
50ad14 |
/* yes */
|
|
Packit Service |
50ad14 |
if (loaduniscrnmap(fd, ubuf))
|
|
Packit Service |
50ad14 |
exit(1);
|
|
Packit Service |
50ad14 |
} else {
|
|
Packit Service |
50ad14 |
/* no */
|
|
Packit Service |
50ad14 |
if (loadscrnmap(fd, buf))
|
|
Packit Service |
50ad14 |
exit(1);
|
|
Packit Service |
50ad14 |
}
|
|
Packit Service |
50ad14 |
}
|
|
Packit Service |
50ad14 |
|
|
Packit Service |
50ad14 |
/*
|
|
Packit Service |
50ad14 |
* Read decimal, octal, hexadecimal, Unicode (U+xxxx) or character
|
|
Packit Service |
50ad14 |
* ('x', x a single byte or a utf8 sequence).
|
|
Packit Service |
50ad14 |
*/
|
|
Packit Service |
50ad14 |
int ctoi(char *s)
|
|
Packit Service |
50ad14 |
{
|
|
Packit Service |
50ad14 |
int i;
|
|
Packit Service |
50ad14 |
|
|
Packit Service |
50ad14 |
if ((strncmp(s, "0x", 2) == 0) &&
|
|
Packit Service |
50ad14 |
(strspn(s + 2, "0123456789abcdefABCDEF") == strlen(s + 2)))
|
|
Packit Service |
50ad14 |
(void)sscanf(s + 2, "%x", &i);
|
|
Packit Service |
50ad14 |
|
|
Packit Service |
50ad14 |
else if ((*s == '0') &&
|
|
Packit Service |
50ad14 |
(strspn(s, "01234567") == strlen(s)))
|
|
Packit Service |
50ad14 |
(void)sscanf(s, "%o", &i);
|
|
Packit Service |
50ad14 |
|
|
Packit Service |
50ad14 |
else if (strspn(s, "0123456789") == strlen(s))
|
|
Packit Service |
50ad14 |
(void)sscanf(s, "%d", &i);
|
|
Packit Service |
50ad14 |
|
|
Packit Service |
50ad14 |
else if ((strncmp(s, "U+", 2) == 0) && strlen(s) == 6 &&
|
|
Packit Service |
50ad14 |
(strspn(s + 2, "0123456789abcdefABCDEF") == 4))
|
|
Packit Service |
50ad14 |
(void)sscanf(s + 2, "%x", &i);
|
|
Packit Service |
50ad14 |
|
|
Packit Service |
50ad14 |
else if ((strlen(s) == 3) && (s[0] == '\'') && (s[2] == '\''))
|
|
Packit Service |
50ad14 |
i = s[1];
|
|
Packit Service |
50ad14 |
|
|
Packit Service |
50ad14 |
else if (s[0] == '\'') {
|
|
Packit Service |
50ad14 |
int err;
|
|
Packit Service |
50ad14 |
char *s1 = s + 1;
|
|
Packit Service |
50ad14 |
|
|
Packit Service |
50ad14 |
i = from_utf8(&s1, 0, &err;;
|
|
Packit Service |
50ad14 |
if (err || s1[0] != '\'' || s1[1] != 0)
|
|
Packit Service |
50ad14 |
return -1;
|
|
Packit Service |
50ad14 |
}
|
|
Packit Service |
50ad14 |
|
|
Packit Service |
50ad14 |
else
|
|
Packit Service |
50ad14 |
return -1;
|
|
Packit Service |
50ad14 |
|
|
Packit Service |
50ad14 |
return i;
|
|
Packit Service |
50ad14 |
}
|
|
Packit Service |
50ad14 |
|
|
Packit Service |
50ad14 |
void saveoldmap(int fd, char *omfil)
|
|
Packit Service |
50ad14 |
{
|
|
Packit Service |
50ad14 |
FILE *fp;
|
|
Packit Service |
50ad14 |
char buf[E_TABSZ];
|
|
Packit Service |
50ad14 |
unsigned short ubuf[E_TABSZ];
|
|
Packit Service |
50ad14 |
int i, havemap, haveumap;
|
|
Packit Service |
50ad14 |
|
|
Packit Service |
50ad14 |
if ((fp = fopen(omfil, "w")) == NULL) {
|
|
Packit Service |
50ad14 |
perror(omfil);
|
|
Packit Service |
50ad14 |
exit(1);
|
|
Packit Service |
50ad14 |
}
|
|
Packit Service |
50ad14 |
havemap = haveumap = 1;
|
|
Packit Service |
50ad14 |
if (getscrnmap(fd, buf))
|
|
Packit Service |
50ad14 |
havemap = 0;
|
|
Packit Service |
50ad14 |
if (getuniscrnmap(fd, ubuf))
|
|
Packit Service |
50ad14 |
haveumap = 0;
|
|
Packit Service |
50ad14 |
if (havemap && haveumap) {
|
|
Packit Service |
50ad14 |
for (i = 0; i < E_TABSZ; i++) {
|
|
Packit Service |
50ad14 |
if ((ubuf[i] & ~0xff) != 0xf000) {
|
|
Packit Service |
50ad14 |
havemap = 0;
|
|
Packit Service |
50ad14 |
break;
|
|
Packit Service |
50ad14 |
}
|
|
Packit Service |
50ad14 |
}
|
|
Packit Service |
50ad14 |
}
|
|
Packit Service |
50ad14 |
if (havemap) {
|
|
Packit Service |
50ad14 |
if (fwrite(buf, sizeof(buf), 1, fp) != 1) {
|
|
Packit Service |
50ad14 |
fprintf(stderr, _("Error writing map to file\n"));
|
|
Packit Service |
50ad14 |
exit(1);
|
|
Packit Service |
50ad14 |
}
|
|
Packit Service |
50ad14 |
} else if (haveumap) {
|
|
Packit Service |
50ad14 |
if (fwrite(ubuf, sizeof(ubuf), 1, fp) != 1) {
|
|
Packit Service |
50ad14 |
fprintf(stderr, _("Error writing map to file\n"));
|
|
Packit Service |
50ad14 |
exit(1);
|
|
Packit Service |
50ad14 |
}
|
|
Packit Service |
50ad14 |
} else {
|
|
Packit Service |
50ad14 |
fprintf(stderr, _("Cannot read console map\n"));
|
|
Packit Service |
50ad14 |
exit(1);
|
|
Packit Service |
50ad14 |
}
|
|
Packit Service |
50ad14 |
fclose(fp);
|
|
Packit Service |
50ad14 |
|
|
Packit Service |
50ad14 |
if (verbose)
|
|
Packit Service |
50ad14 |
printf(_("Saved screen map in `%s'\n"), omfil);
|
|
Packit Service |
50ad14 |
}
|