1
0
forked from drath/libratbag

Add ratbag_hidraw_raw_request to get/set feature reports

Signed-off-by: Benjamin Tissoires <benjamin.tissoires@gmail.com>
This commit is contained in:
Benjamin Tissoires
2015-08-14 22:54:56 -04:00
parent 8d5088b9c6
commit 99f7936cc4
3 changed files with 99 additions and 1 deletions

View File

@@ -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;
}

View File

@@ -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;
}

View File

@@ -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 */