summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBastien Nocera <hadess@hadess.net>2012-02-06 17:32:40 +0000
committerBastien Nocera <hadess@hadess.net>2012-02-06 17:34:23 +0000
commitecb143e1f12eeee3dc51489d5e18cdfef28cfeff (patch)
treeef47998970201f54b374f155c3e38c59feb153d3
parent589e79f91e1352868626369cd723ba1a9dc444b9 (diff)
lib: Add support for button enumeration
Including LEDs, OLEDs, and mode switches.
-rw-r--r--libwacom/libwacom-database.c88
-rw-r--r--libwacom/libwacom.c36
-rw-r--r--libwacom/libwacom.h36
-rw-r--r--libwacom/libwacomint.h12
4 files changed, 164 insertions, 8 deletions
diff --git a/libwacom/libwacom-database.c b/libwacom/libwacom-database.c
index f0c22cb..698a1c8 100644
--- a/libwacom/libwacom-database.c
+++ b/libwacom/libwacom-database.c
@@ -39,6 +39,7 @@
#define SUFFIX ".tablet"
#define FEATURES_GROUP "Features"
#define DEVICE_GROUP "Device"
+#define BUTTONS_GROUP "Buttons"
static WacomClass
libwacom_class_string_to_enum(const char *class)
@@ -188,6 +189,82 @@ libwacom_parse_stylus_keyfile(WacomDeviceDatabase *db, const char *path)
g_strfreev (groups);
}
+struct {
+ const char *key;
+ WacomButtonFlags flag;
+} options[] = {
+ { "Left", WACOM_BUTTON_POSITION_LEFT },
+ { "Right", WACOM_BUTTON_POSITION_RIGHT },
+ { "Top", WACOM_BUTTON_POSITION_TOP },
+ { "Bottom", WACOM_BUTTON_POSITION_BOTTOM },
+ { "Ring", WACOM_BUTTON_RING_MODESWITCH },
+ { "Ring2", WACOM_BUTTON_RING2_MODESWITCH },
+ { "Touchstrip", WACOM_BUTTON_TOUCHSTRIP_MODESWITCH },
+ { "Touchstrip2", WACOM_BUTTON_TOUCHSTRIP2_MODESWITCH },
+ { "OLEDs", WACOM_BUTTON_OLED }
+};
+
+static void
+libwacom_parse_buttons_key(WacomDevice *device,
+ GKeyFile *keyfile,
+ const char *key,
+ WacomButtonFlags flag)
+{
+ guint i;
+ char **vals;
+
+ vals = g_key_file_get_string_list (keyfile, BUTTONS_GROUP, key, NULL, NULL);
+ if (vals == NULL)
+ return;
+ for (i = 0; vals[i] != NULL; i++) {
+ char val;
+
+ val = *vals[i];
+ if (strlen (vals[i]) > 1 ||
+ val < 'A' ||
+ val > 'Z') {
+ g_warning ("Ignoring value '%s' in key '%s'", vals[i], key);
+ continue;
+ }
+ val -= 'A';
+ device->buttons[(int) val] |= flag;
+ }
+
+ g_strfreev (vals);
+}
+
+static int
+libwacom_parse_num_modes (WacomDevice *device,
+ GKeyFile *keyfile,
+ const char *key,
+ WacomButtonFlags flag)
+{
+ int num;
+ guint i;
+
+ num = g_key_file_get_integer (keyfile, BUTTONS_GROUP, key, NULL);
+ if (num > 0)
+ return num;
+ for (i = 0; i < device->num_buttons; i++) {
+ if (device->buttons[i] & flag)
+ num++;
+ }
+ return num;
+}
+
+static void
+libwacom_parse_buttons(WacomDevice *device,
+ GKeyFile *keyfile)
+{
+ guint i;
+
+ for (i = 0; i < G_N_ELEMENTS (options); i++)
+ libwacom_parse_buttons_key(device, keyfile, options[i].key, options[i].flag);
+
+ device->ring_num_modes = libwacom_parse_num_modes(device, keyfile, "RingNumModes", WACOM_BUTTON_RING_MODESWITCH);
+ device->ring2_num_modes = libwacom_parse_num_modes(device, keyfile, "Ring2NumModes", WACOM_BUTTON_RING2_MODESWITCH);
+}
+
static WacomDevice*
libwacom_parse_tablet_keyfile(const char *path)
{
@@ -279,7 +356,16 @@ libwacom_parse_tablet_keyfile(const char *path)
g_warning ("Table '%s' has Ring2 but no Ring. This is impossible", device->match);
device->num_strips = g_key_file_get_integer(keyfile, FEATURES_GROUP, "NumStrips", NULL);
- device->num_buttons = g_key_file_get_integer(keyfile, FEATURES_GROUP, "Buttons", NULL);
+ device->num_buttons = g_key_file_get_integer(keyfile, FEATURES_GROUP, "Buttons", &error);
+ if (device->num_buttons == 0 &&
+ g_error_matches (error, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_KEY_NOT_FOUND)) {
+ g_warning ("Tablet '%s' has no buttons defined, do something!", device->match);
+ g_clear_error (&error);
+ }
+ if (device->num_buttons > 0) {
+ device->buttons = g_new0 (WacomButtonFlags, device->num_buttons);
+ libwacom_parse_buttons(device, keyfile);
+ }
out:
if (keyfile)
diff --git a/libwacom/libwacom.c b/libwacom/libwacom.c
index b7adbd9..123ef99 100644
--- a/libwacom/libwacom.c
+++ b/libwacom/libwacom.c
@@ -181,12 +181,14 @@ libwacom_copy(const WacomDevice *device)
d->product_id = device->product_id;
d->cls = device->cls;
d->bus = device->bus;
- d->num_buttons = device->num_buttons;
- d->supported_styli = g_memdup (device->supported_styli, sizeof(int) * device->num_styli);
- d->num_styli = device->num_styli;
d->num_strips = device->num_strips;
d->features = device->features;
-
+ d->ring_num_modes = device->ring_num_modes;
+ d->ring2_num_modes = device->ring2_num_modes;
+ d->num_styli = device->num_styli;
+ d->supported_styli = g_memdup (device->supported_styli, sizeof(int) * device->num_styli);
+ d->num_buttons = device->num_buttons;
+ d->buttons = g_memdup (device->buttons, sizeof(WacomButtonFlags) * device->num_buttons);
return d;
}
@@ -328,6 +330,7 @@ libwacom_destroy(WacomDevice *device)
g_free (device->match);
g_free (device->supported_styli);
+ g_free (device->buttons);
g_free (device);
}
@@ -400,6 +403,16 @@ int libwacom_has_ring2(WacomDevice *device)
return !!(device->features & FEATURE_RING2);
}
+int libwacom_get_ring_num_modes(WacomDevice *device)
+{
+ return device->ring_num_modes;
+}
+
+int libwacom_get_ring2_num_modes(WacomDevice *device)
+{
+ return device->ring2_num_modes;
+}
+
int libwacom_get_num_strips(WacomDevice *device)
{
return device->num_strips;
@@ -420,6 +433,21 @@ WacomBusType libwacom_get_bustype(WacomDevice *device)
return device->bus;
}
+WacomButtonFlags
+libwacom_get_button_flag(WacomDevice *device,
+ char button)
+{
+ int index;
+
+ g_return_val_if_fail (device->num_buttons > 0, WACOM_BUTTON_NONE);
+ g_return_val_if_fail (button >= 'A', WACOM_BUTTON_NONE);
+ g_return_val_if_fail (button < 'A' + device->num_buttons, WACOM_BUTTON_NONE);
+
+ index = button - 'A';
+
+ return device->buttons[index];
+}
+
const WacomStylus *libwacom_stylus_get_for_id (WacomDeviceDatabase *db, int id)
{
return g_hash_table_lookup (db->stylus_ht, GINT_TO_POINTER(id));
diff --git a/libwacom/libwacom.h b/libwacom/libwacom.h
index 36918b9..b07b21f 100644
--- a/libwacom/libwacom.h
+++ b/libwacom/libwacom.h
@@ -131,6 +131,22 @@ typedef enum {
} WacomStylusType;
/**
+ * Capabilities of the various tablet buttons
+ */
+typedef enum {
+ WACOM_BUTTON_NONE = 0,
+ WACOM_BUTTON_POSITION_LEFT = (1 << 1),
+ WACOM_BUTTON_POSITION_RIGHT = (1 << 2),
+ WACOM_BUTTON_POSITION_TOP = (1 << 3),
+ WACOM_BUTTON_POSITION_BOTTOM = (1 << 4),
+ WACOM_BUTTON_RING_MODESWITCH = (1 << 5),
+ WACOM_BUTTON_RING2_MODESWITCH = (1 << 6),
+ WACOM_BUTTON_TOUCHSTRIP_MODESWITCH = (1 << 7),
+ WACOM_BUTTON_TOUCHSTRIP2_MODESWITCH = (1 << 8),
+ WACOM_BUTTON_OLED = (1 << 9)
+} WacomButtonFlags;
+
+/**
* Allocate a new structure for error reporting.
*
* @return A newly allocated error structure or NULL if the allocation
@@ -319,6 +335,18 @@ int libwacom_has_ring2(WacomDevice *device);
/**
* @param device The tablet to query
+ * @return the number of modes for the touchring if it has a mode switch
+ */
+int libwacom_get_ring_num_modes(WacomDevice *device);
+
+/**
+ * @param device The tablet to query
+ * @return the number of modes for the second touchring if it has a mode switch
+ */
+int libwacom_get_ring2_num_modes(WacomDevice *device);
+
+/**
+ * @param device The tablet to query
* @return the number of touch strips on the tablet
* otherwise
*/
@@ -344,6 +372,14 @@ int libwacom_is_reversible(WacomDevice *device);
*/
WacomBusType libwacom_get_bustype(WacomDevice *device);
+/*
+ * @param device The tablet to query
+ * @param button The ID of the button to check for, between 'A' and 'Z'
+ * @return a WacomButtonFlags with information about the button
+ */
+WacomButtonFlags libwacom_get_button_flag(WacomDevice *device,
+ char button);
+
/**
* Get the WacomStylus for the given tool ID.
*
diff --git a/libwacom/libwacomint.h b/libwacom/libwacomint.h
index dfa0925..f54299b 100644
--- a/libwacom/libwacomint.h
+++ b/libwacom/libwacomint.h
@@ -69,11 +69,17 @@ struct _WacomDevice {
WacomClass cls;
WacomBusType bus;
- int num_buttons;
- int *supported_styli;
- gsize num_styli;
int num_strips;
uint32_t features;
+
+ int ring_num_modes;
+ int ring2_num_modes;
+
+ gsize num_styli;
+ int *supported_styli;
+
+ int num_buttons;
+ WacomButtonFlags *buttons;
};
struct _WacomStylus {