[gnome-control-center] wacom: Bring over files from xinput-calibrator and build utility
- From: Bastien Nocera <hadess src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-control-center] wacom: Bring over files from xinput-calibrator and build utility
- Date: Tue, 10 Jan 2012 19:24:57 +0000 (UTC)
commit e50dbea1953b24e2f3b5de137b339d31784f0dc7
Author: Jason Gerecke <killertofu gmail com>
Date: Tue Jan 3 12:39:06 2012 -0800
wacom: Bring over files from xinput-calibrator and build utility
Copies over files from a trimmed version of xinput-calibrator and
modifies the Makefile.am to build the program as a seperate utility.
This is just to verify the functionality of the code when built with
gnome-control-center.
https://bugzilla.gnome.org/show_bug.cgi?id=657423
configure.ac | 1 +
panels/wacom/Makefile.am | 7 +-
panels/wacom/calibrator/Makefile.am | 38 +++
panels/wacom/calibrator/calibrator.c | 177 +++++++++++++++
panels/wacom/calibrator/calibrator.h | 119 ++++++++++
panels/wacom/calibrator/gui_gtk.c | 411 ++++++++++++++++++++++++++++++++++
panels/wacom/calibrator/gui_gtk.h | 68 ++++++
panels/wacom/calibrator/main.c | 398 ++++++++++++++++++++++++++++++++
panels/wacom/calibrator/main.h | 57 +++++
9 files changed, 1274 insertions(+), 2 deletions(-)
---
diff --git a/configure.ac b/configure.ac
index 1d7ac0d..d8cf527 100644
--- a/configure.ac
+++ b/configure.ac
@@ -401,6 +401,7 @@ panels/user-accounts/data/gnome-user-accounts-panel.desktop.in
panels/user-accounts/data/faces/Makefile
panels/user-accounts/data/icons/Makefile
panels/wacom/Makefile
+panels/wacom/calibrator/Makefile
panels/wacom/gnome-wacom-panel.desktop.in
po/Makefile.in
shell/Makefile
diff --git a/panels/wacom/Makefile.am b/panels/wacom/Makefile.am
index ba4ec69..6d61c1a 100644
--- a/panels/wacom/Makefile.am
+++ b/panels/wacom/Makefile.am
@@ -1,9 +1,12 @@
# This is used in PANEL_CFLAGS
cappletname = wacom
+SUBDIRS = calibrator
+
INCLUDES = \
$(PANEL_CFLAGS) \
$(WACOM_PANEL_CFLAGS) \
+ -I$(srcdir)/calibrator \
-DGNOMELOCALEDIR="\"$(datadir)/locale\"" \
-DGNOMECC_DATA_DIR="\"$(pkgdatadir)\"" \
-DGNOMECC_UI_DIR="\"$(uidir)\"" \
@@ -27,7 +30,7 @@ libwacom_properties_la_SOURCES = \
cc-wacom-nav-button.c \
cc-wacom-nav-button.h
-libwacom_properties_la_LIBADD = $(PANEL_LIBS) $(WACOM_PANEL_LIBS)
+libwacom_properties_la_LIBADD = $(PANEL_LIBS) $(WACOM_PANEL_LIBS) $(builddir)/calibrator/libwacom-calibrator.la
libwacom_properties_la_LDFLAGS = $(PANEL_LDFLAGS)
noinst_PROGRAMS = test-wacom
@@ -44,7 +47,7 @@ test_wacom_SOURCES = \
gsd-input-helper.h
test_wacom_CPPFLAGS = $(INCLUDES)
-test_wacom_LDADD = $(PANEL_LIBS) $(WACOM_PANEL_LIBS)
+test_wacom_LDADD = $(PANEL_LIBS) $(WACOM_PANEL_LIBS) $(builddir)/calibrator/libwacom-calibrator.la
@INTLTOOL_DESKTOP_RULE@
diff --git a/panels/wacom/calibrator/Makefile.am b/panels/wacom/calibrator/Makefile.am
new file mode 100644
index 0000000..cf223c4
--- /dev/null
+++ b/panels/wacom/calibrator/Makefile.am
@@ -0,0 +1,38 @@
+# This is used in PANEL_CFLAGS
+cappletname = wacom
+
+INCLUDES = \
+ $(PANEL_CFLAGS) \
+ $(WACOM_PANEL_CFLAGS) \
+ -DGNOMELOCALEDIR="\"$(datadir)/locale\"" \
+ -DGNOMECC_DATA_DIR="\"$(pkgdatadir)\"" \
+ -DGNOMECC_UI_DIR="\"$(uidir)\"" \
+ -DPIXMAP_DIR=\""$(datadir)/gnome-control-center/pixmaps"\" \
+ $(NULL)
+
+
+noinst_LTLIBRARIES = libwacom-calibrator.la
+
+libwacom_calibrator_la_SOURCES = \
+ calibrator.c \
+ calibrator.h \
+ gui_gtk.c \
+ gui_gtk.h
+
+libwacom_calibrator_la_LIBADD = $(PANEL_LIBS) $(WACOM_PANEL_LIBS)
+libwacom_calibrator_la_LDFLAGS = $(PANEL_LDFLAGS)
+
+noinst_PROGRAMS = test-calibrator
+
+test_calibrator_SOURCES = \
+ main.c \
+ main.h \
+ calibrator.c \
+ calibrator.h \
+ gui_gtk.c \
+ gui_gtk.h
+
+test_calibrator_CPPFLAGS = $(INCLUDES)
+test_calibrator_LDADD = $(PANEL_LIBS) $(WACOM_PANEL_LIBS)
+
+-include $(top_srcdir)/git.mk
diff --git a/panels/wacom/calibrator/calibrator.c b/panels/wacom/calibrator/calibrator.c
new file mode 100644
index 0000000..213d098
--- /dev/null
+++ b/panels/wacom/calibrator/calibrator.c
@@ -0,0 +1,177 @@
+/*
+ * Copyright (c) 2009 Tias Guns
+ * Copyright (c) 2009 Soren Hauberg
+ *
+ * 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 "calibrator.h"
+
+#define SWAP(x,y) do { int t; t=(x); x=(y); y=t; } while (0)
+
+/* reset clicks */
+void
+reset (struct Calib *c)
+{
+ c->num_clicks = 0;
+}
+
+/* add a click with the given coordinates */
+bool
+add_click (struct Calib *c,
+ int x,
+ int y)
+{
+ /* Double-click detection */
+ if (c->threshold_doubleclick > 0 && c->num_clicks > 0)
+ {
+ int i = c->num_clicks-1;
+ while (i >= 0)
+ {
+ if (abs(x - c->clicked_x[i]) <= c->threshold_doubleclick &&
+ abs(y - c->clicked_y[i]) <= c->threshold_doubleclick)
+ {
+ return false;
+ }
+ i--;
+ }
+ }
+
+ /* Mis-click detection */
+ if (c->threshold_misclick > 0 && c->num_clicks > 0)
+ {
+ bool misclick = true;
+
+ if (c->num_clicks == 1)
+ {
+ /* check that along one axis of first point */
+ if (along_axis(c, x,c->clicked_x[0],c->clicked_y[0]) ||
+ along_axis(c, y,c->clicked_x[0],c->clicked_y[0]))
+ {
+ misclick = false;
+ }
+ }
+ else if (c->num_clicks == 2)
+ {
+ /* check that along other axis of first point than second point */
+ if ((along_axis(c, y,c->clicked_x[0],c->clicked_y[0]) &&
+ along_axis(c, c->clicked_x[1],c->clicked_x[0],c->clicked_y[0])) ||
+ (along_axis(c, x,c->clicked_x[0],c->clicked_y[0]) &&
+ along_axis(c, c->clicked_y[1],c->clicked_x[0],c->clicked_y[0])))
+ {
+ misclick = false;
+ }
+ }
+ else if (c->num_clicks == 3)
+ {
+ /* check that along both axis of second and third point */
+ if ((along_axis(c, x,c->clicked_x[1],c->clicked_y[1]) &&
+ along_axis(c, y,c->clicked_x[2],c->clicked_y[2])) ||
+ (along_axis(c, y,c->clicked_x[1],c->clicked_y[1]) &&
+ along_axis(c, x,c->clicked_x[2],c->clicked_y[2])))
+ {
+ misclick = false;
+ }
+ }
+
+ if (misclick)
+ {
+ reset(c);
+ return false;
+ }
+ }
+
+ c->clicked_x[c->num_clicks] = x;
+ c->clicked_y[c->num_clicks] = y;
+ c->num_clicks++;
+
+ return true;
+}
+
+/* check whether the coordinates are along the respective axis */
+bool
+along_axis (struct Calib *c,
+ int xy,
+ int x0,
+ int y0)
+{
+ return ((abs(xy - x0) <= c->threshold_misclick) ||
+ (abs(xy - y0) <= c->threshold_misclick));
+}
+
+/* calculate and apply the calibration */
+bool
+finish (struct Calib *c,
+ int width,
+ int height,
+ XYinfo *new_axys,
+ bool *swap)
+{
+ bool swap_xy;
+ float scale_x;
+ float scale_y;
+ int delta_x;
+ int delta_y;
+ XYinfo axys = {-1, -1, -1, -1};
+
+ if (c->num_clicks != 4)
+ return false;
+
+ /* Should x and y be swapped? */
+ swap_xy = (abs (c->clicked_x [UL] - c->clicked_x [UR]) < abs (c->clicked_y [UL] - c->clicked_y [UR]));
+ if (swap_xy)
+ {
+ SWAP(c->clicked_x[LL], c->clicked_x[UR]);
+ SWAP(c->clicked_y[LL], c->clicked_y[UR]);
+ }
+
+ /* Compute min/max coordinates. */
+ /* These are scaled using the values of old_axys */
+ scale_x = (c->old_axys.x_max - c->old_axys.x_min)/(float)width;
+ axys.x_min = ((c->clicked_x[UL] + c->clicked_x[LL]) * scale_x/2) + c->old_axys.x_min;
+ axys.x_max = ((c->clicked_x[UR] + c->clicked_x[LR]) * scale_x/2) + c->old_axys.x_min;
+ scale_y = (c->old_axys.y_max - c->old_axys.y_min)/(float)height;
+ axys.y_min = ((c->clicked_y[UL] + c->clicked_y[UR]) * scale_y/2) + c->old_axys.y_min;
+ axys.y_max = ((c->clicked_y[LL] + c->clicked_y[LR]) * scale_y/2) + c->old_axys.y_min;
+
+ /* Add/subtract the offset that comes from not having the points in the
+ * corners (using the same coordinate system they are currently in)
+ */
+ delta_x = (axys.x_max - axys.x_min) / (float)(NUM_BLOCKS - 2);
+ axys.x_min -= delta_x;
+ axys.x_max += delta_x;
+ delta_y = (axys.y_max - axys.y_min) / (float)(NUM_BLOCKS - 2);
+ axys.y_min -= delta_y;
+ axys.y_max += delta_y;
+
+ /* If x and y has to be swapped we also have to swap the parameters */
+ if (swap_xy)
+ {
+ SWAP(axys.x_min, axys.y_max);
+ SWAP(axys.y_min, axys.x_max);
+ }
+
+ *new_axys = axys;
+ *swap = swap_xy;
+
+ return true;
+}
+
diff --git a/panels/wacom/calibrator/calibrator.h b/panels/wacom/calibrator/calibrator.h
new file mode 100644
index 0000000..98bc71e
--- /dev/null
+++ b/panels/wacom/calibrator/calibrator.h
@@ -0,0 +1,119 @@
+/*
+ * Copyright (c) 2009 Tias Guns
+ * Copyright (c) 2009 Soren Hauberg
+ *
+ * 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.
+ */
+
+#ifndef _calibrator_h
+#define _calibrator_h
+
+/*
+ * Number of blocks. We partition the screen into 'num_blocks' x 'num_blocks'
+ * rectangles of equal size. We then ask the user to press points that are
+ * located at the corner closes to the center of the four blocks in the corners
+ * of the screen. The following ascii art illustrates the situation. We partition
+ * the screen into 8 blocks in each direction. We then let the user press the
+ * points marked with 'O'.
+ *
+ * +--+--+--+--+--+--+--+--+
+ * | | | | | | | | |
+ * +--O--+--+--+--+--+--O--+
+ * | | | | | | | | |
+ * +--+--+--+--+--+--+--+--+
+ * | | | | | | | | |
+ * +--+--+--+--+--+--+--+--+
+ * | | | | | | | | |
+ * +--+--+--+--+--+--+--+--+
+ * | | | | | | | | |
+ * +--+--+--+--+--+--+--+--+
+ * | | | | | | | | |
+ * +--+--+--+--+--+--+--+--+
+ * | | | | | | | | |
+ * +--O--+--+--+--+--+--O--+
+ * | | | | | | | | |
+ * +--+--+--+--+--+--+--+--+
+ */
+#define NUM_BLOCKS 8
+
+/* Names of the points */
+enum
+{
+ UL = 0, /* Upper-left */
+ UR = 1, /* Upper-right */
+ LL = 2, /* Lower-left */
+ LR = 3 /* Lower-right */
+};
+
+/* struct to hold min/max info of the X and Y axis */
+typedef struct
+{
+ int x_min;
+ int x_max;
+ int y_min;
+ int y_max;
+} XYinfo;
+
+typedef enum
+{
+ false = 0,
+ true = 1
+} bool;
+
+struct Calib
+{
+ /* original axys values */
+ XYinfo old_axys;
+
+ /* nr of clicks registered */
+ int num_clicks;
+
+ /* click coordinates */
+ int clicked_x[4], clicked_y[4];
+
+ /* Threshold to keep the same point from being clicked twice.
+ * Set to zero if you don't want this check
+ */
+ int threshold_doubleclick;
+
+ /* Threshold to detect mis-clicks (clicks not along axes)
+ * A lower value forces more precise calibration
+ * Set to zero if you don't want this check
+ */
+ int threshold_misclick;
+
+ /* manually specified geometry string */
+ const char* geometry;
+};
+
+void reset (struct Calib *c);
+bool add_click (struct Calib *c,
+ int x,
+ int y);
+bool along_axis (struct Calib *c,
+ int xy,
+ int x0,
+ int y0);
+bool finish (struct Calib *c,
+ int width,
+ int height,
+ XYinfo *new_axys,
+ bool *swap);
+
+#endif /* _calibrator_h */
diff --git a/panels/wacom/calibrator/gui_gtk.c b/panels/wacom/calibrator/gui_gtk.c
new file mode 100644
index 0000000..2a3e970
--- /dev/null
+++ b/panels/wacom/calibrator/gui_gtk.c
@@ -0,0 +1,411 @@
+/*
+ * Copyright (c) 2009 Tias Guns
+ * Copyright (c) 2009 Soren Hauberg
+ *
+ * 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 <stdio.h>
+#include <gtk/gtk.h>
+#include <cairo.h>
+
+#include "calibrator.h"
+#include "gui_gtk.h"
+
+#define MAXIMUM(x,y) ((x) > (y) ? (x) : (y))
+
+#ifndef M_PI
+#define M_PI 3.14159265358979323846264338327
+#endif
+
+/* Timeout parameters */
+const int time_step = 100; /* in milliseconds */
+const int max_time = 15000; /* 5000 = 5 sec */
+
+/* Clock appereance */
+const int cross_lines = 25;
+const int cross_circle = 4;
+const int clock_radius = 50;
+const int clock_line_width = 10;
+
+/* Text printed on screen */
+const int font_size = 16;
+#define HELP_LINES (sizeof help_text / sizeof help_text[0])
+const char *help_text[] = {
+ "Touchscreen Calibration",
+ "Press the point, use a stylus to increase precision.",
+ "",
+ "(To abort, press any key or wait)"
+};
+
+struct CalibArea*
+CalibrationArea_(struct Calib *c)
+{
+ struct CalibArea *calib_area;
+ const char *geo = c->geometry;
+
+ calib_area = (struct CalibArea*)calloc(1, sizeof(struct CalibArea));
+ calib_area->calibrator = c;
+ calib_area->drawing_area = gtk_drawing_area_new();
+
+ /* Listen for mouse events */
+ gtk_widget_add_events(calib_area->drawing_area, GDK_KEY_PRESS_MASK | GDK_BUTTON_PRESS_MASK);
+ gtk_widget_set_can_focus(calib_area->drawing_area, TRUE);
+
+ /* Connect callbacks */
+ g_signal_connect(calib_area->drawing_area, "expose-event", G_CALLBACK(on_expose_event), calib_area);
+ g_signal_connect(calib_area->drawing_area, "draw", G_CALLBACK(draw), calib_area);
+ g_signal_connect(calib_area->drawing_area, "button-press-event", G_CALLBACK(on_button_press_event), calib_area);
+ g_signal_connect(calib_area->drawing_area, "key-press-event", G_CALLBACK(on_key_press_event), calib_area);
+
+ /* parse geometry string */
+ if (geo != NULL)
+ {
+ int gw,gh;
+ int res = sscanf(geo,"%dx%d",&gw,&gh);
+ if (res != 2)
+ geo = NULL;
+ else
+ set_display_size(calib_area, gw, gh );\
+ }
+ if (geo == NULL)
+ {
+ GtkAllocation allocation;
+ gtk_widget_get_allocation(calib_area->drawing_area, &allocation);
+ set_display_size(calib_area, allocation.width, allocation.height);
+ }
+
+ /* Setup timer for animation */
+ g_timeout_add(time_step, (GSourceFunc)on_timer_signal, calib_area);
+
+ return calib_area;
+}
+
+void
+set_display_size(struct CalibArea *calib_area,
+ int width,
+ int height)
+{
+ int delta_x;
+ int delta_y;
+
+ calib_area->display_width = width;
+ calib_area->display_height = height;
+
+ /* Compute absolute circle centers */
+ delta_x = calib_area->display_width/NUM_BLOCKS;
+ delta_y = calib_area->display_height/NUM_BLOCKS;
+
+ calib_area->X[UL] = delta_x;
+ calib_area->Y[UL] = delta_y;
+
+ calib_area->X[UR] = calib_area->display_width - delta_x - 1;
+ calib_area->Y[UR] = delta_y;
+
+ calib_area->X[LL] = delta_x;
+ calib_area->Y[LL] = calib_area->display_height - delta_y - 1;
+
+ calib_area->X[LR] = calib_area->display_width - delta_x - 1;
+ calib_area->Y[LR] = calib_area->display_height - delta_y - 1;
+
+ /* reset calibration if already started */
+ reset(calib_area->calibrator);
+}
+
+void
+resize_display(struct CalibArea *calib_area)
+{
+ /* check that screensize did not change (if no manually specified geometry) */
+ GtkAllocation allocation;
+ gtk_widget_get_allocation(calib_area->drawing_area, &allocation);
+ if (calib_area->calibrator->geometry == NULL &&
+ (calib_area->display_width != allocation.width ||
+ calib_area->display_height != allocation.height ))
+ {
+ set_display_size(calib_area, allocation.width, allocation.height);
+ }
+}
+
+bool
+on_expose_event(GtkWidget *widget,
+ GdkEventExpose *event,
+ gpointer data)
+{
+ struct CalibArea *calib_area = (struct CalibArea*)data;
+ GdkWindow *window = gtk_widget_get_window(calib_area->drawing_area);
+
+ if (window)
+ {
+ cairo_t *cr = gdk_cairo_create(window);
+ cairo_save(cr);
+ cairo_rectangle(cr, event->area.x, event->area.y, event->area.width, event->area.height);
+ cairo_clip(cr);
+ draw(widget, cr, data);
+ cairo_restore(cr);
+ }
+ return true;
+}
+
+void
+draw(GtkWidget *widget, cairo_t *cr, gpointer data)
+{
+ struct CalibArea *calib_area = (struct CalibArea*)data;
+ int i;
+ double text_height;
+ double text_width;
+ double x;
+ double y;
+ cairo_text_extents_t extent;
+
+ resize_display(calib_area);
+
+ /* Print the text */
+ cairo_set_font_size(cr, font_size);
+ text_height = -1;
+ text_width = -1;
+ for (i = 0; i != HELP_LINES; i++)
+ {
+ cairo_text_extents(cr, help_text[i], &extent);
+ text_width = MAXIMUM(text_width, extent.width);
+ text_height = MAXIMUM(text_height, extent.height);
+ }
+ text_height += 2;
+
+ x = (calib_area->display_width - text_width) / 2;
+ y = (calib_area->display_height - text_height) / 2 - 60;
+ cairo_set_line_width(cr, 2);
+ cairo_rectangle(cr, x - 10, y - (HELP_LINES*text_height) - 10,
+ text_width + 20, (HELP_LINES*text_height) + 20);
+
+ /* Print help lines */
+ y -= 3;
+ for (i = HELP_LINES-1; i != -1; i--)
+ {
+ cairo_text_extents(cr, help_text[i], &extent);
+ cairo_move_to(cr, x + (text_width-extent.width)/2, y);
+ cairo_show_text(cr, help_text[i]);
+ y -= text_height;
+ }
+ cairo_stroke(cr);
+
+ /* Draw the points */
+ for (i = 0; i <= calib_area->calibrator->num_clicks; i++)
+ {
+ /* set color: already clicked or not */
+ if (i < calib_area->calibrator->num_clicks)
+ cairo_set_source_rgb(cr, 1.0, 1.0, 1.0);
+ else
+ cairo_set_source_rgb(cr, 0.8, 0.0, 0.0);
+
+ cairo_set_line_width(cr, 1);
+ cairo_move_to(cr, calib_area->X[i] - cross_lines, calib_area->Y[i]);
+ cairo_rel_line_to(cr, cross_lines*2, 0);
+ cairo_move_to(cr, calib_area->X[i], calib_area->Y[i] - cross_lines);
+ cairo_rel_line_to(cr, 0, cross_lines*2);
+ cairo_stroke(cr);
+
+ cairo_arc(cr, calib_area->X[i], calib_area->Y[i], cross_circle, 0.0, 2.0 * M_PI);
+ cairo_stroke(cr);
+ }
+
+ /* Draw the clock background */
+ cairo_arc(cr, calib_area->display_width/2, calib_area->display_height/2, clock_radius/2, 0.0, 2.0 * M_PI);
+ cairo_set_source_rgb(cr, 0.5, 0.5, 0.5);
+ cairo_fill_preserve(cr);
+ cairo_stroke(cr);
+
+ cairo_set_line_width(cr, clock_line_width);
+ cairo_arc(cr, calib_area->display_width/2, calib_area->display_height/2, (clock_radius - clock_line_width)/2,
+ 3/2.0*M_PI, (3/2.0*M_PI) + ((double)calib_area->time_elapsed/(double)max_time) * 2*M_PI);
+ cairo_set_source_rgb(cr, 0.0, 0.0, 0.0);
+ cairo_stroke(cr);
+
+
+ /* Draw the message (if any) */
+ if (calib_area->message != NULL)
+ {
+ /* Frame the message */
+ cairo_set_font_size(cr, font_size);
+ cairo_text_extents(cr, calib_area->message, &extent);
+ text_width = extent.width;
+ text_height = extent.height;
+
+ x = (calib_area->display_width - text_width) / 2;
+ y = (calib_area->display_height - text_height + clock_radius) / 2 + 60;
+ cairo_set_line_width(cr, 2);
+ cairo_rectangle(cr, x - 10, y - text_height - 10,
+ text_width + 20, text_height + 25);
+
+ /* Print the message */
+ cairo_move_to(cr, x, y);
+ cairo_show_text(cr, calib_area->message);
+ cairo_stroke(cr);
+ }
+}
+
+void
+redraw(struct CalibArea *calib_area)
+{
+ GdkWindow *win = gtk_widget_get_window(calib_area->drawing_area);
+ if (win)
+ {
+ GdkRectangle rect;
+ rect.x = 0;
+ rect.y = 0;
+ rect.width = calib_area->display_width;
+ rect.height = calib_area->display_height;
+ gdk_window_invalidate_rect(win, &rect, false);
+ }
+}
+
+bool
+on_timer_signal(struct CalibArea *calib_area)
+{
+ GdkWindow *win;
+ GtkWidget *parent = gtk_widget_get_parent(calib_area->drawing_area);
+
+ calib_area->time_elapsed += time_step;
+ if (calib_area->time_elapsed > max_time || parent == NULL)
+ {
+ if (parent)
+ gtk_widget_destroy(parent);
+ return false;
+ }
+
+ /* Update clock */
+ win = gtk_widget_get_window(calib_area->drawing_area);
+ if (win)
+ {
+ GdkRectangle rect;
+ rect.x = calib_area->display_width/2 - clock_radius - clock_line_width;
+ rect.y = calib_area->display_height/2 - clock_radius - clock_line_width;
+ rect.width = 2 * clock_radius + 1 + 2 * clock_line_width;
+ rect.height = 2 * clock_radius + 1 + 2 * clock_line_width;
+ gdk_window_invalidate_rect(win, &rect, false);
+ }
+
+ return true;
+}
+
+bool
+on_button_press_event(GtkWidget *widget,
+ GdkEventButton *event,
+ gpointer data)
+{
+ struct CalibArea *calib_area = (struct CalibArea*)data;
+ bool success;
+
+ /* Handle click */
+ calib_area->time_elapsed = 0;
+ success = add_click(calib_area->calibrator, (int)event->x_root, (int)event->y_root);
+
+ if (!success && calib_area->calibrator->num_clicks == 0)
+ draw_message(calib_area, "Mis-click detected, restarting...");
+ else
+ draw_message(calib_area, NULL);
+
+ /* Are we done yet? */
+ if (calib_area->calibrator->num_clicks >= 4)
+ {
+ GtkWidget *parent = gtk_widget_get_parent(calib_area->drawing_area);
+ if (parent)
+ gtk_widget_destroy(parent);
+ return true;
+ }
+
+ /* Force a redraw */
+ redraw(calib_area);
+
+ return true;
+}
+
+void
+draw_message(struct CalibArea *calib_area,
+ const char *msg)
+{
+ calib_area->message = msg;
+}
+
+bool
+on_key_press_event(GtkWidget *widget,
+ GdkEventKey *event,
+ gpointer data)
+{
+ struct CalibArea *calib_area = (struct CalibArea*)data;
+ GtkWidget *parent = gtk_widget_get_parent(calib_area->drawing_area);
+ if (parent)
+ gtk_widget_destroy(parent);
+ return true;
+}
+
+/**
+ * Creates the windows and other objects required to do calibration
+ * under GTK and then starts the main loop. When the main loop exits,
+ * the calibration will be calculated (if possible) and this function
+ * will then return ('true' if successful, 'false' otherwise).
+ */
+bool
+run_gui(struct Calib *c,
+ XYinfo *new_axys,
+ bool *swap)
+{
+ bool success;
+ struct CalibArea *calib_area = CalibrationArea_(c);
+
+ printf("Current calibration: %d, %d, %d, %d\n",
+ c->old_axys.x_min,
+ c->old_axys.y_min,
+ c->old_axys.x_max,
+ c->old_axys.y_max);
+
+ GdkScreen *screen = gdk_screen_get_default();
+ GtkWidget *win = gtk_window_new(GTK_WINDOW_TOPLEVEL);
+ GdkRectangle rect;
+ /*int num_monitors = screen->get_n_monitors(); TODO, multiple monitors?*/
+
+ g_signal_connect(G_OBJECT(win), "destroy", G_CALLBACK(gtk_main_quit), NULL);
+
+ gdk_screen_get_monitor_geometry(screen, 0, &rect);
+
+ /* when no window manager: explicitely take size of full screen */
+ gtk_window_move(GTK_WINDOW(win), rect.x, rect.y);
+ gtk_window_set_default_size(GTK_WINDOW(win), rect.width, rect.height);
+
+ /* in case of window manager: set as full screen to hide window decorations */
+ gtk_window_fullscreen(GTK_WINDOW(win));
+
+ gtk_container_add(GTK_CONTAINER(win), calib_area->drawing_area);
+ gtk_widget_show_all(win);
+
+ printf("gtk_main entered!\n");
+ gtk_main();
+ printf("gtk_main returned!\n");
+
+ success = finish(calib_area->calibrator, calib_area->display_width, calib_area->display_height, new_axys, swap);
+
+ printf("Final calibration: %d, %d, %d, %d\n",
+ new_axys->x_min,
+ new_axys->y_min,
+ new_axys->x_max,
+ new_axys->y_max);
+
+ return success;
+}
+
diff --git a/panels/wacom/calibrator/gui_gtk.h b/panels/wacom/calibrator/gui_gtk.h
new file mode 100644
index 0000000..b376ff1
--- /dev/null
+++ b/panels/wacom/calibrator/gui_gtk.h
@@ -0,0 +1,68 @@
+/*
+ * Copyright (c) 2009 Tias Guns
+ * Copyright (c) 2009 Soren Hauberg
+ *
+ * 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.
+ */
+
+#ifndef _gui_gtk_h
+#define _gui_gtk_h
+
+#include <gtk/gtk.h>
+
+#include "calibrator.h"
+
+struct CalibArea
+{
+ struct Calib* calibrator;
+ double X[4], Y[4];
+ int display_width, display_height;
+ int time_elapsed;
+
+ const char* message;
+
+ GtkWidget *drawing_area;
+};
+
+struct CalibArea* CalibrationArea_ (struct Calib *c);
+void set_display_size (struct CalibArea *calib_area,
+ int width,
+ int height);
+void resize_display (struct CalibArea *calib_area);
+bool on_expose_event (GtkWidget *widget,
+ GdkEventExpose *event,
+ gpointer data);
+void draw (GtkWidget *widget,
+ cairo_t *cr,
+ gpointer data);
+void redraw (struct CalibArea *calib_area);
+bool on_timer_signal (struct CalibArea *calib_area);
+bool on_button_press_event (GtkWidget *widget,
+ GdkEventButton *event,
+ gpointer data);
+void draw_message (struct CalibArea *calib_area,
+ const char *msg);
+bool on_key_press_event (GtkWidget *widget,
+ GdkEventKey *event,
+ gpointer data);
+bool run_gui (struct Calib *c,
+ XYinfo *new_axys,
+ bool *swap);
+
+#endif /* _gui_gtk_h */
diff --git a/panels/wacom/calibrator/main.c b/panels/wacom/calibrator/main.c
new file mode 100644
index 0000000..85dc9e7
--- /dev/null
+++ b/panels/wacom/calibrator/main.c
@@ -0,0 +1,398 @@
+/*
+ * Copyright (c) 2009 Tias Guns
+ * Copyright (c) 2009 Soren Hauberg
+ *
+ * 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 <ctype.h>
+#include <string.h>
+#include <dirent.h>
+
+#include <X11/extensions/XInput.h>
+
+#include "gui_gtk.h"
+#include "main.h"
+
+/**
+ * find a calibratable touchscreen device (using XInput)
+ *
+ * if pre_device is NULL, the last calibratable device is selected.
+ * retuns number of devices found,
+ * the data of the device is returned in the last 3 function parameters
+ */
+int find_device(const char* pre_device, bool verbose, bool list_devices,
+ XID* device_id, const char** device_name, XYinfo* device_axys)
+{
+ bool pre_device_is_id = true;
+ int found = 0;
+
+ Display* display = XOpenDisplay(NULL);
+ if (display == NULL) {
+ fprintf(stderr, "Unable to connect to X server\n");
+ exit(1);
+ }
+
+ int xi_opcode, event, error;
+ if (!XQueryExtension(display, "XInputExtension", &xi_opcode, &event, &error)) {
+ fprintf(stderr, "X Input extension not available.\n");
+ exit(1);
+ }
+
+ /* verbose, get Xi version */
+ if (verbose) {
+ XExtensionVersion *version = XGetExtensionVersion(display, INAME);
+
+ if (version && (version != (XExtensionVersion*) NoSuchExtension)) {
+ printf("DEBUG: %s version is %i.%i\n",
+ INAME, version->major_version, version->minor_version);
+ XFree(version);
+ }
+ }
+
+ if (pre_device != NULL) {
+ /* check whether the pre_device is an ID (only digits) */
+ int len = strlen(pre_device);
+ int loop;
+ for (loop=0; loop<len; loop++) {
+ if (!isdigit(pre_device[loop])) {
+ pre_device_is_id = false;
+ break;
+ }
+ }
+ }
+
+
+ if (verbose)
+ printf("DEBUG: Skipping virtual master devices and devices without axis valuators.\n");
+ int ndevices;
+ XDeviceInfoPtr list, slist;
+ slist=list=(XDeviceInfoPtr) XListInputDevices (display, &ndevices);
+ int i;
+ for (i=0; i<ndevices; i++, list++)
+ {
+ if (list->use == IsXKeyboard || list->use == IsXPointer) /* virtual master device */
+ continue;
+
+ /* if we are looking for a specific device */
+ if (pre_device != NULL) {
+ if ((pre_device_is_id && list->id == (XID) atoi(pre_device)) ||
+ (!pre_device_is_id && strcmp(list->name, pre_device) == 0)) {
+ /* OK, fall through */
+ } else {
+ /* skip, not this device */
+ continue;
+ }
+ }
+
+ XAnyClassPtr any = (XAnyClassPtr) (list->inputclassinfo);
+ int j;
+ for (j=0; j<list->num_classes; j++)
+ {
+
+ if (any->class == ValuatorClass)
+ {
+ XValuatorInfoPtr V = (XValuatorInfoPtr) any;
+ XAxisInfoPtr ax = (XAxisInfoPtr) V->axes;
+
+ if (V->mode != Absolute) {
+ if (verbose)
+ printf("DEBUG: Skipping device '%s' id=%i, does not report Absolute events.\n",
+ list->name, (int)list->id);
+ } else if (V->num_axes < 2 ||
+ (ax[0].min_value == -1 && ax[0].max_value == -1) ||
+ (ax[1].min_value == -1 && ax[1].max_value == -1)) {
+ if (verbose)
+ printf("DEBUG: Skipping device '%s' id=%i, does not have two calibratable axes.\n",
+ list->name, (int)list->id);
+ } else {
+ /* a calibratable device (has 2 axis valuators) */
+ found++;
+ *device_id = list->id;
+ *device_name = my_strdup(list->name);
+ device_axys->x_min = ax[0].min_value;
+ device_axys->x_max = ax[0].max_value;
+ device_axys->y_min = ax[1].min_value;
+ device_axys->y_max = ax[1].max_value;
+
+ if (list_devices)
+ printf("Device \"%s\" id=%i\n", *device_name, (int)*device_id);
+ }
+
+ }
+
+ /*
+ * Increment 'any' to point to the next item in the linked
+ * list. The length is in bytes, so 'any' must be cast to
+ * a character pointer before being incremented.
+ */
+ any = (XAnyClassPtr) ((char *) any + any->length);
+ }
+
+ }
+ XFreeDeviceList(slist);
+ XCloseDisplay(display);
+
+ return found;
+}
+
+static void usage(char* cmd, unsigned thr_misclick)
+{
+ fprintf(stderr, "Usage: %s [-h|--help] [-v|--verbose] [--list] [--device <device name or id>] [--precalib <minx> <maxx> <miny> <maxy>] [--misclick <nr of pixels>] [--output-type <auto|xorg.conf.d|hal|xinput>] [--fake] [--geometry <w>x<h>]\n", cmd);
+ fprintf(stderr, "\t-h, --help: print this help message\n");
+ fprintf(stderr, "\t-v, --verbose: print debug messages during the process\n");
+ fprintf(stderr, "\t--list: list calibratable input devices and quit\n");
+ fprintf(stderr, "\t--device <device name or id>: select a specific device to calibrate\n");
+ fprintf(stderr, "\t--precalib: manually provide the current calibration setting (eg. the values in xorg.conf)\n");
+ fprintf(stderr, "\t--misclick: set the misclick threshold (0=off, default: %i pixels)\n",
+ thr_misclick);
+ fprintf(stderr, "\t--fake: emulate a fake device (for testing purposes)\n");
+ fprintf(stderr, "\t--geometry: manually provide the geometry (width and height) for the calibration window\n");
+}
+
+struct Calib* main_common(int argc, char** argv)
+{
+ bool verbose = false;
+ bool list_devices = false;
+ bool fake = false;
+ bool precalib = false;
+ XYinfo pre_axys = {-1, -1, -1, -1};
+ const char* pre_device = NULL;
+ const char* geometry = NULL;
+ unsigned thr_misclick = 15;
+ unsigned thr_doubleclick = 7;
+
+ /* parse input */
+ if (argc > 1) {
+ int i;
+ for (i=1; i!=argc; i++) {
+ /* Display help ? */
+ if (strcmp("-h", argv[i]) == 0 ||
+ strcmp("--help", argv[i]) == 0) {
+ fprintf(stderr, "xinput_calibratior, v%s\n\n", "0.0.0");
+ usage(argv[0], thr_misclick);
+ exit(0);
+ } else
+
+ /* Verbose output ? */
+ if (strcmp("-v", argv[i]) == 0 ||
+ strcmp("--verbose", argv[i]) == 0) {
+ verbose = true;
+ } else
+
+ /* Just list devices ? */
+ if (strcmp("--list", argv[i]) == 0) {
+ list_devices = true;
+ } else
+
+ /* Select specific device ? */
+ if (strcmp("--device", argv[i]) == 0) {
+ if (argc > i+1)
+ pre_device = argv[++i];
+ else {
+ fprintf(stderr, "Error: --device needs a device name or id as argument; use --list to list the calibratable input devices.\n\n");
+ usage(argv[0], thr_misclick);
+ exit(1);
+ }
+ } else
+
+ /* Get pre-calibration ? */
+ if (strcmp("--precalib", argv[i]) == 0) {
+ precalib = true;
+ if (argc > i+1)
+ pre_axys.x_min = atoi(argv[++i]);
+ if (argc > i+1)
+ pre_axys.x_max = atoi(argv[++i]);
+ if (argc > i+1)
+ pre_axys.y_min = atoi(argv[++i]);
+ if (argc > i+1)
+ pre_axys.y_max = atoi(argv[++i]);
+ } else
+
+ /* Get mis-click threshold ? */
+ if (strcmp("--misclick", argv[i]) == 0) {
+ if (argc > i+1)
+ thr_misclick = atoi(argv[++i]);
+ else {
+ fprintf(stderr, "Error: --misclick needs a number (the pixel threshold) as argument. Set to 0 to disable mis-click detection.\n\n");
+ usage(argv[0], thr_misclick);
+ exit(1);
+ }
+ } else
+
+ /* specify window geometry? */
+ if (strcmp("--geometry", argv[i]) == 0) {
+ geometry = argv[++i];
+ /* sscanf(argv[++i],"%dx%d",&win_width,&win_height); */
+ } else
+
+ /* Fake calibratable device ? */
+ if (strcmp("--fake", argv[i]) == 0) {
+ fake = true;
+ }
+
+ /* unknown option */
+ else {
+ fprintf(stderr, "Unknown option: %s\n\n", argv[i]);
+ usage(argv[0], thr_misclick);
+ exit(0);
+ }
+ }
+ }
+
+
+ /* Choose the device to calibrate */
+ XID device_id = (XID) -1;
+ const char* device_name = NULL;
+ XYinfo device_axys = {-1, -1, -1, -1};
+ if (fake) {
+ /* Fake a calibratable device */
+ device_name = "Fake_device";
+ device_axys.x_min=0;
+ device_axys.x_max=1000;
+ device_axys.y_min=0;
+ device_axys.y_max=1000;
+
+ if (verbose) {
+ printf("DEBUG: Faking device: %s\n", device_name);
+ }
+ } else {
+ /* Find the right device */
+ int nr_found = find_device(pre_device, verbose, list_devices, &device_id, &device_name, &device_axys);
+
+ if (list_devices) {
+ /* printed the list in find_device */
+ if (nr_found == 0)
+ printf("No calibratable devices found.\n");
+ exit(0);
+ }
+
+ if (nr_found == 0) {
+ if (pre_device == NULL)
+ fprintf (stderr, "Error: No calibratable devices found.\n");
+ else
+ fprintf (stderr, "Error: Device \"%s\" not found; use --list to list the calibratable input devices.\n", pre_device);
+ exit(1);
+
+ } else if (nr_found > 1) {
+ printf ("Warning: multiple calibratable devices found, calibrating last one (%s)\n\tuse --device to select another one.\n", device_name);
+ }
+
+ if (verbose) {
+ printf("DEBUG: Selected device: %s\n", device_name);
+ }
+ }
+
+ /* override min/max XY from command line ? */
+ if (precalib) {
+ if (pre_axys.x_min != -1)
+ device_axys.x_min = pre_axys.x_min;
+ if (pre_axys.x_max != -1)
+ device_axys.x_max = pre_axys.x_max;
+ if (pre_axys.y_min != -1)
+ device_axys.y_min = pre_axys.y_min;
+ if (pre_axys.y_max != -1)
+ device_axys.y_max = pre_axys.y_max;
+
+ if (verbose) {
+ printf("DEBUG: Setting precalibration: %i, %i, %i, %i\n",
+ device_axys.x_min, device_axys.x_max,
+ device_axys.y_min, device_axys.y_max);
+ }
+ }
+
+ /* lastly, presume a standard Xorg driver (evtouch, mutouch, ...) */
+ return CalibratorXorgPrint(device_name, &device_axys,
+ verbose, thr_misclick, thr_doubleclick, geometry);
+}
+
+struct Calib* CalibratorXorgPrint(const char* const device_name0, const XYinfo *axys0, const bool verbose0, const int thr_misclick, const int thr_doubleclick, const char* geometry)
+{
+ struct Calib* c = (struct Calib*)calloc(1, sizeof(struct Calib));
+ c->old_axys = *axys0;
+ c->threshold_misclick = thr_misclick;
+ c->threshold_doubleclick = thr_doubleclick;
+ c->geometry = geometry;
+
+ printf("Calibrating standard Xorg driver \"%s\"\n", device_name0);
+ printf("\tcurrent calibration values: min_x=%d, max_x=%d and min_y=%d, max_y=%d\n",
+ c->old_axys.x_min, c->old_axys.x_max, c->old_axys.y_min, c->old_axys.y_max);
+ printf("\tIf these values are estimated wrong, either supply it manually with the --precalib option, or run the 'get_precalib.sh' script to automatically get it (through HAL).\n");
+
+ return c;
+}
+
+bool finish_data(struct Calib* c, const XYinfo new_axys, int swap_xy)
+{
+ bool success = true;
+
+ /* we suppose the previous 'swap_xy' value was 0 */
+ /* (unfortunately there is no way to verify this (yet)) */
+ int new_swap_xy = swap_xy;
+
+ printf("\n\n--> Making the calibration permanent <--\n");
+ success &= output_xorgconfd(c, new_axys, swap_xy, new_swap_xy);
+
+ return success;
+}
+
+bool output_xorgconfd(struct Calib* c, const XYinfo new_axys, int swap_xy, int new_swap_xy)
+{
+ const char* sysfs_name = "!!Name_Of_TouchScreen!!";
+
+ /* xorg.conf.d snippet */
+ printf(" copy the snippet below into '/etc/X11/xorg.conf.d/99-calibration.conf'\n");
+ printf("Section \"InputClass\"\n");
+ printf(" Identifier \"calibration\"\n");
+ printf(" MatchProduct \"%s\"\n", sysfs_name);
+ printf(" Option \"MinX\" \"%d\"\n", new_axys.x_min);
+ printf(" Option \"MaxX\" \"%d\"\n", new_axys.x_max);
+ printf(" Option \"MinY\" \"%d\"\n", new_axys.y_min);
+ printf(" Option \"MaxY\" \"%d\"\n", new_axys.y_max);
+ if (swap_xy != 0)
+ printf(" Option \"SwapXY\" \"%d\" # unless it was already set to 1\n", new_swap_xy);
+ printf("EndSection\n");
+
+ return true;
+}
+
+int main(int argc, char** argv)
+{
+ int success = 0;
+ XYinfo axys;
+ bool swap_xy;
+
+ struct Calib* calibrator = main_common(argc, argv);
+
+ /* GTK setup */
+ gtk_init(&argc, &argv);
+
+ success = run_gui(calibrator, &axys, &swap_xy);
+ if (success)
+ success = finish_data(calibrator, axys, swap_xy);
+
+ if (!success) {
+ /* TODO, in GUI ? */
+ fprintf(stderr, "Error: unable to apply or save configuration values\n");
+ }
+
+ free(calibrator);
+ return success;
+}
diff --git a/panels/wacom/calibrator/main.h b/panels/wacom/calibrator/main.h
new file mode 100644
index 0000000..fa21073
--- /dev/null
+++ b/panels/wacom/calibrator/main.h
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2009 Tias Guns
+ * Copyright (c) 2009 Soren Hauberg
+ *
+ * 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.
+ */
+
+#ifndef _main_h
+#define _main_h
+
+#include "calibrator.h"
+
+
+/* strdup: non-ansi */
+char* my_strdup(const char* s);
+char* my_strdup(const char* s) {
+ size_t len = strlen(s) + 1;
+ void* p = malloc(len);
+
+ if (p == NULL)
+ return NULL;
+
+ return (char*) memcpy(p, s, len);
+}
+
+int find_device(const char*, bool, bool, XID*, const char**, XYinfo*);
+
+static void usage(char* cmd, unsigned thr_misclick);
+
+struct Calib* main_common(int argc, char** argv);
+
+struct Calib* CalibratorXorgPrint(const char* const device_name, const XYinfo *axys,
+ const bool verbose, const int thr_misclick, const int thr_doubleclick,
+ const char* geometry);
+
+bool finish_data(struct Calib*, const XYinfo new_axys, int swap_xy);
+bool output_xorgconfd(struct Calib*, const XYinfo new_axys, int swap_xy, int new_swap_xy);
+
+int main(int argc, char** argv);
+
+#endif
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]