int
coreCmdProxy_create(SockAddress* console_socket)
{
    char* handshake = NULL;

    // Connect to the ui-core-control service.
    _coreCmdProxy.core_connection =
        core_connection_create_and_switch(console_socket, "ui-core-control",
                                          &handshake);
    if (_coreCmdProxy.core_connection == NULL) {
        derror("Unable to connect to the ui-core-control service: %s\n",
               errno_str);
        return -1;
    }

    // Initialze command writer and response reader.
    _coreCmdProxy.sock = core_connection_get_socket(_coreCmdProxy.core_connection);
    _coreCmdProxy.sync_writer = syncsocket_init(_coreCmdProxy.sock);
    if (_coreCmdProxy.sync_writer == NULL) {
        derror("Unable to initialize CoreCmdProxy writer: %s\n", errno_str);
        coreCmdProxy_destroy();
        return -1;
    }
    _coreCmdProxy.sync_reader = syncsocket_init(_coreCmdProxy.sock);
    if (_coreCmdProxy.sync_reader == NULL) {
        derror("Unable to initialize CoreCmdProxy reader: %s\n", errno_str);
        coreCmdProxy_destroy();
        return -1;
    }


    fprintf(stdout, "ui-core-control is now connected to the core at %s.",
            sock_address_to_string(console_socket));
    if (handshake != NULL) {
        if (handshake[0] != '\0') {
            fprintf(stdout, " Handshake: %s", handshake);
        }
        free(handshake);
    }
    fprintf(stdout, "\n");

    return 0;
}
int
userEventsProxy_create(SockAddress* console_socket)
{
    char* handshake = NULL;

    
    _userEventsProxy.core_connection =
        core_connection_create_and_switch(console_socket, "user-events",
                                          &handshake);
    if (_userEventsProxy.core_connection == NULL) {
        derror("Unable to connect to the user-events service: %s\n",
               errno_str);
        return -1;
    }

    
    _userEventsProxy.sock =
        core_connection_get_socket(_userEventsProxy.core_connection);
    _userEventsProxy.sync_writer = syncsocket_init(_userEventsProxy.sock);
    if (_userEventsProxy.sync_writer == NULL) {
        derror("Unable to initialize UserEventsProxy writer: %s\n", errno_str);
        userEventsProxy_destroy();
        return -1;
    }

    fprintf(stdout, "user-events is now connected to the core at %s.",
            sock_address_to_string(console_socket));
    if (handshake != NULL) {
        if (handshake[0] != '\0') {
            fprintf(stdout, " Handshake: %s", handshake);
        }
        free(handshake);
    }
    fprintf(stdout, "\n");

    return 0;
}
ClientFramebuffer*
clientfb_create(SockAddress* console_socket,
                const char* protocol,
                QFrameBuffer* fb)
{
    char* connect_message = NULL;
    char switch_cmd[256];

    // Connect to the framebuffer service.
    _client_fb.core_connection = core_connection_create(console_socket);
    if (_client_fb.core_connection == NULL) {
        derror("Framebuffer client is unable to connect to the console: %s\n",
               errno_str);
        return NULL;
    }
    if (core_connection_open(_client_fb.core_connection)) {
        core_connection_free(_client_fb.core_connection);
        _client_fb.core_connection = NULL;
        derror("Framebuffer client is unable to open the console: %s\n",
               errno_str);
        return NULL;
    }
    snprintf(switch_cmd, sizeof(switch_cmd), "framebuffer %s", protocol);
    if (core_connection_switch_stream(_client_fb.core_connection, switch_cmd,
                                      &connect_message)) {
        derror("Unable to attach to the framebuffer %s: %s\n",
               switch_cmd, connect_message ? connect_message : "");
        if (connect_message != NULL) {
            free(connect_message);
        }
        core_connection_close(_client_fb.core_connection);
        core_connection_free(_client_fb.core_connection);
        _client_fb.core_connection = NULL;
        return NULL;
    }

    // We expect core framebuffer to return us bits per pixel property in
    // the handshake message.
    _client_fb.bits_per_pixel = 0;
    if (connect_message != NULL) {
        char* bpp = strstr(connect_message, "bitsperpixel=");
        if (bpp != NULL) {
            char* end;
            bpp += strlen("bitsperpixel=");
            end = strchr(bpp, ' ');
            if (end == NULL) {
                end = bpp + strlen(bpp);
            }
            _client_fb.bits_per_pixel = strtol(bpp, &end, 0);
        }
    }

    if (!_client_fb.bits_per_pixel) {
        derror("Unexpected core framebuffer reply: %s\n"
               "Bits per pixel property is not there, or is invalid\n", connect_message);
        core_connection_close(_client_fb.core_connection);
        core_connection_free(_client_fb.core_connection);
        _client_fb.core_connection = NULL;
        return NULL;
    }

    // Now that we're connected lets initialize the descriptor.
    _client_fb.fb = fb;
    _client_fb.sock = core_connection_get_socket(_client_fb.core_connection);
    _client_fb.fb_state = WAIT_HEADER;
    _client_fb.reader_buffer = (uint8_t*)&_client_fb.update_header;
    _client_fb.reader_offset = 0;
    _client_fb.reader_bytes = sizeof(FBUpdateMessage);

    if (connect_message != NULL) {
        free(connect_message);
    }

    // At last setup read callback, and start receiving the updates.
    if (qemu_set_fd_handler(_client_fb.sock, _clientfb_read_cb, NULL, &_client_fb)) {
        derror("Unable to set up framebuffer read callback\n");
        core_connection_close(_client_fb.core_connection);
        core_connection_free(_client_fb.core_connection);
        _client_fb.core_connection = NULL;
        return NULL;
    }
    {
        // Force the core to send us entire framebuffer now, when we're prepared
        // to receive it.
        FBRequestHeader hd;
        SyncSocket* sk = syncsocket_init(_client_fb.sock);

        hd.request_type = AFB_REQUEST_REFRESH;
        syncsocket_start_write(sk);
        syncsocket_write(sk, &hd, sizeof(hd), 500);
        syncsocket_stop_write(sk);
        syncsocket_free(sk);
    }
    fprintf(stdout, "Framebuffer %s is now attached to the core %s\n",
            protocol, sock_address_to_string(console_socket));

    return &_client_fb;
}