The AspectRatio property defines the aspect ratio of that portion
of the tablet's input Area property which should be considered active.
It is defined by two integers which correspond to the width and height
of the region. Being a ratio, both simplified (e.g. 4 3) and non-
simplified (e.g. 1600 1200) definitions are equal.

Ratios with a zero in them are considered incorrect, save for the
special ratio "0 0". This ratio essentially disables the property,
allowing the full use of the input Area.

By adjusting this property to match the aspect ratio of the mapped
output (be it the desktop, a single monitor, or arbitrary portion of
the screen the tablet has been mapped to), it should be possible to
draw a circle onscreen by drawing a circle on the tablet.
---
 include/wacom-properties.h |    9 +++++
 src/wcmCommon.c            |   77 ++++++++++++++++++++++++++++++++++++++------
 src/wcmXCommand.c          |   25 ++++++++++++++
 src/xf86WacomDefs.h        |    3 ++
 tools/xsetwacom.c          |    8 ++++
 5 files changed, 112 insertions(+), 10 deletions(-)

diff --git a/include/wacom-properties.h b/include/wacom-properties.h
index 67db742..c6d1471 100644
--- a/include/wacom-properties.h
+++ b/include/wacom-properties.h
@@ -112,4 +112,13 @@
 #define WACOM_PROP_XI_TYPE_PAD    "PAD"
 #define WACOM_PROP_XI_TYPE_TOUCH  "TOUCH"
 
+/* 32 bit, 2 values
+ * The two integers define the aspect ratio of the "active region" of the
+ * tablet defined by Area. The special ratio "0:0" is defined to mean the
+ * active region encompases the entire Area. If the ratio equals the aspect
+ * ratio of the output, a circle drawn on the tablet should produce a
+ * circle on the display.
+ */
+#define WACOM_PROP_ASPECT_RATIO "Wacom Aspect Ratio"
+
 #endif
diff --git a/src/wcmCommon.c b/src/wcmCommon.c
index e4ff7d9..e40e7d2 100644
--- a/src/wcmCommon.c
+++ b/src/wcmCommon.c
@@ -452,21 +452,79 @@ void wcmRotateAndScaleCoordinates(InputInfoPtr pInfo, 
int* x, int* y)
        AxisInfoPtr axis_x, axis_y;
        int tmp_coord;
 
-       /* scale into on topX/topY area */
        axis_x = &dev->valuator->axes[0];
        axis_y = &dev->valuator->axes[1];
 
-       /* Don't try to scale relative axes */
-       if (axis_x->max_value > axis_x->min_value)
-               *x = xf86ScaleAxis(*x, axis_x->max_value, axis_x->min_value,
-                                  priv->bottomX, priv->topX);
+       /* Scale non-relative axes from the active area to the advertised 
maximums */
+       if ((axis_x->max_value > axis_x->min_value) || (axis_y->max_value > 
axis_y->min_value))
+       {
+               int width, height;
+               int topX, topY, bottomX, bottomY;
 
-       if (axis_y->max_value > axis_y->min_value)
-               *y = xf86ScaleAxis(*y, axis_y->max_value, axis_y->min_value,
-                                  priv->bottomY, priv->topY);
+               /* Find the width and height of the Area in its rotated state */
+               if (common->wcmRotate == ROTATE_NONE || common->wcmRotate == 
ROTATE_HALF)
+               {
+                       width  = priv->bottomX - priv->topX;
+                       height = priv->bottomY - priv->topY;
+               }
+               else
+               {
+                       width  = priv->bottomY - priv->topY;
+                       height = priv->bottomX - priv->topX;
+               }
+
+               /* Adjust the width and height to match the desired aspect 
ratio */
+               if (priv->aspectX != 0 && priv->aspectY != 0)
+               {
+                       float toAspect = (float)priv->aspectX / 
(float)priv->aspectY;
+                       float fromAspect = (float)width / (float)height;
+
+                       if (fromAspect > toAspect)
+                               width = height * toAspect;
+                       else
+                               height = width / toAspect;
+               }
 
-       /* coordinates are now in the axis rage we advertise for the device */
+               /* Determine new top/bottom X/Y values to anchor the active area
+                * of the tablet at the top left, regardless of orientation.
+                */
+               switch (common->wcmRotate)
+               {
+                       case ROTATE_CW:
+                               topX = priv->bottomX - height;
+                               topY = priv->topY;
+                               bottomX = priv->bottomX;
+                               bottomY = priv->topY + width;
+                               break;
+                       case ROTATE_HALF:
+                               topX = priv->bottomX - width;
+                               topY = priv->bottomY - height;
+                               bottomX = priv->bottomX;
+                               bottomY = priv->bottomY;
+                               break;
+                       case ROTATE_CCW:
+                               topX = priv->topX;
+                               topY = priv->bottomY - width;
+                               bottomX = priv->topX + height;
+                               bottomY = priv->bottomY;
+                               break;
+                       case ROTATE_NONE:
+                       default:
+                               topX = priv->topX;
+                               topY = priv->topY;
+                               bottomX = priv->topX + width;
+                               bottomY = priv->topY + height;
+                               break;
+               }
+
+               /* Perform the actual scaling from active area to advertised 
area */
+               *x = xf86ScaleAxis(*x, axis_x->max_value, axis_x->min_value,
+                                  bottomX, topX);
+               *y = xf86ScaleAxis(*y, axis_y->max_value, axis_y->min_value,
+                                  bottomY, topY);
+       }
 
