]> git.gir.st - sendHID.git/blob - main.c
prepare for unicode support
[sendHID.git] / main.c
1 /*
2 description: sends a sequence of keystrokes to the hid device.
3 parameters:
4 device file (e.g. /dev/hidg0)
5 keyboard layout (1=en_us, 2=de_at, 3=de_at-nodeadkeys)
6 unicode method: 1=gtk_holddown, 2=gtk_spaceend, 3=windows
7 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.)
8 */
9 #include <stdio.h>
10 #include <stdlib.h>
11 #include <string.h>
12 #include "scancodes.h"
13
14 //argv-indices
15 #define P_EXE 0 //executable name
16 #define P_DEV 1 //device file
17 #define P_LAY 2 //layout
18 #define P_UNI 3//unicode method
19 #define P_STR 4 //string to type
20 #define NUM_P P_STR+1 //number of parameters
21
22 void send_key (FILE* hid_dev, unsigned short key, unsigned short mod);
23
24 int main (int argc, char** argv) {
25 if (argc != NUM_P) {
26 fprintf (stderr, "Usage: %s <device file> <layout> <unicode> \"<string>\"\n", argv[P_EXE]);
27 return 1;
28 }
29 FILE* hid_dev = fopen ("/dev/hidg0", "w");
30 for (int i = 0; i < strlen (argv[P_STR]); i++) {
31
32 char tmp[UTF8_MAX_LENGTH] = {argv[P_STR][i], argv[P_STR][i+1], argv[P_STR][i+2], '\0'};
33 //TODO: replace by something less stupid
34 if (argv[P_STR][i] < 128) { // not multi byte
35 tmp[1] = '\0';
36 } else { // is multi byte
37 if (argv[P_STR][i] < 0xe0) {
38 i++; //skip next thing
39 tmp[2] = 0;
40 } else {
41 i+=2; //WARN: fails on utf8 > 3 byte
42 }
43 }
44
45 struct keysym* s = toscan (tmp);
46 if (s == NULL) {
47 fprintf (stderr, "Key Symbol not found.\n");
48 return 1;
49 }
50 struct layout* l;
51 int ignore_deadkey = 0;
52 switch (atoi (argv[P_LAY])) {
53 case 0:
54 fprintf (stderr, "This keyboard layout is reserved.\n");
55 return 1;
56 case 1: //en_us
57 l = &(s->en_us);
58 break;
59 case 2: //de_at
60 l = &(s->de_at);
61 break;
62 case 3: //de_at-nodeadkeys
63 l = &(s->de_at);
64 ignore_deadkey = 1;
65 break;
66 default:
67 fprintf (stderr, "Unrecognised keyboard layout.\n");
68 return 1;
69 }
70 if (l->key == 0x00) {
71 //key does not exist in this layout
72 fprintf (stderr, "Key not in this layout!\n");
73 /*TODO: send unicode sequence
74 there are different methods to be used for gtk and
75 winblows. ctrl-shift-u-HEX vs. ctrl-shift-u,HEX,SPACE
76 vs. alt+NUMPAD vs. alt+'+'+HEX
77 */
78 switch (atoi (argv[P_UNI])) {
79 case 0: //skip unicode character entry
80 break;
81 case 1: //gtk: hold ctrl and shift while entering
82 //TODO
83 break;
84 case 2: //gtk: use space as end marker for unicode
85 //TODO
86 case 3: //windows: alt+numpad (decimal)
87 //TODO
88 break;
89 default:
90 fprintf (stderr, "Unicode Method unknown!\n");
91 return 1;
92 }
93 } else {
94 send_key(hid_dev, l->key, l->mod);
95 send_key(hid_dev, '\0', '\0'); //release all keys
96 if (l->is_dead && !ignore_deadkey) {
97 //dead keys need to be pressed twice to show up
98 send_key(hid_dev, l->key, l->mod);
99 send_key(hid_dev, '\0', '\0'); //release all keys
100 }
101 }
102 }
103 fclose (hid_dev);
104
105 return 0;
106 }
107
108 void send_key (FILE* hid_dev, unsigned short key, unsigned short mod) {
109 fprintf (hid_dev, "%c%c%c%c%c%c%c%c", mod, '\0', key, '\0', '\0', '\0', '\0', '\0');
110 }
Imprint / Impressum