From 8cab7fd7a623aaaf07ee5c007d3dff0bb10556b0 Mon Sep 17 00:00:00 2001 From: Benjamin Tissoires Date: Sun, 16 Aug 2015 21:18:11 -0400 Subject: [PATCH] Implement the buttons, sort of Signed-off-by: Benjamin Tissoires --- src/etekcity.c | 41 ++++++++++++++++++------- src/libratbag-private.h | 29 ++++++++++++++++++ src/libratbag.c | 66 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 125 insertions(+), 11 deletions(-) diff --git a/src/etekcity.c b/src/etekcity.c index 59dc8d65..7240a963 100644 --- a/src/etekcity.c +++ b/src/etekcity.c @@ -166,7 +166,6 @@ etekcity_read_profile(struct ratbag_profile *profile, unsigned int index) struct ratbag *ratbag = profile->ratbag; int i, rc, button; __u8 buf[50]; - __u8 data; assert(index <= ETEKCITY_PROFILE_MAX); @@ -179,6 +178,8 @@ etekcity_read_profile(struct ratbag_profile *profile, unsigned int index) if (rc < 50) return; + ratbag_profile_set_drv_data(profile, buf); + log_debug(ratbag->libratbag, "profile: %d %s:%d\n", buf[2], __FILE__, __LINE__); @@ -186,17 +187,9 @@ etekcity_read_profile(struct ratbag_profile *profile, unsigned int index) button = 0; for (i = 0; i < 16; i++) { - data = buf[3 + i * 3]; - if (data) { - log_debug(ratbag->libratbag, - " - button%d: %s (%02x) %s:%d\n", - button, - print_key(data), - data, - __FILE__, __LINE__); - button++; - } + ratbag_profile_get_button_by_index(profile, i); } + ratbag_profile_set_drv_data(profile, NULL); } static int @@ -205,6 +198,30 @@ etekcity_write_profile(struct ratbag_profile *profile) return 0; } +static void +etekcity_read_button(struct ratbag *ratbag, struct ratbag_profile *profile, + struct ratbag_button *button) +{ + __u8 *raw_profile = ratbag_profile_get_drv_data(profile); + __u8 data; + + if (!raw_profile) + return; + + data = raw_profile[3 + button->index * 3]; + if (data) + log_debug(ratbag->libratbag, + " - button%d: %s (%02x) %s:%d\n", + button->index, print_key(data), data, __FILE__, __LINE__); +} + +static int +etekcity_write_button(struct ratbag *ratbag, struct ratbag_profile *profile, + struct ratbag_button *button) +{ + return 0; +} + static int etekcity_probe(struct ratbag *ratbag, const struct ratbag_id id) { @@ -265,4 +282,6 @@ struct ratbag_driver etekcity_driver = { .get_active_profile = etekcity_current_profile, .set_active_profile = etekcity_set_current_profile, .has_capability = etekcity_has_capability, + .read_button = etekcity_read_button, + .write_button = etekcity_write_button, }; diff --git a/src/libratbag-private.h b/src/libratbag-private.h index 348b33bd..9e13cea1 100644 --- a/src/libratbag-private.h +++ b/src/libratbag-private.h @@ -71,6 +71,10 @@ struct ratbag_driver { int (*get_active_profile)(struct ratbag *ratbag); int (*set_active_profile)(struct ratbag *ratbag, unsigned int index); int (*has_capability)(const struct ratbag *ratbag, enum ratbag_capability cap); + void (*read_button)(struct ratbag *ratbag, struct ratbag_profile *profile, + struct ratbag_button *button); + int (*write_button)(struct ratbag *ratbag, struct ratbag_profile *profile, + struct ratbag_button *button); /* private */ struct list link; @@ -81,10 +85,35 @@ struct ratbag_profile { struct list link; unsigned index; struct ratbag *ratbag; + struct list buttons; + void *drv_data; + void *user_data; +}; + +struct ratbag_button { + int refcount; + struct list link; + struct ratbag *ratbag; + struct ratbag_profile *profile; + unsigned index; + enum ratbag_button_type type; + enum ratbag_button_action_type action_type; }; void ratbag_device_init(struct ratbag *rb, int fd); +static inline void +ratbag_profile_set_drv_data(struct ratbag_profile *profile, void *drv_data) +{ + profile->drv_data = drv_data; +} + +static inline void * +ratbag_profile_get_drv_data(struct ratbag_profile *profile) +{ + return profile->drv_data; +} + void log_msg_va(struct libratbag *libratbag, enum libratbag_log_priority priority, diff --git a/src/libratbag.c b/src/libratbag.c index ec4c1bca..09191e14 100644 --- a/src/libratbag.c +++ b/src/libratbag.c @@ -401,6 +401,7 @@ ratbag_create_profile(struct ratbag *ratbag, unsigned int index) profile->index = index; list_insert(&ratbag->profiles, &profile->link); + list_init(&profile->buttons); assert(ratbag->driver->read_profile); ratbag->driver->read_profile(profile, index); @@ -496,3 +497,68 @@ ratbag_set_active_profile(struct ratbag *ratbag, assert(ratbag->driver->set_active_profile); return ratbag->driver->set_active_profile(ratbag, profile->index); } + +static struct ratbag_button * +ratbag_create_button(struct ratbag *ratbag, struct ratbag_profile *profile, + unsigned int index) +{ + struct ratbag_button *button; + + button = zalloc(sizeof(*button)); + if (!button) + return NULL; + + button->refcount = 1; + button->ratbag = ratbag; + button->profile = profile; + button->index = index; + + if (profile) + list_insert(&profile->buttons, &button->link); + + if (ratbag->driver->read_button) + ratbag->driver->read_button(ratbag, profile, button); + + return button; +} + +LIBRATBAG_EXPORT struct ratbag_button* +ratbag_profile_get_button_by_index(struct ratbag_profile *profile, + unsigned int index) +{ + struct ratbag_button *button; + + list_for_each(button, &profile->buttons, link) { + if (button->index == index) { + if (profile->ratbag->driver->read_button) + profile->ratbag->driver->read_button(profile->ratbag, profile, button); + return ratbag_button_ref(button); + } + } + + return ratbag_create_button(profile->ratbag, profile, index); +} + +LIBRATBAG_EXPORT struct ratbag_button * +ratbag_button_ref(struct ratbag_button *button) +{ + button->refcount++; + return button; +} + +LIBRATBAG_EXPORT struct ratbag_button * +ratbag_button_unref(struct ratbag_button *button) +{ + if (button == NULL) + return NULL; + + assert(button->refcount > 0); + button->refcount--; + if (button->refcount > 0) + return button; + + list_remove(&button->link); + free(button); + + return NULL; +}