diff options
author | Gerd Hoffmann <kraxel@redhat.com> | 2010-08-26 23:37:24 +0200 |
---|---|---|
committer | Gerd Hoffmann <kraxel@redhat.com> | 2010-08-26 23:37:24 +0200 |
commit | a05741ce1b9099c3a3df3865e4d0563eec46e2f8 (patch) | |
tree | 488f59ed82e289f86f6fe19c6bb690910ab14734 | |
parent | ea2f97a81015ecf2792e1906a6c0b156ec86cc5b (diff) |
qxl parser: add cursor parsing
-rw-r--r-- | server/red_parse_qxl.c | 46 | ||||
-rw-r--r-- | server/red_parse_qxl.h | 2 | ||||
-rw-r--r-- | server/red_worker.c | 59 |
3 files changed, 59 insertions, 48 deletions
diff --git a/server/red_parse_qxl.c b/server/red_parse_qxl.c index fb46bd8..6fa6ac5 100644 --- a/server/red_parse_qxl.c +++ b/server/red_parse_qxl.c @@ -984,6 +984,44 @@ void red_put_surface_cmd(RedSurfaceCmd *red) /* nothing yet */ } +static void red_get_cursor(RedMemSlotInfo *slots, int group_id, + SpiceCursor *red, QXLPHYSICAL addr) +{ + QXLCursor *qxl; + RedDataChunk chunks; + size_t size; + uint8_t *data; + bool free_data; + + qxl = (QXLCursor *)get_virt(slots, addr, sizeof(*qxl), group_id); + + red->header.unique = qxl->header.unique; + red->header.type = qxl->header.type; + red->header.width = qxl->header.width; + red->header.height = qxl->header.height; + red->header.hot_spot_x = qxl->header.hot_spot_x; + red->header.hot_spot_y = qxl->header.hot_spot_y; + + red->flags = 0; + red->data_size = qxl->data_size; + size = red_get_data_chunks_ptr(slots, group_id, + get_memslot_id(slots, addr), + &chunks, &qxl->chunk); + data = red_linearize_chunk(&chunks, size, &free_data); + red_put_data_chunks(&chunks); + red->data = spice_malloc(size); + memcpy(red->data, data, size); + + if (free_data) { + free(data); + } +} + +static void red_put_cursor(SpiceCursor *red) +{ + free(red->data); +} + void red_get_cursor_cmd(RedMemSlotInfo *slots, int group_id, RedCursorCmd *red, QXLPHYSICAL addr) { @@ -997,7 +1035,7 @@ void red_get_cursor_cmd(RedMemSlotInfo *slots, int group_id, case QXL_CURSOR_SET: red_get_point16_ptr(&red->u.set.position, &qxl->u.set.position); red->u.set.visible = qxl->u.set.visible; - red->u.set.shape = qxl->u.set.shape; + red_get_cursor(slots, group_id, &red->u.set.shape, qxl->u.set.shape); break; case QXL_CURSOR_MOVE: red_get_point16_ptr(&red->u.position, &qxl->u.position); @@ -1011,6 +1049,10 @@ void red_get_cursor_cmd(RedMemSlotInfo *slots, int group_id, void red_put_cursor_cmd(RedCursorCmd *red) { - /* nothing yet */ + switch (red->type) { + case QXL_CURSOR_SET: + red_put_cursor(&red->u.set.shape); + break; + } } diff --git a/server/red_parse_qxl.h b/server/red_parse_qxl.h index 95408f7..1d97249 100644 --- a/server/red_parse_qxl.h +++ b/server/red_parse_qxl.h @@ -99,7 +99,7 @@ typedef struct RedCursorCmd { struct { SpicePoint16 position; uint8_t visible; - SPICE_ADDRESS shape; + SpiceCursor shape; } set; struct { uint16_t length; diff --git a/server/red_worker.c b/server/red_worker.c index 1ed7b83..f525f17 100644 --- a/server/red_worker.c +++ b/server/red_worker.c @@ -6001,8 +6001,6 @@ static void fill_attr(DisplayChannel *display_channel, SpiceMarshaller *m, Spice static void fill_cursor(CursorChannel *cursor_channel, SpiceCursor *red_cursor, CursorItem *cursor, AddBufInfo *addbuf) { - RedChannel *channel = &cursor_channel->base; - addbuf->data = NULL; if (!cursor) { @@ -6012,18 +6010,9 @@ static void fill_cursor(CursorChannel *cursor_channel, SpiceCursor *red_cursor, if (cursor->type == CURSOR_TYPE_DEV) { RedCursorCmd *cursor_cmd; - QXLCursor *qxl_cursor; cursor_cmd = cursor->red_cursor; - qxl_cursor = (QXLCursor *)get_virt(&channel->worker->mem_slots, cursor_cmd->u.set.shape, - sizeof(QXLCursor), cursor->group_id); - red_cursor->flags = 0; - red_cursor->header.unique = qxl_cursor->header.unique; - red_cursor->header.type = qxl_cursor->header.type; - red_cursor->header.width = qxl_cursor->header.width; - red_cursor->header.height = qxl_cursor->header.height; - red_cursor->header.hot_spot_x = qxl_cursor->header.hot_spot_x; - red_cursor->header.hot_spot_y = qxl_cursor->header.hot_spot_y; + *red_cursor = cursor_cmd->u.set.shape; if (red_cursor->header.unique) { if (red_cursor_cache_find(cursor_channel, red_cursor->header.unique)) { @@ -6035,12 +6024,12 @@ static void fill_cursor(CursorChannel *cursor_channel, SpiceCursor *red_cursor, } } - if (qxl_cursor->data_size) { - addbuf->type = BUF_TYPE_CHUNK; - addbuf->data = &qxl_cursor->chunk; - addbuf->size = qxl_cursor->data_size; - addbuf->slot_id = get_memslot_id(&channel->worker->mem_slots, cursor_cmd->u.set.shape); - addbuf->group_id = cursor->group_id; + if (red_cursor->data_size) { + addbuf->type = BUF_TYPE_RAW; + addbuf->data = red_cursor->data; + addbuf->size = red_cursor->data_size; + addbuf->slot_id = 0; + addbuf->group_id = 0; } } else { LocalCursor *local_cursor; @@ -9615,7 +9604,7 @@ typedef struct __attribute__ ((__packed__)) CursorData { SpiceCursor _cursor; } CursorData; -static LocalCursor *_new_local_cursor(QXLCursorHeader *header, int data_size, SpicePoint16 position) +static LocalCursor *_new_local_cursor(SpiceCursorHeader *header, int data_size, SpicePoint16 position) { LocalCursor *local; @@ -9625,12 +9614,8 @@ static LocalCursor *_new_local_cursor(QXLCursorHeader *header, int data_size, Sp local->base.refs = 1; local->base.type = CURSOR_TYPE_LOCAL; + local->red_cursor.header = *header; local->red_cursor.header.unique = 0; - local->red_cursor.header.type = header->type; - local->red_cursor.header.width = header->width; - local->red_cursor.header.height = header->height; - local->red_cursor.header.hot_spot_x = header->hot_spot_x; - local->red_cursor.header.hot_spot_y = header->hot_spot_y; local->red_cursor.flags = 0; local->position = position; @@ -9641,11 +9626,8 @@ static LocalCursor *_new_local_cursor(QXLCursorHeader *header, int data_size, Sp static void red_cursor_flush(RedWorker *worker) { RedCursorCmd *cursor_cmd; - QXLCursor *qxl_cursor; + SpiceCursor *cursor; LocalCursor *local; - uint32_t data_size; - QXLDataChunk *chunk; - uint8_t *dest; if (!worker->cursor || worker->cursor->type == CURSOR_TYPE_LOCAL) { return; @@ -9655,26 +9637,13 @@ static void red_cursor_flush(RedWorker *worker) cursor_cmd = worker->cursor->red_cursor; ASSERT(cursor_cmd->type == QXL_CURSOR_SET); - qxl_cursor = (QXLCursor *)get_virt(&worker->mem_slots, cursor_cmd->u.set.shape, sizeof(QXLCursor), - worker->cursor->group_id); + cursor = &cursor_cmd->u.set.shape; - local = _new_local_cursor(&qxl_cursor->header, qxl_cursor->data_size, + local = _new_local_cursor(&cursor->header, cursor->data_size, worker->cursor_position); ASSERT(local); - data_size = local->data_size; - dest = local->red_cursor.data; - chunk = &qxl_cursor->chunk; - - while (data_size) { - ASSERT(chunk); - ASSERT(chunk->data_size <= data_size); - memcpy(dest, chunk->data, chunk->data_size); - data_size -= chunk->data_size; - dest += chunk->data_size; - chunk = chunk->next_chunk ? - (QXLDataChunk *)get_virt(&worker->mem_slots, chunk->next_chunk, sizeof(QXLDataChunk), - worker->mem_slots.internal_groupslot_id) : NULL; - } + memcpy(local->red_cursor.data, cursor->data, local->data_size); + red_set_cursor(worker, &local->base); red_release_cursor(worker, &local->base); } |