]>
git.gir.st - sendHID.git/blob - main.c
2 (C) 2016 Tobias Girstmair, released under the GNU GPL
4 description: sends a sequence of keystrokes provided from stdin to the hid
6 stops typing at: control characters (including newline), chars not in table, EOF
8 device file (e.g. /dev/hidg0)
9 keyboard layout (1=en_us, 2=de_at, 3=de_at-nodeadkeys)
10 unicode method: 1=gtk_holddown, 2=gtk_spaceend, 3=windows
15 #include "scancodes.h"
17 #define TEXT_LEN 256 //max length of piped text
18 enum params
{//argv-indices:
19 P_EXE
, //executable name
22 P_UNI
, //unicode method
23 NUM_P
//number of parameters
25 enum uni_m
{//unicode methods:
26 SKIP
, //ignore any keys not on the layout
27 GTK_HOLD
, //hold ctrl and shift while entering hex values
28 GTK_SPACE
, //end hex sequence with spacebar
29 WINDOWS
//use alt+numpad
32 ERR_SUCCESS
, //no error
33 ERR_ARGCOUNT
, //wrong number of arguments
34 ERR_SYMBOL
, //symbol not in look up table
35 ERR_LAYOUT
, //parameter P_LAY does not contain a correct keyboard layout
36 ERR_LAZY
//i haven't done this
39 void send_key (FILE* hid_dev
, unsigned short key
, unsigned short mod
);
40 enum errors
send_unicode (FILE* hid_dev
, unsigned int unicode
, enum uni_m method
, enum kbdl layout
);
42 int main (int argc
, char** argv
) {
44 fprintf (stderr
, "Usage: %s <device file> <layout> <unicode>\n", argv
[P_EXE
]);
45 fprintf (stderr
, "Takes string to type from stdin\n");
46 fprintf (stderr
, "<device file>:\ton the Raspberry Pi usually /dev/hidg0\n");
47 fprintf (stderr
, "<layout>:\n\t%d\t%s\n\t%d\t%s\n\t%d\t%s\n",
49 de_AT
, "de_AT (w/ dead keys)",
50 de_ND
, "de_AT-nodeadkeys");
51 fprintf (stderr
, "<unicode>:\n\t%d\t%s\n\t%d\t%s\n\t%d\t%s\n\t%d\t%s\n",
52 SKIP
, "skip over unicode characters",
53 GTK_HOLD
, "X11 Holddown: CTRL+SHIFT+[u, hex]",
54 GTK_SPACE
, "X11 Space: CTRL+SHIFT+u, hex, SPACE",
55 WINDOWS
, "Windows: Alt+[Numpad]");
58 FILE* hid_dev
= fopen (argv
[P_DEV
], "w");
59 char in_string
[TEXT_LEN
];
60 fgets(in_string
, TEXT_LEN
, stdin
);
61 for (int i
= 0; i
< strlen (in_string
); i
++) {
62 if (in_string
[i
] < 32) {
63 if (in_string
[i
] != '\n') fprintf (stderr
, "Cannot print control characters!\n(Is there a newline at the end of your string?\n");
67 char tmp
[UTF8_MAX_LENGTH
] = {in_string
[i
], in_string
[i
+1], in_string
[i
+2], '\0'};
68 //TODO: replace by something less stupid
69 if (in_string
[i
] < 128) { // not multi byte
71 } else { // is multi byte
72 if (in_string
[i
] < 0xe0) {
73 i
++; //skip next thing
76 i
+=2; //WARN: fails on utf8 > 3 byte
80 struct keysym
* s
= toscan (tmp
);
82 fprintf (stderr
, "Key Symbol not found.\n");
86 struct layout
* l
= tolay (s
, atoi (argv
[P_LAY
]));
88 fprintf (stderr
, "Unrecognised keyboard layout.\n");
93 send_key(hid_dev
, l
->key
, l
->mod
);
94 send_key(hid_dev
, '\0', '\0'); //release all keys
96 //dead keys need to be pressed twice to show up
97 send_key(hid_dev
, l
->key
, l
->mod
);
98 send_key(hid_dev
, '\0', '\0'); //release all keys
101 //key does not exist in this layout, use unicode method
102 //fprintf (stderr, "Warning: Key '%s'(0x%x) not in this layout!\n", s->sym, s->unicode);
103 send_unicode (hid_dev
, s
->unicode
, atoi (argv
[P_UNI
]), atoi(argv
[P_LAY
]));
111 void send_key (FILE* hid_dev
, unsigned short key
, unsigned short mod
) {
112 fprintf (hid_dev
, "%c%c%c%c%c%c%c%c", mod
, '\0', key
, '\0', '\0', '\0', '\0', '\0');
115 enum errors
send_unicode (FILE* hid_dev
, unsigned int unicode
, enum uni_m method
, enum kbdl layout
) {
120 if (unicode
== 0x00) {
121 fprintf (stderr
, "Symbol not in lookup table!\n");
129 sprintf (buf
, "%x", unicode
);
131 l
= tolay (s
, layout
);
132 send_key (hid_dev
, l
->key
, MOD_LCTRL
| MOD_LSHIFT
);
133 for (int i
= 0; i
< strlen (buf
); i
++) {
134 s
= toscan ((char[2]){buf
[i
], '\0'});
135 l
= tolay (s
, layout
);
136 send_key (hid_dev
, l
->key
, MOD_LCTRL
| MOD_LSHIFT
);
138 send_key (hid_dev
, '\0', '\0');
141 sprintf (buf
, "%x ", unicode
);
143 l
= tolay (s
, layout
);
144 send_key (hid_dev
, l
->key
, MOD_LCTRL
| MOD_LSHIFT
);
145 for (int i
= 0; i
< strlen (buf
); i
++) {
146 s
= toscan ((char[2]){buf
[i
], '\0'});
147 l
= tolay (s
, layout
);
148 send_key (hid_dev
, l
->key
, MOD_NONE
);
150 send_key (hid_dev
, '\0', '\0');
153 fprintf (stderr
, "windows method not implemented!\n");
156 fprintf (stderr
, "unknown unicode method!\n");
157 return ERR_LAYOUT
; //TODO: better error code