[Spice-commits] 3 commits - server/red-qxl.cpp server/red-worker.cpp server/red-worker.h

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Tue Jun 1 21:09:28 UTC 2021


 server/red-qxl.cpp    |   81 +++++-----
 server/red-worker.cpp |  397 +++++++++++++++++++++-----------------------------
 server/red-worker.h   |  167 ++++++++++++---------
 3 files changed, 308 insertions(+), 337 deletions(-)

New commits:
commit 71284c4984d2a128de62d277ee5f55fb2708b99c
Author: Frediano Ziglio <freddy77 at gmail.com>
Date:   Mon Apr 26 19:27:22 2021 +0100

    red-worker: Limit visibility
    
    Signed-off-by: Frediano Ziglio <freddy77 at gmail.com>
    Acked-by: Victor Toso <victortoso at redhat.com>

diff --git a/server/red-worker.h b/server/red-worker.h
index 6a4a8bea..9626c6eb 100644
--- a/server/red-worker.h
+++ b/server/red-worker.h
@@ -26,7 +26,7 @@
 
 #include "red-channel.h"
 
-SPICE_BEGIN_DECLS
+#include "push-visibility.h"
 
 struct RedWorker;
 
@@ -284,6 +284,6 @@ enum {
 
 void red_qxl_clear_pending(QXLState *qxl_state, int pending);
 
-SPICE_END_DECLS
+#include "pop-visibility.h"
 
 #endif /* RED_WORKER_H_ */
commit 1b02f2d3d0b5db6a9cd102696297b329a25eca05
Author: Frediano Ziglio <freddy77 at gmail.com>
Date:   Mon Apr 26 19:25:59 2021 +0100

    red-worker: Associate message structure and numbers
    
    Makes sure a message is sent with the proper message number.
    Reduce mistakes associating types with wrong registered number.
    Make easier to add new messages in the future.
    Avoids having to type the message number every time, it's inferred
    from the type.
    
    Signed-off-by: Frediano Ziglio <freddy77 at gmail.com>
    Acked-by: Victor Toso <victortoso at redhat.com>

diff --git a/server/red-qxl.cpp b/server/red-qxl.cpp
index 91948ee5..910c2299 100644
--- a/server/red-qxl.cpp
+++ b/server/red-qxl.cpp
@@ -62,6 +62,9 @@ struct QXLState {
     pthread_mutex_t scanout_mutex;
     SpiceMsgDisplayGlScanoutUnix scanout;
     uint64_t gl_draw_cookie;
+
+    template <typename T>
+    inline void send_message(T& message);
 };
 
 #define GL_DRAW_COOKIE_INVALID (~((uint64_t) 0))
@@ -87,6 +90,12 @@ int red_qxl_check_qxl_version(QXLInstance *qxl, int major, int minor)
             ((qxl_major == major) && (qxl_minor >= minor)));
 }
 
+template <typename T>
+inline void QXLState::send_message(T& message)
+{
+    dispatcher->send_message(T::MESSAGE_NUM, &message);
+}
+
 SPICE_GNUC_VISIBLE
 void spice_qxl_update_area(QXLInstance *instance, uint32_t surface_id,
                            struct QXLRect *qxl_area, struct QXLRect *qxl_dirty_rects,
@@ -99,7 +108,7 @@ void spice_qxl_update_area(QXLInstance *instance, uint32_t surface_id,
     payload.qxl_dirty_rects = qxl_dirty_rects;
     payload.num_dirty_rects = num_dirty_rects;
     payload.clear_dirty_region = clear_dirty_region;
-    instance->st->dispatcher->send_message(RED_WORKER_MESSAGE_UPDATE, &payload);
+    instance->st->send_message(payload);
 }
 
 gboolean red_qxl_client_monitors_config(QXLInstance *qxl,
@@ -114,14 +123,13 @@ SPICE_GNUC_VISIBLE
 void spice_qxl_update_area_async(QXLInstance *instance, uint32_t surface_id, QXLRect *qxl_area,
                                  uint32_t clear_dirty_region, uint64_t cookie)
 {
-    RedWorkerMessage message = RED_WORKER_MESSAGE_UPDATE_ASYNC;
     RedWorkerMessageUpdateAsync payload;
 
     payload.base.cookie = cookie;
     payload.surface_id = surface_id;
     payload.qxl_area = *qxl_area;
     payload.clear_dirty_region = clear_dirty_region;
-    instance->st->dispatcher->send_message(message, &payload);
+    instance->st->send_message(payload);
 }
 
 SPICE_GNUC_VISIBLE
@@ -130,29 +138,27 @@ void spice_qxl_add_memslot(QXLInstance *instance, QXLDevMemSlot *mem_slot)
     RedWorkerMessageAddMemslot payload;
 
     payload.mem_slot = *mem_slot;
-    instance->st->dispatcher->send_message(RED_WORKER_MESSAGE_ADD_MEMSLOT, &payload);
+    instance->st->send_message(payload);
 }
 
 SPICE_GNUC_VISIBLE
 void spice_qxl_add_memslot_async(QXLInstance *instance, QXLDevMemSlot *mem_slot, uint64_t cookie)
 {
     RedWorkerMessageAddMemslotAsync payload;
-    RedWorkerMessage message = RED_WORKER_MESSAGE_ADD_MEMSLOT_ASYNC;
 
     payload.base.cookie = cookie;
     payload.mem_slot = *mem_slot;
-    instance->st->dispatcher->send_message(message, &payload);
+    instance->st->send_message(payload);
 }
 
 SPICE_GNUC_VISIBLE
 void spice_qxl_del_memslot(QXLInstance *instance, uint32_t slot_group_id, uint32_t slot_id)
 {
     RedWorkerMessageDelMemslot payload;
-    RedWorkerMessage message = RED_WORKER_MESSAGE_DEL_MEMSLOT;
 
     payload.slot_group_id = slot_group_id;
     payload.slot_id = slot_id;
-    instance->st->dispatcher->send_message(message, &payload);
+    instance->st->send_message(payload);
 }
 
 SPICE_GNUC_VISIBLE
@@ -160,17 +166,16 @@ void spice_qxl_destroy_surfaces(QXLInstance *instance)
 {
     RedWorkerMessageDestroySurfaces payload;
 
-    instance->st->dispatcher->send_message(RED_WORKER_MESSAGE_DESTROY_SURFACES, &payload);
+    instance->st->send_message(payload);
 }
 
 SPICE_GNUC_VISIBLE
 void spice_qxl_destroy_surfaces_async(QXLInstance *instance, uint64_t cookie)
 {
     RedWorkerMessageDestroySurfacesAsync payload;
-    RedWorkerMessage message = RED_WORKER_MESSAGE_DESTROY_SURFACES_ASYNC;
 
     payload.base.cookie = cookie;
-    instance->st->dispatcher->send_message(message, &payload);
+    instance->st->send_message(payload);
 }
 
 /* used by RedWorker */
@@ -189,7 +194,7 @@ void spice_qxl_destroy_primary_surface(QXLInstance *instance, uint32_t surface_i
 {
     RedWorkerMessageDestroyPrimarySurface payload;
     payload.surface_id = surface_id;
-    instance->st->dispatcher->send_message(RED_WORKER_MESSAGE_DESTROY_PRIMARY_SURFACE, &payload);
+    instance->st->send_message(payload);
     red_qxl_destroy_primary_surface_complete(instance->st);
 }
 
@@ -198,11 +203,10 @@ void spice_qxl_destroy_primary_surface_async(QXLInstance *instance,
                                              uint32_t surface_id, uint64_t cookie)
 {
     RedWorkerMessageDestroyPrimarySurfaceAsync payload;
-    RedWorkerMessage message = RED_WORKER_MESSAGE_DESTROY_PRIMARY_SURFACE_ASYNC;
 
     payload.base.cookie = cookie;
     payload.surface_id = surface_id;
-    instance->st->dispatcher->send_message(message, &payload);
+    instance->st->send_message(payload);
 }
 
 /* used by RedWorker */
@@ -222,12 +226,11 @@ void spice_qxl_create_primary_surface_async(QXLInstance *instance, uint32_t surf
                                             QXLDevSurfaceCreate *surface, uint64_t cookie)
 {
     RedWorkerMessageCreatePrimarySurfaceAsync payload;
-    RedWorkerMessage message = RED_WORKER_MESSAGE_CREATE_PRIMARY_SURFACE_ASYNC;
 
     payload.base.cookie = cookie;
     payload.surface_id = surface_id;
     payload.surface = *surface;
-    instance->st->dispatcher->send_message(message, &payload);
+    instance->st->send_message(payload);
 }
 
 SPICE_GNUC_VISIBLE
@@ -238,7 +241,7 @@ void spice_qxl_create_primary_surface(QXLInstance *instance, uint32_t surface_id
 
     payload.surface_id = surface_id;
     payload.surface = *surface;
-    instance->st->dispatcher->send_message(RED_WORKER_MESSAGE_CREATE_PRIMARY_SURFACE, &payload);
+    instance->st->send_message(payload);
     red_qxl_create_primary_surface_complete(instance->st, surface);
 }
 
@@ -247,7 +250,7 @@ void spice_qxl_reset_image_cache(QXLInstance *instance)
 {
     RedWorkerMessageResetImageCache payload;
 
-    instance->st->dispatcher->send_message(RED_WORKER_MESSAGE_RESET_IMAGE_CACHE, &payload);
+    instance->st->send_message(payload);
 }
 
 SPICE_GNUC_VISIBLE
@@ -255,7 +258,7 @@ void spice_qxl_reset_cursor(QXLInstance *instance)
 {
     RedWorkerMessageResetCursor payload;
 
-    instance->st->dispatcher->send_message(RED_WORKER_MESSAGE_RESET_CURSOR, &payload);
+    instance->st->send_message(payload);
 }
 
 SPICE_GNUC_VISIBLE
@@ -264,18 +267,17 @@ void spice_qxl_destroy_surface_wait(QXLInstance *instance, uint32_t surface_id)
     RedWorkerMessageDestroySurfaceWait payload;
 
     payload.surface_id = surface_id;
-    instance->st->dispatcher->send_message(RED_WORKER_MESSAGE_DESTROY_SURFACE_WAIT, &payload);
+    instance->st->send_message(payload);
 }
 
 SPICE_GNUC_VISIBLE
 void spice_qxl_destroy_surface_async(QXLInstance *instance, uint32_t surface_id, uint64_t cookie)
 {
     RedWorkerMessageDestroySurfaceWaitAsync payload;
-    RedWorkerMessage message = RED_WORKER_MESSAGE_DESTROY_SURFACE_WAIT_ASYNC;
 
     payload.base.cookie = cookie;
     payload.surface_id = surface_id;
-    instance->st->dispatcher->send_message(message, &payload);
+    instance->st->send_message(payload);
 }
 
 SPICE_GNUC_VISIBLE
@@ -283,7 +285,7 @@ void spice_qxl_reset_memslots(QXLInstance *instance)
 {
     RedWorkerMessageResetMemslots payload;
 
-    instance->st->dispatcher->send_message(RED_WORKER_MESSAGE_RESET_MEMSLOTS, &payload);
+    instance->st->send_message(payload);
 }
 
 static bool red_qxl_set_pending(QXLState *qxl_state, int pending)
@@ -305,7 +307,7 @@ void spice_qxl_wakeup(QXLInstance *instance)
     if (red_qxl_set_pending(instance->st, RED_DISPATCHER_PENDING_WAKEUP))
         return;
 
-    instance->st->dispatcher->send_message(RED_WORKER_MESSAGE_WAKEUP, &payload);
+    instance->st->send_message(payload);
 }
 
 SPICE_GNUC_VISIBLE
