]>
git.gir.st - sendHID.git/blob - main.c
2 description: sends a sequence of keystrokes provided from stdin to the hid
4 stops typing at: control characters (including newline), chars not in table, EOF
6 device file (e.g. /dev/hidg0)
7 keyboard layout (1=en_us, 2=de_at, 3=de_at-nodeadkeys)
8 unicode method: 1=gtk_holddown, 2=gtk_spaceend, 3=windows
13 #include "scancodes.h"
15 #define TEXT_LEN 256 //max length of piped text
16 enum params
{//argv-indices:
17 P_EXE
, //executable name
20 P_UNI
, //unicode method
21 NUM_P
//number of parameters
23 enum uni_m
{//unicode methods:
24 SKIP
, //ignore any keys not on the layout
25 GTK_HOLD
, //hold ctrl and shift while entering hex values
26 GTK_SPACE
, //end hex sequence with spacebar
27 WINDOWS
//use alt+numpad
30 ERR_SUCCESS
, //no error
31 ERR_ARGCOUNT
, //wrong number of arguments
32 ERR_SYMBOL
, //symbol not in look up table
33 ERR_LAYOUT
, //parameter P_LAY does not contain a correct keyboard layout
34 ERR_LAZY
//i haven't done this
37 void send_key (FILE* hid_dev
, unsigned short key
, unsigned short mod
);
38 enum errors
send_unicode (FILE* hid_dev
, unsigned int unicode
, enum uni_m method
, enum kbdl layout
);
40 int main (int argc
, char** argv
) {
42 fprintf (stderr
, "Usage: %s <device file> <layout> <unicode>\n", argv
[P_EXE
]);
43 fprintf (stderr
, "Takes string to type from stdin\n");
44 fprintf (stderr
, "<device file>:\ton the Raspberry Pi usually /dev/hidg0\n");
45 fprintf (stderr
, "<layout>:\n\t%d\t%s\n\t%d\t%s\n\t%d\t%s\n",
47 de_AT
, "de_AT (w/ dead keys)",
48 de_ND
, "de_AT-nodeadkeys");
49 fprintf (stderr
, "<unicode>:\n\t%d\t%s\n\t%d\t%s\n\t%d\t%s\n\t%d\t%s\n",
50 SKIP
, "skip over unicode characters",
51 GTK_HOLD
, "X11 Holddown: CTRL+SHIFT+[u, hex]",
52 GTK_SPACE
, "X11 Space: CTRL+SHIFT+u, hex, SPACE",
53 WINDOWS
, "Windows: Alt+[Numpad]");
56 FILE* hid_dev
= fopen ("/dev/hidg0", "w");
57 char in_string
[TEXT_LEN
];
58 fgets(in_string
, TEXT_LEN
, stdin
);
59 for (int i
= 0; i
< strlen (in_string
); i
++) {
60 if (in_string
[i
] < 32) {
61 if (in_string
[i
] != '\n') fprintf (stderr
, "Cannot print control characters!\n(Is there a newline at the end of your string?\n");
65 char tmp
[UTF8_MAX_LENGTH
] = {in_string
[i
], in_string
[i
+1], in_string
[i
+2], '\0'};
66 //TODO: replace by something less stupid
67 if (in_string
[i
] < 128) { // not multi byte
69 } else { // is multi byte
70 if (in_string
[i
] < 0xe0) {
71 i
++; //skip next thing
74 i
+=2; //WARN: fails on utf8 > 3 byte
78 struct keysym
* s
= toscan (tmp
);
80 fprintf (stderr
, "Key Symbol not found.\n");
84 struct layout
* l
= tolay (s
, atoi (argv
[P_LAY
]));
86 fprintf (stderr
, "Unrecognised keyboard layout.\n");
91 send_key(hid_dev
, l
->key
, l
->mod
);
92 send_key(hid_dev
, '\0', '\0'); //release all keys
94 //dead keys need to be pressed twice to show up
95 send_key(hid_dev
, l
->key
, l
->mod
);
96 send_key(hid_dev
, '\0', '\0'); //release all keys
99 //key does not exist in this layout, use unicode method
100 //fprintf (stderr, "Warning: Key '%s'(0x%x) not in this layout!\n", s->sym, s->unicode);
101 send_unicode (hid_dev
, s
->unicode
, atoi (argv
[P_UNI
]), atoi(argv
[P_LAY
]));
109 void send_key (FILE* hid_dev
, unsigned short key
, unsigned short mod
) {
110 fprintf (hid_dev
, "%c%c%c%c%c%c%c%c", mod
, '\0', key
, '\0', '\0', '\0', '\0', '\0');
113 enum errors
send_unicode (FILE* hid_dev
, unsigned int unicode
, enum uni_m method
, enum kbdl layout
) {
118 if (unicode
== 0x00) {
119 fprintf (stderr
, "Symbol not in lookup table!\n");
127 sprintf (buf
, "%x", unicode
);
129 l
= tolay (s
, layout
);
130 send_key (hid_dev
, l
->key
, MOD_LCTRL
| MOD_LSHIFT
);
131 for (int i
= 0; i
< strlen (buf
); i
++) {
132 s
= toscan ((char[2]){buf
[i
], '\0'});
133 l
= tolay (s
, layout
);
134 send_key (hid_dev
, l
->key
, MOD_LCTRL
| MOD_LSHIFT
);
136 send_key (hid_dev
, '\0', '\0');
139 sprintf (buf
, "%x ", unicode
);
141 l
= tolay (s
, layout
);
142 send_key (hid_dev
, l
->key
, MOD_LCTRL
| MOD_LSHIFT
);
143 for (int i
= 0; i
< strlen (buf
); i
++) {
144 s
= toscan ((char[2]){buf
[i
], '\0'});
145 l
= tolay (s
, layout
);
146 send_key (hid_dev
, l
->key
, MOD_NONE
);
148 send_key (hid_dev
, '\0', '\0');
151 fprintf (stderr
, "windows method not implemented!\n");
154 fprintf (stderr
, "unknown unicode method!\n");
155 return ERR_LAYOUT
; //TODO: better error code