On Tue, Mar 22, 2011 at 12:13:13AM +0100, Eduard Hasenleithner wrote:
> Here I have a very early draft for setting the Intuos4 OLED display by
> means of xsetwacom.
nice work!
> It defines a new pseudo-property "Wacom Button Image". When
> XChangeDeviceProperty is called with a 2049 octet data, the first
> octet is taken as the button number, and the remaining 2048 octets are
> taken as the image.
this approach isn't all too different to the button mapping. It may be
better to have this nested, i.e. have the button image property contain
atoms that themselves contain the actual image data.
so you have
Wacom Button Immage: 543 562
Wacom Image 1 (543): <image data>
Wacom Image 2 (562): <image data>
(see pixmap comment below though)
> Basic working principle:
> * In wcmUSB.c, at device start (usbStart) the corresponding USB-FS bus
> and device number is derived from the event device. This is done by
> exploiting the layout of "sysfs". Starting at the event char device
> "/sys/dev/char/major:minor" and going into the fourth parent directory
> "../../../.." "busnum" and "devnum" can be read from USB-FS.
> * In wcmXCommand, the Image is sent to the USB device by means of USB-FS.
> * xsetwacom reads a PGM image file for setting the button image
if you're introducing a new format, you should define it as a property and
then use the Atom of this as type. This allows clients to make sure that the
data they're uploading is correct.
similar to the Floating property, in fact. that too isn't a predefined
format but allocated at runtime by the server.
>
> Current rough edges:
> * Relies on sysfs being present
> * Relies on sysfs being accessible using "/sys/dev/char/%d:%d/../../../../%s"
> * Relies on USB-FS "mounted" on /dev/bus/usb
> * No error checks yet
> * No comments
>
> The current version of this patch is not for inclusion into the x11
> wacom driver, but to show a "Proof of Concept" and to support
> discussion if LED support can be included in xsetwacom, and how it has
> to be done.
>
> Questions:
> * Is it possible to link to further libraries? E.g. it might be
> convenient to have xsetwacom setting directly "text" to the buttons.
yes. might make sense to support e.g. png in xsetwacom and convert
internally. I think the easiest way to do this (especially when going the
pixmap path) would be to use cairo.
> * It might be better to use libsysfs to access sysfs. Can we link against it?
yes.
> * Should all the Image functions be moved into a separate file (e.g.
> wcmButtonImage.c)?
yes please
> * Can we use the rendering capabilities of the X-server and send an
> PIXMAP by means of XChangeDeviceProperty?
I think this may be the best option though I need some confirmation from the
graphics guys. That way the property code would be quite simple too, the
property data is simply the drawable ID.
> diff --git a/include/wacom-properties.h b/include/wacom-properties.h
> index dfa454d..023ab2c 100644
> --- a/include/wacom-properties.h
> +++ b/include/wacom-properties.h
> @@ -89,6 +89,7 @@
> if this button is pressed. If the value is None, no action is performed.
> */
> #define WACOM_PROP_BUTTON_ACTIONS "Wacom Button Actions"
> +#define WACOM_PROP_BUTTON_IMAGE "Wacom Button Image"
>
> /* 8 bit, 2 values, priv->debugLevel and common->debugLevel. This property
> * is for use in the driver only and only enabled if --enable-debug is
> diff --git a/src/wcmUSB.c b/src/wcmUSB.c
> index 06f8655..e2acf43 100644
> --- a/src/wcmUSB.c
> +++ b/src/wcmUSB.c
> @@ -26,6 +26,7 @@
> #include <asm/types.h>
> #include <linux/input.h>
> #include <sys/utsname.h>
> +#include <sys/stat.h>
> #include <linux/version.h>
>
> #define MAX_USB_EVENTS 32
> @@ -127,10 +128,13 @@ static Bool usbDetect(InputInfoPtr pInfo)
>
> /*****************************************************************************
> * usbStart --
>
> ****************************************************************************/
> +#define FORMAT "/sys/dev/char/%d:%d/../../../../%s"
> static int
> usbStart(InputInfoPtr pInfo)
> {
> int err;
> + WacomDevicePtr priv = (WacomDevicePtr)pInfo->private;
> + struct stat stat;
>
> #ifdef EVIOCGRAB
> /* Try to grab the event device so that data don't leak to
> /dev/input/mice */
> @@ -142,6 +146,21 @@ usbStart(InputInfoPtr pInfo)
> xf86Msg(X_ERROR, "%s: Wacom X driver can't grab event device
> (%s)\n",
> pInfo->name, strerror(errno));
> #endif
> +
> + if (fstat(pInfo->fd, &stat) >= 0) {
> + FILE *f;
> + char str[100];
> + snprintf(str, sizeof str, FORMAT,
> + major(stat.st_rdev), minor(stat.st_rdev), "busnum");
> + f = fopen(str, "r");
> + fscanf(f, "%hhd", &priv->usbdev_bus);
> + fclose(f);
> + snprintf(str, sizeof str, FORMAT,
> + major(stat.st_rdev), minor(stat.st_rdev), "devnum");
> + f = fopen(str, "r");
> + fscanf(f, "%hhd", &priv->usbdev_dev);
> + fclose(f);
> + }
> return Success;
> }
>
> diff --git a/src/wcmXCommand.c b/src/wcmXCommand.c
> index 4f702b7..4904da0 100644
> --- a/src/wcmXCommand.c
> +++ b/src/wcmXCommand.c
> @@ -25,6 +25,11 @@
> #include "wcmFilter.h"
> #include <exevents.h>
>
> +#include <linux/usbdevice_fs.h>
> +#include <sys/ioctl.h>
> +#include <fcntl.h>
> +#include <unistd.h>
> +
>
> /*****************************************************************************
> * wcmDevSwitchModeCall --
>
> *****************************************************************************/
> @@ -86,6 +91,7 @@ Atom prop_gesture_param;
> Atom prop_hover;
> Atom prop_tooltype;
> Atom prop_btnactions;
> +Atom prop_btn_img;
> #ifdef DEBUG
> Atom prop_debuglevels;
> #endif
> @@ -216,6 +222,7 @@ void InitWcmDeviceProperties(InputInfoPtr pInfo)
> /* default to no actions */
> memset(values, 0, sizeof(values));
> prop_btnactions = InitWcmAtom(pInfo->dev, WACOM_PROP_BUTTON_ACTIONS,
> -32, WCM_MAX_MOUSE_BUTTONS, values);
> + prop_btn_img = InitWcmAtom(pInfo->dev, WACOM_PROP_BUTTON_IMAGE, -32,
> WCM_MAX_MOUSE_BUTTONS, values);
>
> #ifdef DEBUG
> values[0] = priv->debugLevel;
> @@ -423,6 +430,42 @@ static int wcmSetPropertyButtonActions(DeviceIntPtr dev,
> Atom property,
> return Success;
> }
>
> +#define WACOM_SET_LED_IMG _IOW(0x00, 0x00, struct wacom_led_img)
> +#define WACOM_SET_LEFT_HANDED _IOW(0x00, 0x01, struct wacom_handedness)
> +#define WACOM_SET_LED_MODE _IOW(0x00, 0x02, struct wacom_led_mode)
the latter two don't seem to be used?
> +
> +struct wacom_led_img {
> + char buf[2048];
> + int btn;
> +};
> +
> +static int wcmSetButtonImage(DeviceIntPtr dev, Atom property,
> + XIPropertyValuePtr prop, BOOL checkonly)
> +{
> + InputInfoPtr pInfo = (InputInfoPtr) dev->public.devicePrivate;
> + WacomDevicePtr priv = (WacomDevicePtr) pInfo->private;
> + int rv, dev_fd;
> + struct wacom_led_img img;
> + struct usbdevfs_ioctl wrapper;
> + char str[100];
> + unsigned char *data = prop->data;
> + snprintf(str, sizeof str, "/dev/bus/usb/%03d/%03d",
> + priv->usbdev_bus, priv->usbdev_dev);
> + /* TODO: check prop length */
> + dev_fd = open(str, O_RDWR);
> +
> + img.btn = data[0];
> + memcpy(img.buf, data+1, sizeof img.buf);
> +
> + wrapper.ifno = 0;
> + wrapper.ioctl_code = WACOM_SET_LED_IMG;
> + wrapper.data = &img;
> + rv = ioctl(dev_fd, USBDEVFS_IOCTL, &wrapper);
> +
> + close(dev_fd);
> + return Success;
> +}
> +
> struct wheel_strip_update_t {
> /* for CARD8 values, points to fields in struct to be updated */
> int *up1;
> @@ -774,6 +817,9 @@ 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_btn_img)
> + {
> + wcmSetButtonImage(dev, property, prop, checkonly);
> } else
> wcmSetActionProperties(dev, property, prop, checkonly);
>
> diff --git a/src/xf86WacomDefs.h b/src/xf86WacomDefs.h
> index e80afb0..fb0090f 100644
> --- a/src/xf86WacomDefs.h
> +++ b/src/xf86WacomDefs.h
> @@ -297,6 +297,9 @@ struct _WacomDeviceRec
> Atom btn_actions[WCM_MAX_BUTTONS];
> Atom wheel_actions[4];
> Atom strip_actions[4];
> +
> + unsigned char usbdev_bus;
> + unsigned char usbdev_dev;
> };
>
>
> /******************************************************************************
> diff --git a/tools/xsetwacom.c b/tools/xsetwacom.c
> index bb120c0..631fca9 100644
> --- a/tools/xsetwacom.c
> +++ b/tools/xsetwacom.c
> @@ -97,6 +97,7 @@ typedef struct _param
>
> /* get_func/set_func calls for special parameters */
> static void map_button(Display *dpy, XDevice *dev, param_t *param, int argc,
> char **argv);
> +static void set_image(Display *dpy, XDevice *dev, param_t *param, int argc,
> char **argv);
> static void map_wheels(Display *dpy, XDevice *dev, param_t* param, int argc,
> char **argv);
> static void set_mode(Display *dpy, XDevice *dev, param_t *param, int argc,
> char **argv);
> static void get_mode(Display *dpy, XDevice *dev, param_t *param, int argc,
> char **argv);
> @@ -128,6 +129,11 @@ static param_t parameters[] =
> .get_func = get_button,
> },
> {
> + .name = "Image",
> + .desc = "button image",
> + .set_func = set_image,
> + },
> + {
> .name = "ToolDebugLevel",
> .desc = "Level of debugging trace for individual tools "
> "(default is 0 [off]). ",
> @@ -1301,6 +1307,35 @@ static void map_button(Display *dpy, XDevice *dev,
> param_t* param, int argc, cha
> special_map_buttons(dpy, dev, param, button, argc - 1,
> &argv[1]);
> }
>
> +static void set_image(Display *dpy, XDevice *dev, param_t *param, int argc,
> char **argv)
> +{
> + int id, w, h, range, i;
> + Atom prop = None;
> + unsigned char data[2048+1];
> + unsigned char pixel[2];
> + char str[40];
> + FILE *f;
> +
> + sscanf(argv[0], "%hhd", data+0);
> + memset(data+1, id, sizeof data-1);
> + f = fopen(argv[1], "r");
> + fgets(str, sizeof str, f);
> + fscanf(f, "%d %d\n", &w, &h);
> + fscanf(f, "%d\n", &range);
> + for (i=1; i<2049; i++) {
> + fread(pixel, 1, sizeof pixel, f);
> + data[i] = pixel[0] >> 4;
> + }
> + fclose(f);
> + prop = XInternAtom(dpy, WACOM_PROP_BUTTON_IMAGE, True);
> + if (!prop)
> + {
> + fprintf(stderr, "WACOM_PROP_BUTTON_IMAGE not available");
> + return;
> + }
> + XChangeDeviceProperty(dpy, dev, prop, XA_INTEGER, 8, PropModeReplace,
> data, sizeof data);
> +}
> +
> static void set_xydefault(Display *dpy, XDevice *dev, param_t* param, int
> argc, char **argv)
> {
> Atom prop, type;
The interface I'd like to see in xsetwacom is to have
xsetwacom set "device" ButtonImage 1 file.pgm
instead of the button number hidden in the first byte. the button mapping
code can work as an example here. and of course, parsing png or similar
would be nice.
Cheers,
Peter
------------------------------------------------------------------------------
Enable your software for Intel(R) Active Management Technology to meet the
growing manageability and security demands of your customers. Businesses
are taking advantage of Intel(R) vPro (TM) technology - will your software
be a part of the solution? Download the Intel(R) Manageability Checker
today! http://p.sf.net/sfu/intel-dev2devmar
_______________________________________________
Linuxwacom-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/linuxwacom-devel