1
0
forked from drath/libratbag

Add profile implementation

Still not populated with buttons, but it's a good start.

Signed-off-by: Benjamin Tissoires <benjamin.tissoires@gmail.com>
This commit is contained in:
Benjamin Tissoires
2015-08-15 11:38:38 -04:00
parent f4c0d88a1b
commit 30718c2495
5 changed files with 149 additions and 30 deletions

View File

@@ -22,6 +22,7 @@
*/
#include "config.h"
#include <assert.h>
#include <errno.h>
#include <linux/input.h>
#include <stdlib.h>
@@ -30,6 +31,10 @@
#include "libratbag-private.h"
#include "libratbag-hidraw.h"
#define ETEKCITY_PROFILE_MAX 4
#define ETEKCITY_REPORT_ID_KEY_MAPPING 7
static char *
print_key(__u8 key)
{
@@ -117,13 +122,44 @@ etekcity_set_config_profile(struct ratbag *ratbag, __u8 profile, __u8 type)
return ret == sizeof(buf) ? 0 : ret;
}
static void
etekcity_read_profile(struct ratbag_profile *profile, unsigned int index)
{
struct ratbag *ratbag = profile->ratbag;
int i, rc;
__u8 buf[50];
__u8 data;
assert(index <= ETEKCITY_PROFILE_MAX);
etekcity_set_config_profile(ratbag, index, 0x20);
rc = ratbag_hidraw_raw_request(ratbag, ETEKCITY_REPORT_ID_KEY_MAPPING,
buf, sizeof(buf), HID_FEATURE_REPORT, HID_REQ_GET_REPORT);
if (rc < 50)
return;
log_debug(ratbag->libratbag, "profile: %d %s:%d\n",
buf[2],
__FILE__, __LINE__);
for (i = 0; i < 16; i++) {
data = buf[3 + i * 3];
if (data)
log_debug(ratbag->libratbag,
" - button%d: %s (%02x) %s:%d\n",
i,
print_key(data),
data,
__FILE__, __LINE__);
}
}
static int
etekcity_probe(struct ratbag *ratbag, const struct ratbag_id id)
{
int rc, current_profile;
int i;
__u8 data;
__u8 buf[256];
int rc;
struct ratbag_profile *profile;
log_debug(ratbag->libratbag, "data: %d\n", id.data);
@@ -136,8 +172,11 @@ etekcity_probe(struct ratbag *ratbag, const struct ratbag_id id)
return -ENODEV;
}
rc = etekcity_current_profile(ratbag);
if (rc < 0) {
ratbag->num_profiles = ETEKCITY_PROFILE_MAX;
profile = ratbag_get_active_profile(ratbag);
if (!profile) {
log_error(ratbag->libratbag,
"Can't talk to the mouse: '%s' (%d)\n",
strerror(-rc),
@@ -145,32 +184,12 @@ etekcity_probe(struct ratbag *ratbag, const struct ratbag_id id)
return -ENODEV;
}
current_profile = rc;
log_info(ratbag->libratbag,
"'%s' is in profile %d\n",
ratbag_get_name(ratbag),
current_profile);
profile->index);
etekcity_set_config_profile(ratbag, current_profile, 0x20);
rc = ratbag_hidraw_raw_request(ratbag, 7, buf, sizeof(buf),
HID_FEATURE_REPORT, HID_REQ_GET_REPORT);
if (rc >= 40) {
log_debug(ratbag->libratbag, "profile: %d %s:%d\n",
buf[2],
__FILE__, __LINE__);
for (i = 0; i < 16; i++) {
data = buf[3 + i * 3];
if (data)
log_debug(ratbag->libratbag,
" - button%d: %s (%02x) %s:%d\n",
i,
print_key(data),
data,
__FILE__, __LINE__);
}
}
profile = ratbag_profile_unref(profile);
return 0;
}
@@ -190,4 +209,6 @@ struct ratbag_driver etekcity_driver = {
.name = "EtekCity",
.table_ids = etekcity_table,
.probe = etekcity_probe,
.read_profile = etekcity_read_profile,
.get_active_profile = etekcity_current_profile,
};

View File

