Package: kbd Version: 1.14.1 The loadkeys program in the kbd package ignores the KDSKBDIACRUC ioctl in current kernels (and so does the console-tools flavor, as far as i can tell). That means even though I can set both my display and my keyboard into UTF-8 mode and I can display all of the Latin2 characters (for example) if I have them in my console font, there's no way to enter them on a plain US keyboard other than with AltGr + keypad, not quite a user-friendly method.
Enclosed find a trivial C program (tested) using this ioctl to load a compose table with circa 200 entries, and a data file I use with it.
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <linux/kd.h> #include <linux/keyboard.h> #include <sys/ioctl.h> #include <fcntl.h> static int read_compose_file(struct kbdiacruc kdc[MAX_DIACR], FILE* fp) { int num = 0; while(1) { char line[256]; int len; int blanks; if (fgets(line, sizeof(line), fp) == NULL) { if (feof(fp)) return num; else { perror("fgets"); exit(1); } } len = strlen(line); if (line[len-1] != '\n') { fprintf(stderr, "line too long: %s\n", line); exit(1); } blanks = strspn(line, " \t"); if (line[blanks] != '#' || line[blanks] != '\n') { char accent, base; unsigned result; if (num >= MAX_DIACR) { fprintf(stderr, "too many lines: %s\n", line); exit(1); } if (sscanf(line, " %c %c %x", &accent, &base, &result) != 3) { fprintf(stderr, "invalid line: %s\n", line); exit(1); } kdc[num].diacr = (unsigned)(unsigned char)accent; kdc[num].base = (unsigned)(unsigned char)base; kdc[num].result = result; num++; } } } static void stuff_diacruc(int fd, int num, const struct kbdiacruc kdc[MAX_DIACR]) { int i; struct kbdiacrsuc kdcs = { .kb_cnt = num, }; for (i = 0; i < num; ++i) kdcs.kbdiacruc[i] = kdc[i]; if (ioctl(fd, KDSKBDIACRUC, (unsigned long)&kdcs)) { perror("ioctl"); exit(1); } } static void usage(void) { fprintf(stderr, "usage: load_diacruc [TTY_DEVICE [INPUT_FILE]]\n"); fprintf(stderr, "default tty device: /dev/tty1\n"); fprintf(stderr, "default input file: standard input\n"); } int main(int argc, char** argv) { FILE* fp = NULL; const char* tty; int fd; int num; struct kbdiacruc kdc[MAX_DIACR]; switch (argc) { case 3: fp = fopen(argv[2], "r"); if (fp == NULL) { perror(argv[2]); usage(); exit(2); } tty = argv[1]; break; case 2: fp = stdin; tty = argv[1]; break; case 1: fp = stdin; tty = "/dev/tty1"; break; default: usage(); exit(2); } fd = open(tty, O_RDWR); if (fd < 0) { perror(tty); usage(); exit(2); } num = read_compose_file(kdc, fp); stuff_diacruc(fd, num, kdc); }
compose-slavic.inc
Description: data file for compose definitions
-- Ian Zimmerman <i...@buug.org> gpg public key: 1024D/C6FF61AD fingerprint: 66DC D68F 5C1B 4D71 2EE5 BD03 8A00 786C C6FF 61AD Ham is for reading, not for eating.