Skip to content

Commit a6f9c1a

Browse files
committed
Implement escape for type
1 parent ff01b95 commit a6f9c1a

File tree

1 file changed

+113
-39
lines changed

1 file changed

+113
-39
lines changed

Client/tool_type.c

Lines changed: 113 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -73,48 +73,104 @@ static const int32_t ascii2keycode_map[128] = {
7373
KEY_X,KEY_Y,KEY_Z,KEY_LEFTBRACE|FLAG_UPPERCASE,KEY_BACKSLASH|FLAG_UPPERCASE,KEY_RIGHTBRACE|FLAG_UPPERCASE,KEY_GRAVE|FLAG_UPPERCASE,-1
7474
};
7575

76+
static int opt_key_delay_ms = 20;
77+
static int opt_key_hold_ms = 20;
78+
static int opt_next_delay_ms = 0;
79+
7680
static void show_help() {
7781
puts(
7882
"Usage: type [OPTION]... [STRINGS]...\n"
7983
"Type strings.\n"
8084
"\n"
81-
"Options:\n"
82-
" -d, --key-delay=N Delay N milliseconds between key events (up/down each)\n"
83-
" -D, --next-delay=N Delay N milliseconds between strings\n"
84-
" -H, --key-hold=N Time N milliseconds to hold each key for\n"
85+
"Options:");
86+
87+
printf(
88+
" -d, --key-delay=N Delay N milliseconds between keys (the delay between every key down/up pair) (default: %d)\n", opt_key_delay_ms
89+
);
90+
91+
printf(
92+
" -H, --key-hold=N Hold each key for N milliseconds (the delay between key down and up) (default: %d)\n", opt_key_hold_ms
93+
);
94+
95+
printf(
96+
" -D, --next-delay=N Delay N milliseconds between command line strings (default: %d)\n", opt_next_delay_ms
97+
);
98+
99+
puts(
85100
" -f, --file=PATH Specify a file, the contents of which will be be typed as if passed as an argument.\n"
86101
" The filepath may also be '-' to read from stdin\n"
102+
" -e, --escape=BOOL Escape enable (1) or disable (0)\n"
87103
" -h, --help Display this help and exit\n"
88104
"\n"
105+
"Escape is enabled by default when typing command line arguments, and disabled by default when typing from file and stdin."
89106
);
90107
}
91108

92-
static int key_delay = 12;
93-
static int key_hold = 0;
109+
94110

95111
static void type_char(char c, bool delay) {
96-
int kdef = ascii2keycode_map[c];
97-
if (kdef == -1) {
98-
return;
99-
}
112+
int kdef = ascii2keycode_map[c];
113+
if (kdef == -1) {
114+
return;
115+
}
100116

101-
uint16_t kc = kdef & 0xffff;
117+
uint16_t kc = kdef & 0xffff;
102118

103-
if (kdef & FLAG_UPPERCASE) {
104-
uinput_emit(EV_KEY, KEY_LEFTSHIFT, 1, 1);
105-
}
106-
uinput_emit(EV_KEY, kc, 1, 1);
119+
if (kdef & FLAG_UPPERCASE) {
120+
uinput_emit(EV_KEY, KEY_LEFTSHIFT, 1, 1);
121+
}
122+
uinput_emit(EV_KEY, kc, 1, 1);
107123

108-
usleep(key_hold * 1000);
124+
usleep(opt_key_hold_ms * 1000);
109125

110-
uinput_emit(EV_KEY, kc, 0, 1);
111-
if (kdef & FLAG_UPPERCASE) {
112-
uinput_emit(EV_KEY, KEY_LEFTSHIFT, 0, 1);
113-
}
126+
uinput_emit(EV_KEY, kc, 0, 1);
127+
if (kdef & FLAG_UPPERCASE) {
128+
uinput_emit(EV_KEY, KEY_LEFTSHIFT, 0, 1);
129+
}
114130

115-
if (delay) {
116-
usleep(key_delay * 1000);
117-
}
131+
if (delay) {
132+
usleep(opt_key_delay_ms * 1000);
133+
}
134+
}
135+
136+
static int escape(char in) {
137+
static int state = 0;
138+
static char hex_str[3] = {0, 0, 0};
139+
140+
switch (state) {
141+
case 0:
142+
if (in == '\\') {
143+
state = 1;
144+
return -1;
145+
} else {
146+
return in;
147+
}
148+
case 1:
149+
state = 0;
150+
switch (in) {
151+
case 'n':
152+
return '\n';
153+
case 't':
154+
return '\t';
155+
case 'x':
156+
state = 2;
157+
return -1;
158+
case '\\':
159+
return '\\';
160+
default:
161+
return -1;
162+
}
163+
case 2:
164+
state = 3;
165+
hex_str[0] = in;
166+
return -1;
167+
case 3:
168+
state = 0;
169+
hex_str[1] = in;
170+
return (int)strtol(hex_str, NULL, 16);
171+
default:
172+
abort();
173+
}
118174
}
119175

