Esempio n. 1
0
/*
 * Private function name:   vnc_refresh_screen
 * Since version:           0.4.1(-3)
 * Description:             Function to send the key to VNC window to refresh the screen
 * Arguments:               @server [string]: server string to connect to
 *                          @port [string]: string version of port value to connect to
 *                          @scancode [int]: scancode to be sent to the guest's VNC window
 * Returns:                 0 on success, -errno otherwise
 */
int vnc_refresh_screen(char *server, char *port, int scancode)
{
    int sfd;
    tServerFBParams params;

    DPRINTF("%s: Server is %s, port is %s, scancode is %d\n", VNCFUNC, server, port, scancode);

    DPRINTF("%s: server is %s, port is %s\n", VNCFUNC, server, port);

    sfd = vnc_connect(server, port, 1);
    if (sfd < 0) {
        int err = errno;
        DPRINTF("%s: VNC Connection failed with error code %d (%s)\n", VNCFUNC, err, strerror(err));
        close(sfd);
        return -err;
    }

    params = vnc_read_server_init(sfd);

    DPRINTF("%s: Sending key press emulation for key %d\n", VNCFUNC, scancode);
    if (scancode > -1)
        vnc_send_key(sfd, scancode, 1, 0);

    DPRINTF("%s: Requesting framebuffer update\n", VNCFUNC);
    vnc_send_framebuffer_update_request(sfd, 1, params);

    shutdown(sfd, SHUT_RDWR);
    close(sfd);
    DPRINTF("%s: Closed descriptor #%d\n", VNCFUNC, sfd);
    return 0;
}
Esempio n. 2
0
/*
 * Private function name:   vnc_send_keys
 * Since version:           0.4.2
 * Description:             Function to send the key to VNC window
 * Arguments:               @server [string]: server string to specify VNC server
 *                          @port [string]: string version of port value to connect to
 *                          @keys [string]: string to be send to the guest's VNC window
 * Returns:                 0 on success, -errno otherwise
 */
int vnc_send_keys(char *server, char *port, char *keys)
{
    int sfd;
    int i, skip_next;
    tServerFBParams params;

    DPRINTF("%s: server is %s, port is %s, keys are '%s'\n", VNCFUNC, server, port, keys);

    sfd = vnc_connect(server, port, 1);
    if (sfd < 0) {
        int err = errno;
        DPRINTF("%s: VNC Connection failed with error code %d (%s)\n", VNCFUNC, err, strerror(err));
        close(sfd);
        return -err;
    }

    params = vnc_read_server_init(sfd);

    skip_next = 0;
    DPRINTF("%s: About to process key sequence '%s' (%d keys)\n", VNCFUNC, keys, (int)strlen(keys));
    for (i = 0; i < strlen(keys); i++) {
        DPRINTF("%s: Processing key %d: %d [0x%02x]\n", VNCFUNC, i, keys[i], keys[i]);
        if (skip_next) {
            skip_next = 0;
            continue;
        }
        /* Handling for escape characters */
        if ((keys[i] == '\\') && (strlen(keys) > i + 1)) {
            if (keys[i + 1] == 'n')
                keys[i] = 13;
            if (keys[i + 1] == 'r')
                keys[i] = 10;

            skip_next = 1;
        }

        DPRINTF("%s: Sending key press emulation for key %d\n", VNCFUNC, keys[i]);
        vnc_send_key(sfd, keys[i], skip_next, 0);
        DPRINTF("%s: Requesting framebuffer update\n", VNCFUNC);
        vnc_send_framebuffer_update_request(sfd, 1, params);
        DPRINTF("%s: Sending key release emulation for key %d\n", VNCFUNC, keys[i]);
        vnc_send_key(sfd, keys[i], skip_next, 1);

        /* Sleep for 50 ms, required to make VNC server accept the keystroke emulation */
        usleep(50000);
    }

    DPRINTF("%s: All %d keys sent\n", VNCFUNC, (int)strlen(keys));

    while (socket_has_data(sfd, 500000, 0) == 1)
        socket_read(sfd, -1);

    shutdown(sfd, SHUT_RDWR);
    close(sfd);
    DPRINTF("%s: Closed descriptor #%d\n", VNCFUNC, sfd);
    return 0;
}
Esempio n. 3
0
/*
 * Private function name:   vnc_send_pointer_event
 * Since version:           0.4.2
 * Description:             Function to send the mouse pointer event/click to VNC window
 * Arguments:               @server [string]: server string to specify VNC server
 *                          @port [string]: string version of port value to connect to
 *                          @pos_x [int]: position on x-axis of the VNC window
 *                          @pos_y [int]: position on y-axis of the VNC window
 *                          @clicked [int]: mask of what buttons were clicked
 *                          @release [boolean]: release the buttons once clicked
 * Returns:                 0 on success, -errno otherwise
 */
