[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Bug#425969: XRecordEnableContextAsync work in lenny but not in sid.



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 to: