[gnome-settings-daemon] wacom: Add OLED handling for Intuos4
- From: Bastien Nocera <hadess src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-settings-daemon] wacom: Add OLED handling for Intuos4
- Date: Fri, 17 May 2013 07:40:05 +0000 (UTC)
commit a6ed61b72b11cfbdfdcf5faeac49f40abbbf983c
Author: Przemo Firszt <przemo firszt eu>
Date: Tue Oct 2 20:35:06 2012 +0100
wacom: Add OLED handling for Intuos4
https://bugzilla.gnome.org/show_bug.cgi?id=671072
configure.ac | 5 +-
...ings-daemon.peripherals.wacom.gschema.xml.in.in | 5 +
plugins/wacom/Makefile.am | 17 ++-
plugins/wacom/gsd-wacom-device.c | 37 +++-
plugins/wacom/gsd-wacom-device.h | 1 +
plugins/wacom/gsd-wacom-manager.c | 42 ++++-
plugins/wacom/gsd-wacom-oled-helper.c | 183 +++++++++++++++
plugins/wacom/gsd-wacom-oled.c | 232 ++++++++++++++++++++
plugins/wacom/gsd-wacom-oled.h | 38 ++++
...nome.settings-daemon.plugins.wacom.policy.in.in | 15 ++
10 files changed, 556 insertions(+), 19 deletions(-)
---
diff --git a/configure.ac b/configure.ac
index 9560898..af8b3e3 100644
--- a/configure.ac
+++ b/configure.ac
@@ -53,6 +53,7 @@ UPOWER_GLIB_REQUIRED_VERSION=0.9.1
PA_REQUIRED_VERSION=2.0
LIBWACOM_REQUIRED_VERSION=0.7
LIBRSVG_REQUIRED_VERSION=2.36.2
+PANGO_REQUIRED_VERSION=1.20.0
UPOWER_REQUIRED_VERSION=0.9.11
IBUS_REQUIRED_VERSION=1.4.99
GSETTINGS_DESKTOP_SCHEMAS_REQUIRED_VERSION=3.7.2.1
@@ -253,8 +254,8 @@ case $host_os in
have_wacom=no
else
if test x$enable_gudev != xno; then
- PKG_CHECK_MODULES(WACOM, [libwacom >= $LIBWACOM_REQUIRED_VERSION x11 xi xtst gudev-1.0
gnome-desktop-3.0 >= $GNOME_DESKTOP_REQUIRED_VERSION xorg-wacom librsvg-2.0 >= $LIBRSVG_REQUIRED_VERSION
libnotify >= $LIBNOTIFY_REQUIRED_VERSION
-])
+ PKG_CHECK_MODULES(WACOM, [libwacom >= $LIBWACOM_REQUIRED_VERSION x11 xi xtst gudev-1.0
gnome-desktop-3.0 >= $GNOME_DESKTOP_REQUIRED_VERSION xorg-wacom librsvg-2.0 >= $LIBRSVG_REQUIRED_VERSION
libnotify >= $LIBNOTIFY_REQUIRED_VERSION pango >= $PANGO_REQUIRED_VERSION])
+ PKG_CHECK_MODULES(WACOM_OLED, [gudev-1.0])
else
AC_MSG_ERROR([GUdev is necessary to compile Wacom support])
fi
diff --git a/data/org.gnome.settings-daemon.peripherals.wacom.gschema.xml.in.in
b/data/org.gnome.settings-daemon.peripherals.wacom.gschema.xml.in.in
index a10e069..676bb9d 100644
--- a/data/org.gnome.settings-daemon.peripherals.wacom.gschema.xml.in.in
+++ b/data/org.gnome.settings-daemon.peripherals.wacom.gschema.xml.in.in
@@ -107,5 +107,10 @@
<_summary>Key combinations for a touchring or touchstrip custom action</_summary>
<_description>The keyboard shortcuts generated when a touchring or touchstrip is used for custom
actions (up followed by down).</_description>
</key>
+ <key name="oled-label" type="s">
+ <default>''</default>
+ <_summary>Button label for OLED display.</_summary>
+ <_description>Label will be rendered to OLED display belonging to the button</_description>
+ </key>
</schema>
</schemalist>
diff --git a/plugins/wacom/Makefile.am b/plugins/wacom/Makefile.am
index 2bc050c..817db69 100644
--- a/plugins/wacom/Makefile.am
+++ b/plugins/wacom/Makefile.am
@@ -8,6 +8,8 @@ libgsdwacom_la_SOURCES = \
gsd-wacom-manager.c \
gsd-wacom-osd-window.h \
gsd-wacom-osd-window.c \
+ gsd-wacom-oled.h \
+ gsd-wacom-oled.c \
gsd-wacom-device.c \
gsd-wacom-device.h \
gsd-wacom-resources.c
@@ -52,18 +54,27 @@ polkit_policy_DATA = $(polkit_policy_in_files:.policy.in=.policy)
# so it always gets included in the tarball
gsd_wacom_led_helper_SOURCES = gsd-wacom-led-helper.c
+gsd_wacom_oled_helper_SOURCES = gsd-wacom-oled-helper.c
-EXTRA_DIST = $(gsd_wacom_led_helper_SOURCES) wacom.gresource.xml tablet-layout.css
+EXTRA_DIST = $(gsd_wacom_led_helper_SOURCES) wacom.gresource.xml tablet-layout.css \
+ $(gsd_wacom_oled_helper_SOURCES)
if HAVE_GUDEV
-libexec_PROGRAMS = gsd-wacom-led-helper
+libexec_PROGRAMS = gsd-wacom-led-helper gsd-wacom-oled-helper
gsd_wacom_led_helper_LDFLAGS = \
$(BACKLIGHT_HELPER_LIBS) \
-lm
+gsd_wacom_oled_helper_LDFLAGS = \
+ $(WACOM_OLED_LIBS) \
+ -lm
+
gsd_wacom_led_helper_CFLAGS = \
$(BACKLIGHT_HELPER_CFLAGS)
+
+gsd_wacom_oled_helper_CFLAGS = \
+ $(WACOM_OLED_CFLAGS)
else
libexec_PROGRAMS =
endif
@@ -78,6 +89,8 @@ gsd_test_wacom_SOURCES = \
gsd-wacom-manager.h \
gsd-wacom-osd-window.h \
gsd-wacom-osd-window.c \
+ gsd-wacom-oled.h \
+ gsd-wacom-oled.c \
gsd-wacom-device.c \
gsd-wacom-device.h \
gsd-wacom-resources.c
diff --git a/plugins/wacom/gsd-wacom-device.c b/plugins/wacom/gsd-wacom-device.c
index bd58a78..e90371a 100644
--- a/plugins/wacom/gsd-wacom-device.c
+++ b/plugins/wacom/gsd-wacom-device.c
@@ -258,7 +258,8 @@ gsd_wacom_tablet_button_new (const char *name,
GsdWacomTabletButtonPos pos,
int group_id,
int idx,
- int status_led)
+ int status_led,
+ int has_oled)
{
GsdWacomTabletButton *ret;
@@ -277,6 +278,7 @@ gsd_wacom_tablet_button_new (const char *name,
ret->type = type;
ret->pos = pos;
ret->status_led = status_led;
+ ret->has_oled = has_oled;
return ret;
}
@@ -1080,7 +1082,8 @@ gsd_wacom_device_add_ring_modes (WacomDevice *wacom_device,
WACOM_TABLET_BUTTON_POS_LEFT,
group,
0,
- GSD_WACOM_NO_LED));
+ GSD_WACOM_NO_LED,
+ 0));
} else {
for (i = 1; i <= num_modes; i++) {
name = g_strdup_printf (_("Left Ring Mode #%d"), i);
@@ -1092,7 +1095,8 @@ gsd_wacom_device_add_ring_modes (WacomDevice *wacom_device,
WACOM_TABLET_BUTTON_POS_LEFT,
group,
i - 1,
- GSD_WACOM_NO_LED));
+ GSD_WACOM_NO_LED,
+ 0));
g_free (name);
g_free (id);
}
@@ -1109,7 +1113,8 @@ gsd_wacom_device_add_ring_modes (WacomDevice *wacom_device,
WACOM_TABLET_BUTTON_POS_RIGHT,
group,
0,
- GSD_WACOM_NO_LED));
+ GSD_WACOM_NO_LED,
+ 0));
} else {
for (i = 1; i <= num_modes; i++) {
name = g_strdup_printf (_("Right Ring Mode #%d"), i);
@@ -1121,7 +1126,8 @@ gsd_wacom_device_add_ring_modes (WacomDevice *wacom_device,
WACOM_TABLET_BUTTON_POS_RIGHT,
group,
i - 1,
- GSD_WACOM_NO_LED));
+ GSD_WACOM_NO_LED,
+ 0));
g_free (name);
g_free (id);
}
@@ -1160,7 +1166,8 @@ gsd_wacom_device_add_strip_modes (WacomDevice *wacom_device,
WACOM_TABLET_BUTTON_POS_LEFT,
group,
0,
- GSD_WACOM_NO_LED));
+ GSD_WACOM_NO_LED,
+ 0));
} else {
for (i = 1; i <= num_modes; i++) {
name = g_strdup_printf (_("Left Touchstrip Mode #%d"), i);
@@ -1172,7 +1179,8 @@ gsd_wacom_device_add_strip_modes (WacomDevice *wacom_device,
WACOM_TABLET_BUTTON_POS_LEFT,
group,
i - 1,
- GSD_WACOM_NO_LED));
+ GSD_WACOM_NO_LED,
+ 0));
g_free (name);
g_free (id);
}
@@ -1189,7 +1197,8 @@ gsd_wacom_device_add_strip_modes (WacomDevice *wacom_device,
WACOM_TABLET_BUTTON_POS_RIGHT,
group,
0,
- GSD_WACOM_NO_LED));
+ GSD_WACOM_NO_LED,
+ 0));
} else {
for (i = 1; i <= num_modes; i++) {
name = g_strdup_printf (_("Right Touchstrip Mode #%d"), i);
@@ -1201,7 +1210,8 @@ gsd_wacom_device_add_strip_modes (WacomDevice *wacom_device,
WACOM_TABLET_BUTTON_POS_RIGHT,
group,
i - 1,
- GSD_WACOM_NO_LED));
+ GSD_WACOM_NO_LED,
+ 0));
g_free (name);
g_free (id);
}
@@ -1259,6 +1269,7 @@ gsd_wacom_device_add_buttons_dir (WacomDevice *wacom_device,
GList *l;
guint num_buttons, i, button_num;
char *name, *id;
+ gboolean has_oled;
l = NULL;
button_num = 1;
@@ -1275,6 +1286,8 @@ gsd_wacom_device_add_buttons_dir (WacomDevice *wacom_device,
name = g_strdup_printf (button_str, button_num++);
id = g_strdup_printf ("%s%c", button_str_id, i);
+ if (libwacom_get_button_flag (wacom_device, i) & WACOM_BUTTON_OLED)
+ has_oled = TRUE;
l = g_list_append (l, gsd_wacom_tablet_button_new (name,
id,
settings_path,
@@ -1282,7 +1295,8 @@ gsd_wacom_device_add_buttons_dir (WacomDevice *wacom_device,
gsd_wacom_device_button_pos (flags),
flags_to_group (flags),
-1,
- GSD_WACOM_NO_LED));
+ GSD_WACOM_NO_LED,
+ has_oled));
g_free (name);
g_free (id);
}
@@ -1310,7 +1324,8 @@ gsd_wacom_device_add_buttons_dir (WacomDevice *wacom_device,
gsd_wacom_device_button_pos (flags),
flags_to_group (flags),
-1,
- status_led));
+ status_led,
+ FALSE));
g_free (name);
g_free (id);
}
diff --git a/plugins/wacom/gsd-wacom-device.h b/plugins/wacom/gsd-wacom-device.h
index 335945f..3657e88 100644
--- a/plugins/wacom/gsd-wacom-device.h
+++ b/plugins/wacom/gsd-wacom-device.h
@@ -123,6 +123,7 @@ typedef struct
GsdWacomTabletButtonPos pos;
int group_id, idx;
int status_led;
+ int has_oled;
} GsdWacomTabletButton;
void gsd_wacom_tablet_button_free (GsdWacomTabletButton *button);
diff --git a/plugins/wacom/gsd-wacom-manager.c b/plugins/wacom/gsd-wacom-manager.c
index 8a3a426..51fa57c 100644
--- a/plugins/wacom/gsd-wacom-manager.c
+++ b/plugins/wacom/gsd-wacom-manager.c
@@ -49,6 +49,7 @@
#include "gnome-settings-profile.h"
#include "gsd-wacom-manager.h"
#include "gsd-wacom-device.h"
+#include "gsd-wacom-oled.h"
#include "gsd-wacom-osd-window.h"
#define GSD_WACOM_MANAGER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GSD_TYPE_WACOM_MANAGER,
GsdWacomManagerPrivate))
@@ -68,9 +69,10 @@
#define KEY_PRESSURECURVE "pressurecurve"
/* Button settings */
-#define KEY_ACTION_TYPE "action-type"
-#define KEY_CUSTOM_ACTION "custom-action"
+#define KEY_ACTION_TYPE "action-type"
+#define KEY_CUSTOM_ACTION "custom-action"
#define KEY_CUSTOM_ELEVATOR_ACTION "custom-elevator-action"
+#define OLED_LABEL "oled-label"
/* See "Wacom Pressure Threshold" */
#define DEFAULT_PRESSURE_THRESHOLD 27
@@ -701,7 +703,7 @@ reset_pad_buttons (GsdWacomDevice *device)
XCloseDevice (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), xdev);
- /* Reset all the LEDs */
+ /* Reset all the LEDs and OLEDs*/
buttons = gsd_wacom_device_get_buttons (device);
for (l = buttons; l != NULL; l = l->next) {
GsdWacomTabletButton *button = l->data;
@@ -709,16 +711,36 @@ reset_pad_buttons (GsdWacomDevice *device)
button->status_led != GSD_WACOM_NO_LED) {
set_led (device, button, 1);
}
- }
+ if (button->has_oled) {
+ char *label;
+ label = g_settings_get_string (button->settings, OLED_LABEL);
+ set_oled (device, button->id, label);
+ g_free (label);
+ }
+ }
g_list_free (buttons);
}
static void
+gsettings_oled_changed (GSettings *settings,
+ gchar *key,
+ GsdWacomTabletButton *button)
+{
+ GsdWacomDevice *device;
+ char *label;
+
+ label = g_settings_get_string (settings, OLED_LABEL);
+ device = g_object_get_data (G_OBJECT (button->settings), "parent-device");
+ set_oled (device, button->id, label);
+}
+
+static void
set_wacom_settings (GsdWacomManager *manager,
GsdWacomDevice *device)
{
GsdWacomDeviceType type;
GSettings *settings;
+ GList *buttons, *l;
g_debug ("Applying settings for device '%s' (type: %s)",
gsd_wacom_device_get_tool_name (device),
@@ -756,6 +778,18 @@ set_wacom_settings (GsdWacomManager *manager,
id = get_device_id (device);
reset_pad_buttons (device);
grab_button (id, TRUE, manager->priv->screen);
+
+ buttons = gsd_wacom_device_get_buttons (device);
+ for (l = buttons; l != NULL; l = l->next) {
+ GsdWacomTabletButton *button = l->data;
+ if (button->has_oled) {
+ g_signal_connect (G_OBJECT (button->settings), "changed::oled-label",
+ G_CALLBACK (gsettings_oled_changed), button);
+ g_object_set_data (G_OBJECT (button->settings), "parent-device", device);
+ }
+ }
+ g_list_free (buttons);
+
return;
}
diff --git a/plugins/wacom/gsd-wacom-oled-helper.c b/plugins/wacom/gsd-wacom-oled-helper.c
new file mode 100644
index 0000000..ea15264
--- /dev/null
+++ b/plugins/wacom/gsd-wacom-oled-helper.c
@@ -0,0 +1,183 @@
+/*
+ * Copyright (C) 2012 Przemo Firszt <przemo firszt eu>
+ *
+ * The code is derived from gsd-wacom-led-helper.c
+ * written by:
+ * Copyright (C) 2010-2011 Richard Hughes <richard hughsie com>
+ * Copyright (C) 2012 Bastien Nocera <hadess hadess net>
+ *
+ * Licensed under the GNU General Public License Version 2
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+#include <unistd.h>
+
+#include <stdlib.h>
+#include "config.h"
+
+#include <glib.h>
+#include <locale.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <gudev/gudev.h>
+
+static gboolean
+gsd_wacom_oled_helper_write (const gchar *filename, gchar *buffer, GError **error)
+{
+ guchar *image;
+ gint retval;
+ gsize length;
+ gint fd = -1;
+ gboolean ret = TRUE;
+
+ fd = open (filename, O_WRONLY);
+ if (fd < 0) {
+ ret = FALSE;
+ g_set_error (error, 1, 0, "failed to open filename: %s", filename);
+ goto out;
+ }
+
+ image = g_base64_decode (buffer, &length);
+ if (!image)
+ goto out;
+
+ /* write to device file */
+ retval = write (fd, image, length);
+ if (retval != length) {
+ ret = FALSE;
+ g_set_error (error, 1, 0, "writing to %s failed", filename);
+ goto out;
+ }
+out:
+ if (fd >= 0)
+ close (fd);
+ g_free (image);
+ return ret;
+}
+
+static char *
+get_oled_sysfs_path (GUdevDevice *device,
+ int button_num)
+{
+ char *status;
+ char *filename;
+
+ status = g_strdup_printf ("button%d_rawimg", button_num);
+ filename = g_build_filename (g_udev_device_get_sysfs_path (device), "wacom_led", status, NULL);
+ g_free (status);
+
+ return filename;
+}
+
+static char *path = NULL;
+static char *buffer = "";
+static int button_num = -1;
+
+const GOptionEntry options[] = {
+ { "path", '\0', 0, G_OPTION_ARG_FILENAME, &path, "Device path for the Wacom device", NULL },
+ { "buffer", '\0', 0, G_OPTION_ARG_STRING, &buffer, "Image to set base64 encoded", NULL },
+ { "button", '\0', 0, G_OPTION_ARG_INT, &button_num, "Which button icon to set", NULL },
+ { NULL}
+};
+
+
+int main (int argc, char **argv)
+{
+ GOptionContext *context;
+ GUdevClient *client;
+ GUdevDevice *device, *parent;
+ int uid, euid;
+ char *filename;
+ GError *error = NULL;
+ const char * const subsystems[] = { "input", NULL };
+
+ /* get calling process */
+ uid = getuid ();
+ euid = geteuid ();
+ if (uid != 0 || euid != 0) {
+ g_print ("This program can only be used by the root user\n");
+ return 1;
+ }
+
+ context = g_option_context_new (NULL);
+ g_option_context_set_summary (context, "GNOME Settings Daemon Wacom OLED Icon Helper");
+ g_option_context_add_main_entries (context, options, NULL);
+ g_option_context_parse (context, &argc, &argv, NULL);
+
+ if (path == NULL ||
+ button_num < 0) {
+ char *txt;
+
+ txt = g_option_context_get_help (context, FALSE, NULL);
+ g_print ("%s", txt);
+ g_free (txt);
+
+ g_option_context_free (context);
+
+ return 1;
+ }
+ g_option_context_free (context);
+
+ client = g_udev_client_new (subsystems);
+ device = g_udev_client_query_by_device_file (client, path);
+ if (device == NULL) {
+ g_debug ("Could not find device '%s' in udev database", path);
+ goto bail;
+ }
+
+ if (g_udev_device_get_property_as_boolean (device, "ID_INPUT_TABLET") == FALSE &&
+ g_udev_device_get_property_as_boolean (device, "ID_INPUT_TOUCHPAD") == FALSE) {
+ g_debug ("Device '%s' is not a Wacom tablet", path);
+ goto bail;
+ }
+
+ if (g_strcmp0 (g_udev_device_get_property (device, "ID_BUS"), "usb") != 0) {
+ /* FIXME handle Bluetooth OLEDs too */
+ g_debug ("Non-USB OLEDs setting is not (yet) supported");
+ goto bail;
+ }
+
+ parent = g_udev_device_get_parent_with_subsystem (device, "usb", "usb_interface");
+ if (parent == NULL) {
+ g_debug ("Could not find parent USB device for '%s'", path);
+ goto bail;
+ }
+ g_object_unref (device);
+ device = parent;
+
+ filename = get_oled_sysfs_path (device, button_num);
+ if (gsd_wacom_oled_helper_write (filename, buffer, &error) == FALSE) {
+ g_debug ("Could not set OLED icon for '%s': %s", path, error->message);
+ g_error_free (error);
+ g_free (filename);
+ goto bail;
+ }
+ g_free (filename);
+
+ g_debug ("Successfully set OLED icon for '%s', button %d", path, button_num);
+
+ g_object_unref (device);
+ g_object_unref (client);
+
+ return 0;
+
+bail:
+ if (device != NULL)
+ g_object_unref (device);
+ if (client != NULL)
+ g_object_unref (client);
+ return 1;
+}
diff --git a/plugins/wacom/gsd-wacom-oled.c b/plugins/wacom/gsd-wacom-oled.c
new file mode 100644
index 0000000..bdc2bcd
--- /dev/null
+++ b/plugins/wacom/gsd-wacom-oled.c
@@ -0,0 +1,232 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2013 Przemo Firszt <przemo firszt eu>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ */
+
+#include <unistd.h>
+#include <math.h>
+#include <pango/pango.h>
+#include <pango/pangocairo.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <libwacom/libwacom.h>
+
+#include <gtk/gtk.h>
+#include "gsd-wacom-device.h"
+#include "gsd-wacom-oled.h"
+
+static void
+oled_scramble_icon (guchar* image)
+{
+ unsigned char buf[MAX_IMAGE_SIZE];
+ int x, y, i;
+ unsigned char l1, l2, h1, h2;
+
+ for (i = 0; i < MAX_IMAGE_SIZE; i++)
+ buf[i] = image[i];
+
+ for (y = 0; y < (OLED_HEIGHT / 2); y++) {
+ for (x = 0; x < (OLED_WIDTH / 2); x++) {
+ l1 = (0x0F & (buf[OLED_HEIGHT - 1 - x + OLED_WIDTH * y]));
+ l2 = (0x0F & (buf[OLED_HEIGHT - 1 - x + OLED_WIDTH * y] >> 4));
+ h1 = (0xF0 & (buf[OLED_WIDTH - 1 - x + OLED_WIDTH * y] << 4));
+ h2 = (0xF0 & (buf[OLED_WIDTH - 1 - x + OLED_WIDTH * y]));
+
+ image[2 * x + OLED_WIDTH * y] = h1 | l1;
+ image[2 * x + 1 + OLED_WIDTH * y] = h2 | l2;
+ }
+ }
+}
+
+static void
+oled_surface_to_image (guchar *image,
+ cairo_surface_t *surface)
+{
+ unsigned char *csurf;
+ int i, x, y;
+ unsigned char lo, hi;
+
+ cairo_surface_flush (surface);
+ csurf = cairo_image_surface_get_data (surface);
+ i = 0;
+ for (y = 0; y < OLED_HEIGHT; y++) {
+ for (x = 0; x < (OLED_WIDTH / 2); x++) {
+ hi = 0xf0 & csurf[4 * OLED_WIDTH * y + 8 * x + 1];
+ lo = 0x0f & (csurf[4 * OLED_WIDTH * y + 8 * x + 5] >> 4);
+ image[i] = hi | lo;
+ i++;
+ }
+ }
+}
+
+static void
+oled_split_text (char *label,
+ char *line1,
+ char *line2)
+{
+ char delimiters[5] = "+-_ ";
+ char **token;
+ int token_len[MAX_TOKEN];
+ gsize length;
+ int i;
+
+ if (g_utf8_strlen (label, LABEL_SIZE) <= MAX_1ST_LINE_LEN) {
+ g_utf8_strncpy (line1, label, MAX_1ST_LINE_LEN);
+ return;
+ }
+
+ token = g_strsplit_set (label, delimiters, -1);
+
+ if (g_utf8_strlen (token[0], LABEL_SIZE) > MAX_1ST_LINE_LEN) {
+ g_utf8_strncpy (line1, label, MAX_1ST_LINE_LEN);
+ g_utf8_strncpy (line2, label + MAX_1ST_LINE_LEN, LABEL_SIZE - MAX_1ST_LINE_LEN);
+ return;
+ }
+
+ for (i = 0; token[i] != NULL; i++)
+ token_len[i] = g_utf8_strlen (token[i], LABEL_SIZE);
+
+ length = token_len[0];
+ i = 0;
+ while ((length + token_len[i + 1] + 1) <= MAX_1ST_LINE_LEN) {
+ i++;
+ length = length + token_len[i] + 1;
+ }
+
+ g_utf8_strncpy (line1, label, length);
+ g_utf8_strncpy (line2, label + length + 1, LABEL_SIZE - length);
+
+ return;
+}
+
+static void
+oled_render_text (char *label,
+ guchar *image)
+{
+ cairo_t *cr;
+ cairo_surface_t *surface;
+ PangoFontDescription *desc;
+ PangoLayout *layout;
+ int width, height;
+ double dx, dy;
+ char line1[LABEL_SIZE + 1] = "";
+ char line2[LABEL_SIZE + 1] = "";
+ char *buf;
+
+ oled_split_text (label ,line1, line2);
+
+ buf = g_strdup_printf ("%s\n%s", line1, line2);
+
+ surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, OLED_WIDTH, OLED_HEIGHT);
+ cr = cairo_create (surface);
+ cairo_set_source_rgba (cr, 0.0, 0.0, 0.0, 0.99);
+ cairo_paint (cr);
+
+ layout = pango_cairo_create_layout (cr);
+ pango_layout_set_alignment (layout, PANGO_ALIGN_CENTER);
+ pango_layout_set_text (layout, buf, - 1);
+ g_free (buf);
+ desc = pango_font_description_new ();
+
+ pango_font_description_set_family (desc, "Terminal");
+ pango_font_description_set_absolute_size (desc, PANGO_SCALE * 11);
+ pango_layout_set_font_description (layout, desc);
+ pango_font_description_free (desc);
+ pango_layout_get_size (layout, &width, &height);
+ width = width/PANGO_SCALE;
+ cairo_new_path (cr);
+
+ dx = trunc (((double)OLED_WIDTH - width) / 2);
+
+ if (*line2 == '\0')
+ dy = 10;
+ else
+ dy = 4;
+
+ cairo_move_to (cr, dx, dy);
+ cairo_set_source_rgba (cr, 1.0, 1.0, 1.0, 1.0);
+ pango_cairo_update_layout (cr, layout);
+
+ pango_cairo_layout_path (cr, layout);
+ cairo_fill (cr);
+
+ oled_surface_to_image (image, surface);
+
+ g_object_unref (layout);
+ cairo_destroy (cr);
+
+ cairo_surface_destroy (surface);
+}
+
+static char *
+oled_encode_image (char *label)
+{
+ guchar *image;
+
+ image = g_malloc (MAX_IMAGE_SIZE);
+
+ /* convert label to image */
+ oled_render_text (label, image);
+ oled_scramble_icon (image);
+
+ return (g_base64_encode (image, MAX_IMAGE_SIZE));
+}
+
+void
+set_oled (GsdWacomDevice *device,
+ char *button_id,
+ char *label)
+{
+ GError *error = NULL;
+ const char *path;
+ char *command;
+ gboolean ret;
+ char *buffer;
+
+#ifndef HAVE_GUDEV
+ /* Not implemented on non-Linux systems */
+ return;
+#endif
+
+ char *button_id_1;
+ int button_id_short;
+ button_id_1 = g_strdup (button_id);
+ button_id_short = (int)button_id_1[6];
+ button_id_short = button_id_short - 'A' - 1;
+ buffer = oled_encode_image (label);
+
+ path = gsd_wacom_device_get_path (device);
+
+ g_debug ("Setting OLED label '%s' on button %d (device %s)", label, button_id_short, path);
+
+ command = g_strdup_printf ("pkexec " LIBEXECDIR "/gsd-wacom-oled-helper --path %s --button %d
--buffer %s",
+ path, button_id_short, buffer);
+ ret = g_spawn_command_line_sync (command,
+ NULL,
+ NULL,
+ NULL,
+ &error);
+
+ if (ret == FALSE) {
+ g_debug ("Failed to launch '%s': %s", command, error->message);
+ g_error_free (error);
+ }
+
+ g_free (command);
+}
diff --git a/plugins/wacom/gsd-wacom-oled.h b/plugins/wacom/gsd-wacom-oled.h
new file mode 100644
index 0000000..1cdaf65
--- /dev/null
+++ b/plugins/wacom/gsd-wacom-oled.h
@@ -0,0 +1,38 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2013 Przemo Firszt <przemo firszt eu>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ */
+
+#ifndef __GSD_WACOM_OLED_H
+#define __GSD_WACOM_OLED_H
+
+G_BEGIN_DECLS
+
+/* OLED parameters */
+#define OLED_WIDTH 64 /*Width of OLED icon - hardware dependent*/
+#define OLED_HEIGHT 32 /*Height of OLED icon - hardware dependent*/
+#define LABEL_SIZE 30 /*Maximum length of text for OLED icon*/
+#define MAX_TOKEN (LABEL_SIZE >> 1) /*Maximum number of tokens equals half of maximum
number of characters*/
+#define MAX_IMAGE_SIZE 1024 /*Size of buffer for storing OLED image*/
+#define MAX_1ST_LINE_LEN 10 /*Maximum number of characters in 1st line of OLED
icon*/
+
+void set_oled (GsdWacomDevice *device, char *button_id, char *label);
+
+G_END_DECLS
+
+#endif /* __GSD_WACOM_OLED_H */
diff --git a/plugins/wacom/org.gnome.settings-daemon.plugins.wacom.policy.in.in
b/plugins/wacom/org.gnome.settings-daemon.plugins.wacom.policy.in.in
index 9821827..6bf77dd 100644
--- a/plugins/wacom/org.gnome.settings-daemon.plugins.wacom.policy.in.in
+++ b/plugins/wacom/org.gnome.settings-daemon.plugins.wacom.policy.in.in
@@ -27,5 +27,20 @@
<annotate key="org.freedesktop.policykit.exec.path">@libexecdir@/gsd-wacom-led-helper</annotate>
</action>
+ <action id="org.gnome.settings-daemon.plugins.wacom.wacom-oled-helper">
+ <!-- SECURITY:
+ - A normal active user on the local machine does not need permission
+ to change the OLED images for a Wacom tablet
+ -->
+ <_description>Modify the OLED image for a Wacom tablet</_description>
+ <_message>Authentication is required to modify the OLED image for a Wacom tablet</_message>
+ <defaults>
+ <allow_any>no</allow_any>
+ <allow_inactive>no</allow_inactive>
+ <allow_active>yes</allow_active>
+ </defaults>
+ <annotate key="org.freedesktop.policykit.exec.path">@libexecdir@/gsd-wacom-oled-helper</annotate>
+ </action>
+
</policyconfig>
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]