[Spice-devel] [RFC PATCH spice v2 09/20] reds: Add the monitors_guest_output_id hash table
Lukáš Hrázký
lhrazky at redhat.com
Thu Aug 16 16:26:38 UTC 2018
A hash table of (channel_id, monitor_id) -> (guest_output_id) that
is meant to store the guest_output_ids of the streamed channels'
monitors.
Signed-off-by: Lukáš Hrázký <lhrazky at redhat.com>
---
server/reds-private.h | 6 +++++
server/reds.c | 61 +++++++++++++++++++++++++++++++++++++++++++
server/reds.h | 5 ++++
3 files changed, 72 insertions(+)
diff --git a/server/reds-private.h b/server/reds-private.h
index 920edc5c..a4828fec 100644
--- a/server/reds-private.h
+++ b/server/reds-private.h
@@ -123,6 +123,12 @@ struct RedsState {
* client, being passed to the guest */
SpiceBuffer client_monitors_config;
+ /* A map of (channel_id, monitor_id) -> guest_output_id. (channel_id,
+ * monitor_id) is a unique identifier of a monitor. However, that ID has no
+ * meaning in the guest context. for cases the guest monitor ID (called
+ * output ID) is available, it is stored in this hash table.
+ */
+ GHashTable *monitors_guest_output_id;
int mm_time_enabled;
uint32_t mm_time_latency;
diff --git a/server/reds.c b/server/reds.c
index 85043a88..d4356807 100644
--- a/server/reds.c
+++ b/server/reds.c
@@ -262,6 +262,11 @@ typedef struct __attribute__ ((__packed__)) VDInternalBuf {
u;
} VDInternalBuf;
+typedef struct MonitorKey {
+ uint32_t channel_id;
+ uint32_t monitor_id;
+} MonitorKey;
+
SPICE_DECLARE_TYPE(RedCharDeviceVDIPort, red_char_device_vdi_port, CHAR_DEVICE_VDIPORT);
#define RED_TYPE_CHAR_DEVICE_VDIPORT red_char_device_vdi_port_get_type()
@@ -621,6 +626,36 @@ bool reds_config_get_playback_compression(RedsState *reds)
return reds->config->playback_compression;
}
+void reds_store_monitor_guest_output_id(RedsState *reds, uint32_t channel_id,
+ uint32_t monitor_id, uint32_t guest_output_id)
+{
+ MonitorKey *key = g_malloc(sizeof(MonitorKey));
+
+ key->channel_id = channel_id;
+ key->monitor_id = monitor_id;
+
+ g_hash_table_insert(reds->monitors_guest_output_id, key, GUINT_TO_POINTER(guest_output_id));
+}
+
+bool reds_get_monitor_guest_output_id(RedsState *reds, uint32_t channel_id,
+ uint32_t monitor_id, uint32_t *guest_output_id)
+{
+ MonitorKey key = {
+ .channel_id = channel_id,
+ .monitor_id = monitor_id
+ };
+
+ gpointer value;
+ gboolean has_key = g_hash_table_lookup_extended(reds->monitors_guest_output_id, &key, NULL, &value);
+
+ if (!has_key) {
+ return FALSE;
+ }
+
+ *guest_output_id = GPOINTER_TO_INT(value);
+ return TRUE;
+}
+
SpiceMouseMode reds_get_mouse_mode(RedsState *reds)
{
return reds->mouse_mode;
@@ -3354,6 +3389,24 @@ SPICE_GNUC_VISIBLE int spice_server_remove_interface(SpiceBaseInstance *sin)
return 0;
}
+static guint monitor_key_hash(gconstpointer key)
+{
+ const MonitorKey *monitor_key = (const MonitorKey*) key;
+ return g_int_hash(&monitor_key->channel_id) ^ g_int_hash(&monitor_key->monitor_id);
+}
+
+static gboolean monitor_key_equal(gconstpointer a, gconstpointer b)
+{
+ const MonitorKey *mka = (const MonitorKey*) a;
+ const MonitorKey *mkb = (const MonitorKey*) b;
+ return mka->channel_id == mkb->channel_id && mka->monitor_id == mkb->monitor_id;
+}
+
+static void monitor_key_destroy(gpointer key)
+{
+ g_free(key);
+}
+
static int do_spice_init(RedsState *reds, SpiceCoreInterface *core_interface)
{
spice_debug("starting %s", VERSION);
@@ -3404,6 +3457,11 @@ static int do_spice_init(RedsState *reds, SpiceCoreInterface *core_interface)
spice_buffer_free(&reds->client_monitors_config);
+ reds->monitors_guest_output_id = g_hash_table_new_full(&monitor_key_hash,
+ &monitor_key_equal,
+ &monitor_key_destroy,
+ NULL);
+
reds->allow_multiple_clients = getenv(SPICE_DEBUG_ALLOW_MC_ENV) != NULL;
if (reds->allow_multiple_clients) {
spice_warning("spice: allowing multiple client connections");
@@ -3697,6 +3755,9 @@ SPICE_GNUC_VISIBLE void spice_server_destroy(SpiceServer *reds)
reds->channels = NULL;
spice_buffer_free(&reds->client_monitors_config);
+
+ g_hash_table_destroy(reds->monitors_guest_output_id);
+
red_record_unref(reds->record);
reds_cleanup(reds);
#ifdef RED_STATISTICS
diff --git a/server/reds.h b/server/reds.h
index 9f17a5ec..1f10c4b3 100644
--- a/server/reds.h
+++ b/server/reds.h
@@ -50,6 +50,11 @@ gboolean reds_config_get_agent_mouse(const RedsState *reds); // used by inputs_c
int reds_has_vdagent(RedsState *reds); // used by inputs channel
bool reds_config_get_playback_compression(RedsState *reds); // used by playback channel
+void reds_store_monitor_guest_output_id(RedsState *reds, uint32_t channel_id,
+ uint32_t monitor_id, uint32_t guest_output_id);
+bool reds_get_monitor_guest_output_id(RedsState *reds, uint32_t channel_id,
+ uint32_t monitor_id, uint32_t *guest_output_id);
+
void reds_handle_agent_mouse_event(RedsState *reds, const VDAgentMouseState *mouse_state); // used by inputs_channel
GArray* reds_get_renderers(RedsState *reds);
--
2.18.0
More information about the Spice-devel
mailing list