120176
int tool_type(int argc, char **argv) {
@@ -124,24 +180,27 @@ int tool_type(int argc, char **argv) {
124180
}
125181

126182

127-
int next_delay_ms = 0;
183+
128184
const char *file_path = NULL;
129185

186+
int enable_escape = -1;
187+
130188
while (1) {
131189
int c;
132190

133191
static struct option long_options[] = {
134192
{"key-delay", required_argument, 0, 'd'},
135193
{"next-delay", required_argument, 0, 'D'},
136194
{"key-hold", required_argument, 0, 'H'},
195+
{"escape", required_argument, 0, 'e'},
137196
{"file", required_argument, 0, 'f'},
138197
{"help", no_argument, 0, 'h'},
139198
{0, 0, 0, 0}
140199
};
141200
/* getopt_long stores the option index here. */
142201
int option_index = 0;
143202

144-
c = getopt_long (argc, argv, "hd:D:H:f:",
203+
c = getopt_long (argc, argv, "hd:D:H:f:e:",
145204
long_options, &option_index);
146205

147206
/* Detect the end of the options. */
@@ -159,15 +218,15 @@ int tool_type(int argc, char **argv) {
159218
printf ("\n");
160219
break;
161220
case 'd':
162-
key_delay = strtol(optarg, NULL, 10);
221+
opt_key_delay_ms = strtol(optarg, NULL, 10);
163222
break;
164223

165224
case 'D':
166-
next_delay_ms = strtol(optarg, NULL, 10);
225+
opt_next_delay_ms = strtol(optarg, NULL, 10);
167226
break;
168227

169228
case 'H':
170-
key_hold = strtol(optarg, NULL, 10);
229+
opt_key_hold_ms = strtol(optarg, NULL, 10);
171230
break;
172231

173232
case 'f':
@@ -179,6 +238,10 @@ int tool_type(int argc, char **argv) {
179238
exit(0);
180239
break;
181240

241+
case 'e':
242+
enable_escape = strtol(optarg, NULL, 10);
243+
break;
244+
182245
case '?':
183246
/* getopt_long already printed an error message. */
184247
break;
@@ -189,9 +252,13 @@ int tool_type(int argc, char **argv) {
189252
}
190253

191254
if (file_path) {
255+
if (enable_escape == -1) {
256+
enable_escape = 0;
257+
}
258+
192259
int fd = (strcmp(file_path, "-") == 0)
193-
? STDIN_FILENO
194-
: open(file_path, O_RDONLY);
260+
? STDIN_FILENO
261+
: open(file_path, O_RDONLY);
195262

196263
if (fd == -1) {
197264
fprintf(stderr, "ydotool: type: error: failed to open %s: %s\n", file_path,
@@ -205,9 +272,9 @@ int tool_type(int argc, char **argv) {
205272
while ((rc = read(fd, buf, sizeof(buf)))) {
206273
if (rc > 0) {
207274
for (int i = 0; i<rc; i++) {
208-
char c = buf[i];
209-
if (c) {
210-
type_char(c, i != rc - 1);
275+
int c = enable_escape ? escape(buf[i]) : buf[i];
276+
if (c != -1) {
277+
type_char((char)c, i != rc - 1);
211278
}
212279
}
213280
} else if (rc < 0) {
@@ -216,22 +283,29 @@ int tool_type(int argc, char **argv) {
216283
}
217284
}
218285
} else {
286+
if (enable_escape == -1) {
287+
enable_escape = 1;
288+
}
219289

220290
if (optind < argc) {
221291
while (optind < argc) {
222292
char *pstr = argv[optind++];
223293

224-
for (int i = 0;; i++) {
225-
char c = pstr[i];
294+
// printf("pstr: %s\n", pstr);
295+
296+
for (int i = 0; ; i++) {
297+
int c = enable_escape ? escape(pstr[i]) : pstr[i];
226298
char next = pstr[i+1];
227-
if (c) {
228-
type_char(c, next);
229-
} else {
299+
300+
if (c == 0) {
230301
break;
302+
} else if (c != -1) {
303+
type_char((char)c, next);
231304
}
232305
}
233306

234-
usleep(next_delay_ms * 1000);
307+
if (argv[optind])
308+
usleep(opt_next_delay_ms * 1000);
235309
}
236310
} else {
237311
show_help();

0 commit comments

Comments
 (0)