@@ -49,6 +49,9 @@ struct ratbag {
struct input_id ids;
struct ratbag_driver *driver;
struct libratbag *libratbag;
unsigned num_profiles;
struct list profiles;
};
struct ratbag_id {
@@ -61,11 +64,20 @@ struct ratbag_driver {
const struct ratbag_id *table_ids;
int (*probe)(struct ratbag *ratbag, const struct ratbag_id id);
void (*read_profile)(struct ratbag_profile *profile, unsigned int index);
int (*get_active_profile)(struct ratbag *ratbag);
/* private */
struct list link;
};
struct ratbag_profile {
int refcount;
struct list link;
unsigned index;
struct ratbag *ratbag;
};
void ratbag_device_init(struct ratbag *rb, int fd);
void

View File

@@ -194,6 +194,7 @@ ratbag_device_init(struct ratbag *rb, int fd)
rb->evdev_fd = fd;
rb->hidraw_fd = -1;
rb->refcount = 1;
list_init(&rb->profiles);
}
static inline bool
@@ -222,10 +223,13 @@ ratbag_find_driver(struct libratbag *libratbag, struct ratbag *ratbag,
assert(driver->probe);
matched_id.id = *dev_id;
matched_id.data = matching_id->data;
ratbag->driver = driver;
rc = driver->probe(ratbag, matched_id);
if (rc == 0)
return driver;
ratbag->driver = NULL;
if (rc != -ENODEV)
return NULL;
}
@@ -285,8 +289,6 @@ ratbag_new_from_fd(struct libratbag *libratbag, int fd)
goto err_udev;
}
ratbag->driver = driver;
return ratbag;
err_udev:
@@ -384,3 +386,79 @@ libratbag_unref(struct libratbag *libratbag)
return NULL;
}
static struct ratbag_profile *
ratbag_create_profile(struct ratbag *ratbag, unsigned int index)
{
struct ratbag_profile *profile;
profile = zalloc(sizeof(*profile));
if (!profile)
return NULL;
profile->refcount = 1;
profile->ratbag = ratbag;
profile->index = index;
list_insert(&ratbag->profiles, &profile->link);
assert(ratbag->driver->read_profile);
ratbag->driver->read_profile(profile, index);
return profile;
}
LIBRATBAG_EXPORT struct ratbag_profile *
ratbag_profile_ref(struct ratbag_profile *profile)
{
profile->refcount++;
return profile;
}
LIBRATBAG_EXPORT struct ratbag_profile *
ratbag_profile_unref(struct ratbag_profile *profile)
{
if (profile == NULL)
return NULL;
assert(profile->refcount > 0);
profile->refcount--;
if (profile->refcount > 0)
return profile;
list_remove(&profile->link);
free(profile);
return NULL;
}
LIBRATBAG_EXPORT struct ratbag_profile *
ratbag_get_profile_by_index(struct ratbag *ratbag, unsigned int index)
{
struct ratbag_profile *profile;
list_for_each(profile, &ratbag->profiles, link) {
if (profile->index == index) {
assert(ratbag->driver->read_profile);
ratbag->driver->read_profile(profile, index);
return ratbag_profile_ref(profile);
}
}
return ratbag_create_profile(ratbag, index);
}
LIBRATBAG_EXPORT struct ratbag_profile *
ratbag_get_active_profile(struct ratbag *ratbag)
{
int current_profile;
assert(ratbag->driver->get_active_profile);
current_profile = ratbag->driver->get_active_profile(ratbag);
if (current_profile < 0) {
errno = -current_profile;
return NULL;
}
return ratbag_get_profile_by_index(ratbag, current_profile);
}

View File

@@ -5,8 +5,12 @@ global:
libratbag_create_context;
libratbag_ref;
libratbag_unref;
ratbag_get_active_profile;
ratbag_get_name;
ratbag_get_profile_by_index;
ratbag_new_from_fd;
ratbag_profile_ref;
ratbag_profile_unref;
ratbag_unref;
local:
*;

View File

@@ -49,6 +49,7 @@ main(int argc, char **argv)
{
struct ratbag *rb;
struct libratbag *libratbag;
struct ratbag_profile *profile;
char *path;
int fd;
int retval = 0;
@@ -81,7 +82,10 @@ main(int argc, char **argv)
fprintf(stderr, "Opened '%s' (%s).\n", ratbag_get_name(rb), path);
profile = ratbag_get_active_profile(rb);
out:
profile = ratbag_profile_unref(profile);
rb = ratbag_unref(rb);
libratbag_unref(libratbag);
close(fd);