+       /* Rotate the axes if necessary */
        if (common->wcmRotate == ROTATE_CW || common->wcmRotate == ROTATE_CCW)
        {
                tmp_coord = *x;
@@ -489,7 +547,6 @@ void wcmRotateAndScaleCoordinates(InputInfoPtr pInfo, int* 
x, int* y)
                *y = axis_y->max_value - (*y - axis_y->min_value);
        }
 
-
        DBG(10, priv, "rotate/scaled to %d/%d\n", *x, *y);
 }
 
diff --git a/src/wcmXCommand.c b/src/wcmXCommand.c
index 5666bac..f1d722e 100644
--- a/src/wcmXCommand.c
+++ b/src/wcmXCommand.c
@@ -98,6 +98,7 @@ Atom prop_hover;
 Atom prop_tooltype;
 Atom prop_btnactions;
 Atom prop_product_id;
+Atom prop_aspect_ratio;
 #ifdef DEBUG
 Atom prop_debuglevels;
 #endif
@@ -236,6 +237,12 @@ void InitWcmDeviceProperties(InputInfoPtr pInfo)
        values[1] = common->tablet_id;
        prop_product_id = InitWcmAtom(pInfo->dev, XI_PROP_PRODUCT_ID, 32, 2, 
values);
 
+       if (!IsPad(priv))
+       {
+               memset(values, 0, sizeof(values));
+               prop_aspect_ratio = InitWcmAtom(pInfo->dev, 
WACOM_PROP_ASPECT_RATIO, 32, 2, values);
+       }
+
 #ifdef DEBUG
        values[0] = priv->debugLevel;
        values[1] = common->debugLevel;
@@ -828,6 +835,24 @@ int wcmSetProperty(DeviceIntPtr dev, Atom property, 
XIPropertyValuePtr prop,
                if (prop->size != WCM_MAX_MOUSE_BUTTONS)
                        return BadMatch;
                wcmSetPropertyButtonActions(dev, property, prop, checkonly);
+       } else if (property == prop_aspect_ratio)
+       {
+               INT32 *values = (INT32*)prop->data;
+
+               if (prop->size != 2 || prop->format != 32)
+                       return BadValue;
+
+               /* nonzero, nonzero = valid   (defined aspect ratio)
+                * zero, zero       = valid   (floating aspect ratio)
+                * ELSE             = invalid (nonsense aspect ratio) */
+               if ((values[0] && !values[1]) || (!values[0] && values[1]))
+                       return BadValue;
+
+               if (!checkonly)
+               {
+                       priv->aspectX = values[0];
+                       priv->aspectY = values[1];
+               }
        } else
                wcmSetActionProperties(dev, property, prop, checkonly);
 
diff --git a/src/xf86WacomDefs.h b/src/xf86WacomDefs.h
index 94eee2e..0760754 100644
--- a/src/xf86WacomDefs.h
+++ b/src/xf86WacomDefs.h
@@ -320,6 +320,9 @@ struct _WacomDeviceRec
        Atom strip_actions[4];
 
        OsTimerPtr serial_timer; /* timer used for serial number property 
update */
+
+       int aspectX;             /* numerator of aspect ratio; x dimension */
+       int aspectY;             /* denominator of aspect ratio; y dimension */
 };
 
 /******************************************************************************
diff --git a/tools/xsetwacom.c b/tools/xsetwacom.c
index ac474f2..23d06f2 100644
--- a/tools/xsetwacom.c
+++ b/tools/xsetwacom.c
@@ -412,6 +412,14 @@ static param_t parameters[] =
                .prop_flags = PROP_FLAG_WRITEONLY | PROP_FLAG_OUTPUT,
        },
        {
+               .name = "AspectRatio",
+               .desc = "Aspect ratio of the usable region of the tablet's 
Area.",
+               .prop_name = WACOM_PROP_ASPECT_RATIO,
+               .prop_format = 32,
+               .prop_offset = 0,
+               .arg_count = 2,
+       },
+       {
                .name = "all",
                .desc = "Get value for all parameters. ",
                .get_func = get_all,
-- 
1.7.6


------------------------------------------------------------------------------
Get a FREE DOWNLOAD! and learn more about uberSVN rich system, 
user administration capabilities and model configuration. Take 
the hassle out of deploying and managing Subversion and the 
tools developers use with it. http://p.sf.net/sfu/wandisco-d2d-2
_______________________________________________
Linuxwacom-devel mailing list
Linuxwacom-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linuxwacom-devel

Reply via email to