[Spice-devel] [PATCH vd_agent 8/8 v3] Receive the graphics_device_info message

Jonathon Jongsma jjongsma at redhat.com
Thu Jan 17 20:36:33 UTC 2019


Acked-by: Jonathon Jongsma <jjongsma at redhat.com>


On Wed, 2019-01-16 at 13:52 +0100, Lukáš Hrázký wrote:
> The graphics_device_info message contains the device display ID
> information (device address and device display ID). Stores the data
> in a
> hash table in vdagent.
> 
> Signed-off-by: Lukáš Hrázký <lhrazky at redhat.com>
> ---
>  src/vdagent/vdagent.c        |  3 ++
>  src/vdagent/x11-priv.h       |  1 +
>  src/vdagent/x11-randr.c      | 65
> ++++++++++++++++++++++++++++++++++++
>  src/vdagent/x11.c            | 13 ++++++++
>  src/vdagent/x11.h            |  1 +
>  src/vdagentd-proto-strings.h |  1 +
>  src/vdagentd-proto.h         |  1 +
>  src/vdagentd/vdagentd.c      | 16 +++++++++
>  8 files changed, 101 insertions(+)
> 
> diff --git a/src/vdagent/vdagent.c b/src/vdagent/vdagent.c
> index 9642a30..aa52ee9 100644
> --- a/src/vdagent/vdagent.c
> +++ b/src/vdagent/vdagent.c
> @@ -240,6 +240,9 @@ static void daemon_read_complete(struct
> udscs_connection **connp,
>                                                ((VDAgentFileXferDataM
> essage *)data)->id);
>          }
>          break;
> +    case VDAGENTD_GRAPHICS_DEVICE_INFO:
> +        vdagent_x11_handle_graphics_device_info(agent->x11, data,
> header->size);
> +        break;
>      case VDAGENTD_CLIENT_DISCONNECTED:
>          vdagent_clipboards_release_all(agent->clipboards);
>          if (vdagent_finalize_file_xfer(agent)) {
> diff --git a/src/vdagent/x11-priv.h b/src/vdagent/x11-priv.h
> index b31b0a5..0e954cf 100644
> --- a/src/vdagent/x11-priv.h
> +++ b/src/vdagent/x11-priv.h
> @@ -139,6 +139,7 @@ struct vdagent_x11 {
>      int xrandr_minor;
>      int has_xinerama;
>      int dont_send_guest_xorg_res;
> +    GHashTable *graphics_display_infos;
>  };
>  
>  extern int (*vdagent_x11_prev_error_handler)(Display *, XErrorEvent
> *);
> diff --git a/src/vdagent/x11-randr.c b/src/vdagent/x11-randr.c
> index 192b888..405fca9 100644
> --- a/src/vdagent/x11-randr.c
> +++ b/src/vdagent/x11-randr.c
> @@ -727,6 +727,71 @@ static void dump_monitors_config(struct
> vdagent_x11 *x11,
>      }
>  }
>  
> +typedef struct GraphicsDisplayInfo {
> +    char device_address[256];
> +    uint32_t device_display_id;
> +} GraphicsDisplayInfo;
> +
> +// handle the device info message from the server. This will allow
> us to
> +// maintain a mapping from spice display id to xrandr output
> +void vdagent_x11_handle_graphics_device_info(struct vdagent_x11
> *x11, uint8_t *data, size_t size)
> +{
> +    VDAgentGraphicsDeviceInfo *graphics_device_info =
> (VDAgentGraphicsDeviceInfo *)data;
> +    VDAgentDeviceDisplayInfo *device_display_info =
> graphics_device_info->display_info;
> +
> +    void *buffer_end = data + size;
> +
> +    syslog(LOG_INFO, "Received Graphics Device Info:");
> +
> +    for (size_t i = 0; i < graphics_device_info->count; ++i) {
> +        if ((void*) device_display_info > buffer_end ||
> +                (void*) (&device_display_info->device_address +
> +                    device_display_info->device_address_len) >
> buffer_end) {
> +            syslog(LOG_ERR, "Malformed graphics_display_info
> message, "
> +                   "extends beyond the end of the buffer");
> +            break;
> +        }
> +
> +        GraphicsDisplayInfo *value =
> g_malloc(sizeof(GraphicsDisplayInfo));
> +        value->device_address[0] = '\0';
> +
> +        size_t device_address_len = device_display_info-
> >device_address_len;
> +        if (device_address_len > sizeof(value->device_address)) {
> +            syslog(LOG_ERR, "Received a device address longer than
> %lu, "
> +                   "will be truncated!", device_address_len);
> +            device_address_len = sizeof(value->device_address);
> +        }
> +
> +        strncpy(value->device_address,
> +                (char*) device_display_info->device_address,
> +                device_address_len);
> +
> +        if (device_address_len > 0) {
> +            value->device_address[device_address_len - 1] =
> '\0';  // make sure the string is terminated
> +        } else {
> +            syslog(LOG_WARNING, "Zero length device_address received
> for channel_id: %u, monitor_id: %u",
> +                   device_display_info->channel_id,
> device_display_info->monitor_id);
> +        }
> +
> +        value->device_display_id = device_display_info-
> >device_display_id;
> +
> +        syslog(LOG_INFO, "   channel_id: %u monitor_id: %u
> device_address: %s, "
> +               "device_display_id: %u",
> +               device_display_info->channel_id,
> +               device_display_info->monitor_id,
> +               value->device_address,
> +               value->device_display_id);
> +
> +        g_hash_table_insert(x11->graphics_display_infos,
> +                GUINT_TO_POINTER(device_display_info->channel_id +
> device_display_info->monitor_id),
> +                value);
> +
> +        device_display_info = (VDAgentDeviceDisplayInfo*) ((char*)
> device_display_info +
> +            sizeof(VDAgentDeviceDisplayInfo) + device_display_info-
> >device_address_len);
> +    }
> +}
> +
> +
>  /*
>   * Set monitor configuration according to client request.
>   *
> diff --git a/src/vdagent/x11.c b/src/vdagent/x11.c
> index 53d3c48..2473383 100644
> --- a/src/vdagent/x11.c
> +++ b/src/vdagent/x11.c
> @@ -196,6 +196,12 @@ static gchar *vdagent_x11_get_wm_name(struct
> vdagent_x11 *x11)
>  #endif
>  }
>  
> +static void graphics_display_info_destroy(gpointer gdi)
> +{
> +    g_free(gdi);
> +}
> +
> +
>  struct vdagent_x11 *vdagent_x11_create(struct udscs_connection
> *vdagentd,
>      int debug, int sync)
>  {
> @@ -316,6 +322,12 @@ struct vdagent_x11 *vdagent_x11_create(struct
> udscs_connection *vdagentd,
>                 __func__, net_wm_name,
> vdagent_x11_has_icons_on_desktop(x11));
>      g_free(net_wm_name);
>  
> +    x11->graphics_display_infos =
> g_hash_table_new_full(&g_direct_hash,
> +                                                  &g_direct_equal,
> +                                                  NULL,
> +                                                  &graphics_display_
> info_destroy);
> +
> +
>      /* Flush output buffers and consume any pending events */
>      vdagent_x11_do_read(x11);
>  
> @@ -337,6 +349,7 @@ void vdagent_x11_destroy(struct vdagent_x11 *x11,
> int vdagentd_disconnected)
>      }
>  #endif
>  
> +    g_hash_table_destroy(x11->graphics_display_infos);
>      XCloseDisplay(x11->display);
>      g_free(x11->randr.failed_conf);
>      g_free(x11);
> diff --git a/src/vdagent/x11.h b/src/vdagent/x11.h
> index 2117abf..bb2ac80 100644
> --- a/src/vdagent/x11.h
> +++ b/src/vdagent/x11.h
> @@ -51,5 +51,6 @@ void vdagent_x11_client_disconnected(struct
> vdagent_x11 *x11);
>  #endif
>  
>  int vdagent_x11_has_icons_on_desktop(struct vdagent_x11 *x11);
> +void vdagent_x11_handle_graphics_device_info(struct vdagent_x11
> *x11, uint8_t *data, size_t size);
>  
>  #endif
> diff --git a/src/vdagentd-proto-strings.h b/src/vdagentd-proto-
> strings.h
> index 6e7bcee..7e03f46 100644
> --- a/src/vdagentd-proto-strings.h
> +++ b/src/vdagentd-proto-strings.h
> @@ -36,6 +36,7 @@ static const char * const vdagentd_messages[] = {
>          "file xfer data",
>          "file xfer disable",
>          "client disconnected",
> +        "graphics device info",
>  };
>  
>  #endif
> diff --git a/src/vdagentd-proto.h b/src/vdagentd-proto.h
> index f72a890..243a9c6 100644
> --- a/src/vdagentd-proto.h
> +++ b/src/vdagentd-proto.h
> @@ -44,6 +44,7 @@ enum {
>      VDAGENTD_FILE_XFER_DATA,
>      VDAGENTD_FILE_XFER_DISABLE,
>      VDAGENTD_CLIENT_DISCONNECTED,  /* daemon -> client */
> +    VDAGENTD_GRAPHICS_DEVICE_INFO,  /* daemon -> client */
>      VDAGENTD_NO_MESSAGES /* Must always be last */
>  };
>  
> diff --git a/src/vdagentd/vdagentd.c b/src/vdagentd/vdagentd.c
> index 5ed29cc..4b7e68c 100644
> --- a/src/vdagentd/vdagentd.c
> +++ b/src/vdagentd/vdagentd.c
> @@ -373,6 +373,16 @@ static void do_client_file_xfer(struct
> vdagent_virtio_port *vport,
>      udscs_write(conn, msg_type, 0, 0, data, message_header->size);
>  }
>  
> +static void forward_data_to_session_agent(uint32_t type, uint8_t
> *data, size_t size)
> +{
> +    if (active_session_conn == NULL) {
> +        syslog(LOG_DEBUG, "No active session, can't forward message
> (type %u)", type);
> +        return;
> +    }
> +
> +    udscs_write(active_session_conn, type, 0, 0, data, size);
> +}
> +
>  static gsize vdagent_message_min_size[] =
>  {
>      -1, /* Does not exist */
> @@ -391,6 +401,7 @@ static gsize vdagent_message_min_size[] =
>      0, /* VD_AGENT_CLIENT_DISCONNECTED */
>      sizeof(VDAgentMaxClipboard), /* VD_AGENT_MAX_CLIPBOARD */
>      sizeof(VDAgentAudioVolumeSync), /* VD_AGENT_AUDIO_VOLUME_SYNC */
> +    sizeof(VDAgentGraphicsDeviceInfo), /*
> VD_AGENT_GRAPHICS_DEVICE_INFO */
>  };
>  
>  static void vdagent_message_clipboard_from_le(VDAgentMessage
> *message_header,
> @@ -475,6 +486,7 @@ static gboolean vdagent_message_check_size(const
> VDAgentMessage *message_header)
>      case VD_AGENT_CLIPBOARD_GRAB:
>      case VD_AGENT_AUDIO_VOLUME_SYNC:
>      case VD_AGENT_ANNOUNCE_CAPABILITIES:
> +    case VD_AGENT_GRAPHICS_DEVICE_INFO:
>          if (message_header->size < min_size) {
>              syslog(LOG_ERR, "read: invalid message size: %u for
> message type: %u",
>                     message_header->size, message_header->type);
> @@ -548,6 +560,10 @@ static int virtio_port_read_complete(
>          syslog(LOG_DEBUG, "Set max clipboard: %d", max_clipboard);
>          break;
>      }
> +    case VD_AGENT_GRAPHICS_DEVICE_INFO: {
> +        forward_data_to_session_agent(VDAGENTD_GRAPHICS_DEVICE_INFO,
> data, message_header->size);
> +        break;
> +    }
>      case VD_AGENT_AUDIO_VOLUME_SYNC: {
>          VDAgentAudioVolumeSync *vdata = (VDAgentAudioVolumeSync
> *)data;
>          virtio_msg_uint16_from_le((uint8_t *)vdata, message_header-
> >size,



More information about the Spice-devel mailing list