summaryrefslogtreecommitdiff
path: root/src/feature/reprogrammable.c
diff options
context:
space:
mode:
authorLars-Dominik Braun <lars@6xq.net>2012-07-05 16:53:55 +0200
committerLars-Dominik Braun <lars@6xq.net>2012-07-05 16:53:55 +0200
commita5eb4ba1296c6279e5535bf3bcc1f1796707f6c6 (patch)
treef364b89467c2a38ce81e6ca0f2985d7a863c570e /src/feature/reprogrammable.c
downloadlshidpp-a5eb4ba1296c6279e5535bf3bcc1f1796707f6c6.tar.gz
lshidpp-a5eb4ba1296c6279e5535bf3bcc1f1796707f6c6.tar.bz2
lshidpp-a5eb4ba1296c6279e5535bf3bcc1f1796707f6c6.zip
Initial import
Diffstat (limited to 'src/feature/reprogrammable.c')
-rw-r--r--src/feature/reprogrammable.c162
1 files changed, 162 insertions, 0 deletions
diff --git a/src/feature/reprogrammable.c b/src/feature/reprogrammable.c
new file mode 100644
index 0000000..2c3b61d
--- /dev/null
+++ b/src/feature/reprogrammable.c
@@ -0,0 +1,162 @@
+/*
+ * Copyright (c) 2012
+ * Lars-Dominik Braun <lars@6xq.net>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+#include <stdlib.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <assert.h>
+
+#include "reprogrammable.h"
+#include "usb.h"
+#include "device.h"
+
+typedef enum {
+ HIDPP_TASK_VOLUP = 1,
+ HIDPP_TASK_VOLDOWN = 2,
+ HIDPP_TASK_MUTE = 3,
+ HIDPP_TASK_PLAYPAUSE = 4,
+ HIDPP_TASK_NEXTFF = 5,
+ HIDPP_TASK_PREVRW = 6,
+ HIDPP_TASK_STOP = 7,
+ HIDPP_TASK_APPSWITCH = 8,
+} hidppReprogrammableKeyTask_t;
+
+typedef enum {
+ /* reprogrammmable */
+ HIDPP_RK_REPGROGRAMMABLE = (1 << 4),
+ /* affected by fn key */
+ HIDPP_RK_FNTOGGLE = (1 << 3),
+ /* hotkey */
+ HIDPP_RK_HOTKEY = (1 << 2),
+ /* fn key */
+ HIDPP_RK_FN = (1 << 1),
+ /* mouse button */
+ HIDPP_RK_MOUSE = (1 << 0),
+} hidppReprogrammableKeyFlags_t;
+
+typedef struct {
+ uint16_t id;
+ hidppReprogrammableKeyTask_t task;
+ hidppReprogrammableKeyFlags_t flags;
+} hidppReprogrammableKey_t;
+
+typedef struct {
+ hidppReprogrammableKey_t *key;
+ size_t count;
+} hidppReprogrammableData_t;
+
+const char *hidppReprogrammableTaskToStr (const hidppReprogrammableKeyTask_t t) {
+ switch (t) {
+ case HIDPP_TASK_VOLUP:
+ return "volume up";
+ break;
+
+ case HIDPP_TASK_VOLDOWN:
+ return "volume down";
+ break;
+
+ case HIDPP_TASK_MUTE:
+ return "mute";
+ break;
+
+ case HIDPP_TASK_PLAYPAUSE:
+ return "play/pause";
+ break;
+
+ case HIDPP_TASK_NEXTFF:
+ return "next/fast forward";
+ break;
+
+ case HIDPP_TASK_PREVRW:
+ return "previous/rewind";
+ break;
+
+ case HIDPP_TASK_STOP:
+ return "stop";
+ break;
+
+ case HIDPP_TASK_APPSWITCH:
+ return "application switcher";
+ break;
+
+ default:
+ return "unknown";
+ break;
+ }
+}
+
+void hidppReprogrammablePrint (const void * const data) {
+ const hidppReprogrammableData_t * const d = data;
+
+ assert (d != NULL);
+
+ for (size_t i = 0; i < d->count; i++) {
+ const hidppReprogrammableKey_t * const k = &d->key[i];
+ printf (" Key: <name> (0x%x)\n"
+ " Task: %s (%u)\n"
+ " Flags:%s%s%s%s%s (0x%x)\n",
+ k->id,
+ hidppReprogrammableTaskToStr (k->task), k->task,
+ (k->flags & HIDPP_RK_REPGROGRAMMABLE) ? " reprogrammable" : "",
+ (k->flags & HIDPP_RK_FNTOGGLE) ? " fntoggle" : "",
+ (k->flags & HIDPP_RK_HOTKEY) ? " hotkey" : "",
+ (k->flags & HIDPP_RK_FN) ? " fn" : "",
+ (k->flags & HIDPP_RK_MOUSE) ? " mouse" : "",
+ k->flags);
+ }
+}
+
+void hidppReprogrammableGet (hidppDevice_t *d, void ** const retData) {
+ hidppReprogrammableData_t *data;
+ hidppPacket_t rp;
+
+ assert (d != NULL);
+ assert (retData != NULL);
+
+ data = calloc (1, sizeof (*data));
+
+ hidppUsbRequest (d, HIDPP_FEATURE_PROGRAMMABLE_KEYS, 0x0, NULL, 0, &rp);
+ data->count = rp.args[0];
+ data->key = calloc (data->count, sizeof (*data->key));
+
+ for (uint8_t i = 0; i < data->count; i++) {
+ hidppReprogrammableKey_t * const k = &data->key[i];
+
+ hidppUsbRequest (d, HIDPP_FEATURE_PROGRAMMABLE_KEYS, 0x1, &i, 1, &rp);
+
+ k->id = (rp.args[0] << 8) | rp.args[1];
+ k->task = (rp.args[2] << 8) | rp.args[3];
+ k->flags = rp.args[4];
+ }
+
+ *retData = data;
+}
+
+bool hidppReprogrammableAvailable (const hidppDevice_t * const d) {
+ uint8_t ret;
+ return hidppFeatureIdToIdx (d, HIDPP_FEATURE_PROGRAMMABLE_KEYS, &ret);
+}
+
+hidppModule_t moduleReprogrammable = {hidppReprogrammableAvailable,
+ hidppReprogrammableGet, hidppReprogrammablePrint};
+