Hello,

I had some code using SDL2 and FreeRDP that *was* completely working
but now keyboard and mouse events seem to be delayed by one. Mouse
events happen so quickly this is usually not noticed, but the keyboard
events are noticeably strange.

The first keypress sent to the server seems to do nothing. The next
one triggers the reception of the first one, and so on, so that there
is always a pending event. Mouse events can trigger the proper
reception of a keyboard event as well. Some key presses do not
register; e.g. a backspace on the login prompt with a single character
left seems to not be received no matter how many key presses are sent.

If I use freerdp_input_send_keyboard_event I seem to generate two key
presses even if I set the flags to the DOWN and RELEASED flags for
each event, respectively.


It looks like freerdp is not processing the new events for some
reason, but I am not sure of any functions to call to ensure they are
processed. A worker thread is ticking along in the background and SDL2
is receiving events.

Cheers,
    R0b0t1

Here is a summary of what I am doing:

In a worker thread:

while(!freerdp_shall_disconnect(instance)) {
    DWORD status = WAIT_FAILED, n = 0, handle_index = 0;

    //  TODO: Add the input event queue's event to the waitable objects.
    // Cache this value.
    // It looks like no locking is required - leave this out?
    //handles[handle_index++] = Queue_Event(rdpc->input_messages);

    n = freerdp_get_event_handles(
        context, &handles[handle_index], 64 - handle_index
    );
    // TODO: n == 0 is an error, handle it.
    handle_index += n;

    status = WaitForMultipleObjects(
        handle_index, handles, FALSE, INFINITE
    );
    // TODO: status == WAIT_FAILED is an error, handle it.
    if (status == WAIT_FAILED) {
        break;
    }

    if (!freerdp_check_event_handles(context)) {
        // TODO: Autoreconnect?
        break;
    }
}


In the main thread:

switch (event.type) {
case SDL_QUIT:
    quit = true;
    break;
case SDL_WINDOWEVENT: {
    // TODO: Break this out into a function.
    switch (event.window.event) {
    case SDL_WINDOWEVENT_CLOSE: {
        quit = true;
    }
    }
    break;
}
case SDL_KEYDOWN: {
    freerdp_input_send_keyboard_event_ex(rdi->input, true,
        rdpuppet_scancode_sdl2_to_dinput(event.key.keysym.scancode)
    );
    break;
}
case SDL_KEYUP: {
    freerdp_input_send_keyboard_event_ex(rdi->input, false,
        rdpuppet_scancode_sdl2_to_dinput(event.key.keysym.scancode)
    );
    break;
}
case SDL_MOUSEMOTION: {
    freerdp_input_send_mouse_event(rdi->input,
        PTR_FLAGS_MOVE, event.motion.x, event.motion.y
    );
    break;
}
case SDL_MOUSEBUTTONDOWN:
case SDL_MOUSEBUTTONUP: {
    UINT16 ex = 0, flags = 0;

    //  Button up event is done by clearing PTR_FLAGS_DOWN but
    // leaving the button flag set.
    //  For now PTR_FLAGS_DOWN and PTR_XFLAGS_DOWN are the same;
    // if they were not, we would need to handle that here.
    if (event.button.state == SDL_PRESSED)
        flags |= PTR_FLAGS_DOWN;

    switch (event.button.button) {
    case SDL_BUTTON_LEFT:
        flags |= PTR_FLAGS_BUTTON1; break;
    case SDL_BUTTON_RIGHT:
        flags |= PTR_FLAGS_BUTTON2; break;
    case SDL_BUTTON_MIDDLE:
        flags |= PTR_FLAGS_BUTTON3; break;
    case SDL_BUTTON_X1:
        ex = 1;
        flags |= PTR_XFLAGS_BUTTON1; break;
    case SDL_BUTTON_X2:
        ex = 1;
        flags |= PTR_XFLAGS_BUTTON2; break;
    }

    if (!ex)
        freerdp_input_send_mouse_event(rdi->input,
            flags, event.button.x, event.button.y
        );
    else
        freerdp_input_send_extended_mouse_event(rdi->input,
            flags, event.button.x, event.button.y
        );
    break;
}
case SDL_MOUSEWHEEL: {
    UINT16 flags = 0;

    //  The code below assumes that horizontal and vertical
    // scrolling are not folded into the same event. The code will
    // not work if they are as there is only one flag for sign.
    if (event.wheel.x < 0 || event.wheel.y < 0)
        flags |= PTR_FLAGS_WHEEL_NEGATIVE;

    if (event.wheel.x)
        flags |= PTR_FLAGS_HWHEEL;

    if (event.wheel.y)
        flags |= PTR_FLAGS_WHEEL;

    //  Note that the absolute value of the scroll distance is not
    // taken.
    // TODO: Is PTR_FLAGS_WHEEL_NEGATIVE required?
    freerdp_input_send_mouse_event(rdi->input,
        flags, event.wheel.x, event.wheel.y
    );
    break;
}
}

------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
_______________________________________________
FreeRDP-devel mailing list
FreeRDP-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/freerdp-devel

Reply via email to