]> git.proxmox.com Git - spiceterm.git/commitdiff
implement resize
authorDietmar Maurer <dietmar@proxmox.com>
Tue, 17 Sep 2013 10:57:23 +0000 (12:57 +0200)
committerDietmar Maurer <dietmar@proxmox.com>
Tue, 17 Sep 2013 11:13:19 +0000 (13:13 +0200)
screen.c
spiceterm.c
spiceterm.h

index 34ba4c607092cf79b5fdd8dd2ccac2581875b66c..ff36f18d98ef35ffd4449c48b7c8060ad5184312 100644 (file)
--- a/screen.c
+++ b/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 void 
 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);
 }
 
     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,
 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);
  
     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);
 }
 
     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;
     SpiceScreen *spice_screen = g_new0(SpiceScreen, 1);
     SpiceServer* server = spice_server_new();
 
 {
     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();
 
     spice_screen->command_cond = g_cond_new();
     spice_screen->command_mutex = g_mutex_new();
 
index afbda2b3c06fa3744459ca2f4f5a9ab3ba7cb53a..31f719f16c0e2847b62fba263941d48aecd09bb0 100644 (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 };
 
 
                                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);
 
 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;
 
             if (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)
 {
     VDAgentAnnounceCapabilities *caps;
 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;
     }
      
         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;
         break;
+    }
     default:
         DPRINTF(0, "got uknown vdagent message type %d\n", msg->type);
     }
     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)
 {
 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) {
     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) {
     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;
 
         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;
 }
 
     return size;
 }
 
@@ -1925,36 +1966,16 @@ static SpiceCharDeviceInterface my_vdagent_sif = {
     .read               = vmc_read,
 };
 
     .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;
 
 {
     int i;
 
-    SpiceScreen *spice_screen;
-
-    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;
+    g_assert(vt != NULL);
+    g_assert(vt->screen != NULL);
 
 
-    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;
 
     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;
 
 
     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;
     }
     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);
 
     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
      * does not have SPICE_WATCH_EVENT for this */
     GIOChannel *channel = g_io_channel_unix_new(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);
index c2454f8b0ee0d5c39f844aa6dc6f963c8d091548..0fb3f3c7ae7f11d8b1cedc67750ff179ab7f0041 100644 (file)
@@ -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_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_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 {
 uint32_t spice_screen_get_height(void);
 
 typedef struct spiceTerm {
-    int maxx;
-    int maxy;
+    int pty; // pty file descriptor
 
     int width;
     int height;
 
     int width;
     int height;