Sending string (of characters) to active window - Xwindows

This is a discussion on Sending string (of characters) to active window - Xwindows ; Hello, I wrote a simple program that reads the characters from external device (bar code scanner) from serial port (/dev/ttyS1) and feeds it to the currently active window (using XSendEvent). Program works fine on faster computers, but on slow ones ...

+ Reply to Thread
Results 1 to 3 of 3

Thread: Sending string (of characters) to active window

  1. Sending string (of characters) to active window

    Hello,

    I wrote a simple program that reads the characters from external device
    (bar code scanner) from serial port (/dev/ttyS1) and feeds it to the
    currently active window (using XSendEvent).

    Program works fine on faster computers, but on slow ones the situation
    happens (very often) that characters don't get received in the same
    order they were sent. For example, scanner sends 1234567 to serial port,
    my program sends char events 1234567, but the active program (xterm for
    example) receives 3127456.

    Does anyone have an idea how to force the "order" of characters?

    Or is there some other way to send a string to the active window (I
    don't even mind using an external program if needed)?

    Here's the code, perhaps I'm just doing something wrong:

    bckf.cpp
    //-----------------------------------------------------------------------------
    #include
    #include
    #include
    #include
    #include
    #include // serial port stuff
    #include
    #include
    #include
    #include

    /*
    BarCode KeyboardFeeder: BCKF
    Copyright (c) Milan Babuskov 2006.
    Licence: GNU General Public Licence

    Compile:
    g++ bckf.cpp -lX11 -L /usr/X11R6/lib/ -o bckf

    Hint for keycodes: /usr/X11R6/include/X11/keysymdef.h
    */
    //-----------------------------------------------------------------------------
    void SendEvent(XKeyEvent *event, bool press)
    {
    // I tried this, without success
    // XSync(event->display, False);

    if (press)
    XSendEvent(event->display, event->window, True, KeyPressMask,
    (XEvent *)event);
    else
    XSendEvent(event->display, event->window, True, KeyReleaseMask,
    (XEvent *)event);
    XSync(event->display, False);
    }
    //-----------------------------------------------------------------------------
    bool sendChar(int c)
    {
    if (c >= 0x08 && c <= 0x1b) // send a newline
    {
    sendChar(0xff0d);
    c = 0xff0d;
    }

    printf("Sending char : 0x%02x\n", c);
    char disp[] = ":0";
    char *dp = getenv("DISPLAY");
    if (!dp)
    dp = disp;
    else
    printf("Using env.variable $DISPLAY = %s.\n", dp);
    Display *dpy = XOpenDisplay(dp);
    if (dpy == NULL)
    {
    printf("ERROR! Couldn't connect to display %s.\n", dp);
    return false;
    }
    else
    {
    Window cur_focus; // focused window
    int revert_to; // focus state
    // get window with focus
    XGetInputFocus(dpy, &cur_focus, &revert_to);
    if (cur_focus == None)
    {
    printf("WARNING! No window is focused\n");
    return true;
    }
    else
    {
    XKeyEvent event;
    event.display = dpy;
    event.window = cur_focus;
    event.root = RootWindow(event.display,
    DefaultScreen(event.display));
    event.subwindow = None;
    event.time = CurrentTime;
    event.x = 1;
    event.y = 1;
    event.x_root = 1;
    event.y_root = 1;
    event.same_screen = True;
    event.type = KeyPress;
    event.state = 0;
    event.keycode = XKeysymToKeycode(dpy, c);
    SendEvent(&event, true);
    event.type = KeyRelease;
    SendEvent(&event, false);
    }
    XCloseDisplay(dpy);
    }

    // I tried this, without success
    // usleep(20);
    return true;
    }
    //-----------------------------------------------------------------------------
    // Forward declaration
    int InitComPort(const char *port);
    //-----------------------------------------------------------------------------
    int main(int argc, char **argv)
    {
    if (argc != 2)
    {
    printf("Usage: bckf serial_port\n");
    return 1;
    }

    int port = InitComPort(argv[1]);
    if (port == -1)
    return 1;

    while (true)
    {
    char buf[10];
    ssize_t res = read(port, buf, 1);
    if (res > 0)
    {
    int c = buf[0];
    printf("Received char: 0x%02x\n", c);
    if (c >= '0' && c <= '9' || c >= 0x08 && c <= 0x1b)
    if (!sendChar(c)) // called from console?
    break;
    }
    }
    return 0;
    }
    //-----------------------------------------------------------------------------
    int InitComPort(const char *port)
    {
    int c, res;
    struct termios newtio;
    struct termios oldtio;

    int fdSerial = open(port, O_RDWR | O_NOCTTY );
    if (fdSerial < 0)
    {
    printf(0, "Cannot opet port: %s\n%s", port,
    strerror(errno));
    return -1;
    }

    tcgetattr(fdSerial,&oldtio); // save current port settings
    memset(&newtio, 0, sizeof(newtio));
    newtio.c_cflag = B9600 | CS8 | CLOCAL | CREAD;
    newtio.c_iflag = IGNPAR;
    newtio.c_oflag = 0;
    //newtio.c_cc[VTIME] = timeout;
    newtio.c_cc[VMIN] = 1;
    tcflush(fdSerial, TCIOFLUSH);
    tcsetattr(fdSerial,TCSANOW,&newtio);
    return fdSerial;
    }
    //-----------------------------------------------------------------------------


    Thanks in advance,

    --
    Milan Babuskov
    http://njam.sourceforge.net
    http://swoes.blogspot.com

  2. Re: Sending string (of characters) to active window

    Milan Babuskov writes:

    > Hello,
    >
    > I wrote a simple program that reads the characters from external
    > device (bar code scanner) from serial port (/dev/ttyS1) and feeds it
    > to the currently active window (using XSendEvent).
    >
    > Program works fine on faster computers, but on slow ones the situation
    > happens (very often) that characters don't get received in the same
    > order they were sent. For example, scanner sends 1234567 to serial
    > port, my program sends char events 1234567, but the active program
    > (xterm for example) receives 3127456.
    >
    > Does anyone have an idea how to force the "order" of characters?


    The ideal way would be to somehow make the X server read from the
    serial port itself. How to this will obviously vary depending which X
    server you use.

    --
    Måns Rullgård
    mru@inprovide.com

  3. Re: Sending string (of characters) to active window

    Måns Rullgård wrote:
    > The ideal way would be to somehow make the X server read from the
    > serial port itself. How to this will obviously vary depending which X
    > server you use.


    xorg


    --
    Milan Babuskov
    http://njam.sourceforge.net
    http://swoes.blogspot.com

+ Reply to Thread