mirror of
git://git.proxmox.com/git/spiceterm.git
synced 2025-08-22 18:17:13 +00:00
use reasonable names (instead of 'test')
This commit is contained in:
parent
e3759a340c
commit
64bc7a2f9d
4
Makefile
4
Makefile
@ -1,8 +1,8 @@
|
|||||||
|
|
||||||
PROGRAMS=spiceterm
|
PROGRAMS=spiceterm
|
||||||
|
|
||||||
HEADERS=translations.h basic_event_loop.h glyphs.h spiceterm.h
|
HEADERS=translations.h event_loop.h glyphs.h spiceterm.h
|
||||||
SOURCES=test_display_base.c basic_event_loop.c spiceterm.c
|
SOURCES=screen.c event_loop.c spiceterm.c
|
||||||
|
|
||||||
all: ${PROGRAMS}
|
all: ${PROGRAMS}
|
||||||
|
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
#include <glib.h>
|
#include <glib.h>
|
||||||
|
|
||||||
#include <spice/macros.h>
|
#include <spice/macros.h>
|
||||||
#include "basic_event_loop.h"
|
#include "event_loop.h"
|
||||||
|
|
||||||
int debug = 1;
|
int debug = 1;
|
||||||
|
|
@ -41,7 +41,8 @@ typedef struct SimpleSpiceUpdate {
|
|||||||
uint8_t *bitmap;
|
uint8_t *bitmap;
|
||||||
} SimpleSpiceUpdate;
|
} SimpleSpiceUpdate;
|
||||||
|
|
||||||
static void test_spice_destroy_update(SimpleSpiceUpdate *update)
|
static void
|
||||||
|
spice_screen_destroy_update(SimpleSpiceUpdate *update)
|
||||||
{
|
{
|
||||||
if (!update) {
|
if (!update) {
|
||||||
return;
|
return;
|
||||||
@ -57,21 +58,10 @@ static void test_spice_destroy_update(SimpleSpiceUpdate *update)
|
|||||||
#define DEFAULT_WIDTH 640
|
#define DEFAULT_WIDTH 640
|
||||||
#define DEFAULT_HEIGHT 320
|
#define DEFAULT_HEIGHT 320
|
||||||
|
|
||||||
//#define SINGLE_PART 4
|
|
||||||
//static const int angle_parts = 64 / SINGLE_PART;
|
|
||||||
static int unique = 1;
|
static int unique = 1;
|
||||||
//static int color = -1;
|
|
||||||
//static int c_i = 0;
|
|
||||||
|
|
||||||
__attribute__((noreturn))
|
static void
|
||||||
static void sigchld_handler(int signal_num) // wait for the child process and exit
|
set_cmd(QXLCommandExt *ext, uint32_t type, QXLPHYSICAL data)
|
||||||
{
|
|
||||||
int status;
|
|
||||||
wait(&status);
|
|
||||||
exit(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void set_cmd(QXLCommandExt *ext, uint32_t type, QXLPHYSICAL data)
|
|
||||||
{
|
{
|
||||||
ext->cmd.type = type;
|
ext->cmd.type = type;
|
||||||
ext->cmd.data = data;
|
ext->cmd.data = data;
|
||||||
@ -80,39 +70,37 @@ static void set_cmd(QXLCommandExt *ext, uint32_t type, QXLPHYSICAL data)
|
|||||||
ext->flags = 0;
|
ext->flags = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void simple_set_release_info(QXLReleaseInfo *info, intptr_t ptr)
|
static void
|
||||||
|
simple_set_release_info(QXLReleaseInfo *info, intptr_t ptr)
|
||||||
{
|
{
|
||||||
info->id = ptr;
|
info->id = ptr;
|
||||||
//info->group_id = MEM_SLOT_GROUP_ID;
|
//info->group_id = MEM_SLOT_GROUP_ID;
|
||||||
}
|
}
|
||||||
|
|
||||||
// We shall now have a ring of commands, so that we can update
|
/* Note: push_command/get_command are called from different threads */
|
||||||
// it from a separate thread - since get_command is called from
|
|
||||||
// the worker thread, and we need to sometimes do an update_area,
|
|
||||||
// which cannot be done from red_worker context (not via dispatcher,
|
|
||||||
// since you get a deadlock, and it isn't designed to be done
|
|
||||||
// any other way, so no point testing that).
|
|
||||||
|
|
||||||
|
static void
|
||||||
static void push_command(Test *test, QXLCommandExt *ext)
|
push_command(SpiceScreen *spice_screen, QXLCommandExt *ext)
|
||||||
{
|
{
|
||||||
g_mutex_lock(test->command_mutex);
|
g_mutex_lock(spice_screen->command_mutex);
|
||||||
|
|
||||||
while (test->commands_end - test->commands_start >= COMMANDS_SIZE) {
|
while (spice_screen->commands_end - spice_screen->commands_start >= COMMANDS_SIZE) {
|
||||||
g_cond_wait(test->command_cond, test->command_mutex);
|
g_cond_wait(spice_screen->command_cond, spice_screen->command_mutex);
|
||||||
}
|
}
|
||||||
g_assert(test->commands_end - test->commands_start < COMMANDS_SIZE);
|
|
||||||
test->commands[test->commands_end % COMMANDS_SIZE] = ext;
|
|
||||||
test->commands_end++;
|
|
||||||
g_mutex_unlock(test->command_mutex);
|
|
||||||
|
|
||||||
test->qxl_worker->wakeup(test->qxl_worker);
|
g_assert(spice_screen->commands_end - spice_screen->commands_start < COMMANDS_SIZE);
|
||||||
|
|
||||||
|
spice_screen->commands[spice_screen->commands_end % COMMANDS_SIZE] = ext;
|
||||||
|
spice_screen->commands_end++;
|
||||||
|
|
||||||
|
g_mutex_unlock(spice_screen->command_mutex);
|
||||||
|
|
||||||
|
spice_screen->qxl_worker->wakeup(spice_screen->qxl_worker);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* bitmap are freed, so they must be allocated with g_malloc */
|
/* bitmap are freed, so they must be allocated with g_malloc */
|
||||||
SimpleSpiceUpdate *test_spice_create_update_from_bitmap(uint32_t surface_id,
|
static SimpleSpiceUpdate *
|
||||||
QXLRect bbox,
|
spice_screen_update_from_bitmap_cmd(uint32_t surface_id, QXLRect bbox, uint8_t *bitmap)
|
||||||
uint8_t *bitmap)
|
|
||||||
{
|
{
|
||||||
SimpleSpiceUpdate *update;
|
SimpleSpiceUpdate *update;
|
||||||
QXLDrawable *drawable;
|
QXLDrawable *drawable;
|
||||||
@ -158,7 +146,9 @@ SimpleSpiceUpdate *test_spice_create_update_from_bitmap(uint32_t surface_id,
|
|||||||
return update;
|
return update;
|
||||||
}
|
}
|
||||||
|
|
||||||
static SimpleSpiceUpdate *test_draw_char(Test *test, int x, int y, int c, int fg, int bg)
|
static SimpleSpiceUpdate *
|
||||||
|
spice_screen_draw_char_cmd(SpiceScreen *spice_screen, int x, int y, int c,
|
||||||
|
int fg, int bg)
|
||||||
{
|
{
|
||||||
int top, left;
|
int top, left;
|
||||||
uint8_t *dst;
|
uint8_t *dst;
|
||||||
@ -169,8 +159,6 @@ static SimpleSpiceUpdate *test_draw_char(Test *test, int x, int y, int c, int fg
|
|||||||
|
|
||||||
left = x*8;
|
left = x*8;
|
||||||
top = y*16;
|
top = y*16;
|
||||||
|
|
||||||
// printf("DRAWCHAR %d %d %d\n", left, top, c);
|
|
||||||
|
|
||||||
unique++;
|
unique++;
|
||||||
|
|
||||||
@ -217,16 +205,18 @@ static SimpleSpiceUpdate *test_draw_char(Test *test, int x, int y, int c, int fg
|
|||||||
bbox.left = left; bbox.top = top;
|
bbox.left = left; bbox.top = top;
|
||||||
bbox.right = left + bw; bbox.bottom = top + bh;
|
bbox.right = left + bw; bbox.bottom = top + bh;
|
||||||
|
|
||||||
return test_spice_create_update_from_bitmap(0, bbox, bitmap);
|
return spice_screen_update_from_bitmap_cmd(0, bbox, bitmap);
|
||||||
}
|
}
|
||||||
|
|
||||||
void test_spice_scroll(Test *test, int x1, int y1, int x2, int y2, int src_x, int src_y)
|
void
|
||||||
|
spice_screen_scroll(SpiceScreen *spice_screen, int x1, int y1,
|
||||||
|
int x2, int y2, int src_x, int src_y)
|
||||||
{
|
{
|
||||||
SimpleSpiceUpdate *update;
|
SimpleSpiceUpdate *update;
|
||||||
QXLDrawable *drawable;
|
QXLDrawable *drawable;
|
||||||
QXLRect bbox;
|
QXLRect bbox;
|
||||||
|
|
||||||
int surface_id = 0; // fixme
|
int surface_id = 0;
|
||||||
|
|
||||||
update = g_new0(SimpleSpiceUpdate, 1);
|
update = g_new0(SimpleSpiceUpdate, 1);
|
||||||
drawable = &update->drawable;
|
drawable = &update->drawable;
|
||||||
@ -252,16 +242,17 @@ void test_spice_scroll(Test *test, int x1, int y1, int x2, int y2, int src_x, in
|
|||||||
|
|
||||||
set_cmd(&update->ext, QXL_CMD_DRAW, (intptr_t)drawable);
|
set_cmd(&update->ext, QXL_CMD_DRAW, (intptr_t)drawable);
|
||||||
|
|
||||||
push_command(test, &update->ext);
|
push_command(spice_screen, &update->ext);
|
||||||
}
|
}
|
||||||
|
|
||||||
void test_spice_clear(Test *test, int x1, int y1, int x2, int y2)
|
void
|
||||||
|
spice_screen_clear(SpiceScreen *spice_screen, int x1, int y1, int x2, int y2)
|
||||||
{
|
{
|
||||||
SimpleSpiceUpdate *update;
|
SimpleSpiceUpdate *update;
|
||||||
QXLDrawable *drawable;
|
QXLDrawable *drawable;
|
||||||
QXLRect bbox;
|
QXLRect bbox;
|
||||||
|
|
||||||
int surface_id = 0; // fixme
|
int surface_id = 0;
|
||||||
|
|
||||||
update = g_new0(SimpleSpiceUpdate, 1);
|
update = g_new0(SimpleSpiceUpdate, 1);
|
||||||
drawable = &update->drawable;
|
drawable = &update->drawable;
|
||||||
@ -284,13 +275,14 @@ void test_spice_clear(Test *test, int x1, int y1, int x2, int y2)
|
|||||||
|
|
||||||
set_cmd(&update->ext, QXL_CMD_DRAW, (intptr_t)drawable);
|
set_cmd(&update->ext, QXL_CMD_DRAW, (intptr_t)drawable);
|
||||||
|
|
||||||
push_command(test, &update->ext);
|
push_command(spice_screen, &update->ext);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void create_primary_surface(Test *test, uint32_t width,
|
static void
|
||||||
uint32_t height)
|
create_primary_surface(SpiceScreen *spice_screen, uint32_t width,
|
||||||
|
uint32_t height)
|
||||||
{
|
{
|
||||||
QXLWorker *qxl_worker = test->qxl_worker;
|
QXLWorker *qxl_worker = spice_screen->qxl_worker;
|
||||||
QXLDevSurfaceCreate surface = { 0, };
|
QXLDevSurfaceCreate surface = { 0, };
|
||||||
|
|
||||||
g_assert(height <= MAX_HEIGHT);
|
g_assert(height <= MAX_HEIGHT);
|
||||||
@ -299,60 +291,61 @@ static void create_primary_surface(Test *test, uint32_t width,
|
|||||||
g_assert(width > 0);
|
g_assert(width > 0);
|
||||||
|
|
||||||
surface.format = SPICE_SURFACE_FMT_32_xRGB;
|
surface.format = SPICE_SURFACE_FMT_32_xRGB;
|
||||||
surface.width = test->primary_width = width;
|
surface.width = spice_screen->primary_width = width;
|
||||||
surface.height = test->primary_height = height;
|
surface.height = spice_screen->primary_height = height;
|
||||||
surface.stride = -width * 4; /* negative? */
|
surface.stride = -width * 4; /* negative? */
|
||||||
surface.mouse_mode = TRUE; /* unused by red_worker */
|
surface.mouse_mode = TRUE; /* unused by red_worker */
|
||||||
surface.flags = 0;
|
surface.flags = 0;
|
||||||
surface.type = 0; /* unused by red_worker */
|
surface.type = 0; /* unused by red_worker */
|
||||||
surface.position = 0; /* unused by red_worker */
|
surface.position = 0; /* unused by red_worker */
|
||||||
surface.mem = (uint64_t)&test->primary_surface;
|
surface.mem = (uint64_t)&spice_screen->primary_surface;
|
||||||
surface.group_id = MEM_SLOT_GROUP_ID;
|
surface.group_id = MEM_SLOT_GROUP_ID;
|
||||||
|
|
||||||
test->width = width;
|
spice_screen->width = width;
|
||||||
test->height = height;
|
spice_screen->height = height;
|
||||||
|
|
||||||
qxl_worker->create_primary_surface(qxl_worker, 0, &surface);
|
qxl_worker->create_primary_surface(qxl_worker, 0, &surface);
|
||||||
}
|
}
|
||||||
|
|
||||||
QXLDevMemSlot slot = {
|
QXLDevMemSlot slot = {
|
||||||
.slot_group_id = MEM_SLOT_GROUP_ID,
|
.slot_group_id = MEM_SLOT_GROUP_ID,
|
||||||
.slot_id = 0,
|
.slot_id = 0,
|
||||||
.generation = 0,
|
.generation = 0,
|
||||||
.virt_start = 0,
|
.virt_start = 0,
|
||||||
.virt_end = ~0,
|
.virt_end = ~0,
|
||||||
.addr_delta = 0,
|
.addr_delta = 0,
|
||||||
.qxl_ram_size = ~0,
|
.qxl_ram_size = ~0,
|
||||||
};
|
};
|
||||||
|
|
||||||
static void attache_worker(QXLInstance *qin, QXLWorker *_qxl_worker)
|
static void
|
||||||
|
attache_worker(QXLInstance *qin, QXLWorker *_qxl_worker)
|
||||||
{
|
{
|
||||||
Test *test = SPICE_CONTAINEROF(qin, Test, qxl_instance);
|
SpiceScreen *spice_screen = SPICE_CONTAINEROF(qin, SpiceScreen, qxl_instance);
|
||||||
|
|
||||||
if (test->qxl_worker) {
|
if (spice_screen->qxl_worker) {
|
||||||
if (test->qxl_worker != _qxl_worker)
|
g_assert_not_reached();
|
||||||
printf("%s ignored, %p is set, ignoring new %p\n", __func__,
|
|
||||||
test->qxl_worker, _qxl_worker);
|
|
||||||
else
|
|
||||||
printf("%s ignored, redundant\n", __func__);
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
printf("%s\n", __func__);
|
|
||||||
test->qxl_worker = _qxl_worker;
|
spice_screen->qxl_worker = _qxl_worker;
|
||||||
test->qxl_worker->add_memslot(test->qxl_worker, &slot);
|
spice_screen->qxl_worker->add_memslot(spice_screen->qxl_worker, &slot);
|
||||||
create_primary_surface(test, DEFAULT_WIDTH, DEFAULT_HEIGHT);
|
create_primary_surface(spice_screen, DEFAULT_WIDTH, DEFAULT_HEIGHT);
|
||||||
test->qxl_worker->start(test->qxl_worker);
|
spice_screen->qxl_worker->start(spice_screen->qxl_worker);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void set_compression_level(QXLInstance *qin, int level)
|
static void
|
||||||
|
set_compression_level(QXLInstance *qin, int level)
|
||||||
{
|
{
|
||||||
printf("%s\n", __func__);
|
/* not used */
|
||||||
}
|
}
|
||||||
|
|
||||||
static void set_mm_time(QXLInstance *qin, uint32_t mm_time)
|
static void
|
||||||
|
set_mm_time(QXLInstance *qin, uint32_t mm_time)
|
||||||
{
|
{
|
||||||
|
/* not used */
|
||||||
}
|
}
|
||||||
static void get_init_info(QXLInstance *qin, QXLDevInitInfo *info)
|
|
||||||
|
static void
|
||||||
|
get_init_info(QXLInstance *qin, QXLDevInitInfo *info)
|
||||||
{
|
{
|
||||||
memset(info, 0, sizeof(*info));
|
memset(info, 0, sizeof(*info));
|
||||||
info->num_memslots = 1;
|
info->num_memslots = 1;
|
||||||
@ -362,47 +355,50 @@ static void get_init_info(QXLInstance *qin, QXLDevInitInfo *info)
|
|||||||
info->n_surfaces = 1;
|
info->n_surfaces = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// called from spice_server thread (i.e. red_worker thread)
|
/* called from spice_server thread (i.e. red_worker thread) */
|
||||||
static int get_command(QXLInstance *qin, struct QXLCommandExt *ext)
|
static int
|
||||||
|
get_command(QXLInstance *qin, struct QXLCommandExt *ext)
|
||||||
{
|
{
|
||||||
Test *test = SPICE_CONTAINEROF(qin, Test, qxl_instance);
|
SpiceScreen *spice_screen = SPICE_CONTAINEROF(qin, SpiceScreen, qxl_instance);
|
||||||
int res = FALSE;
|
int res = FALSE;
|
||||||
|
|
||||||
g_mutex_lock(test->command_mutex);
|
g_mutex_lock(spice_screen->command_mutex);
|
||||||
|
|
||||||
if ((test->commands_end - test->commands_start) == 0) {
|
if ((spice_screen->commands_end - spice_screen->commands_start) == 0) {
|
||||||
res = FALSE;
|
res = FALSE;
|
||||||
goto ret;
|
goto ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
*ext = *test->commands[test->commands_start % COMMANDS_SIZE];
|
*ext = *spice_screen->commands[spice_screen->commands_start % COMMANDS_SIZE];
|
||||||
g_assert(test->commands_start < test->commands_end);
|
g_assert(spice_screen->commands_start < spice_screen->commands_end);
|
||||||
test->commands_start++;
|
spice_screen->commands_start++;
|
||||||
g_cond_signal(test->command_cond);
|
g_cond_signal(spice_screen->command_cond);
|
||||||
|
|
||||||
res = TRUE;
|
res = TRUE;
|
||||||
|
|
||||||
ret:
|
ret:
|
||||||
g_mutex_unlock(test->command_mutex);
|
g_mutex_unlock(spice_screen->command_mutex);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int req_cmd_notification(QXLInstance *qin)
|
static int
|
||||||
|
req_cmd_notification(QXLInstance *qin)
|
||||||
{
|
{
|
||||||
//Test *test = SPICE_CONTAINEROF(qin, Test, qxl_instance);
|
//SpiceScreen *spice_screen = SPICE_CONTAINEROF(qin, SpiceScreen, qxl_instance);
|
||||||
//test->core->timer_start(test->wakeup_timer, test->wakeup_ms);
|
//spice_screen->core->timer_start(spice_screen->wakeup_timer, spice_screen->wakeup_ms);
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void release_resource(QXLInstance *qin, struct QXLReleaseInfoExt release_info)
|
static void
|
||||||
|
release_resource(QXLInstance *qin, struct QXLReleaseInfoExt release_info)
|
||||||
{
|
{
|
||||||
QXLCommandExt *ext = (QXLCommandExt*)(unsigned long)release_info.info->id;
|
QXLCommandExt *ext = (QXLCommandExt*)(unsigned long)release_info.info->id;
|
||||||
//printf("%s\n", __func__);
|
|
||||||
g_assert(release_info.group_id == MEM_SLOT_GROUP_ID);
|
g_assert(release_info.group_id == MEM_SLOT_GROUP_ID);
|
||||||
switch (ext->cmd.type) {
|
switch (ext->cmd.type) {
|
||||||
case QXL_CMD_DRAW:
|
case QXL_CMD_DRAW:
|
||||||
test_spice_destroy_update((void*)ext);
|
spice_screen_destroy_update((void*)ext);
|
||||||
break;
|
break;
|
||||||
case QXL_CMD_SURFACE:
|
case QXL_CMD_SURFACE:
|
||||||
free(ext);
|
free(ext);
|
||||||
@ -420,15 +416,16 @@ static void release_resource(QXLInstance *qin, struct QXLReleaseInfoExt release_
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#define CURSOR_WIDTH 32
|
#define CURSOR_WIDTH 8
|
||||||
#define CURSOR_HEIGHT 32
|
#define CURSOR_HEIGHT 16
|
||||||
|
|
||||||
static struct {
|
static struct {
|
||||||
QXLCursor cursor;
|
QXLCursor cursor;
|
||||||
uint8_t data[CURSOR_WIDTH * CURSOR_HEIGHT * 4]; // 32bit per pixel
|
uint8_t data[CURSOR_WIDTH * CURSOR_HEIGHT * 4]; // 32bit per pixel
|
||||||
} cursor;
|
} cursor;
|
||||||
|
|
||||||
static void cursor_init()
|
static void
|
||||||
|
cursor_init()
|
||||||
{
|
{
|
||||||
cursor.cursor.header.unique = 0;
|
cursor.cursor.header.unique = 0;
|
||||||
cursor.cursor.header.type = SPICE_CURSOR_TYPE_COLOR32;
|
cursor.cursor.header.type = SPICE_CURSOR_TYPE_COLOR32;
|
||||||
@ -448,19 +445,20 @@ static void cursor_init()
|
|||||||
cursor.cursor.chunk.prev_chunk = cursor.cursor.chunk.next_chunk = 0;
|
cursor.cursor.chunk.prev_chunk = cursor.cursor.chunk.next_chunk = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int get_cursor_command(QXLInstance *qin, struct QXLCommandExt *ext)
|
static int
|
||||||
|
get_cursor_command(QXLInstance *qin, struct QXLCommandExt *ext)
|
||||||
{
|
{
|
||||||
Test *test = SPICE_CONTAINEROF(qin, Test, qxl_instance);
|
SpiceScreen *spice_screen = SPICE_CONTAINEROF(qin, SpiceScreen, qxl_instance);
|
||||||
static int set = 1;
|
static int set = 1;
|
||||||
static int x = 0, y = 0;
|
static int x = 0, y = 0;
|
||||||
QXLCursorCmd *cursor_cmd;
|
QXLCursorCmd *cursor_cmd;
|
||||||
QXLCommandExt *cmd;
|
QXLCommandExt *cmd;
|
||||||
|
|
||||||
if (!test->cursor_notify) {
|
if (!spice_screen->cursor_notify) {
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
test->cursor_notify--;
|
spice_screen->cursor_notify--;
|
||||||
cmd = calloc(sizeof(QXLCommandExt), 1);
|
cmd = calloc(sizeof(QXLCommandExt), 1);
|
||||||
cursor_cmd = calloc(sizeof(QXLCursorCmd), 1);
|
cursor_cmd = calloc(sizeof(QXLCursorCmd), 1);
|
||||||
|
|
||||||
@ -472,13 +470,13 @@ static int get_cursor_command(QXLInstance *qin, struct QXLCommandExt *ext)
|
|||||||
cursor_cmd->u.set.position.y = 0;
|
cursor_cmd->u.set.position.y = 0;
|
||||||
cursor_cmd->u.set.visible = TRUE;
|
cursor_cmd->u.set.visible = TRUE;
|
||||||
cursor_cmd->u.set.shape = (unsigned long)&cursor;
|
cursor_cmd->u.set.shape = (unsigned long)&cursor;
|
||||||
// Only a white rect (32x32) as cursor
|
// white rect as cursor
|
||||||
memset(cursor.data, 255, sizeof(cursor.data));
|
memset(cursor.data, 255, sizeof(cursor.data));
|
||||||
set = 0;
|
set = 0;
|
||||||
} else {
|
} else {
|
||||||
cursor_cmd->type = QXL_CURSOR_MOVE;
|
cursor_cmd->type = QXL_CURSOR_MOVE;
|
||||||
cursor_cmd->u.position.x = x++ % test->primary_width;
|
cursor_cmd->u.position.x = x++ % spice_screen->primary_width;
|
||||||
cursor_cmd->u.position.y = y++ % test->primary_height;
|
cursor_cmd->u.position.y = y++ % spice_screen->primary_height;
|
||||||
}
|
}
|
||||||
|
|
||||||
cmd->cmd.data = (unsigned long)cursor_cmd;
|
cmd->cmd.data = (unsigned long)cursor_cmd;
|
||||||
@ -486,62 +484,67 @@ static int get_cursor_command(QXLInstance *qin, struct QXLCommandExt *ext)
|
|||||||
cmd->group_id = MEM_SLOT_GROUP_ID;
|
cmd->group_id = MEM_SLOT_GROUP_ID;
|
||||||
cmd->flags = 0;
|
cmd->flags = 0;
|
||||||
*ext = *cmd;
|
*ext = *cmd;
|
||||||
//printf("%s\n", __func__);
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int req_cursor_notification(QXLInstance *qin)
|
static int
|
||||||
|
req_cursor_notification(QXLInstance *qin)
|
||||||
{
|
{
|
||||||
printf("%s\n", __func__);
|
/* not used */
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void notify_update(QXLInstance *qin, uint32_t update_id)
|
static void
|
||||||
|
notify_update(QXLInstance *qin, uint32_t update_id)
|
||||||
{
|
{
|
||||||
printf("%s\n", __func__);
|
/* not used */
|
||||||
}
|
}
|
||||||
|
|
||||||
static int flush_resources(QXLInstance *qin)
|
static int
|
||||||
|
flush_resources(QXLInstance *qin)
|
||||||
{
|
{
|
||||||
printf("%s\n", __func__);
|
/* not used */
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int client_monitors_config(QXLInstance *qin,
|
static int
|
||||||
VDAgentMonitorsConfig *monitors_config)
|
client_monitors_config(QXLInstance *qin, VDAgentMonitorsConfig *monitors_config)
|
||||||
{
|
{
|
||||||
if (!monitors_config) {
|
/* not used */
|
||||||
printf("%s: NULL monitors_config\n", __func__);
|
|
||||||
} else {
|
|
||||||
printf("%s: %d\n", __func__, monitors_config->num_of_monitors);
|
|
||||||
}
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void set_client_capabilities(QXLInstance *qin,
|
static void
|
||||||
uint8_t client_present,
|
set_client_capabilities(QXLInstance *qin, uint8_t client_present,
|
||||||
uint8_t caps[58])
|
uint8_t caps[58])
|
||||||
{
|
{
|
||||||
Test *test = SPICE_CONTAINEROF(qin, Test, qxl_instance);
|
SpiceScreen *spice_screen = SPICE_CONTAINEROF(qin, SpiceScreen, qxl_instance);
|
||||||
|
|
||||||
printf("%s: present %d caps %d\n", __func__, client_present, caps[0]);
|
printf("%s: present %d caps %d\n", __func__, client_present, caps[0]);
|
||||||
if (test->on_client_connected && client_present) {
|
|
||||||
test->on_client_connected(test);
|
if (spice_screen->on_client_connected && client_present) {
|
||||||
|
spice_screen->on_client_connected(spice_screen);
|
||||||
}
|
}
|
||||||
if (test->on_client_disconnected && !client_present) {
|
if (spice_screen->on_client_disconnected && !client_present) {
|
||||||
test->on_client_disconnected(test);
|
spice_screen->on_client_disconnected(spice_screen);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int client_count = 0;
|
static int client_count = 0;
|
||||||
|
|
||||||
static void client_connected(Test *test)
|
static void
|
||||||
|
client_connected(SpiceScreen *spice_screen)
|
||||||
{
|
{
|
||||||
printf("Client connected\n");
|
printf("Client connected\n");
|
||||||
client_count++;
|
client_count++;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void client_disconnected(Test *test)
|
static void
|
||||||
|
client_disconnected(SpiceScreen *spice_screen)
|
||||||
{
|
{
|
||||||
|
|
||||||
if (client_count > 0) {
|
if (client_count > 0) {
|
||||||
@ -551,21 +554,21 @@ static void client_disconnected(Test *test)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void do_conn_timeout(void *opaque)
|
static void
|
||||||
|
do_conn_timeout(void *opaque)
|
||||||
{
|
{
|
||||||
// Test *test = opaque;
|
// SpiceScreen *spice_screen = opaque;
|
||||||
|
|
||||||
if (client_count <= 0) {
|
if (client_count <= 0) {
|
||||||
printf("do_conn_timeout\n");
|
printf("connection timeout\n");
|
||||||
exit (0); // fixme: cleanup?
|
exit (0); // fixme: cleanup?
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
QXLInterface display_sif = {
|
QXLInterface display_sif = {
|
||||||
.base = {
|
.base = {
|
||||||
.type = SPICE_INTERFACE_QXL,
|
.type = SPICE_INTERFACE_QXL,
|
||||||
.description = "test",
|
.description = "spiceterm display server",
|
||||||
.major_version = SPICE_INTERFACE_QXL_MAJOR,
|
.major_version = SPICE_INTERFACE_QXL_MAJOR,
|
||||||
.minor_version = SPICE_INTERFACE_QXL_MINOR
|
.minor_version = SPICE_INTERFACE_QXL_MINOR
|
||||||
},
|
},
|
||||||
@ -586,32 +589,34 @@ QXLInterface display_sif = {
|
|||||||
.set_client_capabilities = set_client_capabilities,
|
.set_client_capabilities = set_client_capabilities,
|
||||||
};
|
};
|
||||||
|
|
||||||
/* interface for tests */
|
void
|
||||||
void test_add_display_interface(Test* test)
|
spice_screen_add_display_interface(SpiceScreen* spice_screen)
|
||||||
{
|
{
|
||||||
spice_server_add_interface(test->server, &test->qxl_instance.base);
|
spice_server_add_interface(spice_screen->server, &spice_screen->qxl_instance.base);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int vmc_write(SpiceCharDeviceInstance *sin, const uint8_t *buf, int len)
|
/* vdagent interface - not sure why we need that? */
|
||||||
|
static int
|
||||||
|
vmc_write(SpiceCharDeviceInstance *sin, const uint8_t *buf, int len)
|
||||||
{
|
{
|
||||||
// printf("%s: %d\n", __func__, len);
|
|
||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int vmc_read(SpiceCharDeviceInstance *sin, uint8_t *buf, int len)
|
static int
|
||||||
|
vmc_read(SpiceCharDeviceInstance *sin, uint8_t *buf, int len)
|
||||||
{
|
{
|
||||||
// printf("%s: %d\n", __func__, len);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void vmc_state(SpiceCharDeviceInstance *sin, int connected)
|
static void
|
||||||
|
vmc_state(SpiceCharDeviceInstance *sin, int connected)
|
||||||
{
|
{
|
||||||
// printf("%s: %d\n", __func__, connected);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static SpiceCharDeviceInterface vdagent_sif = {
|
static SpiceCharDeviceInterface vdagent_sif = {
|
||||||
.base.type = SPICE_INTERFACE_CHAR_DEVICE,
|
.base.type = SPICE_INTERFACE_CHAR_DEVICE,
|
||||||
.base.description = "test spice virtual channel char device",
|
.base.description = "spice virtual channel char device",
|
||||||
.base.major_version = SPICE_INTERFACE_CHAR_DEVICE_MAJOR,
|
.base.major_version = SPICE_INTERFACE_CHAR_DEVICE_MAJOR,
|
||||||
.base.minor_version = SPICE_INTERFACE_CHAR_DEVICE_MINOR,
|
.base.minor_version = SPICE_INTERFACE_CHAR_DEVICE_MINOR,
|
||||||
.state = vmc_state,
|
.state = vmc_state,
|
||||||
@ -626,20 +631,14 @@ SpiceCharDeviceInstance vdagent_sin = {
|
|||||||
.subtype = "vdagent",
|
.subtype = "vdagent",
|
||||||
};
|
};
|
||||||
|
|
||||||
void test_add_agent_interface(SpiceServer *server)
|
void
|
||||||
|
spice_screen_add_agent_interface(SpiceServer *server)
|
||||||
{
|
{
|
||||||
spice_server_add_interface(server, &vdagent_sin.base);
|
spice_server_add_interface(server, &vdagent_sin.base);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void kbd_push_key(SpiceKbdInstance *sin, uint8_t frag)
|
void
|
||||||
{
|
spice_screen_draw_char(SpiceScreen *spice_screen, int x, int y, gunichar ch, TextAttributes attrib)
|
||||||
Test *test = SPICE_CONTAINEROF(sin, Test, keyboard_sin);
|
|
||||||
|
|
||||||
printf("KEYCODE %u %p\n", frag, test);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void test_draw_update_char(Test *test, int x, int y, gunichar ch, TextAttributes attrib)
|
|
||||||
{
|
{
|
||||||
int fg, bg;
|
int fg, bg;
|
||||||
|
|
||||||
@ -657,6 +656,7 @@ void test_draw_update_char(Test *test, int x, int y, gunichar ch, TextAttributes
|
|||||||
|
|
||||||
// unsuported attributes = (attrib.blink || attrib.unvisible)
|
// unsuported attributes = (attrib.blink || attrib.unvisible)
|
||||||
|
|
||||||
|
// fixme:
|
||||||
//if (attrib.uline) {
|
//if (attrib.uline) {
|
||||||
//rfbDrawLine (vt->screen, rx, ry + 14, rxe, ry + 14, fg);
|
//rfbDrawLine (vt->screen, rx, ry + 14, rxe, ry + 14, fg);
|
||||||
//}
|
//}
|
||||||
@ -664,54 +664,36 @@ void test_draw_update_char(Test *test, int x, int y, gunichar ch, TextAttributes
|
|||||||
int c = vt_fontmap[ch];
|
int c = vt_fontmap[ch];
|
||||||
|
|
||||||
SimpleSpiceUpdate *update;
|
SimpleSpiceUpdate *update;
|
||||||
update = test_draw_char(test, x, y, c, fg, bg);
|
update = spice_screen_draw_char_cmd(spice_screen, x, y, c, fg, bg);
|
||||||
push_command(test, &update->ext);
|
push_command(spice_screen, &update->ext);
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint8_t kbd_get_leds(SpiceKbdInstance *sin)
|
SpiceScreen *
|
||||||
{
|
spice_screen_new(SpiceCoreInterface *core)
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static SpiceKbdInterface keyboard_sif = {
|
|
||||||
.base.type = SPICE_INTERFACE_KEYBOARD ,
|
|
||||||
.base.description = "spiceterm keyboard device",
|
|
||||||
.base.major_version = SPICE_INTERFACE_KEYBOARD_MAJOR,
|
|
||||||
.base.minor_version = SPICE_INTERFACE_KEYBOARD_MINOR,
|
|
||||||
.push_scan_freg = kbd_push_key,
|
|
||||||
.get_leds = kbd_get_leds,
|
|
||||||
};
|
|
||||||
|
|
||||||
void test_add_keyboard_interface(Test* test)
|
|
||||||
{
|
|
||||||
spice_server_add_interface(test->server, &test->keyboard_sin.base);
|
|
||||||
}
|
|
||||||
|
|
||||||
Test *test_new(SpiceCoreInterface *core)
|
|
||||||
{
|
{
|
||||||
int port = 5912;
|
int port = 5912;
|
||||||
Test *test = g_new0(Test, 1);
|
SpiceScreen *spice_screen = g_new0(SpiceScreen, 1);
|
||||||
SpiceServer* server = spice_server_new();
|
SpiceServer* server = spice_server_new();
|
||||||
|
|
||||||
test->command_cond = g_cond_new();
|
spice_screen->command_cond = g_cond_new();
|
||||||
test->command_mutex = g_mutex_new();
|
spice_screen->command_mutex = g_mutex_new();
|
||||||
|
|
||||||
test->on_client_connected = client_connected,
|
spice_screen->on_client_connected = client_connected,
|
||||||
test->on_client_disconnected = client_disconnected,
|
spice_screen->on_client_disconnected = client_disconnected,
|
||||||
|
|
||||||
test->qxl_instance.base.sif = &display_sif.base;
|
spice_screen->qxl_instance.base.sif = &display_sif.base;
|
||||||
test->qxl_instance.id = 0;
|
spice_screen->qxl_instance.id = 0;
|
||||||
|
|
||||||
test->keyboard_sin.base.sif = &keyboard_sif.base;
|
spice_screen->core = core;
|
||||||
|
spice_screen->server = server;
|
||||||
test->core = core;
|
|
||||||
test->server = server;
|
spice_screen->cursor_notify = NOTIFY_CURSOR_BATCH;
|
||||||
|
|
||||||
|
printf("listening on port %d (unsecure)\n", port);
|
||||||
|
|
||||||
test->cursor_notify = NOTIFY_CURSOR_BATCH;
|
|
||||||
// some common initialization for all display tests
|
|
||||||
printf("TESTER: listening on port %d (unsecure)\n", port);
|
|
||||||
spice_server_set_port(server, port);
|
spice_server_set_port(server, port);
|
||||||
spice_server_set_noauth(server);
|
spice_server_set_noauth(server);
|
||||||
|
|
||||||
int res = spice_server_init(server, core);
|
int res = spice_server_init(server, core);
|
||||||
if (res != 0) {
|
if (res != 0) {
|
||||||
g_error("spice_server_init failed, res = %d\n", res);
|
g_error("spice_server_init failed, res = %d\n", res);
|
||||||
@ -720,8 +702,8 @@ Test *test_new(SpiceCoreInterface *core)
|
|||||||
cursor_init();
|
cursor_init();
|
||||||
|
|
||||||
int timeout = 10; // max time to wait for client connection
|
int timeout = 10; // max time to wait for client connection
|
||||||
test->conn_timeout_timer = core->timer_add(do_conn_timeout, test);
|
spice_screen->conn_timeout_timer = core->timer_add(do_conn_timeout, spice_screen);
|
||||||
test->core->timer_start(test->conn_timeout_timer, timeout*1000);
|
spice_screen->core->timer_start(spice_screen->conn_timeout_timer, timeout*1000);
|
||||||
|
|
||||||
return test;
|
return spice_screen;
|
||||||
}
|
}
|
55
spiceterm.c
55
spiceterm.c
@ -49,7 +49,7 @@
|
|||||||
|
|
||||||
#include <gdk/gdkkeysyms.h>
|
#include <gdk/gdkkeysyms.h>
|
||||||
|
|
||||||
#include "basic_event_loop.h"
|
#include "event_loop.h"
|
||||||
#include "translations.h"
|
#include "translations.h"
|
||||||
|
|
||||||
/* define this for debugging */
|
/* define this for debugging */
|
||||||
@ -111,7 +111,7 @@ draw_char_at (spiceTerm *vt, int x, int y, unicode ch, TextAttributes attrib)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
test_draw_update_char(vt->screen, x, y, ch, attrib);
|
spice_screen_draw_char(vt->screen, x, y, ch, attrib);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -235,8 +235,8 @@ spiceterm_scroll_down (spiceTerm *vt, int top, int bottom, int lines)
|
|||||||
int y1 = y0 + h;
|
int y1 = y0 + h;
|
||||||
int y2 = bottom*16;
|
int y2 = bottom*16;
|
||||||
|
|
||||||
test_spice_scroll(vt->screen, 0, y1, vt->screen->primary_width, y2, 0, y0);
|
spice_screen_scroll(vt->screen, 0, y1, vt->screen->primary_width, y2, 0, y0);
|
||||||
test_spice_clear(vt->screen, 0, y0, vt->screen->primary_width, y1);
|
spice_screen_clear(vt->screen, 0, y0, vt->screen->primary_width, y1);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -256,8 +256,8 @@ spiceterm_scroll_up (spiceTerm *vt, int top, int bottom, int lines, int moveattr
|
|||||||
int y1 = (top + lines)*16;
|
int y1 = (top + lines)*16;
|
||||||
int y2 = bottom*16;
|
int y2 = bottom*16;
|
||||||
|
|
||||||
test_spice_scroll(vt->screen, 0, y0, vt->screen->primary_width, y2 -h, 0, y1);
|
spice_screen_scroll(vt->screen, 0, y0, vt->screen->primary_width, y2 -h, 0, y1);
|
||||||
test_spice_clear(vt->screen, 0, y2 -h, vt->screen->primary_width, y2);
|
spice_screen_clear(vt->screen, 0, y2 -h, vt->screen->primary_width, y2);
|
||||||
|
|
||||||
if (!moveattr) {
|
if (!moveattr) {
|
||||||
return;
|
return;
|
||||||
@ -1619,45 +1619,26 @@ create_spiceterm (int argc, char** argv, int maxx, int maxy)
|
|||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
Test *test;
|
SpiceScreen *spice_screen;
|
||||||
|
|
||||||
SpiceCoreInterface *core = basic_event_loop_init();
|
SpiceCoreInterface *core = basic_event_loop_init();
|
||||||
test = test_new(core);
|
spice_screen = spice_screen_new(core);
|
||||||
//spice_server_set_image_compression(server, SPICE_IMAGE_COMPRESS_OFF);
|
//spice_server_set_image_compression(server, SPICE_IMAGE_COMPRESS_OFF);
|
||||||
test_add_display_interface(test);
|
spice_screen_add_display_interface(spice_screen);
|
||||||
test_add_agent_interface(test->server);
|
spice_screen_add_agent_interface(spice_screen->server);
|
||||||
|
|
||||||
spiceTerm *vt = (spiceTerm *)calloc (sizeof(spiceTerm), 1);
|
spiceTerm *vt = (spiceTerm *)calloc (sizeof(spiceTerm), 1);
|
||||||
|
|
||||||
vt->keyboard_sin.base.sif = &my_keyboard_sif.base;
|
vt->keyboard_sin.base.sif = &my_keyboard_sif.base;
|
||||||
spice_server_add_interface(test->server, &vt->keyboard_sin.base);
|
spice_server_add_interface(spice_screen->server, &vt->keyboard_sin.base);
|
||||||
|
|
||||||
/*
|
// screen->setXCutText = spiceterm_set_xcut_text;
|
||||||
rfbColourMap *cmap =&screen->colourMap;
|
// screen->ptrAddEvent = spiceterm_pointer_event;
|
||||||
cmap->data.bytes = malloc (16*3);
|
// screen->newClientHook = new_client;
|
||||||
for(i=0;i<16;i++) {
|
// screen->desktopName = "SPICE Command Terminal";
|
||||||
cmap->data.bytes[i*3 + 0] = default_red[color_table[i]];
|
|
||||||
cmap->data.bytes[i*3 + 1] = default_grn[color_table[i]];
|
|
||||||
cmap->data.bytes[i*3 + 2] = default_blu[color_table[i]];
|
|
||||||
}
|
|
||||||
cmap->count = 16;
|
|
||||||
cmap->is16 = FALSE;
|
|
||||||
screen->serverFormat.trueColour = FALSE;
|
|
||||||
|
|
||||||
screen->kbdAddEvent = spiceterm_kbd_event;
|
vt->maxx = spice_screen->width;
|
||||||
|
vt->maxy = spice_screen->height;
|
||||||
screen->setXCutText = spiceterm_set_xcut_text;
|
|
||||||
|
|
||||||
screen->ptrAddEvent = spiceterm_pointer_event;
|
|
||||||
|
|
||||||
screen->desktopName = "SPICE Command Terminal";
|
|
||||||
|
|
||||||
screen->newClientHook = new_client;
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
vt->maxx = test->width;
|
|
||||||
vt->maxy = test->height;
|
|
||||||
|
|
||||||
vt->width = vt->maxx / 8;
|
vt->width = vt->maxx / 8;
|
||||||
vt->height = vt->maxy / 16;
|
vt->height = vt->maxy / 16;
|
||||||
@ -1695,7 +1676,7 @@ create_spiceterm (int argc, char** argv, int maxx, int maxy)
|
|||||||
|
|
||||||
vt->altcells = (TextCell *)calloc (sizeof (TextCell), vt->width*vt->height);
|
vt->altcells = (TextCell *)calloc (sizeof (TextCell), vt->width*vt->height);
|
||||||
|
|
||||||
vt->screen = test;
|
vt->screen = spice_screen;
|
||||||
|
|
||||||
return vt;
|
return vt;
|
||||||
}
|
}
|
||||||
|
29
spiceterm.h
29
spiceterm.h
@ -28,9 +28,9 @@ typedef struct TextCell {
|
|||||||
#define MAX_HEIGHT 2048
|
#define MAX_HEIGHT 2048
|
||||||
#define MAX_WIDTH 2048
|
#define MAX_WIDTH 2048
|
||||||
|
|
||||||
typedef struct Test Test;
|
typedef struct SpiceScreen SpiceScreen;
|
||||||
|
|
||||||
struct Test {
|
struct SpiceScreen {
|
||||||
SpiceCoreInterface *core;
|
SpiceCoreInterface *core;
|
||||||
SpiceServer *server;
|
SpiceServer *server;
|
||||||
|
|
||||||
@ -62,24 +62,21 @@ struct Test {
|
|||||||
struct QXLCommandExt* commands[COMMANDS_SIZE];
|
struct QXLCommandExt* commands[COMMANDS_SIZE];
|
||||||
|
|
||||||
// callbacks
|
// callbacks
|
||||||
void (*on_client_connected)(Test *test);
|
void (*on_client_connected)(SpiceScreen *spice_screen);
|
||||||
void (*on_client_disconnected)(Test *test);
|
void (*on_client_disconnected)(SpiceScreen *spice_screen);
|
||||||
};
|
};
|
||||||
|
|
||||||
void test_add_display_interface(Test *test);
|
SpiceScreen* spice_screen_new(SpiceCoreInterface* core);
|
||||||
void test_add_agent_interface(SpiceServer *server); // TODO - Test *test
|
|
||||||
void test_add_keyboard_interface(Test *test);
|
|
||||||
Test* test_new(SpiceCoreInterface* core);
|
|
||||||
|
|
||||||
void test_draw_update_char(Test *test, int x, int y, gunichar ch, TextAttributes attrib);
|
void spice_screen_add_display_interface(SpiceScreen *spice_screen);
|
||||||
void test_spice_scroll(Test *test, int x1, int y1, int x2, int y2, int src_x, int src_y);
|
void spice_screen_add_agent_interface(SpiceServer *server);
|
||||||
void test_spice_clear(Test *test, int x1, int y1, int x2, int y2);
|
void spice_screen_draw_char(SpiceScreen *spice_screen, int x, int y, gunichar ch, TextAttributes attrib);
|
||||||
|
void spice_screen_scroll(SpiceScreen *spice_screen, int x1, int y1, int x2, int y2, int src_x, int src_y);
|
||||||
|
void spice_screen_clear(SpiceScreen *spice_screen, int x1, int y1, int x2, int y2);
|
||||||
|
|
||||||
|
|
||||||
uint32_t test_get_width(void);
|
uint32_t spice_screen_get_width(void);
|
||||||
uint32_t test_get_height(void);
|
uint32_t spice_screen_get_height(void);
|
||||||
|
|
||||||
void spice_test_config_parse_args(int argc, char **argv);
|
|
||||||
|
|
||||||
typedef struct spiceTerm {
|
typedef struct spiceTerm {
|
||||||
int maxx;
|
int maxx;
|
||||||
@ -104,7 +101,7 @@ typedef struct spiceTerm {
|
|||||||
TextCell *cells;
|
TextCell *cells;
|
||||||
TextCell *altcells;
|
TextCell *altcells;
|
||||||
|
|
||||||
Test *screen;
|
SpiceScreen *screen;
|
||||||
SpiceKbdInstance keyboard_sin;
|
SpiceKbdInstance keyboard_sin;
|
||||||
|
|
||||||
// cursor
|
// cursor
|
||||||
|
Loading…
x
Reference in New Issue
Block a user