mirror of
https://gitlab.freedesktop.org/libinput/libinput.git
synced 2026-01-09 14:30:17 +01:00
tools: record: allow for an output file without --o
libinput record touchpad.yml /dev/input/eventX or just libinput record touchpad.yml are simpler invocations and since we're quite limited in what we can record (i.e. only device files) we can just check the argument list to figure out whether there is something to record to. Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
This commit is contained in:
parent
c48e5cf9a6
commit
6ed3a0b079
3 changed files with 110 additions and 5 deletions
|
|
@ -2411,6 +2411,28 @@ usage(void)
|
|||
program_invocation_short_name);
|
||||
}
|
||||
|
||||
enum ftype {
|
||||
F_FILE = 8,
|
||||
F_DEVICE,
|
||||
F_NOEXIST,
|
||||
};
|
||||
|
||||
static inline enum ftype is_char_dev(const char *path)
|
||||
{
|
||||
struct stat st;
|
||||
|
||||
if (strneq(path, "/dev", 4))
|
||||
return F_DEVICE;
|
||||
|
||||
if (stat(path, &st) != 0) {
|
||||
if (errno == ENOENT)
|
||||
return F_NOEXIST;
|
||||
return F_FILE;
|
||||
}
|
||||
|
||||
return S_ISCHR(st.st_mode) ? F_DEVICE : F_FILE;
|
||||
}
|
||||
|
||||
enum options {
|
||||
OPT_AUTORESTART,
|
||||
OPT_HELP,
|
||||
|
|
@ -2491,6 +2513,72 @@ main(int argc, char **argv)
|
|||
}
|
||||
}
|
||||
|
||||
ndevices = argc - optind;
|
||||
|
||||
/* We allow for multiple arguments after the options, *one* of which
|
||||
* may be the output file. That one must be the first or the last to
|
||||
* prevent users from running
|
||||
* libinput record /dev/input/event0 output.yml /dev/input/event1
|
||||
* because this will only backfire anyway.
|
||||
*/
|
||||
if (ndevices >= 1 && output_arg == NULL) {
|
||||
char *first, *last;
|
||||
enum ftype ftype_first;
|
||||
|
||||
first = argv[optind];
|
||||
last = argv[argc - 1];
|
||||
|
||||
ftype_first = is_char_dev(first);
|
||||
if (ndevices == 1) {
|
||||
/* arg is *not* a char device, so let's assume it's
|
||||
* the output file */
|
||||
if (ftype_first != F_DEVICE) {
|
||||
output_arg = first;
|
||||
optind++;
|
||||
ndevices--;
|
||||
}
|
||||
/* multiple arguments, yay */
|
||||
} else {
|
||||
enum ftype ftype_last = is_char_dev(last);
|
||||
/*
|
||||
first is device, last is file -> last
|
||||
first is device, last is device -> noop
|
||||
first is device, last !exist -> last
|
||||
first is file, last is device -> first
|
||||
first is file, last is file -> error
|
||||
first is file, last !exist -> error
|
||||
first !exist, last is device -> first
|
||||
first !exist, last is file -> error
|
||||
first !exit, last !exist -> error
|
||||
*/
|
||||
#define _m(f, l) (((f) << 8) | (l))
|
||||
switch (_m(ftype_first, ftype_last)) {
|
||||
case _m(F_FILE, F_DEVICE):
|
||||
case _m(F_FILE, F_NOEXIST):
|
||||
case _m(F_NOEXIST, F_DEVICE):
|
||||
output_arg = first;
|
||||
optind++;
|
||||
ndevices--;
|
||||
break;
|
||||
case _m(F_DEVICE, F_FILE):
|
||||
case _m(F_DEVICE, F_NOEXIST):
|
||||
output_arg = last;
|
||||
ndevices--;
|
||||
break;
|
||||
case _m(F_DEVICE, F_DEVICE):
|
||||
break;
|
||||
case _m(F_FILE, F_FILE):
|
||||
case _m(F_NOEXIST, F_FILE):
|
||||
case _m(F_NOEXIST, F_NOEXIST):
|
||||
fprintf(stderr, "Ambiguous device vs output file list. Please use --output-file.\n");
|
||||
rc = EXIT_INVALID_USAGE;
|
||||
goto out;
|
||||
}
|
||||
#undef _m
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (ctx.timeout > 0 && output_arg == NULL) {
|
||||
fprintf(stderr,
|
||||
"Option --autorestart requires --output-file\n");
|
||||
|
|
@ -2499,15 +2587,13 @@ main(int argc, char **argv)
|
|||
|
||||
ctx.outfile = safe_strdup(output_arg);
|
||||
|
||||
ndevices = argc - optind;
|
||||
|
||||
if (all) {
|
||||
char **devices; /* NULL-terminated */
|
||||
char **d;
|
||||
|
||||
if (output_arg == NULL) {
|
||||
fprintf(stderr,
|
||||
"Option --all requires --output-file\n");
|
||||
"Option --all requires an output file\n");
|
||||
rc = EXIT_INVALID_USAGE;
|
||||
goto out;
|
||||
}
|
||||
|
|
@ -2527,7 +2613,7 @@ main(int argc, char **argv)
|
|||
} else if (ndevices > 1) {
|
||||
if (ndevices > 1 && output_arg == NULL) {
|
||||
fprintf(stderr,
|
||||
"Recording multiple devices requires --output-file\n");
|
||||
"Recording multiple devices requires an output file\n");
|
||||
rc = EXIT_INVALID_USAGE;
|
||||
goto out;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,7 +10,17 @@ prints them in a format that can later be replayed with the \fBlibinput
|
|||
replay(1)\fR tool. This tool needs to run as root to read from the device.
|
||||
.PP
|
||||
The output of this tool is YAML, see \fBFILE FORMAT\fR for more details.
|
||||
By default it prints to stdout unless the \fB-o\fR option is given.
|
||||
By default it prints to stdout unless an output file is provided. For
|
||||
example, these are valid invocations:
|
||||
|
||||
.B libinput record /dev/input/event3 touchpad.yml
|
||||
|
||||
.B libinput record recording.yml
|
||||
|
||||
.B libinput record --all all-devices.yml
|
||||
|
||||
.B libinput record /dev/input/event3 /dev/input/event4 tp-and-keyboard.yml
|
||||
|
||||
.PP
|
||||
The events recorded are independent of libinput itself, updating or
|
||||
removing libinput will not change the event stream.
|
||||
|
|
@ -44,6 +54,9 @@ greater than 0.
|
|||
.PD 1
|
||||
Specifies the output file to use. If \fB\-\-autorestart\fR is given,
|
||||
the filename is used as prefix only.
|
||||
Where \-\-output-file is not given and the first \fBor\fR last argument is
|
||||
not an input device, the first \fBor\fR last argument will be the output
|
||||
file.
|
||||
.TP 8
|
||||
.B \-\-show\-keycodes
|
||||
Show keycodes as-is in the recording. By default, common keys are obfuscated
|
||||
|
|
|
|||
|
|
@ -269,6 +269,7 @@ class TestRecord(TestLibinputTool):
|
|||
|
||||
def test_all(self):
|
||||
self.run_command_success(['--all', '-o', self.outfile])
|
||||
self.run_command_success(['--all', self.outfile])
|
||||
|
||||
def test_autorestart(self):
|
||||
self.run_command_success(['--autorestart=2'])
|
||||
|
|
@ -280,9 +281,14 @@ class TestRecord(TestLibinputTool):
|
|||
|
||||
def test_device_single(self):
|
||||
self.run_command_success(['/dev/input/event0'])
|
||||
self.run_command_success(['/dev/input/event0', self.outfile])
|
||||
self.run_command_success([self.outfile, '/dev/input/event0'])
|
||||
self.run_command_success([self.outfile, '/dev/input/event0'])
|
||||
|
||||
def test_device_multiple(self):
|
||||
self.run_command_success(['-o', self.outfile, '/dev/input/event0', '/dev/input/event1'])
|
||||
self.run_command_success([self.outfile, '/dev/input/event0', '/dev/input/event1'])
|
||||
self.run_command_success(['/dev/input/event0', '/dev/input/event1', self.outfile])
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue