From c05d522a1d840b801c6bdaf635b61a9cd6a991b3 Mon Sep 17 00:00:00 2001
From: Přemysl Janouch
Date: Sun, 2 Jun 2013 23:50:33 +0200
Subject: Add a GTK+ GUI
---
CMakeLists.txt | 67 +++++++-
config.h.in | 11 +-
org.sensei-raw-ctl.policy.in | 17 ++
quote-file.cmake | 4 +
sensei-raw-ctl-gui.c | 379 ++++++++++++++++++++++++++++++++++++++++++
sensei-raw-ctl-gui.desktop.in | 8 +
sensei-raw-ctl-gui.svg | 37 +++++
sensei-raw-ctl-gui.ui | 199 ++++++++++++++++++++++
sensei-raw-ctl.c | 16 +-
sensei-raw.svg | 37 +++++
10 files changed, 757 insertions(+), 18 deletions(-)
create mode 100644 org.sensei-raw-ctl.policy.in
create mode 100644 quote-file.cmake
create mode 100644 sensei-raw-ctl-gui.c
create mode 100644 sensei-raw-ctl-gui.desktop.in
create mode 100644 sensei-raw-ctl-gui.svg
create mode 100644 sensei-raw-ctl-gui.ui
create mode 100644 sensei-raw.svg
diff --git a/CMakeLists.txt b/CMakeLists.txt
index e34375c..35b3ce6 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -6,13 +6,66 @@ find_package (PkgConfig REQUIRED)
pkg_check_modules (dependencies REQUIRED libusb-1.0)
include_directories (${dependencies_INCLUDE_DIRS})
-configure_file (${CMAKE_CURRENT_SOURCE_DIR}/config.h.in
- ${CMAKE_CURRENT_BINARY_DIR}/config.h)
-include_directories (${CMAKE_CURRENT_BINARY_DIR})
-
-add_executable (${CMAKE_PROJECT_NAME} ${CMAKE_PROJECT_NAME}.c)
-target_link_libraries (${CMAKE_PROJECT_NAME} ${dependencies_LIBRARIES})
+option (DEVELOPER_MODE "Developer mode" OFF)
include (GNUInstallDirs)
-install (TARGETS ${CMAKE_PROJECT_NAME} DESTINATION ${CMAKE_INSTALL_BINDIR})
+configure_file (${PROJECT_SOURCE_DIR}/config.h.in
+ ${PROJECT_BINARY_DIR}/config.h)
+include_directories (${PROJECT_BINARY_DIR})
+
+add_executable (${PROJECT_NAME} ${PROJECT_NAME}.c)
+target_link_libraries (${PROJECT_NAME} ${dependencies_LIBRARIES})
+install (TARGETS ${PROJECT_NAME} DESTINATION ${CMAKE_INSTALL_BINDIR})
+
+pkg_check_modules (gtk3 gtk+-3.0)
+set (BUILD_GUI ${gtk3_FOUND} CACHE BOOL "Whether to build the GTK+ frontend")
+
+if (BUILD_GUI)
+ include_directories (${gtk3_INCLUDE_DIRS})
+ link_directories (${gtk3_LIBRARY_DIRS})
+
+ set (ui_in ${PROJECT_SOURCE_DIR}/${PROJECT_NAME}-gui.ui)
+ set (ui_out ${PROJECT_BINARY_DIR}/${PROJECT_NAME}-gui-ui.c)
+ add_custom_command (OUTPUT ${ui_out}
+ COMMAND ${CMAKE_COMMAND} -D "input=${ui_in}" -D "output=${ui_out}"
+ -D var_name=ui -P "${PROJECT_SOURCE_DIR}/quote-file.cmake"
+ DEPENDS ${ui_in}
+ COMMENT "Wrapping the UI file into a source file" VERBATIM)
+
+ configure_file (${PROJECT_SOURCE_DIR}/${PROJECT_NAME}-gui.desktop.in
+ ${PROJECT_BINARY_DIR}/${PROJECT_NAME}-gui.desktop)
+ install (FILES ${PROJECT_BINARY_DIR}/${PROJECT_NAME}-gui.desktop
+ DESTINATION ${CMAKE_INSTALL_DATADIR}/applications)
+ install (FILES ${PROJECT_SOURCE_DIR}/${PROJECT_NAME}-gui.svg
+ DESTINATION ${CMAKE_INSTALL_DATADIR}/icons/hicolor/scalable/apps)
+
+ set (polkit_id "org.${PROJECT_NAME}.policy")
+ configure_file (${PROJECT_SOURCE_DIR}/${polkit_id}.in
+ ${PROJECT_BINARY_DIR}/${polkit_id})
+ install (FILES ${PROJECT_BINARY_DIR}/${polkit_id}
+ DESTINATION ${CMAKE_INSTALL_DATADIR}/polkit-1/actions)
+
+ add_executable (${PROJECT_NAME}-gui ${PROJECT_NAME}-gui.c ${ui_out})
+ set_target_properties (${PROJECT_NAME}-gui PROPERTIES
+ COMPILE_FLAGS "${gtk3_CFLAGS_OTHER}")
+ target_link_libraries (${PROJECT_NAME}-gui ${gtk3_LIBRARIES})
+ install (TARGETS ${PROJECT_NAME}-gui
+ DESTINATION ${CMAKE_INSTALL_BINDIR})
+endif (BUILD_GUI)
+
+set (CPACK_PACKAGE_DESCRIPTION_SUMMARY "SteelSeries Sensei Raw control utility")
+set (CPACK_PACKAGE_VERSION ${project_VERSION})
+set (CPACK_PACKAGE_VENDOR "Premysl Janouch")
+set (CPACK_PACKAGE_CONTACT "Přemysl Janouch ")
+set (CPACK_RESOURCE_FILE_LICENSE "${PROJECT_SOURCE_DIR}/LICENSE")
+
+set (CPACK_GENERATOR "TGZ;ZIP")
+set (CPACK_PACKAGE_FILE_NAME
+ "${PROJECT_NAME}-${project_VERSION}-${CMAKE_SYSTEM_NAME}-${CMAKE_SYSTEM_PROCESSOR}")
+
+set (CPACK_SOURCE_GENERATOR "TGZ;ZIP")
+set (CPACK_SOURCE_IGNORE_FILES "/\\\\.git;/build;/CMakeLists.txt.user")
+set (CPACK_SOURCE_PACKAGE_FILE_NAME "${PROJECT_NAME}-${project_VERSION}")
+set (CPACK_SET_DESTDIR TRUE)
+include (CPack)
diff --git a/config.h.in b/config.h.in
index d00c838..36afa2c 100644
--- a/config.h.in
+++ b/config.h.in
@@ -4,6 +4,11 @@
#define PROJECT_NAME "${CMAKE_PROJECT_NAME}"
#define PROJECT_VERSION "${project_VERSION}"
-#endif /* ! CONFIG_H */
-
-
+#cmakedefine DEVELOPER_MODE
+#ifdef DEVELOPER_MODE
+ #define PROJECT_INSTALL_BINDIR "${PROJECT_BINARY_DIR}"
+#else // ! DEVELOPER_MODE
+ #define PROJECT_INSTALL_BINDIR "${CMAKE_INSTALL_FULL_BINDIR}"
+#endif // ! DEVELOPER MODE
+
+#endif // ! CONFIG_H
diff --git a/org.sensei-raw-ctl.policy.in b/org.sensei-raw-ctl.policy.in
new file mode 100644
index 0000000..e37f0dd
--- /dev/null
+++ b/org.sensei-raw-ctl.policy.in
@@ -0,0 +1,17 @@
+
+
+
+ ${PROJECT_NAME}-gui
+
+ Device access
+ Authentication is required to access the USB device
+
+ no
+ no
+ auth_admin_keep
+
+ ${CMAKE_INSTALL_FULL_BINDIR}/${PROJECT_NAME}
+
+
diff --git a/quote-file.cmake b/quote-file.cmake
new file mode 100644
index 0000000..6f9159e
--- /dev/null
+++ b/quote-file.cmake
@@ -0,0 +1,4 @@
+file (READ ${input} contents)
+string (REPLACE "\n" "\\n\"\n\"" contents "${contents}")
+file (WRITE ${output}
+ "const char ${var_name}[] = \n\"${contents}\";\n")
diff --git a/sensei-raw-ctl-gui.c b/sensei-raw-ctl-gui.c
new file mode 100644
index 0000000..46272de
--- /dev/null
+++ b/sensei-raw-ctl-gui.c
@@ -0,0 +1,379 @@
+/*
+ * sensei-raw-ctl-gui.c: SteelSeries Sensei Raw control utility - GTK+ GUI
+ *
+ * Very tightly coupled with the sensei-raw-ctl utility.
+ *
+ * Copyright (c) 2013, Přemysl Janouch
+ * All rights reserved.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ */
+
+#include
+#include
+#include
+
+#include
+#include
+
+#include "config.h"
+
+/** User interface string for GtkBuilder. */
+extern const char ui[];
+
+/* To translate combo box entries into sensei-raw-ctl arguments. */
+static gchar *pulsation_list[] = { "steady", "slow", "medium", "fast", NULL };
+static gchar *intensity_list[] = { "off", "low", "medium", "high", NULL };
+
+/* GtkNotebook pages within the UI. */
+enum
+{
+ PAGE_PROBING,
+ PAGE_NO_DEVICE,
+ PAGE_SETTINGS,
+ PAGE_COUNT
+};
+
+/* sensei-raw-ctl output values. */
+enum
+{
+ OUT_INTENSITY,
+ OUT_PULSATION,
+ OUT_CPI_LED_OFF,
+ OUT_CPI_LED_ON,
+ OUT_POLLING,
+ OUT_COUNT
+};
+
+// ----- User interface -------------------------------------------------------
+
+static void
+fatal (GtkWidget *parent, const gchar *message)
+{
+ GtkWidget *dialog = gtk_message_dialog_new (GTK_WINDOW (parent),
+ GTK_DIALOG_DESTROY_WITH_PARENT,
+ GTK_MESSAGE_ERROR, GTK_BUTTONS_CLOSE, _("Fatal error"));
+ gtk_message_dialog_format_secondary_text
+ (GTK_MESSAGE_DIALOG (dialog), "%s", message);
+ gtk_dialog_run (GTK_DIALOG (dialog));
+ gtk_widget_destroy (dialog);
+ gtk_main_quit ();
+}
+
+static void
+set_page (GtkBuilder *builder, gint page)
+{
+ GtkNotebook *notebook = GTK_NOTEBOOK
+ (gtk_builder_get_object (builder, "notebook"));
+ gtk_notebook_set_current_page (notebook, page);
+}
+
+static gboolean
+spawn_ctl (gchar **argv, gchar **out, GtkBuilder *builder)
+{
+ GError *error = NULL;
+ gint status;
+ gchar *err;
+
+ GtkWidget *win = GTK_WIDGET (gtk_builder_get_object (builder, "win"));
+ if (!g_spawn_sync (NULL, argv, NULL, G_SPAWN_SEARCH_PATH, NULL, NULL,
+ out, &err, &status, &error))
+ {
+ fatal (win, error->message);
+ g_error_free (error);
+ return FALSE;
+ }
+
+ if (WIFEXITED (status) && WEXITSTATUS (status) == 0)
+ return TRUE;
+
+ if (strstr (err, "no suitable device"))
+ set_page (builder, PAGE_NO_DEVICE);
+ else
+ fatal (win, err);
+
+ g_clear_pointer (out, g_free);
+ g_free (err);
+ return FALSE;
+}
+
+static gboolean
+set_combo (GtkComboBox *combo, gchar *list[], const gchar *word)
+{
+ gint i;
+ for (i = 0; list[i]; i++)
+ if (!strcmp (word, list[i]))
+ {
+ gtk_combo_box_set_active (combo, i);
+ return TRUE;
+ }
+ return FALSE;
+}
+
+static gboolean
+set_scale (GtkRange *scale, const gchar *word, const gchar *follows)
+{
+ gchar *end;
+ gint64 value = g_ascii_strtoll (word, &end, 10);
+ if (strcmp (end, follows))
+ return FALSE;
+
+ gtk_range_set_value (scale, value);
+ return TRUE;
+}
+
+static void
+load_configuration (GtkBuilder *builder)
+{
+ gchar *argv[] = { "pkexec",
+ PROJECT_INSTALL_BINDIR "/" PROJECT_NAME, "--show", NULL };
+
+ gchar *out;
+ if (!spawn_ctl (argv, &out, builder))
+ return;
+
+ GRegex *regex = g_regex_new ("(?<=: ).*$", G_REGEX_MULTILINE, 0, NULL);
+ GMatchInfo *info;
+ g_regex_match (regex, out, 0, &info);
+
+ gint line = 0;
+ gchar *word = NULL;
+
+ while (g_match_info_matches (info))
+ {
+ g_free (word);
+ word = g_match_info_fetch (info, 0);
+ switch (line++)
+ {
+ case OUT_INTENSITY:
+ if (!set_combo (GTK_COMBO_BOX (gtk_builder_get_object
+ (builder, "intensity_combo")), intensity_list, word))
+ goto out;
+ break;
+ case OUT_PULSATION:
+ if (!set_combo (GTK_COMBO_BOX (gtk_builder_get_object
+ (builder, "pulsation_combo")), pulsation_list, word))
+ goto out;
+ break;
+ case OUT_CPI_LED_OFF:
+ if (!set_scale (GTK_RANGE (gtk_builder_get_object
+ (builder, "cpi_off_scale")), word, ""))
+ goto out;
+ break;
+ case OUT_CPI_LED_ON:
+ if (!set_scale (GTK_RANGE (gtk_builder_get_object
+ (builder, "cpi_on_scale")), word, ""))
+ goto out;
+ break;
+ case OUT_POLLING:
+ if (!set_scale (GTK_RANGE (gtk_builder_get_object
+ (builder, "polling_scale")), word, "Hz"))
+ goto out;
+ }
+ g_match_info_next (info, NULL);
+ }
+
+ set_page (builder, PAGE_SETTINGS);
+
+out:
+ g_free (word);
+ g_match_info_free (info);
+ g_regex_unref (regex);
+ g_free (out);
+
+ if (line != OUT_COUNT)
+ fatal (GTK_WIDGET (gtk_builder_get_object (builder, "win")),
+ _("Internal error"));
+}
+
+static void
+retry_load (GtkBuilder *builder)
+{
+ set_page (builder, PAGE_PROBING);
+ load_configuration (builder);
+}
+
+static void
+save_configuration (GtkBuilder *builder)
+{
+ gchar *polling = g_strdup_printf ("%.0f", gtk_range_get_value
+ (GTK_RANGE (gtk_builder_get_object (builder, "polling_scale"))));
+ gchar *cpi_on = g_strdup_printf ("%.0f", gtk_range_get_value
+ (GTK_RANGE (gtk_builder_get_object (builder, "cpi_on_scale"))));
+ gchar *cpi_off = g_strdup_printf ("%.0f", gtk_range_get_value
+ (GTK_RANGE (gtk_builder_get_object (builder, "cpi_off_scale"))));
+
+ GtkComboBox *combo;
+ gint active;
+
+ combo = GTK_COMBO_BOX (gtk_builder_get_object (builder, "pulsation_combo"));
+ active = gtk_combo_box_get_active (combo);
+ g_assert (active >= 0 && active < G_N_ELEMENTS (pulsation_list) - 1);
+ gchar *pulsation = pulsation_list[active];
+
+ combo = GTK_COMBO_BOX (gtk_builder_get_object (builder, "intensity_combo"));
+ active = gtk_combo_box_get_active (combo);
+ g_assert (active >= 0 && active < G_N_ELEMENTS (intensity_list) - 1);
+ gchar *intensity = intensity_list[active];
+
+ gchar *argv[] = { "pkexec", PROJECT_INSTALL_BINDIR "/" PROJECT_NAME,
+ "--polling", polling, "--cpi-on", cpi_on, "--cpi-off", cpi_off,
+ "--pulsation", pulsation, "--intensity", intensity, "--save", NULL };
+
+ gchar *out;
+ if (spawn_ctl (argv, &out, builder))
+ g_free (out);
+
+ g_free (polling);
+ g_free (cpi_on);
+ g_free (cpi_off);
+}
+
+static void
+on_set_mode_normal (GtkBuilder *builder)
+{
+ gchar *out, *argv[] = { "pkexec",
+ PROJECT_INSTALL_BINDIR "/" PROJECT_NAME, "--mode", "normal", NULL };
+ if (spawn_ctl (argv, &out, builder))
+ g_free (out);
+}
+
+static void
+on_set_mode_legacy (GtkBuilder *builder)
+{
+ gchar *out, *argv[] = { "pkexec",
+ PROJECT_INSTALL_BINDIR "/" PROJECT_NAME, "--mode", "compat", NULL };
+ if (spawn_ctl (argv, &out, builder))
+ g_free (out);
+}
+
+// ----- User interface -------------------------------------------------------
+
+static gboolean
+on_change_value (GtkRange *range, GtkScrollType scroll, gdouble value,
+ gpointer user_data)
+{
+ GtkAdjustment *adjustment = gtk_range_get_adjustment (range);
+ static const gint steps[] = { 125, 250, 500, 1000 };
+
+ switch (scroll)
+ {
+ gint i;
+ case GTK_SCROLL_NONE:
+ case GTK_SCROLL_JUMP:
+ for (i = 0; i < G_N_ELEMENTS (steps); i++)
+ if (i == G_N_ELEMENTS (steps) - 1 ||
+ value < (steps[i] + steps[i + 1]) / 2)
+ {
+ value = steps[i];
+ break;
+ }
+ break;
+ case GTK_SCROLL_STEP_BACKWARD:
+ case GTK_SCROLL_PAGE_BACKWARD:
+ value = gtk_adjustment_get_value (adjustment);
+ for (i = 0; i < G_N_ELEMENTS (steps) - 1; i++)
+ if (steps[i + 1] >= value)
+ {
+ value = steps[i];
+ break;
+ }
+ break;
+ case GTK_SCROLL_STEP_FORWARD:
+ case GTK_SCROLL_PAGE_FORWARD:
+ value = gtk_adjustment_get_value (adjustment);
+ for (i = 0; i < G_N_ELEMENTS (steps); i++)
+ if (steps[i] > value)
+ {
+ value = steps[i];
+ break;
+ }
+ break;
+ case GTK_SCROLL_START:
+ value = steps[0];
+ break;
+ case GTK_SCROLL_END:
+ value = steps[G_N_ELEMENTS (steps) - 1];
+ break;
+ default:
+ g_assert_not_reached ();
+ }
+
+ gtk_adjustment_set_value (adjustment, value);
+ return TRUE;
+}
+
+static gboolean
+on_change_value_steps (GtkRange *range, GtkScrollType scroll, gdouble value,
+ gpointer user_data)
+{
+ GtkAdjustment *adjustment = gtk_range_get_adjustment (range);
+ gdouble lower = gtk_adjustment_get_lower (adjustment);
+ gdouble step = gtk_adjustment_get_step_increment (adjustment);
+ value = lower + (int) ((value - lower) / step + 0.5) * step;
+ gtk_adjustment_set_value (adjustment, value);
+ return TRUE;
+}
+
+static gchar *
+on_format_value (GtkScale *scale, gdouble value)
+{
+ return g_strdup_printf (_("%gHz"), value);
+}
+
+int
+main (int argc, char *argv[])
+{
+ gtk_init (&argc, &argv);
+ gtk_window_set_default_icon_name (PROJECT_NAME "-gui");
+
+ GError *error = NULL;
+ GtkBuilder *builder = gtk_builder_new ();
+ if (!gtk_builder_add_from_string (builder, ui, -1, &error))
+ {
+ g_printerr ("%s: %s\n", _("Error"), error->message);
+ exit (EXIT_FAILURE);
+ }
+
+ GtkWidget *win = GTK_WIDGET (gtk_builder_get_object (builder, "win"));
+ g_signal_connect (win, "destroy", G_CALLBACK (gtk_main_quit), NULL);
+ g_signal_connect_swapped (win, "map-event",
+ G_CALLBACK (load_configuration), builder);
+ gtk_widget_show_all (win);
+
+ g_signal_connect (gtk_builder_get_object (builder, "polling_scale"),
+ "change-value", G_CALLBACK (on_change_value), NULL);
+ g_signal_connect (gtk_builder_get_object (builder, "polling_scale"),
+ "format-value", G_CALLBACK (on_format_value), NULL);
+
+ g_signal_connect (gtk_builder_get_object (builder, "cpi_off_scale"),
+ "change-value", G_CALLBACK (on_change_value_steps), NULL);
+ g_signal_connect (gtk_builder_get_object (builder, "cpi_on_scale"),
+ "change-value", G_CALLBACK (on_change_value_steps), NULL);
+
+ g_signal_connect_swapped (gtk_builder_get_object (builder, "retry_button"),
+ "clicked", G_CALLBACK (retry_load), builder);
+
+ g_signal_connect_swapped (gtk_builder_get_object (builder, "normal_button"),
+ "clicked", G_CALLBACK (on_set_mode_normal), builder);
+ g_signal_connect_swapped (gtk_builder_get_object (builder, "legacy_button"),
+ "clicked", G_CALLBACK (on_set_mode_legacy), builder);
+ g_signal_connect_swapped (gtk_builder_get_object (builder, "apply_button"),
+ "clicked", G_CALLBACK (save_configuration), builder);
+
+ gtk_main ();
+ g_object_unref (builder);
+ return 0;
+}
+
diff --git a/sensei-raw-ctl-gui.desktop.in b/sensei-raw-ctl-gui.desktop.in
new file mode 100644
index 0000000..202d429
--- /dev/null
+++ b/sensei-raw-ctl-gui.desktop.in
@@ -0,0 +1,8 @@
+[Desktop Entry]
+Type=Application
+Name=${CMAKE_PROJECT_NAME}-gui
+GenericName=SteelSeries Sensei Raw control utility
+Icon=${CMAKE_PROJECT_NAME}-gui
+Exec=${CMAKE_PROJECT_NAME}-gui
+StartupNotify=true
+Categories=Settings;System;Utility;GTK;
diff --git a/sensei-raw-ctl-gui.svg b/sensei-raw-ctl-gui.svg
new file mode 100644
index 0000000..2bb1c26
--- /dev/null
+++ b/sensei-raw-ctl-gui.svg
@@ -0,0 +1,37 @@
+
+
+
diff --git a/sensei-raw-ctl-gui.ui b/sensei-raw-ctl-gui.ui
new file mode 100644
index 0000000..7b6ae27
--- /dev/null
+++ b/sensei-raw-ctl-gui.ui
@@ -0,0 +1,199 @@
+
+
+
+
+
+
+
+
diff --git a/sensei-raw-ctl.c b/sensei-raw-ctl.c
index 8e0c18b..970c31b 100644
--- a/sensei-raw-ctl.c
+++ b/sensei-raw-ctl.c
@@ -86,8 +86,8 @@ out:
#define USB_VENDOR_STEELSERIES 0x1038
#define USB_PRODUCT_STEELSERIES_SENSEI 0x1369
-#define GET_REPORT 0x01
-#define SET_REPORT 0x09
+#define USB_GET_REPORT 0x01
+#define USB_SET_REPORT 0x09
#define SENSEI_CTL_IFACE 0
@@ -108,7 +108,7 @@ enum sensei_pulsation
/* Just guessing the names, could be anything */
enum sensei_mode
{
- MODE_COMPATIBILITY = 1,
+ MODE_LEGACY = 1,
MODE_NORMAL
};
@@ -148,7 +148,7 @@ sensei_send_command (libusb_device_handle *device,
{
int result = libusb_control_transfer (device, LIBUSB_ENDPOINT_OUT
| LIBUSB_REQUEST_TYPE_CLASS | LIBUSB_RECIPIENT_INTERFACE,
- SET_REPORT, 0x0200, 0x0000, data, length, 0);
+ USB_SET_REPORT, 0x0200, 0x0000, data, length, 0);
return result < 0 ? result : 0;
}
@@ -215,7 +215,7 @@ sensei_load_config (libusb_device_handle *device,
int result = libusb_control_transfer (device, LIBUSB_ENDPOINT_IN
| LIBUSB_REQUEST_TYPE_CLASS | LIBUSB_RECIPIENT_INTERFACE,
- GET_REPORT, 0x0300, 0x0000, data, sizeof data, 0);
+ USB_GET_REPORT, 0x0300, 0x0000, data, sizeof data, 0);
if (result < 0)
return result;
@@ -287,7 +287,7 @@ show_usage (const char *program_name)
printf (" --version Show program version and exit\n");
printf (" --show Show current mouse settings and exit\n");
printf (" --mode X Set the mode of the mouse"
- " (can be either 'compat' or 'normal')\n");
+ " (can be either 'legacy' or 'normal')\n");
printf (" --polling X Set polling to X Hz (1000, 500, 250, 125)\n");
printf (" --cpi-on X Set CPI with the LED on to X\n");
printf (" --cpi-off X Set CPI with the LED off to X\n");
@@ -369,8 +369,8 @@ parse_options (int argc, char *argv[],
options->save_to_rom = true;
break;
case 'm':
- if (!strcasecmp (optarg, "compat"))
- new_config->mode = MODE_COMPATIBILITY;
+ if (!strcasecmp (optarg, "legacy"))
+ new_config->mode = MODE_LEGACY;
else if (!strcasecmp (optarg, "normal"))
new_config->mode = MODE_NORMAL;
else
diff --git a/sensei-raw.svg b/sensei-raw.svg
new file mode 100644
index 0000000..238a08d
--- /dev/null
+++ b/sensei-raw.svg
@@ -0,0 +1,37 @@
+
+
+
--
cgit v1.2.3-70-g09d2