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:
parent
eddeb8650c
commit
8f53ae816c
26
screen.c
26
screen.c
@ -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();
|
||||
|
||||
|
138
spiceterm.c
138
spiceterm.c
@ -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,17 +2001,68 @@ 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++) {
|
||||
vt->cells[i].ch = ' ';
|
||||
vt->cells[i].attrib = vt->default_attrib;
|
||||
}
|
||||
|
||||
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);
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user