summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--configure.ac3
-rw-r--r--data/org.gnome.settings-daemon.peripherals.wacom.gschema.xml.in.in5
-rw-r--r--plugins/wacom/gsd-wacom-manager.c183
3 files changed, 190 insertions, 1 deletions
diff --git a/configure.ac b/configure.ac
index 3bf00831..95608983 100644
--- a/configure.ac
+++ b/configure.ac
@@ -253,7 +253,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])
+ 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
+])
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 721d5304..a10e0699 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
@@ -46,6 +46,11 @@
<_summary>Wacom tablet PC feature</_summary>
<_description>Enable this to only report stylus events when the tip is pressed.</_description>
</key>
+ <key name="last-calibrated-resolution" type="(ii)">
+ <default>(-1, -1)</default>
+ <_summary>Wacom last calibrated resolution</_summary>
+ <_description>Holds the last calibrated resolution to help check if calibration is needed.</_description>
+ </key>
<key name="display" type="as">
<default>["", "", ""]</default>
<_summary>Wacom display mapping</_summary>
diff --git a/plugins/wacom/gsd-wacom-manager.c b/plugins/wacom/gsd-wacom-manager.c
index 86ca454d..8a3a4260 100644
--- a/plugins/wacom/gsd-wacom-manager.c
+++ b/plugins/wacom/gsd-wacom-manager.c
@@ -32,8 +32,10 @@
#include <locale.h>
#include <glib.h>
+#include <glib/gi18n-lib.h>
#include <gtk/gtk.h>
#include <gdk/gdkx.h>
+#include <libnotify/notify.h>
#include <X11/Xatom.h>
#include <X11/extensions/XTest.h>
#include <X11/keysym.h>
@@ -58,6 +60,7 @@
#define KEY_AREA "area"
#define KEY_DISPLAY "display"
#define KEY_KEEP_ASPECT "keep-aspect"
+#define KEY_LAST_CALIBRATED_RESOLUTION "last-calibrated-resolution"
/* Stylus and Eraser settings */
#define KEY_BUTTON_MAPPING "buttonmapping"
@@ -72,6 +75,9 @@
/* See "Wacom Pressure Threshold" */
#define DEFAULT_PRESSURE_THRESHOLD 27
+#define CALIBRATION_NOTIFICATION_TIMEOUT 15000
+#define SHOW_CALIBRATION_TIMEOUT 2000
+
struct GsdWacomManagerPrivate
{
guint start_idle_id;
@@ -87,6 +93,10 @@ struct GsdWacomManagerPrivate
/* Help OSD window */
GtkWidget *osd_window;
+
+ guint notification_timeout_src_id;
+ NotifyNotification *calibration_notification;
+ GsdWacomDevice *calibration_device;
};
static void gsd_wacom_manager_class_init (GsdWacomManagerClass *klass);
@@ -790,6 +800,9 @@ wacom_settings_changed (GSettings *settings,
type != WACOM_TYPE_PAD &&
type != WACOM_TYPE_TOUCH)
set_absolute (device, g_settings_get_boolean (settings, key));
+ } else if (g_str_equal (key, KEY_LAST_CALIBRATED_RESOLUTION)) {
+ /* We do nothing as this is used only for
+ checking whether calibration is needed*/
} else if (g_str_equal (key, KEY_AREA)) {
if (type != WACOM_TYPE_CURSOR &&
type != WACOM_TYPE_PAD &&
@@ -1363,6 +1376,164 @@ gsd_wacom_manager_idle_cb (GsdWacomManager *manager)
return FALSE;
}
+static gboolean
+check_need_for_calibration (GsdWacomManager *manager,
+ GsdWacomDevice *device)
+{
+ GSettings *settings;
+ GVariant *variant;
+ gint width, height;
+ GdkScreen *screen;
+ gint monitor;
+ GdkRectangle geometry;
+
+ width = -1;
+ height = -1;
+
+ screen = gdk_screen_get_default ();
+ monitor = gsd_wacom_device_get_display_monitor (device);
+
+ if (monitor < 0) {
+ geometry.width = gdk_screen_get_width (screen);
+ geometry.height = gdk_screen_get_height (screen);
+ } else {
+ gdk_screen_get_monitor_geometry (screen, monitor, &geometry);
+ }
+
+ settings = gsd_wacom_device_get_settings (device);
+
+ variant = g_settings_get_value (settings, KEY_LAST_CALIBRATED_RESOLUTION);
+
+ g_variant_get (variant, "(ii)", &width, &height);
+
+ g_debug ("Last calibrated resolution: %d, %d", width, height);
+
+ return width == -1 || width != geometry.width ||
+ height == -1 || height != geometry.height;
+}
+
+static void
+remove_notification (GsdWacomManager *manager)
+{
+ g_clear_object (&manager->priv->calibration_notification);
+ manager->priv->calibration_device = NULL;
+}
+
+static void
+on_notification_closed (NotifyNotification *notification,
+ GsdWacomManager *manager)
+{
+ remove_notification (manager);
+}
+
+static void
+on_notification_action (NotifyNotification *notification,
+ gchar *action,
+ gpointer data)
+{
+ gboolean success;
+ gchar *command;
+ const gchar *device_name;
+ GError *error = NULL;
+ GsdWacomManager *manager = GSD_WACOM_MANAGER (data);
+
+ device_name = gsd_wacom_device_get_name (manager->priv->calibration_device);
+
+ if (g_strcmp0 (action, "run-calibration") == 0) {
+ command = g_strdup_printf ("gnome-control-center wacom \"%s\" run-calibration",
+ device_name);
+ success = g_spawn_command_line_async (command, &error);
+ if (!success) {
+ g_warning ("Failure launching gnome-control-center: %s",
+ error->message);
+ g_clear_error (&error);
+ }
+ g_free (command);
+ }
+
+ notify_notification_close (manager->priv->calibration_notification, NULL);
+ remove_notification (manager);
+}
+
+static void
+remove_calibration_notification (GsdWacomManager *manager)
+{
+ GsdWacomManagerPrivate *priv;
+
+ priv = manager->priv;
+
+ if (priv->calibration_notification) {
+ notify_notification_close (priv->calibration_notification, NULL);
+ g_clear_object (&priv->calibration_notification);
+ }
+ if (manager->priv->notification_timeout_src_id > 0) {
+ g_source_remove (manager->priv->notification_timeout_src_id);
+ manager->priv->notification_timeout_src_id = 0;
+ }
+ manager->priv->calibration_device = NULL;
+}
+
+static gboolean
+notify_need_for_calibration_real (gpointer data)
+{
+ GsdWacomManager *manager = GSD_WACOM_MANAGER (data);
+ GsdWacomManagerPrivate *priv;
+ gchar *msg_body = NULL;
+
+ priv = manager->priv;
+
+ if (priv->calibration_notification) {
+ notify_notification_close (priv->calibration_notification, NULL);
+ g_clear_object (&priv->calibration_notification);
+ }
+ msg_body = g_strdup_printf (_("Tablet %s needs to be calibrated."),
+ gsd_wacom_device_get_name (priv->calibration_device));
+ priv->calibration_notification = notify_notification_new (_("Calibration needed"),
+ msg_body,
+ NULL);
+
+ notify_notification_set_app_name (priv->calibration_notification,
+ _("Wacom Settings"));
+ notify_notification_set_timeout (priv->calibration_notification,
+ CALIBRATION_NOTIFICATION_TIMEOUT);
+ notify_notification_set_urgency (priv->calibration_notification,
+ NOTIFY_URGENCY_NORMAL);
+ /* TRANSLATORS: launches the calibration screen for the
+ tablet in question */
+ notify_notification_add_action (priv->calibration_notification,
+ "run-calibration",
+ _("Calibrate"),
+ on_notification_action,
+ manager,
+ NULL);
+
+ g_signal_connect (priv->calibration_notification,
+ "closed",
+ G_CALLBACK (on_notification_closed),
+ manager);
+
+ notify_notification_show (priv->calibration_notification, NULL);
+
+ priv->notification_timeout_src_id = 0;
+ g_free (msg_body);
+ return FALSE;
+}
+
+/* We need to have the notifications being shown from a
+ * timeout function since when the monitor's size changes
+ * we may get several calls to on_screen_changed_cb and
+ * in the first call, the monitor's size is still not updated.
+ */
+static void
+notify_need_for_calibration (GsdWacomManager *manager,
+ GsdWacomDevice *device)
+{
+ manager->priv->calibration_device = device;
+ manager->priv->notification_timeout_src_id = g_timeout_add (SHOW_CALIBRATION_TIMEOUT,
+ notify_need_for_calibration_real,
+ manager);
+}
+
/*
* The monitors-changed signal is emitted when the number, size or
* position of the monitors attached to the screen change.
@@ -1397,6 +1568,14 @@ on_screen_changed_cb (GnomeRRScreen *rr_screen,
if (type != WACOM_TYPE_TOUCH) {
if (gsd_wacom_device_is_screen_tablet (device) == FALSE)
set_keep_aspect (device, g_settings_get_boolean (settings, KEY_KEEP_ASPECT));
+ else if (type == WACOM_TYPE_STYLUS) {
+ remove_calibration_notification (manager);
+ if (check_need_for_calibration (manager, device)) {
+ notify_need_for_calibration (manager,
+ device);
+ }
+ }
+
set_area (device, g_settings_get_value (settings, KEY_AREA));
}
set_display (device, g_settings_get_value (settings, KEY_DISPLAY));
@@ -1524,6 +1703,10 @@ gsd_wacom_manager_finalize (GObject *object)
if (wacom_manager->priv->start_idle_id != 0)
g_source_remove (wacom_manager->priv->start_idle_id);
+ if (wacom_manager->priv->notification_timeout_src_id != 0)
+ g_source_remove (wacom_manager->priv->notification_timeout_src_id);
+ remove_notification (wacom_manager);
+
G_OBJECT_CLASS (gsd_wacom_manager_parent_class)->finalize (object);
}