5
0
mirror of git://git.proxmox.com/git/spiceterm.git synced 2024-12-22 13:34:06 +03:00

implement resize

This commit is contained in:
Dietmar Maurer 2013-09-17 12:57:23 +02:00
parent eddeb8650c
commit 8f53ae816c
3 changed files with 130 additions and 40 deletions

View File

@ -90,9 +90,6 @@ spice_screen_destroy_update(SimpleSpiceUpdate *update)
g_free(update);
}
#define DEFAULT_WIDTH 640
#define DEFAULT_HEIGHT 320
static int unique = 0x0ffff + 1;
static void
@ -350,6 +347,22 @@ create_primary_surface(SpiceScreen *spice_screen, uint32_t width,
qxl_worker->create_primary_surface(qxl_worker, 0, &surface);
}
void
spice_screen_resize(SpiceScreen *spice_screen, uint32_t width,
uint32_t height)
{
QXLWorker *qxl_worker = spice_screen->qxl_worker;
if (spice_screen->width == width && spice_screen->height == height) {
return;
}
qxl_worker->destroy_primary_surface(qxl_worker, 0);
create_primary_surface(spice_screen, width, height);
}
QXLDevMemSlot slot = {
.slot_group_id = MEM_SLOT_GROUP_ID,
.slot_id = 0,
@ -371,7 +384,7 @@ attache_worker(QXLInstance *qin, QXLWorker *_qxl_worker)
spice_screen->qxl_worker = _qxl_worker;
spice_screen->qxl_worker->add_memslot(spice_screen->qxl_worker, &slot);
create_primary_surface(spice_screen, DEFAULT_WIDTH, DEFAULT_HEIGHT);
create_primary_surface(spice_screen, spice_screen->width, spice_screen->height);
spice_screen->qxl_worker->start(spice_screen->qxl_worker);
}
@ -668,12 +681,15 @@ spice_screen_draw_char(SpiceScreen *spice_screen, int x, int y, gunichar2 ch,
}
SpiceScreen *
spice_screen_new(SpiceCoreInterface *core, guint timeout)
spice_screen_new(SpiceCoreInterface *core, uint32_t width, uint32_t height, guint timeout)
{
int port = 5912;
SpiceScreen *spice_screen = g_new0(SpiceScreen, 1);
SpiceServer* server = spice_server_new();
spice_screen->width = width;
spice_screen->height = height;
spice_screen->command_cond = g_cond_new();
spice_screen->command_mutex = g_mutex_new();

View File

@ -79,6 +79,8 @@ unsigned char color_table[] = { 0, 4, 2, 6, 1, 5, 3, 7,
8,12,10,14, 9,13,11,15 };
static void spiceterm_resize(spiceTerm *vt, uint32_t width, uint32_t height);
static void vdagent_grab_clipboard(spiceTerm *vt, uint8_t selection);
static void vdagent_request_clipboard(spiceTerm *vt, uint8_t selection);
@ -1444,7 +1446,7 @@ my_kbd_push_keyval(SpiceKbdInstance *sin, uint32_t keySym, int flags)
if (vt->y_displ != vt->y_base) {
vt->y_displ = vt->y_base;
spiceterm_refresh (vt);
spiceterm_refresh(vt);
}
if (esc) {
@ -1621,6 +1623,38 @@ spiceterm_motion_event(spiceTerm *vt, uint32_t x, uint32_t y, uint32_t buttons)
}
}
static void
vdagent_reply(spiceTerm *vt, uint32_t type, uint32_t error)
{
uint32_t size;
size = sizeof(VDAgentReply);
int msg_size = sizeof(VDIChunkHeader) + sizeof(VDAgentMessage) + size;
g_assert((vdagent_write_buffer_pos + msg_size) < VDAGENT_WBUF_SIZE);
unsigned char *buf = vdagent_write_buffer + vdagent_write_buffer_pos;
vdagent_write_buffer_pos += msg_size;
memset(buf, 0, msg_size);
VDIChunkHeader *hdr = (VDIChunkHeader *)buf;
VDAgentMessage *msg = (VDAgentMessage *)&hdr[1];
VDAgentReply *reply = (VDAgentReply *)&msg[1];
reply->type = type;
reply->error = error;
hdr->port = VDP_CLIENT_PORT;
hdr->size = sizeof(VDAgentMessage) + size;
msg->protocol = VD_AGENT_PROTOCOL;
msg->type = VD_AGENT_REPLY;
msg->opaque = 0;
msg->size = size;
spice_server_char_device_wakeup(&vt->vdagent_sin);
}
static void vdagent_send_capabilities(spiceTerm *vt, uint32_t request)
{
VDAgentAnnounceCapabilities *caps;
@ -1876,9 +1910,17 @@ vmc_write(SpiceCharDeviceInstance *sin, const uint8_t *buf, int len)
break;
}
case VD_AGENT_MONITORS_CONFIG:
/* ignore for now */
case VD_AGENT_MONITORS_CONFIG: {
VDAgentMonitorsConfig *list = (VDAgentMonitorsConfig *)&msg[1];
g_assert(list->num_of_monitors > 0);
DPRINTF(0, "VD_AGENT_MONITORS_CONFIG %d %d %d", list->num_of_monitors,
list->monitors[0].width, list->monitors[0].height);
spiceterm_resize(vt, list->monitors[0].width, list->monitors[0].height);
vdagent_reply(vt, VD_AGENT_MONITORS_CONFIG, VD_AGENT_SUCCESS);
break;
}
default:
DPRINTF(0, "got uknown vdagent message type %d\n", msg->type);
}
@ -1889,7 +1931,7 @@ vmc_write(SpiceCharDeviceInstance *sin, const uint8_t *buf, int len)
static int
vmc_read(SpiceCharDeviceInstance *sin, uint8_t *buf, int len)
{
DPRINTF(0, "%d %d", len, vdagent_write_buffer_pos);
DPRINTF(1, "%d %d", len, vdagent_write_buffer_pos);
g_assert(len >= 8);
if (!vdagent_write_buffer_pos) {
@ -1899,13 +1941,12 @@ vmc_read(SpiceCharDeviceInstance *sin, uint8_t *buf, int len)
int size = (len >= vdagent_write_buffer_pos) ? vdagent_write_buffer_pos : len;
memcpy(buf, vdagent_write_buffer, size);
if (size < vdagent_write_buffer_pos) {
DPRINTF(0, "MOVE %d", size);
memmove(vdagent_write_buffer, vdagent_write_buffer + size,
vdagent_write_buffer_pos - size);
}
vdagent_write_buffer_pos -= size;
DPRINTF(0, "RET %d %d", size, vdagent_write_buffer_pos);
DPRINTF(1, "RET %d %d", size, vdagent_write_buffer_pos);
return size;
}
@ -1925,36 +1966,16 @@ static SpiceCharDeviceInterface my_vdagent_sif = {
.read = vmc_read,
};
static spiceTerm *
create_spiceterm(int argc, char** argv, int maxx, int maxy, guint timeout)
static void
init_spiceterm(spiceTerm *vt, uint32_t width, uint32_t height)
{
int i;
SpiceScreen *spice_screen;
g_assert(vt != NULL);
g_assert(vt->screen != NULL);
SpiceCoreInterface *core = basic_event_loop_init();
spice_screen = spice_screen_new(core, timeout);
//spice_server_set_image_compression(server, SPICE_IMAGE_COMPRESS_OFF);
spiceTerm *vt = (spiceTerm *)calloc (sizeof(spiceTerm), 1);
vt->keyboard_sin.base.sif = &my_keyboard_sif.base;
spice_server_add_interface(spice_screen->server, &vt->keyboard_sin.base);
vt->vdagent_sin.base.sif = &my_vdagent_sif.base;
vt->vdagent_sin.subtype = "vdagent";
spice_server_add_interface(spice_screen->server, &vt->vdagent_sin.base);
// screen->setXCutText = spiceterm_set_xcut_text;
// screen->ptrAddEvent = spiceterm_pointer_event;
// screen->newClientHook = new_client;
// screen->desktopName = "SPICE Command Terminal";
vt->maxx = spice_screen->width;
vt->maxy = spice_screen->height;
vt->width = vt->maxx / 8;
vt->height = vt->maxy / 16;
vt->width = width / 8;
vt->height = height / 16;
vt->total_height = vt->height * 20;
vt->scroll_height = 0;
@ -1980,6 +2001,14 @@ create_spiceterm(int argc, char** argv, int maxx, int maxy, guint timeout)
vt->cur_attrib = vt->default_attrib;
if (vt->cells) {
vt->cx = 0;
vt->cy = 0;
vt->cx_saved = 0;
vt->cy_saved = 0;
g_free(vt->cells);
}
vt->cells = (TextCell *)calloc (sizeof (TextCell), vt->width*vt->total_height);
for (i = 0; i < vt->width*vt->total_height; i++) {
@ -1987,10 +2016,53 @@ create_spiceterm(int argc, char** argv, int maxx, int maxy, guint timeout)
vt->cells[i].attrib = vt->default_attrib;
}
vt->altcells = (TextCell *)calloc (sizeof (TextCell), vt->width*vt->height);
if (vt->altcells) {
g_free(vt->altcells);
}
vt->altcells = (TextCell *)calloc (sizeof (TextCell), vt->width*vt->height);
}
static void
spiceterm_resize(spiceTerm *vt, uint32_t width, uint32_t height)
{
DPRINTF(0, "width=%u height=%u", width, height);
if (vt->screen->width == width && vt->screen->height == height) {
return;
}
spice_screen_resize(vt->screen, width, height);
init_spiceterm(vt, width, height);
struct winsize dimensions;
dimensions.ws_col = vt->width;
dimensions.ws_row = vt->height;
ioctl(vt->pty, TIOCSWINSZ, &dimensions);
}
static spiceTerm *
create_spiceterm(int argc, char** argv, uint32_t maxx, uint32_t maxy, guint timeout)
{
SpiceCoreInterface *core = basic_event_loop_init();
SpiceScreen *spice_screen = spice_screen_new(core, maxx, maxy, timeout);
//spice_server_set_image_compression(server, SPICE_IMAGE_COMPRESS_OFF);
spiceTerm *vt = (spiceTerm *)calloc (sizeof(spiceTerm), 1);
vt->keyboard_sin.base.sif = &my_keyboard_sif.base;
spice_server_add_interface(spice_screen->server, &vt->keyboard_sin.base);
vt->vdagent_sin.base.sif = &my_vdagent_sif.base;
vt->vdagent_sin.subtype = "vdagent";
spice_server_add_interface(spice_screen->server, &vt->vdagent_sin.base);
vt->screen = spice_screen;
init_spiceterm(vt, maxx, maxy);
return vt;
}
@ -2110,6 +2182,8 @@ main (int argc, char** argv)
exit (-1);
}
vt->pty = master;
/* watch for errors - we need to use glib directly because spice
* does not have SPICE_WATCH_EVENT for this */
GIOChannel *channel = g_io_channel_unix_new(master);

View File

@ -58,8 +58,9 @@ struct SpiceScreen {
void (*on_client_disconnected)(SpiceScreen *spice_screen);
};
SpiceScreen* spice_screen_new(SpiceCoreInterface* core, guint timeout);
SpiceScreen* spice_screen_new(SpiceCoreInterface* core, uint32_t width, uint32_t height, guint timeout);
void spice_screen_resize(SpiceScreen *spice_screen, uint32_t width, uint32_t height);
void spice_screen_draw_char(SpiceScreen *spice_screen, int x, int y, gunichar2 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);
@ -67,8 +68,7 @@ uint32_t spice_screen_get_width(void);
uint32_t spice_screen_get_height(void);
typedef struct spiceTerm {
int maxx;
int maxy;
int pty; // pty file descriptor
int width;
int height;