int vnc_send_pointer_event(char *server, char *port, int pos_x, int pos_y, int clicked, int release)
{
    int sfd;
    tServerFBParams params;

    DPRINTF("%s: Server is %s, port is %s, x is %d, y is %d, clicked is %d, release is %d\n", VNCFUNC,
            server, port, pos_x, pos_y, clicked, release);

    sfd = vnc_connect(server, port, 0);
    if (sfd < 0) {
        int err = errno;
        DPRINTF("%s: VNC Connection failed with error code %d (%s)\n", VNCFUNC, err, strerror(err));
        close(sfd);
        return -err;
    }

    params = vnc_read_server_init(sfd);

    if (((pos_x > params.width) || (pos_y < 0))
        || ((pos_y > params.height) || (pos_y < 0))) {
        DPRINTF("%s: Required positions out of range (width = %d, height = %d, x = %d, y = %d) for '%s'\n",
                VNCFUNC, params.width, params.height, pos_x, pos_y, params.desktopName);
        return -EINVAL;
    }

    socket_read(sfd, -1);
    vnc_set_pixel_format(sfd, params);
    vnc_set_encoding(sfd);
    socket_read(sfd, -1);
    usleep(50000);

    /* Following paragraph moves mouse pointer to [0, 0] (left upper corner) */
    vnc_send_client_pointer(sfd, 0, 0x7FFF, 0x7FFF);
    socket_read(sfd, -1);
    vnc_send_client_pointer(sfd, 0, 0, 0);
    socket_read(sfd, -1);

    vnc_send_client_pointer(sfd, clicked, (pos_x / 2), (params.height - pos_y) / 2);
    socket_read(sfd, -1);
    vnc_send_client_pointer(sfd, 0, (pos_x / 2), ((params.height - pos_y) / 2));
    socket_read(sfd, -1);

    if (release) {
        vnc_send_client_pointer(sfd, clicked, (pos_x / 2), (params.height - pos_y) / 2);
        socket_read(sfd, -1);
        vnc_send_client_pointer(sfd, 0, (pos_x / 2), (params.height - pos_y) / 2);
        socket_read(sfd, -1);
    }

    shutdown(sfd, SHUT_RDWR);
    close(sfd);

    DPRINTF("%s: Closed descriptor #%d\n", VNCFUNC, sfd);

    return 0;
}
Esempio n. 4
0
/*
 * Private function name:   vnc_get_bitmap
 * Since version:           0.4.5
 * Description:             Function to get the bitmap from the VNC window
 * Arguments:               @server [string]: server string to specify VNC server
 *                          @port [string]: string version of port value to connect to
 *                          @fn [string]: string version of filename
 * Returns:                 0 on success, -errno otherwise
 */
int vnc_get_bitmap(char *server, char *port, char *fn)
{
    int sfd;
    long pattern_size;
    tServerFBParams params;
    char file[] = "/tmp/libvirt-php-tmp-XXXXXX";

    if (mkstemp(file) == 0)
        return -ENOENT;

    if (fn == NULL)
        return -ENOENT;

    sfd = vnc_connect(server, port, 1);
    if (sfd < 0) {
        int err = errno;
        DPRINTF("%s: VNC Connection failed with error code %d (%s)\n", VNCFUNC, err, strerror(err));
        close(sfd);
        return -err;
    }

    params = vnc_read_server_init(sfd);

    pattern_size = params.width * params.height * (params.bpp / 8);
    DPRINTF("%s: %ld\n", VNCFUNC, pattern_size);

    vnc_set_pixel_format(sfd, params);
    vnc_set_encoding(sfd);

    DPRINTF("%s: Requesting framebuffer update\n", VNCFUNC);
    vnc_send_framebuffer_update_request(sfd, 1, params);

    while (socket_has_data(sfd, 50000, 0) == 0) {
        continue;
    }
    socket_read_and_save(sfd, file, pattern_size);

    shutdown(sfd, SHUT_RDWR);
    close(sfd);

    vnc_raw_to_bmp(file, fn, params.width, params.height);
    unlink(file);
    DPRINTF("%s: Closed descriptor #%d\n", VNCFUNC, sfd);
    return 0;
}
Esempio n. 5
0
/*
 * Private function name:   vnc_get_dimensions
 * Since version:           0.4.3
 * Description:             Function to get the dimensions of VNC window
 * Arguments:               @server [string]: server string to specify VNC server
 *                          @port [string]: string version of port value to connect to
 *                          @width [out int]: pointer to integer to carry width argument
 *                          @height [out int]: pointer to integer to carry height argument
 * Returns:                 0 on success, -errno otherwise
 */