@@ -316,24 +318,23 @@ void spice_qxl_oom(QXLInstance *instance)
     if (red_qxl_set_pending(instance->st, RED_DISPATCHER_PENDING_OOM))
         return;
 
-    instance->st->dispatcher->send_message(RED_WORKER_MESSAGE_OOM, &payload);
+    instance->st->send_message(payload);
 }
 
 void red_qxl_start(QXLInstance *qxl)
 {
     RedWorkerMessageStart payload;
 
-    qxl->st->dispatcher->send_message(RED_WORKER_MESSAGE_START, &payload);
+    qxl->st->send_message(payload);
 }
 
 SPICE_GNUC_VISIBLE
 void spice_qxl_flush_surfaces_async(QXLInstance *instance, uint64_t cookie)
 {
     RedWorkerMessageFlushSurfacesAsync payload;
-    RedWorkerMessage message = RED_WORKER_MESSAGE_FLUSH_SURFACES_ASYNC;
 
     payload.base.cookie = cookie;
-    instance->st->dispatcher->send_message(message, &payload);
+    instance->st->send_message(payload);
 }
 
 SPICE_GNUC_VISIBLE
@@ -341,14 +342,13 @@ void spice_qxl_monitors_config_async(QXLInstance *instance, QXLPHYSICAL monitors
                                      int group_id, uint64_t cookie)
 {
     RedWorkerMessageMonitorsConfigAsync payload;
-    RedWorkerMessage message = RED_WORKER_MESSAGE_MONITORS_CONFIG_ASYNC;
 
     payload.base.cookie = cookie;
     payload.monitors_config = monitors_config;
     payload.group_id = group_id;
     payload.max_monitors = instance->st->max_monitors;
 
-    instance->st->dispatcher->send_message(message, &payload);
+    instance->st->send_message(payload);
 }
 
 SPICE_GNUC_VISIBLE
@@ -356,14 +356,14 @@ void spice_qxl_driver_unload(QXLInstance *instance)
 {
     RedWorkerMessageDriverUnload payload;
 
-    instance->st->dispatcher->send_message(RED_WORKER_MESSAGE_DRIVER_UNLOAD, &payload);
+    instance->st->send_message(payload);
 }
 
 void red_qxl_stop(QXLInstance *qxl)
 {
     RedWorkerMessageStop payload;
 
-    qxl->st->dispatcher->send_message(RED_WORKER_MESSAGE_STOP, &payload);
+    qxl->st->send_message(payload);
 }
 
 SPICE_GNUC_VISIBLE
@@ -373,7 +373,7 @@ void spice_qxl_loadvm_commands(QXLInstance *instance, struct QXLCommandExt *ext,
 
     payload.count = count;
     payload.ext = ext;
-    instance->st->dispatcher->send_message(RED_WORKER_MESSAGE_LOADVM_COMMANDS, &payload);
+    instance->st->send_message(payload);
 }
 
 uint32_t red_qxl_get_ram_size(QXLInstance *qxl)
@@ -451,7 +451,7 @@ void spice_qxl_gl_scanout(QXLInstance *qxl,
     pthread_mutex_unlock(&qxl_state->scanout_mutex);
 
     /* FIXME: find a way to coallesce all pending SCANOUTs */
-    qxl_state->dispatcher->send_message(RED_WORKER_MESSAGE_GL_SCANOUT, &payload);
+    qxl_state->send_message(payload);
     reds_update_client_mouse_allowed(qxl_state->reds);
 }
 
