diff options
Diffstat (limited to 'tools/kcm/kcm.cpp')
-rw-r--r-- | tools/kcm/kcm.cpp | 421 |
1 files changed, 0 insertions, 421 deletions
diff --git a/tools/kcm/kcm.cpp b/tools/kcm/kcm.cpp deleted file mode 100644 index 3e6320b..0000000 --- a/tools/kcm/kcm.cpp +++ /dev/null @@ -1,421 +0,0 @@ -#include <stdio.h> -#include <string.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <fcntl.h> -#include <unistd.h> -#include <ui/KeycodeLabels.h> -#include <stdlib.h> -#include <ctype.h> -#include <map> -#include <string> -#include <utils/ByteOrder.h> - -using namespace std; - -enum { - LENDIAN, - BENDIAN -}; - -/* - * 1: KeyEvent name - * 2: display_label - * 3: number - * 4..7: base, shift, alt, shift-alt - */ -#define COLUMNS (3+4) - -struct KeyRecord -{ - int lineno; - int values[COLUMNS]; -}; - -struct PropValue -{ - PropValue() { lineno = -1; } - PropValue(const PropValue& that) { lineno=that.lineno; value=that.value; } - PropValue(int l, const string& v) { lineno = l; value = v; } - - int lineno; - string value; -}; - -static int usage(); - -// 0 -- ok -// >0 -- error -static int parse_key_line(const char* filename, int lineno, char* line, - KeyRecord* out); -static int write_kr(int fd, const KeyRecord& kr); - -int g_endian; - -int -main(int argc, char** argv) -{ - int err; - if (argc != 3) { - return usage(); - } - - const char* filename = argv[1]; - const char* outfilename = argv[2]; - - int in = open(filename, O_RDONLY); - if (in == -1) { - fprintf(stderr, "kcm: error opening file for read: %s\n", filename); - return 1; - } - - off_t size = lseek(in, 0, SEEK_END); - lseek(in, 0, SEEK_SET); - - char* input = (char*)malloc(size+1); - read(in, input, size); - input[size] = '\0'; - - close(in); - in = -1; - - map<string,PropValue> properties; - map<int,KeyRecord> keys; - int errorcount = 0; - int lineno = 1; - char *thisline = input; - while (*thisline) { - KeyRecord kr; - char *nextline = thisline; - - while (*nextline != '\0' && *nextline != '\n' && *nextline != '\r') { - nextline++; - } - - // eat whitespace, but not newlines - while (*thisline != '\0' && (*thisline == ' ' || *thisline == '\t')) { - thisline++; - } - - // find the end of the line - char lineend = *nextline; - *nextline = '\0'; - if (lineend == '\r' && nextline[1] == '\n') { - nextline++; - } - - if (*thisline == '\0' || *thisline == '\r' || *thisline == '\n' - || *thisline == '#') { - // comment or blank line - } - else if (*thisline == '[') { - // property - syntax [name=value] - // look for = - char* prop = thisline+1; - char* end = prop; - while (*end != '\0' && *end != '=') { - end++; - } - if (*end != '=') { - fprintf(stderr, "%s:%d: invalid property line: %s\n", - filename, lineno, thisline); - errorcount++; - } else { - *end = '\0'; - char* value = end+1; - end = nextline; - while (end > prop && *end != ']') { - end--; - } - if (*end != ']') { - fprintf(stderr, "%s:%d: property missing closing ]: %s\n", - filename, lineno, thisline); - errorcount++; - } else { - *end = '\0'; - properties[prop] = PropValue(lineno, value); - } - } - } - else { - // key - err = parse_key_line(filename, lineno, thisline, &kr); - if (err == 0) { - kr.lineno = lineno; - - map<int,KeyRecord>::iterator old = keys.find(kr.values[0]); - if (old != keys.end()) { - fprintf(stderr, "%s:%d: keycode %d already defined\n", - filename, lineno, kr.values[0]); - fprintf(stderr, "%s:%d: previously defined here\n", - filename, old->second.lineno); - errorcount++; - } - - keys[kr.values[0]] = kr; - } - else if (err > 0) { - errorcount += err; - } - } - lineno++; - - nextline++; - thisline = nextline; - - if (errorcount > 20) { - fprintf(stderr, "%s:%d: too many errors. stopping.\n", filename, - lineno); - return 1; - } - } - - free(input); - - map<string,PropValue>::iterator sit = properties.find("type"); - if (sit == properties.end()) { - fprintf(stderr, "%s: key character map must contain type property.\n", - argv[0]); - errorcount++; - } - PropValue pv = sit->second; - unsigned char kbdtype = 0; - if (pv.value == "NUMERIC") { - kbdtype = 1; - } - else if (pv.value == "Q14") { - kbdtype = 2; - } - else if (pv.value == "QWERTY") { - kbdtype = 3; - } - else { - fprintf(stderr, "%s:%d: keyboard type must be one of NUMERIC, Q14 " - " or QWERTY, not %s\n", filename, pv.lineno, pv.value.c_str()); - } - - if (errorcount != 0) { - return 1; - } - - int out = open(outfilename, O_RDWR|O_CREAT|O_TRUNC, 0660); - if (out == -1) { - fprintf(stderr, "kcm: error opening file for write: %s\n", outfilename); - return 1; - } - - int count = keys.size(); - - map<int,KeyRecord>::iterator it; - int n; - - /** - * File Format: - * Offset Description Value - * 0 magic string "keychar" - * 8 endian marker 0x12345678 - * 12 version 0x00000002 - * 16 key count number of key entries - * 20 keyboard type NUMERIC, Q14, QWERTY, etc. - * 21 padding 0 - * 32 the keys - */ - err = write(out, "keychar", 8); - if (err == -1) goto bad_write; - - n = htodl(0x12345678); - err = write(out, &n, 4); - if (err == -1) goto bad_write; - - n = htodl(0x00000002); - err = write(out, &n, 4); - if (err == -1) goto bad_write; - - n = htodl(count); - err = write(out, &n, 4); - if (err == -1) goto bad_write; - - err = write(out, &kbdtype, 1); - if (err == -1) goto bad_write; - - char zero[11]; - memset(zero, 0, 11); - err = write(out, zero, 11); - if (err == -1) goto bad_write; - - for (it = keys.begin(); it != keys.end(); it++) { - const KeyRecord& kr = it->second; - /* - printf("%2d/ [%d] [%d] [%d] [%d] [%d] [%d] [%d]\n", kr.lineno, - kr.values[0], kr.values[1], kr.values[2], kr.values[3], - kr.values[4], kr.values[5], kr.values[6]); - */ - err = write_kr(out, kr); - if (err == -1) goto bad_write; - } - - close(out); - return 0; - -bad_write: - fprintf(stderr, "kcm: fatal error writing to file: %s\n", outfilename); - close(out); - unlink(outfilename); - return 1; -} - -static int usage() -{ - fprintf(stderr, - "usage: kcm INPUT OUTPUT\n" - "\n" - "INPUT keycharmap file\n" - "OUTPUT compiled keycharmap file\n" - ); - return 1; -} - -static int -is_whitespace(const char* p) -{ - while (*p) { - if (!isspace(*p)) { - return 0; - } - p++; - } - return 1; -} - - -static int -parse_keycode(const char* filename, int lineno, char* str, int* value) -{ - const KeycodeLabel *list = KEYCODES; - while (list->literal) { - if (0 == strcmp(str, list->literal)) { - *value = list->value; - return 0; - } - list++; - } - - char* endptr; - *value = strtol(str, &endptr, 0); - if (*endptr != '\0') { - fprintf(stderr, "%s:%d: expected keycode label or number near: " - "%s\n", filename, lineno, str); - return 1; - } - - if (*value == 0) { - fprintf(stderr, "%s:%d: 0 is not a valid keycode.\n", - filename, lineno); - return 1; - } - - return 0; -} - -static int -parse_number(const char* filename, int lineno, char* str, int* value) -{ - int len = strlen(str); - - if (len == 3 && str[0] == '\'' && str[2] == '\'') { - if (str[1] > 0 && str[1] < 127) { - *value = (int)str[1]; - return 0; - } else { - fprintf(stderr, "%s:%d: only low ascii characters are allowed in" - " quotes near: %s\n", filename, lineno, str); - return 1; - } - } - - char* endptr; - *value = strtol(str, &endptr, 0); - if (*endptr != '\0') { - fprintf(stderr, "%s:%d: expected number or quoted ascii but got: %s\n", - filename, lineno, str); - return 1; - } - - if (*value >= 0xfffe || *value < 0) { - fprintf(stderr, "%s:%d: unicode char out of range (no negatives, " - "nothing larger than 0xfffe): %s\n", filename, lineno, str); - return 1; - } - - return 0; -} - -static int -parse_key_line(const char* filename, int lineno, char* line, KeyRecord* out) -{ - char* p = line; - - int len = strlen(line); - char* s[COLUMNS]; - for (int i=0; i<COLUMNS; i++) { - s[i] = (char*)malloc(len+1); - } - - for (int i = 0; i < COLUMNS; i++) { - while (*p != '\0' && isspace(*p)) { - p++; - } - - if (*p == '\0') { - fprintf(stderr, "%s:%d: not enough on this line: %s\n", filename, - lineno, line); - return 1; - } - - char *p1 = p; - while (*p != '\0' && !isspace(*p)) { - p++; - } - - memcpy(s[i], p1, p - p1); - s[i][p - p1] = '\0'; - } - - while (*p != '\0' && isspace(*p)) { - *p++; - } - if (*p != '\0') { - fprintf(stderr, "%s:%d: too much on one line near: %s\n", filename, - lineno, p); - fprintf(stderr, "%s:%d: -->%s<--\n", filename, lineno, line); - return 1; - } - - int errorcount = parse_keycode(filename, lineno, s[0], &out->values[0]); - for (int i=1; i<COLUMNS && errorcount == 0; i++) { - errorcount += parse_number(filename, lineno, s[i], &out->values[i]); - } - - return errorcount; -} - -struct WrittenRecord -{ - unsigned int keycode; // 4 bytes - unsigned short values[COLUMNS - 1]; // 6*2 bytes = 12 - // 16 bytes total -}; - -static int -write_kr(int fd, const KeyRecord& kr) -{ - WrittenRecord wr; - - wr.keycode = htodl(kr.values[0]); - for (int i=0; i<COLUMNS - 1; i++) { - wr.values[i] = htods(kr.values[i+1]); - } - - return write(fd, &wr, sizeof(WrittenRecord)); -} - |