int vnc_get_dimensions(char *server, char *port, int *width, int *height)
{
    int sfd;
    tServerFBParams params;

    if (!width && !height) {
        DPRINTF("%s: Neither width or height output value not defined\n", VNCFUNC);
        return -EINVAL;
    }

    DPRINTF("%s: server is %s, port is %s\n", VNCFUNC, server, port);

    sfd = vnc_connect(server, port, 1);
    if (sfd < 0) {
        int err = errno;
        DPRINTF("%s: VNC Connection failed with error code %d (%s)\n", VNCFUNC, err, strerror(err));
        close(sfd);
        return -err;
    }

    params = vnc_read_server_init(sfd);

    if (width) {
        *width = params.width;

        DPRINTF("%s: Output parameter of width set to %d\n", VNCFUNC, *width);
    }

    if (height) {
        *height = params.height;

        DPRINTF("%s: Output parameter of height set to %d\n", VNCFUNC, *height);
    }

    while (socket_has_data(sfd, 500000, 0) == 1)
        socket_read(sfd, -1);

    shutdown(sfd, SHUT_RDWR);
    close(sfd);
    DPRINTF("%s: Closed descriptor #%d\n", VNCFUNC, sfd);
    return 0;
}
Esempio n. 6
0
static void* vnc_worker_thread( void *obj )
{
    filter_t* p_filter = (filter_t*)obj;
    filter_sys_t *p_sys = p_filter->p_sys;
    vlc_thread_t update_thread;
    int canc = vlc_savecancel ();

    msg_Dbg( p_filter, "VNC worker thread started" );

    int fd = vnc_connect( p_filter );
    if( fd == -1 )
    {
        msg_Err( p_filter, "Error occurred while handshaking VNC host" );
        return NULL;
    }

    /* Create an empty picture for VNC the data */
    picture_t *pic =  picture_New( VLC_CODEC_YUVA, p_sys->i_vnc_width,
                                   p_sys->i_vnc_height, 1, 1 );
    if( likely(pic != NULL) )
    {
        vlc_mutex_lock( &p_sys->lock );
        p_sys->i_socket = fd;
        p_sys->p_pic = pic;
        vlc_mutex_unlock( &p_sys->lock );
    }
    else
    {
        net_Close( fd );
        return NULL;
    }

    write_update_request( p_filter, false );

    /* create the update request thread */
    bool polling = var_InheritBool( p_filter, RMTOSD_CFG "vnc-polling" );
    if( polling
     && vlc_clone( &update_thread, update_request_thread,
                   p_filter, VLC_THREAD_PRIORITY_LOW ) )
    {
        msg_Err( p_filter, "cannot spawn VNC update request thread" );
        polling = false;
    }

    vlc_cleanup_push( polling ? update_thread_cleanup : dummy_cleanup,
                      &update_thread );

    /* connection is initialized, now read and handle server messages */
    for( ;; )
    {
        rfbServerToClientMsg msg;
        int i_msgSize;

        memset( &msg, 0, sizeof(msg) );
        vlc_restorecancel (canc);

        if( !read_exact(p_filter, fd, &msg, 1 ) )
        {
            msg_Err( p_filter, "Error while waiting for next server message");
            break;
        }
        switch (msg.type)
        {
        case rfbFramebufferUpdate:
            i_msgSize = sz_rfbFramebufferUpdateMsg;
            break;
        case rfbSetColourMapEntries:
            i_msgSize = sz_rfbSetColourMapEntriesMsg;
            break;
        case rfbBell:
            i_msgSize = sz_rfbBellMsg;
            break;
        case rfbServerCutText:
            i_msgSize = sz_rfbServerCutTextMsg;
            break;
        case rfbReSizeFrameBuffer:
            i_msgSize = sz_rfbReSizeFrameBufferMsg;
            break;
        default:
            i_msgSize = 0;
            msg_Err( p_filter, "Invalid message %u received", msg.type );
            break;
        }

        if( i_msgSize <= 0 )
            break;

        if( --i_msgSize > 0 )
        {
            if ( !read_exact( p_filter, fd, ((char *)&msg) + 1, i_msgSize ) )
            {
                msg_Err( p_filter, "Error while reading message of type %u",
                         msg.type );
                break;
            }
        }

        canc = vlc_savecancel ();
        process_server_message( p_filter, &msg);
    }

    vlc_cleanup_pop();
    if( polling )
        update_thread_cleanup( &update_thread );

    msg_Dbg( p_filter, "VNC message reader thread ended" );
    vlc_restorecancel (canc);
    return NULL;
}