From 532ac5cc876173466c372dbecbfe0a02afeaee5c Mon Sep 17 00:00:00 2001 From: girst Date: Thu, 11 Feb 2016 13:51:46 +0100 Subject: [PATCH] initial code import --- Makefile | 2 + main.c | 67 ++++++++++++++++++++++++++++ scancodes.c | 123 ++++++++++++++++++++++++++++++++++++++++++++++++++++ scancodes.h | 20 +++++++++ 4 files changed, 212 insertions(+) create mode 100644 Makefile create mode 100644 main.c create mode 100644 scancodes.c create mode 100644 scancodes.h diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..0ae7269 --- /dev/null +++ b/Makefile @@ -0,0 +1,2 @@ +all: + gcc -std=c99 -Wall -Werror main.c scancodes.c -o scan diff --git a/main.c b/main.c new file mode 100644 index 0000000..681660b --- /dev/null +++ b/main.c @@ -0,0 +1,67 @@ +/* +description: sends a sequence of keystrokes to the hid device. +parameters: + device file (e.g. /dev/hidg0) + keyboard layout (e.g. en_us; only a limited number are supported and they do not follow unix-naming conventions for convenience) + the string to send (as whitespace is important, the `echo` way of concatenating all parameters is not supported. if your string has white space in it and you are in an interactive session, quote your string. +*/ +#include +#include +#include +#include "scancodes.h" + +void send_key (FILE* hid_dev, unsigned short key, unsigned short mod); + +int main (int argc, char** argv) { + if (argc != 4) { + fprintf (stderr, "Usage: %s \"\"\n", argv[0]); + return 1; + } + FILE* hid_dev = fopen ("/dev/hidg0", "w"); + for (int i = 0; i < strlen (argv[3]); i++) { + + char tmp[UTF8_MAX_LENGTH] = {argv[3][i], argv[3][i+1], argv[3][i+2], '\0'}; + //TODO: replace by something less stupid + if (argv[3][i] < 128) { // not multi byte + tmp[1] = '\0'; + } else { // is multi byte + if (argv[3][i] < 0xe0) { + i++; //skip next thing + tmp[2] = 0; + } else { + i+=2; //WARN: fails on utf8 > 3 byte + } + } + + struct keysym* s = toscan (tmp); + if (s == NULL) { + fprintf (stderr, "Key Symbol not found.\n"); + return 1; + } + switch (atoi (argv[2])) { + case 0: + fprintf (stderr, "This keyboard layout is reserved.\n"); + return 1; + case 1: //en_us + send_key(hid_dev, s->en_us.key, s->en_us.mod); + break; + case 2: //de_at + send_key(hid_dev, s->de_at.key, s->de_at.mod);//, s->de_at.is_dead); + break; + case 3: //de_at-nodeadkeys + send_key(hid_dev, s->de_at.key, s->de_at.mod); + break; + default: + fprintf (stderr, "Unrecognised keyboard layout.\n"); + return 1; + } + send_key(hid_dev, '\0', '\0'); + } + fclose (hid_dev); + + return 0; +} + +void send_key (FILE* hid_dev, unsigned short key, unsigned short mod) { + fprintf (hid_dev, "%c%c%c%c%c%c%c%c", mod, '\0', key, '\0', '\0', '\0', '\0', '\0'); +} diff --git a/scancodes.c b/scancodes.c new file mode 100644 index 0000000..1f6592e --- /dev/null +++ b/scancodes.c @@ -0,0 +1,123 @@ +#include +#include "scancodes.h" + +struct keysym keysyms[] = { + /*[0] = {"", {NULL, NULL}, {NULL, NULL}},*/ + [1] = {"ä", {0x00, 0x00}, {0x34, 0x00}, .unicode = 0xe4}, + {"Ä", {0x00, 0x00}, {0x34, 0x02}, .unicode = 0xc4}, + {"ö", {0x00, 0x00}, {0x33, 0x00}, .unicode = 0xf6}, + {"Ö", {0x00, 0x00}, {0x33, 0x02}, .unicode = 0xd6}, + {"ü", {0x00, 0x00}, {0x2f, 0x00}, .unicode = 0xfc}, + {"Ü", {0x00, 0x00}, {0x2f, 0x02}, .unicode = 0xdc}, + {"ß", {0x00, 0x00}, {0x2d, 0x00}, .unicode = 0xdf}, + {"€", {0x00, 0x00}, {0x08, 0x40}, .unicode = 0x20ac}, + {"µ", {0x00, 0x00}, {0x10, 0x40}, .unicode = 0x3bc}, + {"°", {0x00, 0x00}, {0x35, 0x02}, .unicode = 0xb0}, + {"§", {0x00, 0x00}, {0x20, 0x02}, .unicode = 0xa7}, + [32] = {" ", {0x2c, 0x00}, {0x2c, 0x00}}, + {"!", {0x1e, 0x02}, {0x1e, 0x02}}, + {"\"",{0x34, 0x02}, {0x1f, 0x02}}, + {"#", {0x20, 0x02}, {0x31, 0x00}}, + {"$", {0x21, 0x02}, {0x21, 0x02}}, + {"%", {0x22, 0x02}, {0x22, 0x02}}, + {"&", {0x24, 0x02}, {0x23, 0x02}}, + {"'", {0x34, 0x00}, {0x31, 0x02}}, + {"(", {0x26, 0x02}, {0x25, 0x02}}, + {")", {0x27, 0x02}, {0x26, 0x02}}, + {"*", {0x25, 0x02}, {0x30, 0x02}}, + {"+", {0x2e, 0x02}, {0x30, 0x00}}, + {"´", {0x32, 0x00}, {0x2e, 0x00, 1}}, + {"-", {0x2d, 0x00}, {0x38, 0x00}}, + {".", {0x37, 0x00}, {0x37, 0x00}}, + {"/", {0x38, 0x00}, {0x24, 0x02}}, + {"0", {0x27, 0x00}, {0x27, 0x00}}, + {"1", {0x1e, 0x00}, {0x1e, 0x00}}, + {"2", {0x1f, 0x00}, {0x1f, 0x00}}, + {"3", {0x20, 0x00}, {0x20, 0x00}}, + {"4", {0x21, 0x00}, {0x21, 0x00}}, + {"5", {0x22, 0x00}, {0x22, 0x00}}, + {"6", {0x23, 0x00}, {0x23, 0x00}}, + {"7", {0x24, 0x00}, {0x24, 0x00}}, + {"8", {0x25, 0x00}, {0x25, 0x00}}, + {"9", {0x26, 0x00}, {0x26, 0x00}}, + {":", {0x33, 0x02}, {0x37, 0x02}}, + {";", {0x33, 0x00}, {0x36, 0x02}}, + {"<", {0x36, 0x02}, {0x64, 0x00}}, + {"=", {0x2e, 0x00}, {0x27, 0x02}}, + {">", {0x37, 0x02}, {0x64, 0x02}}, + {"?", {0x38, 0x02}, {0x2d, 0x02}}, + {"@", {0x1f, 0x02}, {0x14, 0x40}}, + {"A", {0x04, 0x02}, {0x04, 0x02}}, + {"B", {0x05, 0x02}, {0x05, 0x02}}, + {"C", {0x06, 0x02}, {0x06, 0x02}}, + {"D", {0x07, 0x02}, {0x07, 0x02}}, + {"E", {0x08, 0x02}, {0x08, 0x02}}, + {"F", {0x09, 0x02}, {0x09, 0x02}}, + {"G", {0x0a, 0x02}, {0x0a, 0x02}}, + {"H", {0x0b, 0x02}, {0x0b, 0x02}}, + {"I", {0x0c, 0x02}, {0x0c, 0x02}}, + {"J", {0x0d, 0x02}, {0x0d, 0x02}}, + {"K", {0x0e, 0x02}, {0x0e, 0x02}}, + {"L", {0x0f, 0x02}, {0x0f, 0x02}}, + {"M", {0x10, 0x02}, {0x10, 0x02}}, + {"N", {0x11, 0x02}, {0x11, 0x02}}, + {"O", {0x12, 0x02}, {0x12, 0x02}}, + {"P", {0x13, 0x02}, {0x13, 0x02}}, + {"Q", {0x14, 0x02}, {0x14, 0x02}}, + {"R", {0x15, 0x02}, {0x15, 0x02}}, + {"S", {0x16, 0x02}, {0x16, 0x02}}, + {"T", {0x17, 0x02}, {0x17, 0x02}}, + {"U", {0x18, 0x02}, {0x18, 0x02}}, + {"V", {0x19, 0x02}, {0x19, 0x02}}, + {"W", {0x1a, 0x02}, {0x1a, 0x02}}, + {"X", {0x1b, 0x02}, {0x1b, 0x02}}, + {"Y", {0x1c, 0x02}, {0x1d, 0x02}}, + {"Z", {0x1d, 0x02}, {0x1c, 0x02}}, + {"[", {0x2f, 0x00}, {0x25, 0x40}}, + {"\\",{0x31, 0x00}, {0x2d, 0x40}}, + {"]", {0x30, 0x00}, {0x26, 0x40}}, + {"^", {0x23, 0x02}, {0x35, 0x00, 1}}, + {"_", {0x2d, 0x02}, {0x38, 0x02}}, + {"`", {0x35, 0x00}, {0x2e, 0x02, 1}}, + {"a", {0x04, 0x00}, {0x04, 0x00}}, + {"b", {0x05, 0x00}, {0x05, 0x00}}, + {"c", {0x06, 0x00}, {0x06, 0x00}}, + {"d", {0x07, 0x00}, {0x07, 0x00}}, + {"e", {0x08, 0x00}, {0x08, 0x00}}, + {"f", {0x09, 0x00}, {0x09, 0x00}}, + {"g", {0x0a, 0x00}, {0x0a, 0x00}}, + {"h", {0x0b, 0x00}, {0x0b, 0x00}}, + {"i", {0x0c, 0x00}, {0x0c, 0x00}}, + {"j", {0x0d, 0x00}, {0x0d, 0x00}}, + {"k", {0x0e, 0x00}, {0x0e, 0x00}}, + {"l", {0x0f, 0x00}, {0x0f, 0x00}}, + {"m", {0x10, 0x00}, {0x10, 0x00}}, + {"n", {0x11, 0x00}, {0x11, 0x00}}, + {"o", {0x12, 0x00}, {0x12, 0x00}}, + {"p", {0x13, 0x00}, {0x13, 0x00}}, + {"q", {0x14, 0x00}, {0x14, 0x00}}, + {"r", {0x15, 0x00}, {0x15, 0x00}}, + {"s", {0x16, 0x00}, {0x16, 0x00}}, + {"t", {0x17, 0x00}, {0x17, 0x00}}, + {"u", {0x18, 0x00}, {0x18, 0x00}}, + {"v", {0x19, 0x00}, {0x19, 0x00}}, + {"w", {0x1a, 0x00}, {0x1a, 0x00}}, + {"x", {0x1b, 0x00}, {0x1b, 0x00}}, + {"y", {0x1c, 0x00}, {0x1d, 0x00}}, + {"z", {0x1d, 0x00}, {0x1c, 0x00}}, + {"{", {0x2f, 0x02}, {0x24, 0x40}}, + {"|", {0x31, 0x02}, {0x64, 0x40}}, + {"}", {0x30, 0x02}, {0x27, 0x40}}, + {"~", {0x35, 0x02}, {0x30, 0x40}} +}; + +struct keysym* toscan (const char* utf8) { + if (utf8[1] == '\0') return &(keysyms[(int)utf8[0]]); //if char is not wide, it is on the corrent ascii position in the look up table + for (int i = 0; i < sizeof (keysyms)/sizeof (struct keysym); i++) { + if (strcmp (keysyms[i].sym, utf8) == 0) { + return &(keysyms[i]); + } + } + return NULL; // error +} + diff --git a/scancodes.h b/scancodes.h new file mode 100644 index 0000000..b4e461f --- /dev/null +++ b/scancodes.h @@ -0,0 +1,20 @@ +#ifndef __SCANCODES_H__ +#define __SCANCODES_H__ + +#define UTF8_MAX_LENGTH 4 + +struct layout { + unsigned short key; //scancode of normal key + //if this is NULL, the key does not exist in this layout. + unsigned short mod; //bitmask of modifier keys + short is_dead; //is dead key (needs to be pressed twice) +}; +struct keysym { + char sym [UTF8_MAX_LENGTH]; //utf-8 encoded key symbol + struct layout en_us; //substructure for this layout + struct layout de_at; + long int unicode; //the unicode number to send via alt+numpad or ^U if char is not available in a keyboard layout +}; + +struct keysym* toscan (const char* utf8);//returns the layout struct of a keysym +#endif -- 2.39.3