mirror of
https://github.com/libratbag/libratbag.git
synced 2026-11-07 23:23:52 +01:00
Add ratbag_hidraw_raw_request to get/set feature reports
Signed-off-by: Benjamin Tissoires <benjamin.tissoires@gmail.com>
This commit is contained in:
@@ -30,10 +30,27 @@
|
||||
#include "libratbag-private.h"
|
||||
#include "libratbag-hidraw.h"
|
||||
|
||||
static int
|
||||
etekcity_current_profile(struct ratbag *ratbag)
|
||||
{
|
||||
__u8 buf[3];
|
||||
int ret;
|
||||
|
||||
ret = ratbag_hidraw_raw_request(ratbag, 5, buf, sizeof(buf),
|
||||
HID_FEATURE_REPORT, HID_REQ_GET_REPORT);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
if (ret != 3)
|
||||
return -EIO;
|
||||
|
||||
return buf[2];
|
||||
}
|
||||
|
||||
static int
|
||||
etekcity_probe(struct ratbag *ratbag, const struct ratbag_id id)
|
||||
{
|
||||
int rc;
|
||||
int rc, current_profile;
|
||||
|
||||
log_debug(ratbag->libratbag, "data: %d\n", id.data);
|
||||
|
||||
@@ -46,6 +63,22 @@ etekcity_probe(struct ratbag *ratbag, const struct ratbag_id id)
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
rc = etekcity_current_profile(ratbag);
|
||||
if (rc < 0) {
|
||||
log_error(ratbag->libratbag,
|
||||
"Can't talk to the mouse: '%s' (%d)\n",
|
||||
strerror(-rc),
|
||||
rc);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
current_profile = rc;
|
||||
|
||||
log_info(ratbag->libratbag,
|
||||
"'%s' is in profile %d\n",
|
||||
ratbag_get_name(ratbag),
|
||||
current_profile);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -25,10 +25,16 @@
|
||||
#include <fcntl.h>
|
||||
#include <libudev.h>
|
||||
#include <linux/hidraw.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "libratbag-hidraw.h"
|
||||
#include "libratbag-private.h"
|
||||
|
||||
/* defined in include/linux.hid.h in the kernel, but not exported */
|
||||
#ifndef HID_MAX_BUFFER_SIZE
|
||||
#define HID_MAX_BUFFER_SIZE 4096 /* 4kb */
|
||||
#endif
|
||||
|
||||
int
|
||||
ratbag_open_hidraw(struct ratbag *ratbag)
|
||||
{
|
||||
@@ -64,3 +70,38 @@ err:
|
||||
close(fd);
|
||||
return -errno;
|
||||
}
|
||||
|
||||
int ratbag_hidraw_raw_request(struct ratbag *ratbag, unsigned char reportnum,
|
||||
__u8 *buf, size_t len, unsigned char rtype, int reqtype)
|
||||
{
|
||||
char tmp_buf[HID_MAX_BUFFER_SIZE];
|
||||
int rc;
|
||||
|
||||
if (len < 1 || len > HID_MAX_BUFFER_SIZE || !buf || ratbag->hidraw_fd < 0)
|
||||
return -EINVAL;
|
||||
|
||||
if (rtype != HID_FEATURE_REPORT)
|
||||
return -ENOTSUP;
|
||||
|
||||
switch (reqtype) {
|
||||
case HID_REQ_GET_REPORT:
|
||||
memset(tmp_buf, 0, len);
|
||||
tmp_buf[0] = reportnum;
|
||||
|
||||
rc = ioctl(ratbag->hidraw_fd, HIDIOCGFEATURE(len), tmp_buf);
|
||||
if (rc < 0)
|
||||
return -errno;
|
||||
|
||||
memcpy(buf, tmp_buf, rc);
|
||||
return rc;
|
||||
case HID_REQ_SET_REPORT:
|
||||
buf[0] = reportnum;
|
||||
rc = ioctl(ratbag->hidraw_fd, HIDIOCSFEATURE(len), buf);
|
||||
if (rc < 0)
|
||||
return -errno;
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
@@ -24,8 +24,32 @@
|
||||
#ifndef LIBRATBAG_HIDRAW_H
|
||||
#define LIBRATBAG_HIDRAW_H
|
||||
|
||||
#include <linux/hid.h>
|
||||
|
||||
#include "libratbag.h"
|
||||
|
||||
/* defined in the internal hid API in the kernel */
|
||||
#define HID_INPUT_REPORT 0
|
||||
#define HID_OUTPUT_REPORT 1
|
||||
#define HID_FEATURE_REPORT 2
|
||||
|
||||
int ratbag_open_hidraw(struct ratbag *ratbag);
|
||||
|
||||
/**
|
||||
* ratbag_hidraw_raw_request - send report request to device
|
||||
*
|
||||
* @ratbag: ratbag device
|
||||
* @reportnum: report ID
|
||||
* @buf: in/out data to transfer
|
||||
* @len: length of buf
|
||||
* @rtype: HID report type
|
||||
* @reqtype: HID_REQ_GET_REPORT or HID_REQ_SET_REPORT
|
||||
*
|
||||
* @return: count of data transfered, negative if error
|
||||
*
|
||||
* Same behavior as hid_hw_request, but with raw buffers instead.
|
||||
*/
|
||||
int ratbag_hidraw_raw_request(struct ratbag *ratbag, unsigned char reportnum,
|
||||
__u8 *buf, size_t len, unsigned char rtype, int reqtype);
|
||||
|
||||
#endif /* LIBRATBAG_HIDRAW_H */
|
||||
|
||||
Reference in New Issue
Block a user