diff --git a/tools/kcm/kcm.cpp b/tools/kcm/kcm.cpp
new file mode 100644
index 0000000..3e6320b
--- /dev/null
+++ b/tools/kcm/kcm.cpp
@@ -0,0 +1,421 @@
+#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));
+}
+
