Package: xorg
Version: 1:7.2-3

XRecordEnableContextAsync works well with lenny up to date (xorg
1:7.1.0-18) but not with sid up to date (xorg 1:7.2-3
) on the same computer.
XRecordEnableContext works on twice.

I attach a little piece of code that work on lenny but not sid.

If you replace XRecordEnableContextAsync with XRecordEnableContext and remove
XRecordProcessReplies it work on sid too, but the record is
synchronous now and cannot be integrated in an interactive gui app.
I'm not sure which of XRecordEnableContextAsync and
XRecordProcessReplies doesn't do it's job correctly.

To reproduce the bug, build the code with gcc main.c -lX11 -lXtst, run
it and move the mouse. if it work, it should catch the mouse motion
and print it on stdout.
#include <X11/Xproto.h>
#include <X11/Xlib.h>
#include <X11/extensions/record.h>

#include <stdio.h>
#include <stdlib.h>

typedef union { 
  unsigned char    type ;
  xEvent           event ;
  xResourceReq     req   ;
  xGenericReply    reply ;
  xError           error ;
  xConnSetupPrefix setup;
} XRecordDatum ;


int click = 0;
int press = 0;
int release = 0;
int other = 0;
int event = 0;
int button1down = 0;
int button2down = 0;
int button3down = 0;
int distance = -1;
int oldX = 0;
int oldY = 0;

void dispatch(XPointer pointer, XRecordInterceptData *data)
{
    if ((data==NULL) || (!data->data))
    {
        XRecordFreeData(data);
        return;
    }

    ++event;
    XRecordDatum *xrec_data  = (XRecordDatum *) data->data;
    if (data->category == XRecordFromServer)
    {
        switch (xrec_data->type)
        {
        case MotionNotify:
                if (distance >= 0)
                {
                    int x = xrec_data->event.u.keyButtonPointer.rootX - oldX;
                    int y = xrec_data->event.u.keyButtonPointer.rootY - oldY;
                    distance += x*x + y*y;
                }
                else
                {
                    distance = 0;
                }

                oldX = xrec_data->event.u.keyButtonPointer.rootX;
                oldY = xrec_data->event.u.keyButtonPointer.rootY;
            break;

        case ButtonPress:
            if (xrec_data->event.u.u.detail == Button1)
            {
                button1down = 1;
            }
            else if (xrec_data->event.u.u.detail == Button2)
            {
                button2down = 1;
            }
            else if (xrec_data->event.u.u.detail == Button3)
            {
                button3down = 1;
            }
            break;

        case ButtonRelease:
            if (xrec_data->event.u.u.detail == Button1)
            {
                if (button1down)
                {
                    click++;
                }
                button1down = 0;
            }
            else if (xrec_data->event.u.u.detail == Button2)
            {
                if (button2down)
                {
                    click++;
                }
                button2down = 0;
            }
            else if (xrec_data->event.u.u.detail == Button3)
            {
                if (button3down)
                {
                    click++;
                }
                button3down = 0;
            }
            break;

        }
    }
    else
    {
        ++other;
    }


    XRecordFreeData(data);

    printf("Events n°%i ** clicks : %i ** distance : %i ** other : %i\n", event, click, distance, other);
}


int main(int argc, char **argv)
{

    char *display_name = getenv ("DISPLAY");
    Display *dpy = XOpenDisplay(display_name);
    if (!dpy)
    {
        // unable to open display
        printf("fail to open display\n");
        return -1;
    }

    XRecordClientSpec xrcs[1];
    xrcs[0] = XRecordAllClients;

    XRecordRange *xr_range = XRecordAllocRange();
    XRecordRange *xr_array[1];
    xr_array[0] = xr_range;

    if (!xr_range)
    {
        printf("fail to create range\n");
        XCloseDisplay(dpy);
        return -1;
    }

    xr_range->delivered_events.first = ButtonPress;
    xr_range->delivered_events.last = MotionNotify;

    XRecordContext xrc = XRecordCreateContext(
        dpy,
        XRecordFromServerTime,
        xrcs,
        1,
        xr_array,
        1
    );

    int res  = XRecordEnableContextAsync(dpy, xrc, dispatch, 0);

    if (res != 0)
    {
        printf("XRecord enabled\n");
        while (click <= 10)
        {
            XRecordProcessReplies(dpy);
        }
    }
    else
    {
        printf("fail to work\n");
    }

    XRecordDisableContext(dpy, xrc);
    XRecordFreeContext(dpy, xrc);
    XFree(xr_range);
    XCloseDisplay(dpy);
    printf("quit\n");

    return 0;
}

Reply via email to