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 + 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 +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 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(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,