samples/hid/hid_surface_dial.c
Source file repositories/reference/linux-study-clean/samples/hid/hid_surface_dial.c
File Facts
- System
- Linux kernel
- Corpus path
samples/hid/hid_surface_dial.c- Extension
.c- Size
- 4498 bytes
- Lines
- 204
- Domain
- Support Tooling And Documentation
- Bucket
- samples
- Inferred role
- Support Tooling And Documentation: implementation source
- Status
- source implementation candidate
Why This File Exists
Repository support layer: documentation, build tooling, samples, user-space helper tools, generated initramfs support, licenses, and validation utilities.
- Repository support layer: documentation, build tooling, samples, user-space helper tools, generated initramfs support, licenses, and validation utilities.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
assert.herrno.hfcntl.hlibgen.hsignal.hstdbool.hstdio.hstdlib.hstring.hsys/resource.hunistd.hlinux/bpf.hlinux/errno.hbpf/bpf.hbpf/libbpf.hhid_surface_dial.skel.h
Detected Declarations
struct haptic_syscall_argsfunction int_exitfunction usagefunction get_hid_idfunction set_hapticfunction main
Annotated Snippet
struct haptic_syscall_args {
unsigned int hid;
int retval;
};
static void int_exit(int sig)
{
running = false;
exit(0);
}
static void usage(const char *prog)
{
fprintf(stderr,
"%s: %s [OPTIONS] /sys/bus/hid/devices/0BUS:0VID:0PID:00ID\n\n"
" OPTIONS:\n"
" -r N\t set the given resolution to the device (number of ticks per 360°)\n\n",
__func__, prog);
fprintf(stderr,
"This program will morph the Microsoft Surface Dial into a mouse,\n"
"and depending on the chosen resolution enable or not the haptic feedback:\n"
"- a resolution (-r) of 3600 will report 3600 'ticks' in one full rotation\n"
" without haptic feedback\n"
"- any other resolution will report N 'ticks' in a full rotation with haptic\n"
" feedback\n"
"\n"
"A good default for low resolution haptic scrolling is 72 (1 'tick' every 5\n"
"degrees), and set to 3600 for smooth scrolling.\n");
}
static int get_hid_id(const char *path)
{
const char *str_id, *dir;
char uevent[1024];
int fd;
memset(uevent, 0, sizeof(uevent));
snprintf(uevent, sizeof(uevent) - 1, "%s/uevent", path);
fd = open(uevent, O_RDONLY | O_NONBLOCK);
if (fd < 0)
return -ENOENT;
close(fd);
dir = basename((char *)path);
str_id = dir + sizeof("0003:0001:0A37.");
return (int)strtol(str_id, NULL, 16);
}
static int set_haptic(struct hid_surface_dial *skel, int hid_id)
{
struct haptic_syscall_args args = {
.hid = hid_id,
.retval = -1,
};
int haptic_fd, err;
DECLARE_LIBBPF_OPTS(bpf_test_run_opts, tattr,
.ctx_in = &args,
.ctx_size_in = sizeof(args),
);
haptic_fd = bpf_program__fd(skel->progs.set_haptic);
if (haptic_fd < 0) {
fprintf(stderr, "can't locate haptic prog: %m\n");
return 1;
}
err = bpf_prog_test_run_opts(haptic_fd, &tattr);
if (err) {
fprintf(stderr, "can't set haptic configuration to hid device %d: %m (err: %d)\n",
hid_id, err);
return 1;
}
return 0;
}
int main(int argc, char **argv)
{
struct hid_surface_dial *skel;
const char *optstr = "r:";
struct bpf_link *link;
const char *sysfs_path;
int err, opt, hid_id, resolution = 72;
while ((opt = getopt(argc, argv, optstr)) != -1) {
switch (opt) {
case 'r':
{
Annotation
- Immediate include surface: `assert.h`, `errno.h`, `fcntl.h`, `libgen.h`, `signal.h`, `stdbool.h`, `stdio.h`, `stdlib.h`.
- Detected declarations: `struct haptic_syscall_args`, `function int_exit`, `function usage`, `function get_hid_id`, `function set_haptic`, `function main`.
- Atlas domain: Support Tooling And Documentation / samples.
- Implementation status: source implementation candidate.
Implementation Notes
- This generated page is the file-by-file coverage layer; curated subsystem chapters should link here when they synthesize a multi-file control flow.
- Core OS pages should be promoted from atlas-only to deep-reviewed when they explain data structures, invariants, locking, lifecycle, and C implementation snippets.
- Driver-family pages are intentionally pattern-oriented unless they are part of the selected PCIe/NVMe representative device path.