#include #include #include #include #include #include #include #include #include #include #include "linux/kd.h" #include "cpio.h" #include "isys.h" #include "lang.h" #include "stubs.h" int isysLoadFont(void) { char font[65536]; struct console_font_op cfo; unsigned short map[E_TABSZ]; struct unimapdesc d; struct unimapinit u; struct unipair desc[2048]; gzFile stream; int rc; #if defined (__s390__) || defined (__s390x__) return 0; #endif stream = gunzip_open("/etc/screenfont.gz"); if (!stream) return -EACCES; gunzip_read(stream, &cfo, sizeof(cfo)); gunzip_read(stream, font, sizeof(font)); gunzip_read(stream, map, sizeof(map)); gunzip_read(stream, &d.entry_ct, sizeof(d.entry_ct)); d.entries = desc; gunzip_read(stream, desc, d.entry_ct * sizeof(desc[0])); gunzip_close(stream); cfo.data = font; cfo.op = KD_FONT_OP_SET; rc = ioctl(1, KDFONTOP, &cfo); if (rc) return rc; rc = ioctl(1, PIO_UNIMAPCLR, &u); if (rc) return rc; rc = ioctl(1, PIO_UNIMAP, &d); if (rc) return rc; rc = ioctl(1, PIO_UNISCRNMAP, map); if (rc) return rc; /* activate the font map */ fprintf(stderr, "\033(K"); return 0; } int isysSetUnicodeKeymap(void) { int console; #if defined (__s390__) || defined (__s390x__) return 0; #endif console = open("/dev/console", O_RDWR); if (console < 0) return -EACCES; /* place keyboard in unicode mode */ ioctl(console, KDSKBMODE, K_UNICODE); close(console); return 0; } /* the file pointer must be at the beginning of the section already! */ int loadKeymap(gzFile stream) { int console; int kmap, key; struct kbentry entry; int keymaps[MAX_NR_KEYMAPS]; int count = 0; int magic; short keymap[NR_KEYS]; #if defined (__s390__) || defined (__s390x__) return 0; #endif if (isVioConsole()) return 0; if (gunzip_read(stream, &magic, sizeof(magic)) != sizeof(magic)) return -EIO; if (magic != KMAP_MAGIC) return -EINVAL; if (gunzip_read(stream, keymaps, sizeof(keymaps)) != sizeof(keymaps)) return -EINVAL; console = open("/dev/console", O_RDWR); if (console < 0) return -EACCES; for (kmap = 0; kmap < MAX_NR_KEYMAPS; kmap++) { if (!keymaps[kmap]) continue; if (gunzip_read(stream, keymap, sizeof(keymap)) != sizeof(keymap)) { close(console); return -EIO; } count++; for (key = 0; key < NR_KEYS; key++) { entry.kb_index = key; entry.kb_table = kmap; entry.kb_value = keymap[key]; if (KTYP(entry.kb_value) != KT_SPEC) { if (ioctl(console, KDSKBENT, &entry)) { int ret = errno; close(console); return ret; } } } } close(console); return 0; } int isysLoadKeymap(char * keymap) { int num = -1; int rc; gzFile f; struct kmapHeader hdr; struct kmapInfo * infoTable; char buf[16384]; /* I hope this is big enough */ int i; f = gunzip_open("/etc/keymaps.gz"); if (!f) return -EACCES; if (gunzip_read(f, &hdr, sizeof(hdr)) != sizeof(hdr)) { gunzip_close(f); return -EINVAL; } i = hdr.numEntries * sizeof(*infoTable); infoTable = alloca(i); if (gunzip_read(f, infoTable, i) != i) { gunzip_close(f); return -EIO; } for (i = 0; i < hdr.numEntries; i++) if (!strcmp(infoTable[i].name, keymap)) { num = i; break; } if (num == -1) { gunzip_close(f); return -ENOENT; } for (i = 0; i < num; i++) { if (gunzip_read(f, buf, infoTable[i].size) != infoTable[i].size) { gunzip_close(f); return -EIO; } } rc = loadKeymap(f); gunzip_close(f); return rc; } /* returns 0 on success, 1 on failure */ extern int bterm_main(int argc, char **argv); int isysStartBterm(void) { char * btermargs[4] = { "bterm", "-s", "-f", NULL }; int rc; struct stat sb; /* if we've already successfully started bterm, we don't need to again */ if (!access("/var/run/bterm.run", R_OK)) return 0; /* assume that if we're already on a pty we can handle unicode */ fstat(0, &sb); if (major(sb.st_rdev) == 3 || major(sb.st_rdev) == 136) return 0; if (!access("/etc/font.bgf.gz", R_OK)) btermargs[3] = "/etc/font.bgf.gz"; else if (!access("/usr/lib/bogl/font.bgf.gz", R_OK)) btermargs[3] = "/usr/lib/bogl/font.bgf.gz"; else if (!access("font.bgf.gz", R_OK)) btermargs[3] = "font.bgf.gz"; else return 1; rc = bterm_main(4, btermargs); if (!rc) { int fd = open("/var/run/bterm.run", O_CREAT | O_TRUNC | O_RDWR, 0600); close(fd); } return rc; }