diff --git a/gdk/broadway/broadway-server.c b/gdk/broadway/broadway-server.c index 5d9cafe3ea..d7e5516501 100644 --- a/gdk/broadway/broadway-server.c +++ b/gdk/broadway/broadway-server.c @@ -59,6 +59,9 @@ struct _BroadwayServer { gint32 focused_window_id; /* -1 => none */ gint show_keyboard; + guint32 next_texture_id; + GHashTable *textures; + guint32 screen_width; guint32 screen_height; @@ -138,6 +141,8 @@ broadway_server_init (BroadwayServer *server) server->last_seen_time = 1; server->id_ht = g_hash_table_new (NULL, NULL); server->id_counter = 0; + server->textures = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, + (GDestroyNotify)g_bytes_unref); root = g_new0 (BroadwayWindow, 1); root->id = server->id_counter++; @@ -160,6 +165,7 @@ broadway_server_finalize (GObject *object) g_free (server->address); g_free (server->ssl_cert); g_free (server->ssl_key); + g_hash_table_destroy (server->textures); G_OBJECT_CLASS (broadway_server_parent_class)->finalize (object); } @@ -1630,6 +1636,27 @@ broadway_server_window_update (BroadwayServer *server, window->buffer = buffer; } +guint32 +broadway_server_upload_texture (BroadwayServer *server, + GBytes *texture) +{ + guint32 id; + + id = ++server->next_texture_id; + g_hash_table_replace (server->textures, + GINT_TO_POINTER (id), + g_bytes_ref (texture)); + + return id; +} + +void +broadway_server_release_texture (BroadwayServer *server, + guint32 id) +{ + g_hash_table_remove (server->textures, GINT_TO_POINTER (id)); +} + gboolean broadway_server_window_move_resize (BroadwayServer *server, gint id, diff --git a/gdk/broadway/broadway-server.h b/gdk/broadway/broadway-server.h index b5d319133a..7cb7694a5b 100644 --- a/gdk/broadway/broadway-server.h +++ b/gdk/broadway/broadway-server.h @@ -76,6 +76,10 @@ gboolean broadway_server_window_translate (BroadwayServer * cairo_region_t *area, gint dx, gint dy); +guint32 broadway_server_upload_texture (BroadwayServer *server, + GBytes *texture); +void broadway_server_release_texture (BroadwayServer *server, + guint32 id); cairo_surface_t * broadway_server_create_surface (int width, int height); void broadway_server_window_update (BroadwayServer *server, diff --git a/gdk/broadway/broadwayd.c b/gdk/broadway/broadwayd.c index d26c5dc6dc..ee0cd5fa00 100644 --- a/gdk/broadway/broadwayd.c +++ b/gdk/broadway/broadwayd.c @@ -84,6 +84,8 @@ client_free (BroadwayClient *client) static void client_disconnected (BroadwayClient *client) { + GHashTableIter iter; + gpointer key, value; GList *l; if (client->disconnect_idle != 0) @@ -104,6 +106,10 @@ client_disconnected (BroadwayClient *client) g_list_free (client->windows); client->windows = NULL; + g_hash_table_iter_init (&iter, client->textures); + while (g_hash_table_iter_next (&iter, &key, &value)) + broadway_server_release_texture (server, GPOINTER_TO_INT (value)); + broadway_server_flush (server); client_free (client); @@ -221,6 +227,7 @@ client_handle_request (BroadwayClient *client, BroadwayReplyUngrabPointer reply_ungrab_pointer; cairo_surface_t *surface; guint32 before_serial, now_serial; + guint32 global_id; int fd; before_serial = broadway_server_get_next_serial (server); @@ -329,13 +336,21 @@ client_handle_request (BroadwayClient *client, close (fd); texture = g_bytes_new_take (data, request->upload_texture.size); + global_id = broadway_server_upload_texture (server, texture); + g_bytes_unref (texture); + g_hash_table_replace (client->textures, GINT_TO_POINTER (request->release_texture.id), - texture); + GINT_TO_POINTER (global_id)); } break; case BROADWAY_REQUEST_RELEASE_TEXTURE: - g_hash_table_remove (client->textures, GINT_TO_POINTER (request->release_texture.id)); + global_id = GPOINTER_TO_INT (g_hash_table_lookup (client->textures, + GINT_TO_POINTER (request->release_texture.id))); + if (global_id != 0) + broadway_server_release_texture (server, global_id); + g_hash_table_remove (client->textures, + GINT_TO_POINTER (request->release_texture.id)); break; case BROADWAY_REQUEST_MOVE_RESIZE: @@ -481,7 +496,7 @@ incoming_client (GSocketService *service, client = g_new0 (BroadwayClient, 1); client->id = client_id_count++; client->connection = g_object_ref (connection); - client->textures = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, (GDestroyNotify)g_bytes_unref); + client->textures = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, NULL); input = g_io_stream_get_input_stream (G_IO_STREAM (client->connection)); client->in = input;