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);
|
g_free(update);
|
||||||
}
|
}
|
||||||
|
|
||||||
#define DEFAULT_WIDTH 640
|
|
||||||
#define DEFAULT_HEIGHT 320
|
|
||||||
|
|
||||||
static int unique = 0x0ffff + 1;
|
static int unique = 0x0ffff + 1;
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -350,6 +347,22 @@ create_primary_surface(SpiceScreen *spice_screen, uint32_t width,
|
|||||||
qxl_worker->create_primary_surface(qxl_worker, 0, &surface);
|
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 = {
|
QXLDevMemSlot slot = {
|
||||||
.slot_group_id = MEM_SLOT_GROUP_ID,
|
.slot_group_id = MEM_SLOT_GROUP_ID,
|
||||||
.slot_id = 0,
|
.slot_id = 0,
|
||||||
@ -371,7 +384,7 @@ attache_worker(QXLInstance *qin, QXLWorker *_qxl_worker)
|
|||||||
|
|
||||||
spice_screen->qxl_worker = _qxl_worker;
|
spice_screen->qxl_worker = _qxl_worker;
|
||||||
spice_screen->qxl_worker->add_memslot(spice_screen->qxl_worker, &slot);
|
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);
|
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 *
|
SpiceScreen *
|
||||||
spice_screen_new(SpiceCoreInterface *core, guint timeout)
|
spice_screen_new(SpiceCoreInterface *core, uint32_t width, uint32_t height, guint timeout)
|
||||||
{
|
{
|
||||||
int port = 5912;
|
int port = 5912;
|
||||||
SpiceScreen *spice_screen = g_new0(SpiceScreen, 1);
|
SpiceScreen *spice_screen = g_new0(SpiceScreen, 1);
|
||||||
SpiceServer* server = spice_server_new();
|
SpiceServer* server = spice_server_new();
|
||||||
|
|
||||||
|
spice_screen->width = width;
|
||||||
|
spice_screen->height = height;
|
||||||
|
|
||||||
spice_screen->command_cond = g_cond_new();
|
spice_screen->command_cond = g_cond_new();
|
||||||
spice_screen->command_mutex = g_mutex_new();
|
spice_screen->command_mutex = g_mutex_new();
|
||||||
|
|
||||||
|
140
spiceterm.c
140
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 };
|
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_grab_clipboard(spiceTerm *vt, uint8_t selection);
|
||||||
static void vdagent_request_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) {
|
if (vt->y_displ != vt->y_base) {
|
||||||
vt->y_displ = vt->y_base;
|
vt->y_displ = vt->y_base;
|
||||||
spiceterm_refresh (vt);
|
spiceterm_refresh(vt);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (esc) {
|
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)
|
static void vdagent_send_capabilities(spiceTerm *vt, uint32_t request)
|
||||||
{
|
{
|
||||||
VDAgentAnnounceCapabilities *caps;
|
VDAgentAnnounceCapabilities *caps;
|
||||||
@ -1876,9 +1910,17 @@ vmc_write(SpiceCharDeviceInstance *sin, const uint8_t *buf, int len)
|
|||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case VD_AGENT_MONITORS_CONFIG:
|
case VD_AGENT_MONITORS_CONFIG: {
|
||||||
/* ignore for now */
|
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;
|
break;
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
DPRINTF(0, "got uknown vdagent message type %d\n", msg->type);
|
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
|
static int
|
||||||
vmc_read(SpiceCharDeviceInstance *sin, uint8_t *buf, int len)
|
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);
|
g_assert(len >= 8);
|
||||||
|
|
||||||
if (!vdagent_write_buffer_pos) {
|
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;
|
int size = (len >= vdagent_write_buffer_pos) ? vdagent_write_buffer_pos : len;
|
||||||
memcpy(buf, vdagent_write_buffer, size);
|
memcpy(buf, vdagent_write_buffer, size);
|
||||||
if (size < vdagent_write_buffer_pos) {
|
if (size < vdagent_write_buffer_pos) {
|
||||||
DPRINTF(0, "MOVE %d", size);
|
|
||||||
memmove(vdagent_write_buffer, vdagent_write_buffer + size,
|
memmove(vdagent_write_buffer, vdagent_write_buffer + size,
|
||||||
vdagent_write_buffer_pos - size);
|
vdagent_write_buffer_pos - 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;
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1925,36 +1966,16 @@ static SpiceCharDeviceInterface my_vdagent_sif = {
|
|||||||
.read = vmc_read,
|
.read = vmc_read,
|
||||||
};
|
};
|
||||||
|
|
||||||
static spiceTerm *
|
static void
|
||||||
create_spiceterm(int argc, char** argv, int maxx, int maxy, guint timeout)
|
init_spiceterm(spiceTerm *vt, uint32_t width, uint32_t height)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
SpiceScreen *spice_screen;
|
g_assert(vt != NULL);
|
||||||
|
g_assert(vt->screen != NULL);
|
||||||
|
|
||||||
SpiceCoreInterface *core = basic_event_loop_init();
|
vt->width = width / 8;
|
||||||
spice_screen = spice_screen_new(core, timeout);
|
vt->height = height / 16;
|
||||||
//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->total_height = vt->height * 20;
|
vt->total_height = vt->height * 20;
|
||||||
vt->scroll_height = 0;
|
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;
|
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);
|
vt->cells = (TextCell *)calloc (sizeof (TextCell), vt->width*vt->total_height);
|
||||||
|
|
||||||
for (i = 0; i < vt->width*vt->total_height; i++) {
|
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->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;
|
vt->screen = spice_screen;
|
||||||
|
|
||||||
|
init_spiceterm(vt, maxx, maxy);
|
||||||
|
|
||||||
return vt;
|
return vt;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2110,6 +2182,8 @@ main (int argc, char** argv)
|
|||||||
exit (-1);
|
exit (-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
vt->pty = master;
|
||||||
|
|
||||||
/* watch for errors - we need to use glib directly because spice
|
/* watch for errors - we need to use glib directly because spice
|
||||||
* does not have SPICE_WATCH_EVENT for this */
|
* does not have SPICE_WATCH_EVENT for this */
|
||||||
GIOChannel *channel = g_io_channel_unix_new(master);
|
GIOChannel *channel = g_io_channel_unix_new(master);
|
||||||
|
@ -58,8 +58,9 @@ struct SpiceScreen {
|
|||||||
void (*on_client_disconnected)(SpiceScreen *spice_screen);
|
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_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_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);
|
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);
|
uint32_t spice_screen_get_height(void);
|
||||||
|
|
||||||
typedef struct spiceTerm {
|
typedef struct spiceTerm {
|
||||||
int maxx;
|
int pty; // pty file descriptor
|
||||||
int maxy;
|
|
||||||
|
|
||||||
int width;
|
int width;
|
||||||
int height;
|
int height;
|
||||||
|
Loading…
Reference in New Issue
Block a user