On Mon, Jun 04, 2012 at 08:19:51AM +0200, Cedric Sodhi wrote:
> On Mon, Jun 04, 2012 at 09:58:27AM +1000, Peter Hutterer wrote:
> > On Thu, May 31, 2012 at 08:02:18PM +0200, Cedric Sodhi wrote:
> > > Hello,
> > > 
> > > now there ais all kind of multiness involved with wacom,
> > > 
> > > Multitouch (as in, well, multitouch),
> > > 
> > > Multiple Pointers (as in, one or more pointers from the touchscreen,
> > > others from the digizizer, ...)
> > > 
> > > Multiple Devices (as in, touchscreen, digitizer, yet another
> > > touchscreen, ...)
> > > 
> > > all of which become increasingly important. I'm particularly affected
> > > because my computer, a tablet by the name of "EEE Slate" consists of the
> > > following two devices
> > > 
> > > * A Wacom ISDV4 Digitizer
> > > * An EETI eGalax Touchscreen, also powered by the Wacom driver (thanks
> > > to Chris and Ben Tissoires from linux-input at this point again, without
> > > whom I'd not have gotten this to work in the first place)
> > > 
> > > Which it is of course not the canonical case, one may equally imagine
> > > the same situation with the eGalax replaced by some Wacom touchscreen.
> > > 
> > > For my personal case, I've solved the dilemma of the touchscreen and the
> > > wacom fighting with eachother by adding some rather ugly hacks to the X
> > > driver, none of which is sustainable or desirable in the long run.
> > > 
> > > There is still the multitouch issue - with the newest X.org and evdev I
> > > could use multitouch, indeed, and thereby abandon wacom.
> > > 
> > > Long story short:
> > > 
> > > How are things to proceed from here. Is there a master plan which
> > > rectifies all the three issues at once and provides one consistent
> > > solution for arbitrary configurations, and also incorporates multitouch
> > > and multipointer?
> > > 
> > > I know the whole issue spreads through all layers of the input-world,
> > > from the x-driver, to the kernel level.
> > > 
> > > I guess people like Peter have the ultimate overview of the whole
> > > sitation. I'd like to contribute, preferably at the X driver layer, but
> > > the current situation is very unclear to me - I don't even want to think
> > > of wayland, which just makes the future possibilities even less
> > > transparent.
> > > 
> > > Could you sum up the whole situation in a few short sentences and
> > > outline which responsibility goes where and which issues have already
> > > been solved or subjected to a plan which is meant to solve them?
> > > 
> > > To sum up, what's the situation of and relation among
> > > 
> > > MPX <->
> > >   Multitouch <->
> > >      Precedence and MPX/Multitouch accross multiple,
> > >            inherently unrelated (arbitrary) devices
> > > 
> > > in wacom and linux input in general?
> > 
> > MPX and multitouch are orthogonal and neither affects the other. You can
> > have multiple MPX master devices that support multitouch.
> > 
> > Within the wacom driver we have code to ignore touch if pen input is active,
> > but this code doesn't trigger if the devices are driven by different
> > drivers. I don't really have a good answer here, the input drivers are too
> > isolated from each other to do anything in the driver, so what we'll need is
> > most likely some client-side support thing, similar to syndaemon.
> > not impossible but tricky, though it should be easier with the new
> > per-device idletime counters.
> 
> Well yes, that apparently is status quo. So I may interpret your reply
> as a "No" with regard to the question, whether such precedence mechanism
> is planned or available?
> 
> I did not particularly hope that this would be the answer, but I
> expected it. In fact, I meant to imply that if this is not the case, I'd
> like to change that (thought I had the impression the issue were already
> being addressed by novelties in the kernel's event code and >XI2.2).
> 
> In that case, I will reply on the xorg list with a suggestion how to
> implement such "precedence" mechanism in Xorg, natively - so that it may
> generically be used for any combination of Devices, multitouch or not,
> on the same bus or not.

I don't think there will be a good option to do this generically, it relies
on a lot of context. server 1.13 will have per-device idletimers so it will
be easy to watch the idle time on each device and deactivate others based on
that.
e.g. in your case, you'll likely disable the touch device whenever the pen
idletimer goes to 0 and re-enable if it goes back to e.g. 500ms.

I've attached a test program that I used to debug the idle counters, this
will be a good starting point.

Cheers,
  Peter
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <stdint.h>
#include <assert.h>

#include <X11/Xlib.h>
#include <X11/extensions/sync.h>

int have_xsync_extension(Display *dpy)
{
    int event_base = 0;
    int error_base;
    int major = 3, minor = 1;

    if (!XSyncInitialize(dpy, &major, &minor))
        return 0;

    printf("XSync %d.%d\n", major, minor);

    if (!XSyncQueryExtension(dpy, &event_base, &error_base))
        return 0;

    return event_base;
}

void print_system_counters(Display *dpy)
{
    XSyncSystemCounter *counters;
    int ncounters;
    int i;
    uint64_t resolution;

    printf("System counters available:\n");
    counters = XSyncListSystemCounters(dpy, &ncounters);

    for (i = 0; i < ncounters; i++) {
        resolution = (uint64_t)counters[i].resolution.hi << 32 | 
counters[i].resolution.lo;
        printf("        %s (%ld): resolution %ld\n",
                counters[i].name,
                counters[i].counter,
                resolution);
    }

    XSyncFreeSystemCounterList(counters);
}

XSyncCounter get_idle_counter(Display *dpy)
{
    XSyncSystemCounter *counters;
    static XSyncCounter idle = 0;
    int ncounters;
    int i;

    if (idle != 0)
        return idle;

    counters = XSyncListSystemCounters(dpy, &ncounters);

    for (i = 0; i < ncounters; i++) {
        if (strcmp(counters[i].name, "IDLETIME") == 0)
        {
            idle = counters[i].counter;
            break;
        }
    }

    XSyncFreeSystemCounterList(counters);

    return idle;
}

XSyncCounter get_idle_counter_for_device(Display *dpy, int deviceid)
{
    XSyncSystemCounter *counters;
    XSyncCounter idle = 0;
    int ncounters;
    int i;
    char name[25];

    counters = XSyncListSystemCounters(dpy, &ncounters);

    sprintf(name, "DEVICEIDLETIME %d", deviceid);
    for (i = 0; i < ncounters; i++) {
        if (strcmp(counters[i].name, name) == 0)
        {
            idle = counters[i].counter;
            break;
        }
    }

    XSyncFreeSystemCounterList(counters);

    return idle;
}

void _watch_counter(Display *dpy, XSyncCounter counter,
                   int timeout, int delta, XSyncValueType mode,
                   XSyncTestType test)
{
    XSyncAlarmAttributes attr;
    unsigned long mask;
    XSyncValue _delta, _timeout;
    XSyncAlarm alarm;

    memset(&attr, 0, sizeof(attr));

    mask = XSyncCACounter | XSyncCAValueType | XSyncCAValue |
           XSyncCATestType | XSyncCADelta | XSyncCAEvents;

    XSyncIntToValue(&_delta, delta); /* delta value */
    XSyncIntToValue(&_timeout, timeout); /* ms */

    attr.events = True;
    attr.trigger.counter = counter;
    attr.trigger.value_type = mode;
    attr.trigger.test_type = test;
    attr.trigger.wait_value = _timeout;
    attr.delta = _delta;

    alarm = XSyncCreateAlarm(dpy, mask, &attr);
    printf("alarm is %ld\n", alarm);

}

void watch_counter_positive(Display *dpy, XSyncCounter counter,
        int timeout, int delta)
{
    _watch_counter(dpy, counter, timeout, delta, XSyncAbsolute,
            XSyncPositiveTransition);
}

void watch_counter_negative(Display *dpy, XSyncCounter counter,
        int timeout, int delta)
{
    _watch_counter(dpy, counter, timeout, delta, XSyncAbsolute,
            XSyncNegativeTransition);
}

void print_alarm(Display *dpy, XSyncAlarmNotifyEvent *event)
{
    uint64_t counter, alarm;

    counter = (uint64_t)XSyncValueHigh32(event->counter_value) << 32 | 
XSyncValueLow32(event->counter_value);
    alarm = (uint64_t)XSyncValueHigh32(event->alarm_value) << 32 | 
XSyncValueLow32(event->alarm_value);

    printf("AlarmNotify on %ld: counter %ld alarm %ld state %d\n", event->alarm,
            counter, alarm, event->state);
}

int main (int argc, char **argv)
{
    Display *dpy;
    int event_base = 0;
    XSyncCounter idle;
    int deviceid = 0;

    dpy = XOpenDisplay(NULL);
    assert(dpy);

    event_base = have_xsync_extension(dpy);
    if (!event_base) {
        printf ("Could not find XSYNC extension\n");
        return 1;
    }

    if (argc > 1)
        deviceid = atoi(argv[1]);

    print_system_counters(dpy);

    if (deviceid)
        idle = get_idle_counter_for_device(dpy, deviceid);
    else
        idle = get_idle_counter(dpy);

    /* 0.5 seconds idle */
    watch_counter_positive(dpy, idle, 500, 0);
    /* when we break idle */
    watch_counter_negative(dpy, idle, 500, 0);
    XFlush(dpy);

    while(1)
    {
        XEvent ev;
        XNextEvent(dpy, &ev);

        if (ev.type == event_base + XSyncAlarmNotify)
            print_alarm(dpy, (XSyncAlarmNotifyEvent*)&ev);
    }

    XCloseDisplay(dpy);

    return 0;
}
------------------------------------------------------------------------------
Live Security Virtual Conference
Exclusive live event will cover all the ways today's security and 
threat landscape has changed and how IT managers can respond. Discussions 
will include endpoint security, mobile security and the latest in malware 
threats. http://www.accelacomm.com/jaw/sfrnl04242012/114/50122263/
_______________________________________________
Linuxwacom-devel mailing list
Linuxwacom-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linuxwacom-devel

Reply via email to