diff --git a/client/src/main.c b/client/src/main.c index 6762001d..57fb610c 100644 --- a/client/src/main.c +++ b/client/src/main.c @@ -976,9 +976,17 @@ static void spice_setCursorRGBAImage(int width, int height, int hx, int hy, g_state.spiceHotX = hx; g_state.spiceHotY = hy; - void * copied = malloc(width * height * 4); - memcpy(copied, data, width * height * 4); - renderQueue_cursorImage(false, width, height, width * 4, copied); + const uint8_t * rgba = data; + uint8_t * bgra = malloc(width * height * 4); + for (int i = 0; i < width * height; ++i) + { + bgra[i * 4 + 0] = rgba[i * 4 + 2]; + bgra[i * 4 + 1] = rgba[i * 4 + 1]; + bgra[i * 4 + 2] = rgba[i * 4 + 0]; + bgra[i * 4 + 3] = rgba[i * 4 + 3]; + } + renderQueue_cursorImage( + LG_CURSOR_COLOR, width, height, width * 4, bgra); } static void spice_setCursorMonoImage(int width, int height, int hx, int hy, @@ -989,9 +997,37 @@ static void spice_setCursorMonoImage(int width, int height, int hx, int hy, int stride = (width + 7) / 8; uint8_t * buffer = malloc(stride * height * 2); - memcpy(buffer, xorMask, stride * height); - memcpy(buffer + stride * height, andMask, stride * height); - renderQueue_cursorImage(true, width, height * 2, stride, buffer); + memcpy(buffer, andMask, stride * height); + memcpy(buffer + stride * height, xorMask, stride * height); + renderQueue_cursorImage( + LG_CURSOR_MONOCHROME, width, height * 2, stride, buffer); +} + +static void spice_setCursorColorImage(int width, int height, int hx, int hy, + const void * data, const void * maskData) +{ + g_state.spiceHotX = hx; + g_state.spiceHotY = hy; + + const uint8_t * rgba = data; + const uint8_t * andMask = maskData; + const int maskStride = (width + 7) / 8; + uint8_t * bgra = malloc(width * height * 4); + for (int y = 0; y < height; ++y) + { + for (int x = 0; x < width; ++x) + { + const int i = y * width + x; + bgra[i * 4 + 0] = rgba[i * 4 + 2]; + bgra[i * 4 + 1] = rgba[i * 4 + 1]; + bgra[i * 4 + 2] = rgba[i * 4 + 0]; + bgra[i * 4 + 3] = + andMask[y * maskStride + x / 8] & (0x80U >> (x % 8)) ? 255 : 0; + } + } + + renderQueue_cursorImage( + LG_CURSOR_MASKED_COLOR, width, height, width * 4, bgra); } static void spice_setCursorState(bool visible, int x, int y) @@ -1034,11 +1070,12 @@ int spiceThread(void * arg) }, .cursor = { - .enable = true, - .autoConnect = false, - .setRGBAImage = spice_setCursorRGBAImage, - .setMonoImage = spice_setCursorMonoImage, - .setState = spice_setCursorState, + .enable = true, + .autoConnect = false, + .setRGBAImage = spice_setCursorRGBAImage, + .setMonoImage = spice_setCursorMonoImage, + .setColorImage = spice_setCursorColorImage, + .setState = spice_setCursorState, }, #if ENABLE_AUDIO .playback = diff --git a/client/src/render_queue.c b/client/src/render_queue.c index 34839d01..e76a85b4 100644 --- a/client/src/render_queue.c +++ b/client/src/render_queue.c @@ -224,16 +224,16 @@ void renderQueue_cursorState(bool visible, int x, int y, int hx, int hy) ll_push(l_renderQueue, cmd); } -void renderQueue_cursorImage(bool monochrome, int width, int height, int pitch, - uint8_t * data) +void renderQueue_cursorImage(LG_RendererCursor type, + int width, int height, int pitch, uint8_t * data) { - RenderCommand * cmd = malloc(sizeof(*cmd)); - cmd->op = CURSOR_OP_IMAGE; - cmd->cursorImage.monochrome = monochrome; - cmd->cursorImage.width = width; - cmd->cursorImage.height = height; - cmd->cursorImage.pitch = pitch; - cmd->cursorImage.data = data; + RenderCommand * cmd = malloc(sizeof(*cmd)); + cmd->op = CURSOR_OP_IMAGE; + cmd->cursorImage.type = type; + cmd->cursorImage.width = width; + cmd->cursorImage.height = height; + cmd->cursorImage.pitch = pitch; + cmd->cursorImage.data = data; ll_push(l_renderQueue, cmd); } @@ -288,7 +288,7 @@ void renderQueue_process(void) case CURSOR_OP_IMAGE: RENDERER(onMouseShape, - cmd->cursorImage.monochrome ? LG_CURSOR_MONOCHROME : LG_CURSOR_COLOR, + cmd->cursorImage.type, cmd->cursorImage.width, cmd->cursorImage.height, cmd->cursorImage.pitch, cmd->cursorImage.data); free(cmd->cursorImage.data); diff --git a/client/src/render_queue.h b/client/src/render_queue.h index 2f7e947d..2e689a87 100644 --- a/client/src/render_queue.h +++ b/client/src/render_queue.h @@ -86,11 +86,11 @@ typedef struct struct { - bool monochrome; - int width; - int height; - int pitch; - uint8_t * data; + LG_RendererCursor type; + int width; + int height; + int pitch; + uint8_t * data; } cursorImage; }; @@ -117,5 +117,6 @@ void renderQueue_surfaceFormat(const LG_RendererFormat format, void renderQueue_cursorState(bool visible, int x, int y, int hx, int hy); -void renderQueue_cursorImage(bool monochrome, int width, int height, int pitch, +void renderQueue_cursorImage(LG_RendererCursor type, + int width, int height, int pitch, uint8_t * data); diff --git a/repos/PureSpice b/repos/PureSpice index 96c1f8c5..4f0f5b5b 160000 --- a/repos/PureSpice +++ b/repos/PureSpice @@ -1 +1 @@ -Subproject commit 96c1f8c5c465596b6befdc5fa2f31be622d4060c +Subproject commit 4f0f5b5b9f513eba6b65b8f5e66bc30feb858436