-
Notifications
You must be signed in to change notification settings - Fork 0
/
evdev_mpers.c
134 lines (113 loc) · 2.89 KB
/
evdev_mpers.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
/*
* Copyright (c) 2015 Etienne Gemsa <[email protected]>
* Copyright (c) 2015-2016 Dmitry V. Levin <[email protected]>
* Copyright (c) 2015-2019 The strace developers.
* All rights reserved.
*
* SPDX-License-Identifier: LGPL-2.1-or-later
*/
#include "defs.h"
#ifdef HAVE_LINUX_INPUT_H
# include DEF_MPERS_TYPE(struct_ff_effect)
# include <linux/ioctl.h>
# include <linux/input.h>
typedef struct ff_effect struct_ff_effect;
#endif /* HAVE_LINUX_INPUT_H */
#include MPERS_DEFS
#ifdef HAVE_LINUX_INPUT_H
static void
decode_envelope(void *const data)
{
const struct ff_envelope *const envelope = data;
tprintf(", envelope={attack_length=%" PRIu16
", attack_level=%" PRIu16
", fade_length=%" PRIu16
", fade_level=%#x}",
envelope->attack_length,
envelope->attack_level,
envelope->fade_length,
envelope->fade_level);
}
static int
ff_effect_ioctl(struct tcb *const tcp, const kernel_ulong_t arg)
{
tprints(", ");
struct_ff_effect ffe;
#ifdef ENABLE_DATASERIES
DS_SET_IOCTL_SIZE(kernel_ulong_t);
#endif /* ENABLE_DATASERIES */
if (umove_or_printaddr(tcp, arg, &ffe))
return RVAL_IOCTL_DECODED;
tprints("{type=");
print_evdev_ff_type(ffe.type);
tprintf(", id=%" PRIu16
", direction=%" PRIu16 ", ",
ffe.id,
ffe.direction);
if (abbrev(tcp)) {
tprints("...}");
return RVAL_IOCTL_DECODED;
}
tprintf("trigger={button=%" PRIu16
", interval=%" PRIu16 "}"
", replay={length=%" PRIu16
", delay=%" PRIu16 "}",
ffe.trigger.button,
ffe.trigger.interval,
ffe.replay.length,
ffe.replay.delay);
switch (ffe.type) {
case FF_CONSTANT:
tprintf(", constant={level=%" PRId16,
ffe.u.constant.level);
decode_envelope(&ffe.u.constant.envelope);
tprints("}");
break;
case FF_RAMP:
tprintf(", ramp={start_level=%" PRId16
", end_level=%" PRId16,
ffe.u.ramp.start_level,
ffe.u.ramp.end_level);
decode_envelope(&ffe.u.ramp.envelope);
tprints("}");
break;
case FF_PERIODIC:
tprintf(", periodic={waveform=%" PRIu16
", period=%" PRIu16
", magnitude=%" PRId16
", offset=%" PRId16
", phase=%" PRIu16,
ffe.u.periodic.waveform,
ffe.u.periodic.period,
ffe.u.periodic.magnitude,
ffe.u.periodic.offset,
ffe.u.periodic.phase);
decode_envelope(&ffe.u.periodic.envelope);
tprintf(", custom_len=%u, custom_data=",
ffe.u.periodic.custom_len);
printaddr(ptr_to_kulong(ffe.u.periodic.custom_data));
tprints("}");
break;
case FF_RUMBLE:
tprintf(", rumble={strong_magnitude=%" PRIu16
", weak_magnitude=%" PRIu16 "}",
ffe.u.rumble.strong_magnitude,
ffe.u.rumble.weak_magnitude);
break;
default:
break;
}
tprints("}");
return RVAL_IOCTL_DECODED;
}
MPERS_PRINTER_DECL(int, evdev_write_ioctl_mpers, struct tcb *const tcp,
const unsigned int code, const kernel_ulong_t arg)
{
switch (code) {
case EVIOCSFF:
return ff_effect_ioctl(tcp, arg);
default:
return RVAL_DECODED;
}
}
#endif /* HAVE_LINUX_INPUT_H */