@@ -462,7 +462,6 @@ void spice_qxl_gl_draw_async(QXLInstance *qxl,
                              uint64_t cookie)
 {
     QXLState *qxl_state;
-    RedWorkerMessage message = RED_WORKER_MESSAGE_GL_DRAW_ASYNC;
     RedWorkerMessageGlDraw draw = {
         {
             .x = x,
@@ -482,7 +481,7 @@ void spice_qxl_gl_draw_async(QXLInstance *qxl,
     spice_return_if_fail(qxl_state->gl_draw_cookie == GL_DRAW_COOKIE_INVALID);
 
     qxl_state->gl_draw_cookie = cookie;
-    qxl_state->dispatcher->send_message(message, &draw);
+    qxl_state->send_message(draw);
 }
 
 void red_qxl_gl_draw_async_complete(QXLInstance *qxl)
@@ -591,7 +590,7 @@ void red_qxl_destroy(QXLInstance *qxl)
 
     /* send message to close thread */
     RedWorkerMessageClose message;
-    qxl_state->dispatcher->send_message(RED_WORKER_MESSAGE_CLOSE_WORKER, &message);
+    qxl_state->send_message(message);
     red_worker_free(qxl_state->worker);
     /* this must be done after calling red_worker_free */
     qxl->st = nullptr;
@@ -640,28 +639,28 @@ void red_qxl_on_ic_change(QXLInstance *qxl, SpiceImageCompression ic)
 {
     RedWorkerMessageSetCompression payload;
     payload.image_compression = ic;
-    qxl->st->dispatcher->send_message(RED_WORKER_MESSAGE_SET_COMPRESSION, &payload);
+    qxl->st->send_message(payload);
 }
 
 void red_qxl_on_sv_change(QXLInstance *qxl, int sv)
 {
     RedWorkerMessageSetStreamingVideo payload;
     payload.streaming_video = sv;
-    qxl->st->dispatcher->send_message(RED_WORKER_MESSAGE_SET_STREAMING_VIDEO, &payload);
+    qxl->st->send_message(payload);
 }
 
 void red_qxl_on_vc_change(QXLInstance *qxl, GArray *video_codecs)
 {
     RedWorkerMessageSetVideoCodecs payload;
     payload.video_codecs = g_array_ref(video_codecs);
-    qxl->st->dispatcher->send_message(RED_WORKER_MESSAGE_SET_VIDEO_CODECS, &payload);
+    qxl->st->send_message(payload);
 }
 
 void red_qxl_set_mouse_mode(QXLInstance *qxl, uint32_t mode)
 {
     RedWorkerMessageSetMouseMode payload;
     payload.mode = mode;
-    qxl->st->dispatcher->send_message(RED_WORKER_MESSAGE_SET_MOUSE_MODE, &payload);
+    qxl->st->send_message(payload);
 }
 
 RedsState* red_qxl_get_server(QXLState *qxl_state)
diff --git a/server/red-worker.cpp b/server/red-worker.cpp
index d2e262ae..2be223b4 100644
--- a/server/red-worker.cpp
+++ b/server/red-worker.cpp
@@ -781,10 +781,10 @@ static void worker_dispatcher_record(void *opaque, uint32_t message_type, void *
 
 template <typename T>
 static inline void
-register_handler(Dispatcher *dispatcher, uint32_t message_type,
+register_handler(Dispatcher *dispatcher,
                  void (*handler)(RedWorker*, T*), bool ack)
 {
-    dispatcher->register_handler(message_type,
+    dispatcher->register_handler(T::MESSAGE_NUM,
                                  reinterpret_cast<dispatcher_handle_message>(handler),
                                  sizeof(T),
                                  ack);
@@ -794,127 +794,96 @@ static void register_callbacks(Dispatcher *dispatcher)
 {
     /* TODO: register cursor & display specific msg in respective channel files */
     register_handler(dispatcher,
-                     RED_WORKER_MESSAGE_UPDATE,
                      handle_dev_update,
                      true);
     register_handler(dispatcher,
-                     RED_WORKER_MESSAGE_UPDATE_ASYNC,
                      handle_dev_update_async,
                      false);
     register_handler(dispatcher,
-                     RED_WORKER_MESSAGE_ADD_MEMSLOT,
                      handle_dev_add_memslot,
                      true);
     register_handler(dispatcher,
-                     RED_WORKER_MESSAGE_ADD_MEMSLOT_ASYNC,
                      handle_dev_add_memslot_async,
                      false);
     register_handler(dispatcher,
-                     RED_WORKER_MESSAGE_DEL_MEMSLOT,
                      handle_dev_del_memslot,
                      false);
     register_handler(dispatcher,
-                     RED_WORKER_MESSAGE_DESTROY_SURFACES,
                      handle_dev_destroy_surfaces,
                      true);
     register_handler(dispatcher,
-                     RED_WORKER_MESSAGE_DESTROY_SURFACES_ASYNC,
                      handle_dev_destroy_surfaces_async,
                      false);
     register_handler(dispatcher,
-                     RED_WORKER_MESSAGE_DESTROY_PRIMARY_SURFACE,
                      handle_dev_destroy_primary_surface,
                      true);
     register_handler(dispatcher,
-                     RED_WORKER_MESSAGE_DESTROY_PRIMARY_SURFACE_ASYNC,
                      handle_dev_destroy_primary_surface_async,
                      false);
     register_handler(dispatcher,
-                     RED_WORKER_MESSAGE_CREATE_PRIMARY_SURFACE_ASYNC,
                      handle_dev_create_primary_surface_async,
                      false);
     register_handler(dispatcher,
-                     RED_WORKER_MESSAGE_CREATE_PRIMARY_SURFACE,
                      handle_dev_create_primary_surface,
                      true);
     register_handler(dispatcher,
-                     RED_WORKER_MESSAGE_RESET_IMAGE_CACHE,
                      handle_dev_reset_image_cache,
                      true);
     register_handler(dispatcher,
-                     RED_WORKER_MESSAGE_RESET_CURSOR,
                      handle_dev_reset_cursor,
                      true);
     register_handler(dispatcher,
-                     RED_WORKER_MESSAGE_WAKEUP,
                      handle_dev_wakeup,
                      false);
     register_handler(dispatcher,
-                     RED_WORKER_MESSAGE_OOM,
                      handle_dev_oom,
                      false);
     register_handler(dispatcher,
-                     RED_WORKER_MESSAGE_START,
                      handle_dev_start,
                      false);
     register_handler(dispatcher,
-                     RED_WORKER_MESSAGE_FLUSH_SURFACES_ASYNC,
                      handle_dev_flush_surfaces_async,
                      false);
     register_handler(dispatcher,
-                     RED_WORKER_MESSAGE_STOP,
                      handle_dev_stop,
                      true);
     register_handler(dispatcher,
-                     RED_WORKER_MESSAGE_LOADVM_COMMANDS,
                      handle_dev_loadvm_commands,
                      true);
     register_handler(dispatcher,
-                     RED_WORKER_MESSAGE_SET_COMPRESSION,
                      handle_dev_set_compression,
                      false);
     register_handler(dispatcher,
-                     RED_WORKER_MESSAGE_SET_STREAMING_VIDEO,
                      handle_dev_set_streaming_video,
                      false);
     register_handler(dispatcher,
-                     RED_WORKER_MESSAGE_SET_VIDEO_CODECS,
                      handle_dev_set_video_codecs,
                      false);
     register_handler(dispatcher,
-                     RED_WORKER_MESSAGE_SET_MOUSE_MODE,
                      handle_dev_set_mouse_mode,
                      false);
     register_handler(dispatcher,
-                     RED_WORKER_MESSAGE_DESTROY_SURFACE_WAIT,
                      handle_dev_destroy_surface_wait,
                      true);
     register_handler(dispatcher,
-                     RED_WORKER_MESSAGE_DESTROY_SURFACE_WAIT_ASYNC,
                      handle_dev_destroy_surface_wait_async,
                      false);
     register_handler(dispatcher,
-                     RED_WORKER_MESSAGE_RESET_MEMSLOTS,
                      handle_dev_reset_memslots,
                      false);
     register_handler(dispatcher,
-                     RED_WORKER_MESSAGE_MONITORS_CONFIG_ASYNC,
                      handle_dev_monitors_config_async,
                      false);
     register_handler(dispatcher,
-                     RED_WORKER_MESSAGE_DRIVER_UNLOAD,
                      handle_dev_driver_unload,
                      false);
     register_handler(dispatcher,
-                     RED_WORKER_MESSAGE_GL_SCANOUT,
                      handle_dev_gl_scanout,
                      false);
     register_handler(dispatcher,
-                     RED_WORKER_MESSAGE_GL_DRAW_ASYNC,
                      handle_dev_gl_draw_async,
                      false);
     register_handler(dispatcher,
-                     RED_WORKER_MESSAGE_CLOSE_WORKER,
                      handle_dev_close,
                      false);
 }
diff --git a/server/red-worker.h b/server/red-worker.h
index 181bff70..6a4a8bea 100644
--- a/server/red-worker.h
+++ b/server/red-worker.h
@@ -28,7 +28,7 @@
 
 SPICE_BEGIN_DECLS
 
-typedef struct RedWorker RedWorker;
+struct RedWorker;
 
 RedWorker* red_worker_new(QXLInstance *qxl);
 bool       red_worker_run(RedWorker *worker);
@@ -40,7 +40,7 @@ void red_qxl_create_primary_surface_complete(QXLState *qxl_state, const QXLDevSu
 bool red_qxl_is_running(QXLInstance *qxl);
 void red_qxl_set_running(QXLInstance *qxl, bool running);
 
-typedef uint32_t RedWorkerMessage;
+using RedWorkerMessage = uint32_t;
 
 /* Keep message order, only append new messages!
  * Replay code store enum values into save files.
@@ -99,152 +99,183 @@ enum {
     RED_WORKER_MESSAGE_COUNT // LAST
 };
 
-typedef struct RedWorkerMessageUpdate {
+struct RedWorkerMessageUpdate {
+    enum { MESSAGE_NUM = RED_WORKER_MESSAGE_UPDATE };
     uint32_t surface_id;
     QXLRect * qxl_area;
     QXLRect * qxl_dirty_rects;
     uint32_t num_dirty_rects;
     uint32_t clear_dirty_region;
-} RedWorkerMessageUpdate;
+};
 
-typedef struct RedWorkerMessageAsync {
+struct RedWorkerMessageAsync {
     uint64_t cookie;
-} RedWorkerMessageAsync;
+};
 
-typedef struct RedWorkerMessageUpdateAsync {
+struct RedWorkerMessageUpdateAsync {
+    enum { MESSAGE_NUM = RED_WORKER_MESSAGE_UPDATE_ASYNC };
     RedWorkerMessageAsync base;
     uint32_t surface_id;
     QXLRect qxl_area;
     uint32_t clear_dirty_region;
-} RedWorkerMessageUpdateAsync;
+};
 
-typedef struct RedWorkerMessageAddMemslot {
+struct RedWorkerMessageAddMemslot {
+    enum { MESSAGE_NUM = RED_WORKER_MESSAGE_ADD_MEMSLOT };
     QXLDevMemSlot mem_slot;
-} RedWorkerMessageAddMemslot;
+};
 
-typedef struct RedWorkerMessageAddMemslotAsync {
+struct RedWorkerMessageAddMemslotAsync {
+    enum { MESSAGE_NUM = RED_WORKER_MESSAGE_ADD_MEMSLOT_ASYNC };
     RedWorkerMessageAsync base;
     QXLDevMemSlot mem_slot;
-} RedWorkerMessageAddMemslotAsync;
+};
 
-typedef struct RedWorkerMessageDelMemslot {
+struct RedWorkerMessageDelMemslot {
+    enum { MESSAGE_NUM = RED_WORKER_MESSAGE_DEL_MEMSLOT };
     uint32_t slot_group_id;
     uint32_t slot_id;
-} RedWorkerMessageDelMemslot;
+};
 
-typedef struct RedWorkerMessageDestroySurfaces {
+struct RedWorkerMessageDestroySurfaces {
+    enum { MESSAGE_NUM = RED_WORKER_MESSAGE_DESTROY_SURFACES };
     uint8_t dummy_empty_field[0]; // C/C++ compatibility
-} RedWorkerMessageDestroySurfaces;
+};
 
-typedef struct RedWorkerMessageDestroySurfacesAsync {
+struct RedWorkerMessageDestroySurfacesAsync {
+    enum { MESSAGE_NUM = RED_WORKER_MESSAGE_DESTROY_SURFACES_ASYNC };
     RedWorkerMessageAsync base;
-} RedWorkerMessageDestroySurfacesAsync;
+};
 
 
-typedef struct RedWorkerMessageDestroyPrimarySurface {
+struct RedWorkerMessageDestroyPrimarySurface {
+    enum { MESSAGE_NUM = RED_WORKER_MESSAGE_DESTROY_PRIMARY_SURFACE };
     uint32_t surface_id;
-} RedWorkerMessageDestroyPrimarySurface;
+};
 
-typedef struct RedWorkerMessageDestroyPrimarySurfaceAsync {
+struct RedWorkerMessageDestroyPrimarySurfaceAsync {
+    enum { MESSAGE_NUM = RED_WORKER_MESSAGE_DESTROY_PRIMARY_SURFACE_ASYNC };
     RedWorkerMessageAsync base;
     uint32_t surface_id;
-} RedWorkerMessageDestroyPrimarySurfaceAsync;
+};
 
-typedef struct RedWorkerMessageCreatePrimarySurfaceAsync {
+struct RedWorkerMessageCreatePrimarySurfaceAsync {
+    enum { MESSAGE_NUM = RED_WORKER_MESSAGE_CREATE_PRIMARY_SURFACE_ASYNC };
     RedWorkerMessageAsync base;
     uint32_t surface_id;
     QXLDevSurfaceCreate surface;
-} RedWorkerMessageCreatePrimarySurfaceAsync;
+};
 
-typedef struct RedWorkerMessageCreatePrimarySurface {
+struct RedWorkerMessageCreatePrimarySurface {
+    enum { MESSAGE_NUM = RED_WORKER_MESSAGE_CREATE_PRIMARY_SURFACE };
     uint32_t surface_id;
     QXLDevSurfaceCreate surface;
-} RedWorkerMessageCreatePrimarySurface;
+};
 
-typedef struct RedWorkerMessageResetImageCache {
+struct RedWorkerMessageResetImageCache {
+    enum { MESSAGE_NUM = RED_WORKER_MESSAGE_RESET_IMAGE_CACHE };
     uint8_t dummy_empty_field[0]; // C/C++ compatibility
-} RedWorkerMessageResetImageCache;
+};
 
-typedef struct RedWorkerMessageResetCursor {
+struct RedWorkerMessageResetCursor {
+    enum { MESSAGE_NUM = RED_WORKER_MESSAGE_RESET_CURSOR };
     uint8_t dummy_empty_field[0]; // C/C++ compatibility
-} RedWorkerMessageResetCursor;
+};
 
-typedef struct RedWorkerMessageWakeup {
+struct RedWorkerMessageWakeup {
+    enum { MESSAGE_NUM = RED_WORKER_MESSAGE_WAKEUP };
     uint8_t dummy_empty_field[0]; // C/C++ compatibility
-} RedWorkerMessageWakeup;
+};
 
-typedef struct RedWorkerMessageOom {
+struct RedWorkerMessageOom {
+    enum { MESSAGE_NUM = RED_WORKER_MESSAGE_OOM };
     uint8_t dummy_empty_field[0]; // C/C++ compatibility
-} RedWorkerMessageOom;
+};
 
-typedef struct RedWorkerMessageStart {
+struct RedWorkerMessageStart {
+    enum { MESSAGE_NUM = RED_WORKER_MESSAGE_START };
     uint8_t dummy_empty_field[0]; // C/C++ compatibility
-} RedWorkerMessageStart;
+};
 
-typedef struct RedWorkerMessageFlushSurfacesAsync {
+struct RedWorkerMessageFlushSurfacesAsync {
+    enum { MESSAGE_NUM = RED_WORKER_MESSAGE_FLUSH_SURFACES_ASYNC };
     RedWorkerMessageAsync base;
-} RedWorkerMessageFlushSurfacesAsync;
+};
 
-typedef struct RedWorkerMessageStop {
+struct RedWorkerMessageStop {
+    enum { MESSAGE_NUM = RED_WORKER_MESSAGE_STOP };
     uint8_t dummy_empty_field[0]; // C/C++ compatibility
-} RedWorkerMessageStop;
+};
 
 /* this command is sync, so it's ok to pass a pointer */
-typedef struct RedWorkerMessageLoadvmCommands {
+struct RedWorkerMessageLoadvmCommands {
+    enum { MESSAGE_NUM = RED_WORKER_MESSAGE_LOADVM_COMMANDS };
     uint32_t count;
     QXLCommandExt *ext;
-} RedWorkerMessageLoadvmCommands;
+};
 
-typedef struct RedWorkerMessageSetCompression {
+struct RedWorkerMessageSetCompression {
+    enum { MESSAGE_NUM = RED_WORKER_MESSAGE_SET_COMPRESSION };
     SpiceImageCompression image_compression;
-} RedWorkerMessageSetCompression;
+};
 
-typedef struct RedWorkerMessageSetStreamingVideo {
+struct RedWorkerMessageSetStreamingVideo {
+    enum { MESSAGE_NUM = RED_WORKER_MESSAGE_SET_STREAMING_VIDEO };
     uint32_t streaming_video;
-} RedWorkerMessageSetStreamingVideo;
+};
 
-typedef struct RedWorkerMessageSetVideoCodecs {
+struct RedWorkerMessageSetVideoCodecs {
+    enum { MESSAGE_NUM = RED_WORKER_MESSAGE_SET_VIDEO_CODECS };
     GArray* video_codecs;
-} RedWorkerMessageSetVideoCodecs;
+};
 
-typedef struct RedWorkerMessageSetMouseMode {
+struct RedWorkerMessageSetMouseMode {
+    enum { MESSAGE_NUM = RED_WORKER_MESSAGE_SET_MOUSE_MODE };
     uint32_t mode;
-} RedWorkerMessageSetMouseMode;
+};
 
-typedef struct RedWorkerMessageDestroySurfaceWait {
+struct RedWorkerMessageDestroySurfaceWait {
+    enum { MESSAGE_NUM = RED_WORKER_MESSAGE_DESTROY_SURFACE_WAIT };
     uint32_t surface_id;
-} RedWorkerMessageDestroySurfaceWait;
+};
 
-typedef struct RedWorkerMessageDestroySurfaceWaitAsync {
+struct RedWorkerMessageDestroySurfaceWaitAsync {
+    enum { MESSAGE_NUM = RED_WORKER_MESSAGE_DESTROY_SURFACE_WAIT_ASYNC };
     RedWorkerMessageAsync base;
     uint32_t surface_id;
-} RedWorkerMessageDestroySurfaceWaitAsync;
+};
 
-typedef struct RedWorkerMessageResetMemslots {
-} RedWorkerMessageResetMemslots;
+struct RedWorkerMessageResetMemslots {
+    enum { MESSAGE_NUM = RED_WORKER_MESSAGE_RESET_MEMSLOTS };
+};
 
-typedef struct RedWorkerMessageMonitorsConfigAsync {
+struct RedWorkerMessageMonitorsConfigAsync {
+    enum { MESSAGE_NUM = RED_WORKER_MESSAGE_MONITORS_CONFIG_ASYNC };
     RedWorkerMessageAsync base;
     QXLPHYSICAL monitors_config;
     int group_id;
     unsigned int max_monitors;
-} RedWorkerMessageMonitorsConfigAsync;
+};
 
-typedef struct RedWorkerMessageDriverUnload {
+struct RedWorkerMessageDriverUnload {
+    enum { MESSAGE_NUM = RED_WORKER_MESSAGE_DRIVER_UNLOAD };
     uint8_t dummy_empty_field[0]; // C/C++ compatibility
-} RedWorkerMessageDriverUnload;
+};
 
-typedef struct RedWorkerMessageGlScanout {
+struct RedWorkerMessageGlScanout {
+    enum { MESSAGE_NUM = RED_WORKER_MESSAGE_GL_SCANOUT };
     uint8_t dummy_empty_field[0]; // C/C++ compatibility
-} RedWorkerMessageGlScanout;
+};
 
-typedef struct RedWorkerMessageClose {
+struct RedWorkerMessageClose {
+    enum { MESSAGE_NUM = RED_WORKER_MESSAGE_CLOSE_WORKER };
     uint8_t dummy_empty_field[0]; // C/C++ compatibility
-} RedWorkerMessageClose;
+};
 
-typedef struct RedWorkerMessageGlDraw {
+struct RedWorkerMessageGlDraw {
+    enum { MESSAGE_NUM = RED_WORKER_MESSAGE_GL_DRAW_ASYNC };
     SpiceMsgDisplayGlDraw draw;
-} RedWorkerMessageGlDraw;
+};
 
 enum {
     RED_DISPATCHER_PENDING_WAKEUP,
commit c8e4e467be4fff153902425cfca86a29e295894e
Author: Frediano Ziglio <freddy77 at gmail.com>
Date:   Wed Apr 21 10:07:17 2021 +0100

    red-worker: Reduce casts needed in dispatcher handlers
    
    Use a template to deduct type and avoid casts in every handler.
    The reinterpret_cast seems strong but is safe as converting
    a function with 2 typed pointers and a void return into a function
    with 2 void pointers and a void return.
    The unsafety left (not a regressions) is the association between
    handler number and message type.
    
    Signed-off-by: Frediano Ziglio <freddy77 at gmail.com>
    Acked-by: Victor Toso <victortoso at redhat.com>

diff --git a/server/red-worker.cpp b/server/red-worker.cpp
index 69a16e9d..d2e262ae 100644
--- a/server/red-worker.cpp
+++ b/server/red-worker.cpp
@@ -329,10 +329,9 @@ static void flush_all_qxl_commands(RedWorker *worker)
     flush_cursor_commands(worker);
 }
 
-static void handle_dev_update_async(void *opaque, void *payload)
+static void
+handle_dev_update_async(RedWorker* worker, RedWorkerMessageUpdateAsync* msg)
 {
-    auto worker = (RedWorker*) opaque;
-    auto msg = (RedWorkerMessageUpdateAsync*) payload;
     QXLRect *qxl_dirty_rects = nullptr;
     uint32_t num_dirty_rects = 0;
 
@@ -350,10 +349,9 @@ static void handle_dev_update_async(void *opaque, void *payload)
     red_qxl_async_complete(worker->qxl, msg->base.cookie);
 }
 
-static void handle_dev_update(void *opaque, void *payload)
+static void
+handle_dev_update(RedWorker *worker, RedWorkerMessageUpdate *msg)
 {
-    auto worker = (RedWorker*) opaque;
-    auto msg = (RedWorkerMessageUpdate*) payload;
     QXLRect *qxl_dirty_rects = msg->qxl_dirty_rects;
 
     spice_return_if_fail(red_qxl_is_running(worker->qxl));
@@ -367,31 +365,27 @@ static void handle_dev_update(void *opaque, void *payload)
     }
 }
 
-static void handle_dev_del_memslot(void *opaque, void *payload)
+static void
+handle_dev_del_memslot(RedWorker* worker, RedWorkerMessageDelMemslot* msg)
 {
-    auto worker = (RedWorker*) opaque;
-    auto msg = (RedWorkerMessageDelMemslot*) payload;
     uint32_t slot_id = msg->slot_id;
     uint32_t slot_group_id = msg->slot_group_id;
 
     memslot_info_del_slot(&worker->mem_slots, slot_group_id, slot_id);
 }
 
-static void handle_dev_destroy_surface_wait(void *opaque, void *payload)
+static void
+handle_dev_destroy_surface_wait(RedWorker* worker, RedWorkerMessageDestroySurfaceWait* msg)
 {
-    auto msg = (RedWorkerMessageDestroySurfaceWait*) payload;
-    auto worker = (RedWorker*) opaque;
-
     spice_return_if_fail(msg->surface_id == 0);
 
     flush_all_qxl_commands(worker);
     display_channel_destroy_surface_wait(worker->display_channel, msg->surface_id);
 }
 
-static void handle_dev_destroy_surfaces(void *opaque, void *payload)
+static void
+handle_dev_destroy_surfaces(RedWorker* worker, RedWorkerMessageDestroySurfaces*)
 {
-    auto worker = (RedWorker*) opaque;
-
     flush_all_qxl_commands(worker);
     display_channel_destroy_surfaces(worker->display_channel);
     worker->cursor_channel->reset();
@@ -450,11 +444,9 @@ static void dev_create_primary_surface(RedWorker *worker, uint32_t surface_id,
     worker->cursor_channel->do_init();
 }
 
-static void handle_dev_create_primary_surface(void *opaque, void *payload)
+static void
+handle_dev_create_primary_surface(RedWorker* worker, RedWorkerMessageCreatePrimarySurface* msg)
 {
-    auto msg = (RedWorkerMessageCreatePrimarySurface*) payload;
-    auto worker = (RedWorker*) opaque;
-
     dev_create_primary_surface(worker, msg->surface_id, msg->surface);
 }
 
@@ -480,19 +472,18 @@ static void destroy_primary_surface(RedWorker *worker, uint32_t surface_id)
     worker->cursor_channel->reset();
 }
 
-static void handle_dev_destroy_primary_surface(void *opaque, void *payload)
+static void
+handle_dev_destroy_primary_surface(RedWorker* worker, RedWorkerMessageDestroyPrimarySurface* msg)
 {
-    auto msg = (RedWorkerMessageDestroyPrimarySurface*) payload;
-    auto worker = (RedWorker*) opaque;
     uint32_t surface_id = msg->surface_id;
 
     destroy_primary_surface(worker, surface_id);
 }
 
-static void handle_dev_destroy_primary_surface_async(void *opaque, void *payload)
+static void
+handle_dev_destroy_primary_surface_async(RedWorker* worker,
+                                         RedWorkerMessageDestroyPrimarySurfaceAsync* msg)
 {
-    auto msg = (RedWorkerMessageDestroyPrimarySurfaceAsync*) payload;
-    auto worker = (RedWorker*) opaque;
     uint32_t surface_id = msg->surface_id;
 
     destroy_primary_surface(worker, surface_id);
@@ -500,20 +491,17 @@ static void handle_dev_destroy_primary_surface_async(void *opaque, void *payload
     red_qxl_async_complete(worker->qxl, msg->base.cookie);
 }
 
-static void handle_dev_flush_surfaces_async(void *opaque, void *payload)
+static void
+handle_dev_flush_surfaces_async(RedWorker* worker, RedWorkerMessageFlushSurfacesAsync* msg)
 {
-    auto worker = (RedWorker*) opaque;
-    auto msg = (RedWorkerMessageFlushSurfacesAsync*) payload;
-
     flush_all_qxl_commands(worker);
     display_channel_flush_all_surfaces(worker->display_channel);
     red_qxl_async_complete(worker->qxl, msg->base.cookie);
 }
 
-static void handle_dev_stop(void *opaque, void *payload)
+static void
+handle_dev_stop(RedWorker* worker, RedWorkerMessageStop*)
 {
-    auto worker = (RedWorker*) opaque;
-
     spice_debug("stop");
     if (!red_qxl_is_running(worker->qxl)) {
 	    return;
@@ -534,10 +522,9 @@ static void handle_dev_stop(void *opaque, void *payload)
     worker->cursor_channel->wait_all_sent(COMMON_CLIENT_TIMEOUT);
 }
 
-static void handle_dev_start(void *opaque, void *payload)
+static void
+handle_dev_start(RedWorker* worker, RedWorkerMessageStart*)
 {
-    auto worker = (RedWorker*) opaque;
-
     if (red_qxl_is_running(worker->qxl)) {
         return;
     }
@@ -554,17 +541,16 @@ static void handle_dev_start(void *opaque, void *payload)
     worker->event_timeout = 0;
 }
 
-static void handle_dev_wakeup(void *opaque, void *payload)
+static void
+handle_dev_wakeup(RedWorker* worker, RedWorkerMessageWakeup*)
 {
-    auto worker = (RedWorker*) opaque;
-
     stat_inc_counter(worker->wakeup_counter, 1);
     red_qxl_clear_pending(worker->qxl->st, RED_DISPATCHER_PENDING_WAKEUP);
 }
 
-static void handle_dev_oom(void *opaque, void *payload)
+static void
+handle_dev_oom(RedWorker* worker, RedWorkerMessageOom*)
 {
-    auto worker = (RedWorker*) opaque;
     DisplayChannel *display = worker->display_channel;
 
     int ring_is_empty;
@@ -583,45 +569,39 @@ static void handle_dev_oom(void *opaque, void *payload)
     red_qxl_clear_pending(worker->qxl->st, RED_DISPATCHER_PENDING_OOM);
 }
 
-static void handle_dev_reset_cursor(void *opaque, void *payload)
+static void
+handle_dev_reset_cursor(RedWorker* worker, RedWorkerMessageResetCursor*)
 {
-    auto worker = (RedWorker*) opaque;
-
     worker->cursor_channel->reset();
 }
 
-static void handle_dev_reset_image_cache(void *opaque, void *payload)
+static void
+handle_dev_reset_image_cache(RedWorker* worker, RedWorkerMessageResetImageCache*)
 {
-    auto worker = (RedWorker*) opaque;
-
     display_channel_reset_image_cache(worker->display_channel);
 }
 
-static void handle_dev_destroy_surface_wait_async(void *opaque, void *payload)
+static void
+handle_dev_destroy_surface_wait_async(RedWorker* worker,
+                                      RedWorkerMessageDestroySurfaceWaitAsync *msg)
 {
-    auto msg = (RedWorkerMessageDestroySurfaceWaitAsync*) payload;
-    auto worker = (RedWorker*) opaque;
-
     display_channel_destroy_surface_wait(worker->display_channel, msg->surface_id);
     red_qxl_async_complete(worker->qxl, msg->base.cookie);
 }
 
-static void handle_dev_destroy_surfaces_async(void *opaque, void *payload)
+static void
+handle_dev_destroy_surfaces_async(RedWorker* worker, RedWorkerMessageDestroySurfacesAsync* msg)
 {
-    auto worker = (RedWorker*) opaque;
-    auto msg = (RedWorkerMessageDestroySurfacesAsync*) payload;
-
     flush_all_qxl_commands(worker);
     display_channel_destroy_surfaces(worker->display_channel);
     worker->cursor_channel->reset();
     red_qxl_async_complete(worker->qxl, msg->base.cookie);
 }
 
-static void handle_dev_create_primary_surface_async(void *opaque, void *payload)
+static void
+handle_dev_create_primary_surface_async(RedWorker* worker,
+                                        RedWorkerMessageCreatePrimarySurfaceAsync* msg)
 {
-    auto msg = (RedWorkerMessageCreatePrimarySurfaceAsync*) payload;
-    auto worker = (RedWorker*) opaque;
-
     dev_create_primary_surface(worker, msg->surface_id, msg->surface);
     red_qxl_create_primary_surface_complete(worker->qxl->st, &msg->surface);
     red_qxl_async_complete(worker->qxl, msg->base.cookie);
@@ -632,10 +612,9 @@ static inline uint32_t qxl_monitors_config_size(uint32_t heads)
     return sizeof(QXLMonitorsConfig) + sizeof(QXLHead) * heads;
 }
 
-static void handle_dev_monitors_config_async(void *opaque, void *payload)
+static void
+handle_dev_monitors_config_async(RedWorker* worker, RedWorkerMessageMonitorsConfigAsync* msg)
 {
-    auto msg = (RedWorkerMessageMonitorsConfigAsync*) payload;
-    auto worker = (RedWorker*) opaque;
     uint16_t count, max_allowed;
     const QXLMonitorsConfig *dev_monitors_config =
         (QXLMonitorsConfig*)memslot_get_virt(&worker->mem_slots, msg->monitors_config,
@@ -676,10 +655,9 @@ async_complete:
     red_qxl_async_complete(worker->qxl, msg->base.cookie);
 }
 
-static void handle_dev_set_compression(void *opaque, void *payload)
+static void
+handle_dev_set_compression(RedWorker* worker, RedWorkerMessageSetCompression* msg)
 {
-    auto msg = (RedWorkerMessageSetCompression*) payload;
-    auto worker = (RedWorker*) opaque;
     SpiceImageCompression image_compression = msg->image_compression;
 
     display_channel_set_image_compression(worker->display_channel, image_compression);
@@ -688,28 +666,22 @@ static void handle_dev_set_compression(void *opaque, void *payload)
     display_channel_compress_stats_reset(worker->display_channel);
 }
 
-static void handle_dev_set_streaming_video(void *opaque, void *payload)
+static void
+handle_dev_set_streaming_video(RedWorker* worker, RedWorkerMessageSetStreamingVideo* msg)
 {
-    auto msg = (RedWorkerMessageSetStreamingVideo*) payload;
-    auto worker = (RedWorker*) opaque;
-
     display_channel_set_stream_video(worker->display_channel, msg->streaming_video);
 }
 
-static void handle_dev_set_video_codecs(void *opaque, void *payload)
+static void
+handle_dev_set_video_codecs(RedWorker* worker, RedWorkerMessageSetVideoCodecs* msg)
 {
-    auto msg = (RedWorkerMessageSetVideoCodecs*) payload;
-    auto worker = (RedWorker*) opaque;
-
     display_channel_set_video_codecs(worker->display_channel, msg->video_codecs);
     g_array_unref(msg->video_codecs);
 }
 
-static void handle_dev_set_mouse_mode(void *opaque, void *payload)
+static void
+handle_dev_set_mouse_mode(RedWorker* worker, RedWorkerMessageSetMouseMode* msg)
 {
-    auto msg = (RedWorkerMessageSetMouseMode*) payload;
-    auto worker = (RedWorker*) opaque;
-
     spice_debug("mouse mode %u", msg->mode);
     worker->cursor_channel->set_mouse_mode(msg->mode);
 }
@@ -721,10 +693,9 @@ static void dev_add_memslot(RedWorker *worker, QXLDevMemSlot mem_slot)
                           mem_slot.generation);
 }
 
-static void handle_dev_add_memslot(void *opaque, void *payload)
+static void
+handle_dev_add_memslot(RedWorker* worker, RedWorkerMessageAddMemslot* msg)
 {
-    auto worker = (RedWorker*) opaque;
-    auto msg = (RedWorkerMessageAddMemslot*) payload;
     QXLDevMemSlot mem_slot = msg->mem_slot;
 
     memslot_info_add_slot(&worker->mem_slots, mem_slot.slot_group_id, mem_slot.slot_id,
@@ -732,49 +703,40 @@ static void handle_dev_add_memslot(void *opaque, void *payload)
                           mem_slot.generation);
 }
 
-static void handle_dev_add_memslot_async(void *opaque, void *payload)
+static void
+handle_dev_add_memslot_async(RedWorker* worker, RedWorkerMessageAddMemslotAsync* msg)
 {
-    auto msg = (RedWorkerMessageAddMemslotAsync*) payload;
-    auto worker = (RedWorker*) opaque;
-
     dev_add_memslot(worker, msg->mem_slot);
     red_qxl_async_complete(worker->qxl, msg->base.cookie);
 }
 
-static void handle_dev_reset_memslots(void *opaque, void *payload)
+static void
+handle_dev_reset_memslots(RedWorker* worker, RedWorkerMessageResetMemslots*)
 {
-    auto worker = (RedWorker*) opaque;
-
     memslot_info_reset(&worker->mem_slots);
 }
 
-static void handle_dev_driver_unload(void *opaque, void *payload)
+static void
+handle_dev_driver_unload(RedWorker* worker, RedWorkerMessageDriverUnload*)
 {
-    auto worker = (RedWorker*) opaque;
-
     worker->driver_cap_monitors_config = false;
 }
 
-static
-void handle_dev_gl_scanout(void *opaque, void *payload)
+static void
+handle_dev_gl_scanout(RedWorker* worker, RedWorkerMessageGlScanout*)
 {
-    auto worker = (RedWorker*) opaque;
-
     display_channel_gl_scanout(worker->display_channel);
 }
 
-static
-void handle_dev_gl_draw_async(void *opaque, void *payload)
+static void
+handle_dev_gl_draw_async(RedWorker* worker, RedWorkerMessageGlDraw* draw)
 {
-    auto worker = (RedWorker*) opaque;
-    auto draw = (RedWorkerMessageGlDraw*) payload;
-
     display_channel_gl_draw(worker->display_channel, &draw->draw);
 }
 
-static void handle_dev_close(void *opaque, void *payload)
+static void
+handle_dev_close(RedWorker* worker, RedWorkerMessageClose*)
 {
-    auto worker = (RedWorker*) opaque;
     g_main_loop_quit(worker->loop);
 }
 
@@ -794,10 +756,9 @@ static bool loadvm_command(RedWorker *worker, QXLCommandExt *ext)
     return TRUE;
 }
 
-static void handle_dev_loadvm_commands(void *opaque, void *payload)
+static void
+handle_dev_loadvm_commands(RedWorker* worker, RedWorkerMessageLoadvmCommands* msg)
 {
-    auto msg = (RedWorkerMessageLoadvmCommands*) payload;
-    auto worker = (RedWorker*) opaque;
     uint32_t i;
     uint32_t count = msg->count;
     QXLCommandExt *ext = msg->ext;
@@ -818,133 +779,144 @@ static void worker_dispatcher_record(void *opaque, uint32_t message_type, void *
     red_record_event(worker->record, 1, message_type);
 }
 
+template <typename T>
+static inline void
+register_handler(Dispatcher *dispatcher, uint32_t message_type,
+                 void (*handler)(RedWorker*, T*), bool ack)
+{
+    dispatcher->register_handler(message_type,
+                                 reinterpret_cast<dispatcher_handle_message>(handler),
+                                 sizeof(T),
+                                 ack);
+}
+
 static void register_callbacks(Dispatcher *dispatcher)
 {
     /* TODO: register cursor & display specific msg in respective channel files */
-    dispatcher->register_handler(RED_WORKER_MESSAGE_UPDATE,
-                                 handle_dev_update,
-                                 sizeof(RedWorkerMessageUpdate),
-                                 true);
-    dispatcher->register_handler(RED_WORKER_MESSAGE_UPDATE_ASYNC,
-                                 handle_dev_update_async,
-                                 sizeof(RedWorkerMessageUpdateAsync),
-                                 false);
-    dispatcher->register_handler(RED_WORKER_MESSAGE_ADD_MEMSLOT,
-                                 handle_dev_add_memslot,
-                                 sizeof(RedWorkerMessageAddMemslot),
-                                 true);
-    dispatcher->register_handler(RED_WORKER_MESSAGE_ADD_MEMSLOT_ASYNC,
-                                 handle_dev_add_memslot_async,
-                                 sizeof(RedWorkerMessageAddMemslotAsync),
-                                 false);
-    dispatcher->register_handler(RED_WORKER_MESSAGE_DEL_MEMSLOT,
-                                 handle_dev_del_memslot,
-                                 sizeof(RedWorkerMessageDelMemslot),
-                                 false);
-    dispatcher->register_handler(RED_WORKER_MESSAGE_DESTROY_SURFACES,
-                                 handle_dev_destroy_surfaces,
-                                 sizeof(RedWorkerMessageDestroySurfaces),
-                                 true);
-    dispatcher->register_handler(RED_WORKER_MESSAGE_DESTROY_SURFACES_ASYNC,
-                                 handle_dev_destroy_surfaces_async,
-                                 sizeof(RedWorkerMessageDestroySurfacesAsync),
-                                 false);
-    dispatcher->register_handler(RED_WORKER_MESSAGE_DESTROY_PRIMARY_SURFACE,
-                                 handle_dev_destroy_primary_surface,
-                                 sizeof(RedWorkerMessageDestroyPrimarySurface),
-                                 true);
-    dispatcher->register_handler(RED_WORKER_MESSAGE_DESTROY_PRIMARY_SURFACE_ASYNC,
-                                 handle_dev_destroy_primary_surface_async,
-                                 sizeof(RedWorkerMessageDestroyPrimarySurfaceAsync),
-                                 false);
-    dispatcher->register_handler(RED_WORKER_MESSAGE_CREATE_PRIMARY_SURFACE_ASYNC,
-                                 handle_dev_create_primary_surface_async,
-                                 sizeof(RedWorkerMessageCreatePrimarySurfaceAsync),
-                                 false);
-    dispatcher->register_handler(RED_WORKER_MESSAGE_CREATE_PRIMARY_SURFACE,
-                                 handle_dev_create_primary_surface,
-                                 sizeof(RedWorkerMessageCreatePrimarySurface),
-                                 true);
-    dispatcher->register_handler(RED_WORKER_MESSAGE_RESET_IMAGE_CACHE,
-                                 handle_dev_reset_image_cache,
-                                 sizeof(RedWorkerMessageResetImageCache),
-                                 true);
-    dispatcher->register_handler(RED_WORKER_MESSAGE_RESET_CURSOR,
-                                 handle_dev_reset_cursor,
-                                 sizeof(RedWorkerMessageResetCursor),
-                                 true);
-    dispatcher->register_handler(RED_WORKER_MESSAGE_WAKEUP,
-                                 handle_dev_wakeup,
-                                 sizeof(RedWorkerMessageWakeup),
-                                 false);
-    dispatcher->register_handler(RED_WORKER_MESSAGE_OOM,
-                                 handle_dev_oom,
-                                 sizeof(RedWorkerMessageOom),
-                                 false);
-    dispatcher->register_handler(RED_WORKER_MESSAGE_START,
-                                 handle_dev_start,
-                                 sizeof(RedWorkerMessageStart),
-                                 false);
-    dispatcher->register_handler(RED_WORKER_MESSAGE_FLUSH_SURFACES_ASYNC,
-                                 handle_dev_flush_surfaces_async,
-                                 sizeof(RedWorkerMessageFlushSurfacesAsync),
-                                 false);
-    dispatcher->register_handler(RED_WORKER_MESSAGE_STOP,
-                                 handle_dev_stop,
-                                 sizeof(RedWorkerMessageStop),
-                                 true);
-    dispatcher->register_handler(RED_WORKER_MESSAGE_LOADVM_COMMANDS,
-                                 handle_dev_loadvm_commands,
-                                 sizeof(RedWorkerMessageLoadvmCommands),
-                                 true);
-    dispatcher->register_handler(RED_WORKER_MESSAGE_SET_COMPRESSION,
-                                 handle_dev_set_compression,
-                                 sizeof(RedWorkerMessageSetCompression),
-                                 false);
-    dispatcher->register_handler(RED_WORKER_MESSAGE_SET_STREAMING_VIDEO,
-                                 handle_dev_set_streaming_video,
-                                 sizeof(RedWorkerMessageSetStreamingVideo),
-                                 false);
-    dispatcher->register_handler(RED_WORKER_MESSAGE_SET_VIDEO_CODECS,
-                                 handle_dev_set_video_codecs,
-                                 sizeof(RedWorkerMessageSetVideoCodecs),
-                                 false);
-    dispatcher->register_handler(RED_WORKER_MESSAGE_SET_MOUSE_MODE,
-                                 handle_dev_set_mouse_mode,
-                                 sizeof(RedWorkerMessageSetMouseMode),
-                                 false);
-    dispatcher->register_handler(RED_WORKER_MESSAGE_DESTROY_SURFACE_WAIT,
-                                 handle_dev_destroy_surface_wait,
-                                 sizeof(RedWorkerMessageDestroySurfaceWait),
-                                 true);
-    dispatcher->register_handler(RED_WORKER_MESSAGE_DESTROY_SURFACE_WAIT_ASYNC,
-                                 handle_dev_destroy_surface_wait_async,
-                                 sizeof(RedWorkerMessageDestroySurfaceWaitAsync),
-                                 false);
-    dispatcher->register_handler(RED_WORKER_MESSAGE_RESET_MEMSLOTS,
-                                 handle_dev_reset_memslots,
-                                 sizeof(RedWorkerMessageResetMemslots),
-                                 false);
-    dispatcher->register_handler(RED_WORKER_MESSAGE_MONITORS_CONFIG_ASYNC,
-                                 handle_dev_monitors_config_async,
-                                 sizeof(RedWorkerMessageMonitorsConfigAsync),
-                                 false);
-    dispatcher->register_handler(RED_WORKER_MESSAGE_DRIVER_UNLOAD,
-                                 handle_dev_driver_unload,
-                                 sizeof(RedWorkerMessageDriverUnload),
-                                 false);
-    dispatcher->register_handler(RED_WORKER_MESSAGE_GL_SCANOUT,
-                                 handle_dev_gl_scanout,
-                                 sizeof(RedWorkerMessageGlScanout),
-                                 false);
-    dispatcher->register_handler(RED_WORKER_MESSAGE_GL_DRAW_ASYNC,
-                                 handle_dev_gl_draw_async,
-                                 sizeof(RedWorkerMessageGlDraw),
-                                 false);
-    dispatcher->register_handler(RED_WORKER_MESSAGE_CLOSE_WORKER,
-                                 handle_dev_close,
-                                 sizeof(RedWorkerMessageClose),
-                                 false);
+    register_handler(dispatcher,
+                     RED_WORKER_MESSAGE_UPDATE,
+                     handle_dev_update,
+                     true);
+    register_handler(dispatcher,
+                     RED_WORKER_MESSAGE_UPDATE_ASYNC,
+                     handle_dev_update_async,
+                     false);
+    register_handler(dispatcher,
+                     RED_WORKER_MESSAGE_ADD_MEMSLOT,
+                     handle_dev_add_memslot,
+                     true);
+    register_handler(dispatcher,
+                     RED_WORKER_MESSAGE_ADD_MEMSLOT_ASYNC,
+                     handle_dev_add_memslot_async,
+                     false);
+    register_handler(dispatcher,
+                     RED_WORKER_MESSAGE_DEL_MEMSLOT,
+                     handle_dev_del_memslot,
+                     false);
+    register_handler(dispatcher,
+                     RED_WORKER_MESSAGE_DESTROY_SURFACES,
+                     handle_dev_destroy_surfaces,
+                     true);
+    register_handler(dispatcher,
+                     RED_WORKER_MESSAGE_DESTROY_SURFACES_ASYNC,
+                     handle_dev_destroy_surfaces_async,
+                     false);
+    register_handler(dispatcher,
+                     RED_WORKER_MESSAGE_DESTROY_PRIMARY_SURFACE,
+                     handle_dev_destroy_primary_surface,
+                     true);
+    register_handler(dispatcher,
+                     RED_WORKER_MESSAGE_DESTROY_PRIMARY_SURFACE_ASYNC,
+                     handle_dev_destroy_primary_surface_async,
+                     false);
+    register_handler(dispatcher,
+                     RED_WORKER_MESSAGE_CREATE_PRIMARY_SURFACE_ASYNC,
+                     handle_dev_create_primary_surface_async,
+                     false);
+    register_handler(dispatcher,
+                     RED_WORKER_MESSAGE_CREATE_PRIMARY_SURFACE,
+                     handle_dev_create_primary_surface,
+                     true);
+    register_handler(dispatcher,
+                     RED_WORKER_MESSAGE_RESET_IMAGE_CACHE,
+                     handle_dev_reset_image_cache,
+                     true);
+    register_handler(dispatcher,
+                     RED_WORKER_MESSAGE_RESET_CURSOR,
+                     handle_dev_reset_cursor,
+                     true);
+    register_handler(dispatcher,
+                     RED_WORKER_MESSAGE_WAKEUP,
+                     handle_dev_wakeup,
+                     false);
+    register_handler(dispatcher,
+                     RED_WORKER_MESSAGE_OOM,
+                     handle_dev_oom,
+                     false);
+    register_handler(dispatcher,
+                     RED_WORKER_MESSAGE_START,
+                     handle_dev_start,
+                     false);
+    register_handler(dispatcher,
+                     RED_WORKER_MESSAGE_FLUSH_SURFACES_ASYNC,
+                     handle_dev_flush_surfaces_async,
+                     false);
+    register_handler(dispatcher,
+                     RED_WORKER_MESSAGE_STOP,
+                     handle_dev_stop,
+                     true);
+    register_handler(dispatcher,
+                     RED_WORKER_MESSAGE_LOADVM_COMMANDS,
+                     handle_dev_loadvm_commands,
+                     true);
+    register_handler(dispatcher,
+                     RED_WORKER_MESSAGE_SET_COMPRESSION,
+                     handle_dev_set_compression,
+                     false);
+    register_handler(dispatcher,
+                     RED_WORKER_MESSAGE_SET_STREAMING_VIDEO,
+                     handle_dev_set_streaming_video,
+                     false);
+    register_handler(dispatcher,
+                     RED_WORKER_MESSAGE_SET_VIDEO_CODECS,
+                     handle_dev_set_video_codecs,
+                     false);
+    register_handler(dispatcher,
+                     RED_WORKER_MESSAGE_SET_MOUSE_MODE,
+                     handle_dev_set_mouse_mode,
+                     false);
+    register_handler(dispatcher,
+                     RED_WORKER_MESSAGE_DESTROY_SURFACE_WAIT,
+                     handle_dev_destroy_surface_wait,
+                     true);
+    register_handler(dispatcher,
+                     RED_WORKER_MESSAGE_DESTROY_SURFACE_WAIT_ASYNC,
+                     handle_dev_destroy_surface_wait_async,
+                     false);
+    register_handler(dispatcher,
+                     RED_WORKER_MESSAGE_RESET_MEMSLOTS,
+                     handle_dev_reset_memslots,
+                     false);
+    register_handler(dispatcher,
+                     RED_WORKER_MESSAGE_MONITORS_CONFIG_ASYNC,
+                     handle_dev_monitors_config_async,
+                     false);
+    register_handler(dispatcher,
+                     RED_WORKER_MESSAGE_DRIVER_UNLOAD,
+                     handle_dev_driver_unload,
+                     false);
+    register_handler(dispatcher,
+                     RED_WORKER_MESSAGE_GL_SCANOUT,
+                     handle_dev_gl_scanout,
+                     false);
+    register_handler(dispatcher,
+                     RED_WORKER_MESSAGE_GL_DRAW_ASYNC,
+                     handle_dev_gl_draw_async,
+                     false);
+    register_handler(dispatcher,
+                     RED_WORKER_MESSAGE_CLOSE_WORKER,
+                     handle_dev_close,
+                     false);
 }
 
 


More information about the Spice-commits mailing list