]> git.proxmox.com Git - spiceterm.git/blobdiff - spiceterm.c
move spice input/vdagent related code to input.c
[spiceterm.git] / spiceterm.c
index 3031606f4ae31dcb4210b6b4482531991c4f336e..85067901033dcee33245724c58a6d02b90e08bdc 100644 (file)
@@ -78,12 +78,6 @@ static int debug = 0;
 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);
-
 static void
 print_usage(const char *msg)
 {
@@ -184,7 +178,7 @@ spiceterm_show_cursor(spiceTerm *vt, int show)
     }
 }
 
-static void
+void
 spiceterm_refresh(spiceTerm *vt)
 {
     int x, y, y1;
@@ -330,7 +324,7 @@ spiceterm_scroll_up(spiceTerm *vt, int top, int bottom, int lines, int moveattr)
     }
 }
 
-static void
+void
 spiceterm_virtual_scroll(spiceTerm *vt, int lines)
 {
     if (vt->altbuf || lines == 0) return;
@@ -362,7 +356,7 @@ spiceterm_virtual_scroll(spiceTerm *vt, int lines)
     spiceterm_refresh(vt);
 }
 
-static void
+void
 spiceterm_respond_esc(spiceTerm *vt, const char *esc)
 {
     int len = strlen(esc);
@@ -373,6 +367,24 @@ spiceterm_respond_esc(spiceTerm *vt, const char *esc)
         for (i = 0; i < len; i++) {
             vt->ibuf[vt->ibuf_count++] = esc[i];
         }
+    } else {
+        fprintf(stderr, "input buffer oferflow\n");
+        return;
+    }
+}
+
+void
+spiceterm_respond_data(spiceTerm *vt, int len, uint8_t *data)
+{
+    int i;
+
+    if (vt->ibuf_count < (IBUFSIZE - len)) {
+        for (i = 0; i < len; i++) {
+            vt->ibuf[vt->ibuf_count++] = data[i];
+        }
+    } else {
+        fprintf(stderr, "input buffer oferflow\n");
+        return;
     }
 }
 
@@ -1283,24 +1295,7 @@ spiceterm_puts(spiceTerm *vt, const char *buf, int len)
     return len;
 }
 
-/* fixme:
 void
-spiceterm_set_xcut_text(char* str, int len, struct _rfbClientRec* cl)
-{
-  spiceTerm *vt =(spiceTerm *)cl->screen->screenData;
-
-  // seems str is Latin-1 encoded
-  if (vt->selection) free (vt->selection);
-  vt->selection = (gunichar2 *)malloc (len*sizeof (gunichar2));
-  int i;
-  for (i = 0; i < len; i++) {
-    vt->selection[i] = str[i] & 0xff;
-  }
-  vt->selection_len = len;
-}
-*/
-
-static void
 spiceterm_update_watch_mask(spiceTerm *vt, gboolean writable)
 {
     g_assert(vt != NULL);
@@ -1335,252 +1330,15 @@ spiceterm_respond_unichar2(spiceTerm *vt, gunichar2 uc)
         gint len = g_unichar_to_utf8(uc, buf);
 
         if (len > 0) {
-            if ((vt->ibuf_count + len) < IBUFSIZE) {
-                int i;
-                for (i = 0; i < len; i++) {
-                    vt->ibuf[vt->ibuf_count++] = buf[i];
-                }
-            } else {
-                fprintf(stderr, "warning: input buffer overflow\n");
-            }
-        }
-    } else {
-        if ((vt->ibuf_count + 1) < IBUFSIZE) {
-            vt->ibuf[vt->ibuf_count++] = (char)uc;
-        } else {
-            fprintf(stderr, "warning: input buffer overflow\n");
-        }
-    }
-}
-
-static uint8_t
-my_kbd_get_leds(SpiceKbdInstance *sin)
-{
-    return 0;
-}
-
-#define KBD_MOD_CONTROL_L_FLAG (1<<0)
-#define KBD_MOD_CONTROL_R_FLAG (1<<1)
-#define KBD_MOD_SHIFT_L_FLAG (1<<2)
-#define KBD_MOD_SHIFT_R_FLAG (1<<3)
-
-static int kbd_flags = 0;
-static void
-my_kbd_push_key(SpiceKbdInstance *sin, uint8_t frag)
-{
-    spiceTerm *vt = SPICE_CONTAINEROF(sin, spiceTerm, keyboard_sin);
-
-    char *esc = NULL; // used to send special keys
-
-    static int e0_mode = 0;
-
-    DPRINTF(1, "enter frag=%02x flags=%08x", frag, kbd_flags);
-
-    if (e0_mode) {
-        e0_mode = 0;
-        switch (frag) {
-        case 0x1d: // press Control_R
-            kbd_flags |= KBD_MOD_CONTROL_R_FLAG;
-            break;
-        case  0x9d: // release Control_R
-            kbd_flags &= ~KBD_MOD_CONTROL_R_FLAG;
-            break;
-        case 0x47: // press Home
-            esc = "OH";
-            break;
-        case 0x4f: // press END
-            esc = "OF";
-            break;
-        case 0x48: // press UP
-            esc = "OA";
-            break;
-        case 0x50: // press DOWN
-            esc = "OB";
-            break;
-        case 0x4b: // press LEFT
-            esc = "OD";
-            break;
-        case 0x4d: // press RIGHT
-            esc = "OC";
-            break;
-        case 0x52: // press INSERT
-            esc = "[2~";
-            break;
-        case 0x49: // press PAGE_UP
-            if (kbd_flags & (KBD_MOD_SHIFT_L_FLAG|KBD_MOD_SHIFT_R_FLAG)) {
-                spiceterm_virtual_scroll (vt, -vt->height/2);
-            }
-            break;
-        case 0x51: // press PAGE_DOWN
-            if (kbd_flags & (KBD_MOD_SHIFT_L_FLAG|KBD_MOD_SHIFT_R_FLAG)) {
-                spiceterm_virtual_scroll (vt, vt->height/2);
-            }
-            break;
-        }
-    } else {
-        switch (frag) {
-        case 0xe0:
-            e0_mode = 1;
-            break;
-        case 0x1d: // press Control_L
-            kbd_flags |= KBD_MOD_CONTROL_L_FLAG;
-            break;
-        case 0x9d: // release Control_L
-            kbd_flags &= ~KBD_MOD_CONTROL_L_FLAG;
-            break;
-        case 0x2a: // press Shift_L
-            kbd_flags |= KBD_MOD_SHIFT_L_FLAG;
-            break;
-        case 0xaa: // release Shift_L
-            kbd_flags &= ~KBD_MOD_SHIFT_L_FLAG;
-            break;
-        case 0x36: // press Shift_R
-            kbd_flags |= KBD_MOD_SHIFT_R_FLAG;
-            break;
-        case 0xb6: // release Shift_R
-            kbd_flags &= ~KBD_MOD_SHIFT_R_FLAG;
-            break;
-        case 0x52: // press KP_INSERT
-            esc = "[2~";
-            break;
-        case 0x53: // press KP_Delete
-            esc = "[3~";
-            break;
-        case 0x47: // press KP_Home
-            esc = "OH";
-            break;
-        case 0x4f: // press KP_END
-            esc = "OF";
-            break;
-        case 0x48: // press KP_UP
-            esc = "OA";
-            break;
-        case 0x50: // press KP_DOWN
-            esc = "OB";
-            break;
-        case 0x4b: // press KP_LEFT
-            esc = "OD";
-            break;
-        case 0x4d: // press KP_RIGHT
-            esc = "OC";
-            break;
-        case 0x3b: // press F1
-            esc = "OP";
-            break;
-        case 0x3c: // press F2
-            esc = "OQ";
-            break;
-        case 0x3d: // press F3
-            esc = "OR";
-            break;
-        case 0x3e: // press F4
-            esc = "OS";
-            break;
-        case 0x3f: // press F5
-            esc = "[15~";
-            break;
-        case 0x40: // press F6
-            esc = "[17~";
-            break;
-        case 0x41: // press F7
-            esc = "[18~";
-            break;
-        case 0x42: // press F8
-            esc = "[19~";
-            break;
-        case 0x43: // press F9
-            esc = "[20~";
-            break;
-        case 0x44: // press F10
-            esc = "[21~";
-            break;
-        case 0x57: // press F11
-            esc = "[23~";
-            break;
-        case 0x58: // press F12
-            esc = "[24~";
-            break;
-        }
-    }
-
-    if (esc) {
-        DPRINTF(1, "escape=%s", esc);
-        spiceterm_respond_esc(vt, esc);
-
-        if (vt->y_displ != vt->y_base) {
-            vt->y_displ = vt->y_base;
-            spiceterm_refresh(vt);
-        }
-
-        spiceterm_update_watch_mask(vt, TRUE);
-    }
-
-    DPRINTF(1, "leave frag=%02x flags=%08x", frag, kbd_flags);
-    return;
-}
-
-static void
-my_kbd_push_utf8(SpiceKbdInstance *sin, uint32_t size, uint8_t *data)
-{
-    spiceTerm *vt = SPICE_CONTAINEROF(sin, spiceTerm, keyboard_sin);
-
-    DPRINTF(1, " size=%d data[0]=%02x", size, data[0]);
-
-    if (vt->ibuf_count + size >= IBUFSIZE) {
-        fprintf(stderr, "input buffer oferflow\n");
-        return;
-    }
-
-     if (kbd_flags & (KBD_MOD_CONTROL_L_FLAG|KBD_MOD_CONTROL_R_FLAG)) {
-        if (size != 1) return;
-        if (data[0] >= 'a' && data[0] <= 'z') {
-            vt->ibuf[vt->ibuf_count++] = data[0] - 'a' + 1;
-        } else if (data[0] >= 'A' && data[0] <= 'Z') {
-            vt->ibuf[vt->ibuf_count++] = data[0] - 'A' + 1;
+            spiceterm_respond_data(vt, len, (uint8_t *)buf);           
         }
     } else {
-        if (size == 1 && data[0] == 0x7f) {
-            /* use an escape sequence for DELETE, else it behaves
-             * like BACKSPACE 
-             */
-            spiceterm_respond_esc(vt, "[3~");
-        } else {
-            int i;
-            for (i = 0; i < size; i++) {
-                vt->ibuf[vt->ibuf_count++] = data[i];
-            }
-        }
-    }
-    
-    if (vt->y_displ != vt->y_base) {
-        vt->y_displ = vt->y_base;
-        spiceterm_refresh(vt);
+        uint8_t buf[1] = { (uint8_t)uc };
+        spiceterm_respond_data(vt, 1, buf);           
     }
-
-    spiceterm_update_watch_mask(vt, TRUE);
-
-    return;
 }
 
-static SpiceKbdInterface my_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     = my_kbd_push_key,
-    .get_leds           = my_kbd_get_leds,
-    .push_utf8          = my_kbd_push_utf8,
-};
-
-
-/* vdagent interface - to get mouse/clipboarde support */
-
-#define VDAGENT_WBUF_SIZE (1024*50)
-static unsigned char vdagent_write_buffer[VDAGENT_WBUF_SIZE];
-static int vdagent_write_buffer_pos = 0;
-static int agent_owns_clipboard[256] = { 0, };
-
-static void
+void
 spiceterm_clear_selection(spiceTerm *vt)
 {
     DPRINTF(1, "mark_active = %d", vt->mark_active);
@@ -1592,7 +1350,7 @@ spiceterm_clear_selection(spiceTerm *vt)
     spiceterm_unselect_all(vt);
 }
  
-static void
+void
 spiceterm_motion_event(spiceTerm *vt, uint32_t x, uint32_t y, uint32_t buttons)
 {
     DPRINTF(1, "mask=%08x x=%d y=%d", buttons, x ,y);
@@ -1631,7 +1389,7 @@ spiceterm_motion_event(spiceTerm *vt, uint32_t x, uint32_t y, uint32_t buttons)
 
         if(button2_released) {
 
-            if (agent_owns_clipboard[VD_AGENT_CLIPBOARD_SELECTION_PRIMARY]) {
+            if (vdagent_owns_clipboard(vt)) {
                 if (vt->selection) {
                     int i;
                     for(i = 0; i < vt->selection_len; i++) {
@@ -1644,7 +1402,7 @@ spiceterm_motion_event(spiceTerm *vt, uint32_t x, uint32_t y, uint32_t buttons)
                     }
                 }
             } else {
-                vdagent_request_clipboard(vt, VD_AGENT_CLIPBOARD_SELECTION_PRIMARY);
+                vdagent_request_clipboard(vt);
             } 
         }
 
@@ -1716,355 +1474,11 @@ spiceterm_motion_event(spiceTerm *vt, uint32_t x, uint32_t y, uint32_t buttons)
 
         DPRINTF(1, "selection length = %d", vt->selection_len);
 
-        vdagent_grab_clipboard(vt, VD_AGENT_CLIPBOARD_SELECTION_PRIMARY);
-    }
-}
-
-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
-dump_message(unsigned char *buf, int size)
-{
-    int i;
-
-    for (i = 0; i < size; i++) {
-        printf("%d  %02X\n", i, buf[i]);
-    }
-
-    // exit(0);
-}
-
-static void vdagent_send_capabilities(spiceTerm *vt, uint32_t request)
-{
-    VDAgentAnnounceCapabilities *caps;
-    uint32_t size;
-
-    size = sizeof(*caps) + VD_AGENT_CAPS_BYTES;
-    caps = calloc(1, size);
-    g_assert(caps != NULL);
-
-    caps->request = request;
-    VD_AGENT_SET_CAPABILITY(caps->caps, VD_AGENT_CAP_MOUSE_STATE);
-    VD_AGENT_SET_CAPABILITY(caps->caps, VD_AGENT_CAP_MONITORS_CONFIG);
-    VD_AGENT_SET_CAPABILITY(caps->caps, VD_AGENT_CAP_REPLY);
-    VD_AGENT_SET_CAPABILITY(caps->caps, VD_AGENT_CAP_CLIPBOARD_BY_DEMAND);
-    VD_AGENT_SET_CAPABILITY(caps->caps, VD_AGENT_CAP_CLIPBOARD_SELECTION);
-    VD_AGENT_SET_CAPABILITY(caps->caps, VD_AGENT_CAP_SPARSE_MONITORS_CONFIG);
-    VD_AGENT_SET_CAPABILITY(caps->caps, VD_AGENT_CAP_GUEST_LINEEND_LF);
-
-    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;
-
-    VDIChunkHeader *hdr = (VDIChunkHeader *)buf;
-    VDAgentMessage *msg = (VDAgentMessage *)&hdr[1];
-    hdr->port = VDP_CLIENT_PORT;
-    hdr->size = sizeof(VDAgentMessage) + size;
-    msg->protocol = VD_AGENT_PROTOCOL;
-    msg->type = VD_AGENT_ANNOUNCE_CAPABILITIES;
-    msg->opaque = 0;
-    msg->size = size;
-
-    memcpy(buf + sizeof(VDIChunkHeader) + sizeof(VDAgentMessage), (uint8_t *)caps, size);
-
-    if (0) dump_message(buf, msg_size);
-
-    spice_server_char_device_wakeup(&vt->vdagent_sin);
-
-    free(caps);
-}
-
-static void vdagent_grab_clipboard(spiceTerm *vt, uint8_t selection)
-{
-    uint32_t size;
-    
-    agent_owns_clipboard[selection] = 1;
-
-    size = 8;
-
-    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];
-    uint8_t *grab = (uint8_t *)&msg[1];
-    *((uint8_t *)grab) = selection;
-    *((uint32_t *)(grab + 4)) = VD_AGENT_CLIPBOARD_UTF8_TEXT;
-
-    hdr->port = VDP_CLIENT_PORT;
-    hdr->size = sizeof(VDAgentMessage) + size;
-
-    msg->protocol = VD_AGENT_PROTOCOL;
-    msg->type = VD_AGENT_CLIPBOARD_GRAB;
-    msg->opaque = 0;
-    msg->size = size;
-
-    if (0) dump_message(buf, msg_size);
-
-    spice_server_char_device_wakeup(&vt->vdagent_sin);
-}
-
-static void vdagent_request_clipboard(spiceTerm *vt, uint8_t selection)
-{
-    uint32_t size;
-    
-    size = 4 + sizeof(VDAgentClipboardRequest);
-
-    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];
-    uint8_t *data = (uint8_t *)&msg[1];
-    *((uint32_t *)data) = 0;
-    data[0] = selection;
-    ((uint32_t *)data)[1] = VD_AGENT_CLIPBOARD_UTF8_TEXT;
-
-    hdr->port = VDP_CLIENT_PORT;
-    hdr->size = sizeof(VDAgentMessage) + size;
-
-    msg->protocol = VD_AGENT_PROTOCOL;
-    msg->type = VD_AGENT_CLIPBOARD_REQUEST;
-    msg->opaque = 0;
-    msg->size = size;
-
-    if (0) dump_message(buf, msg_size);
-
-    spice_server_char_device_wakeup(&vt->vdagent_sin);
-}
-
-static void vdagent_send_clipboard(spiceTerm *vt, uint8_t selection)
-{
-    uint32_t size;
-    
-    if (selection != VD_AGENT_CLIPBOARD_SELECTION_PRIMARY) {
-        fprintf(stderr, "clipboard select %d is not supported\n", selection);
-        return;
-    }
-
-    gchar *sel_data;
-    glong sel_len;
-    if (vt->utf8) {
-        sel_data = g_utf16_to_utf8(vt->selection, vt->selection_len, NULL, &sel_len, NULL);
-    } else {
-        sel_len = vt->selection_len;
-        sel_data = g_malloc(sel_len);
-        int i;
-        for (i = 0; i < sel_len; i++) { sel_data[i] =  (char)vt->selection[i]; }
-        sel_data[sel_len] = 0;
-    }
-
-    size = 8 + sel_len;
-
-    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];
-    uint8_t *data = (uint8_t *)&msg[1];
-    *((uint8_t *)data) = selection;
-    data += 4;
-    *((uint32_t *)data) = VD_AGENT_CLIPBOARD_UTF8_TEXT;
-    data += 4;
-
-    memcpy(data, sel_data, sel_len);
-    g_free(sel_data);
-
-    hdr->port = VDP_CLIENT_PORT;
-    hdr->size = sizeof(VDAgentMessage) + size;
-
-    msg->protocol = VD_AGENT_PROTOCOL;
-    msg->type = VD_AGENT_CLIPBOARD;
-    msg->opaque = 0;
-    msg->size = size;
-
-    spice_server_char_device_wakeup(&vt->vdagent_sin);
-}
-
-static int
-vmc_write(SpiceCharDeviceInstance *sin, const uint8_t *buf, int len)
-{
-    spiceTerm *vt = SPICE_CONTAINEROF(sin, spiceTerm, vdagent_sin);
-
-    VDIChunkHeader *hdr = (VDIChunkHeader *)buf;
-    VDAgentMessage *msg = (VDAgentMessage *)&hdr[1];
-
-    //g_assert(hdr->port == VDP_SERVER_PORT);
-    g_assert(msg->protocol == VD_AGENT_PROTOCOL);
-
-    DPRINTF(1, "%d %d %d %d", len, hdr->port, msg->protocol, msg->type);
-
-    switch (msg->type) {
-    case VD_AGENT_MOUSE_STATE: { 
-        VDAgentMouseState *info = (VDAgentMouseState *)&msg[1];
-        spiceterm_motion_event(vt, info->x, info->y, info->buttons);
-        break;
-    }
-    case VD_AGENT_ANNOUNCE_CAPABILITIES: {
-        VDAgentAnnounceCapabilities *caps = (VDAgentAnnounceCapabilities *)&msg[1];
-        DPRINTF(1, "VD_AGENT_ANNOUNCE_CAPABILITIES %d", caps->request);
-        int i;
-        
-        int caps_size = VD_AGENT_CAPS_SIZE_FROM_MSG_SIZE(hdr->size);
-        for (i = 0; i < VD_AGENT_END_CAP; i++) {
-            DPRINTF(1, "CAPABILITIES %d %d", i, VD_AGENT_HAS_CAPABILITY(caps->caps, caps_size, i));
-        }
-
-        vdagent_send_capabilities(vt, 0);
-        break;
-    }
-    case VD_AGENT_CLIPBOARD_GRAB: {
-        VDAgentClipboardGrab *grab = (VDAgentClipboardGrab *)&msg[1];
-        uint8_t selection = *((uint8_t *)grab);
-        DPRINTF(1, "VD_AGENT_CLIPBOARD_GRAB %d", selection);
-        agent_owns_clipboard[selection] = 0;
-        spiceterm_clear_selection(vt);
-        break;
-    }
-    case VD_AGENT_CLIPBOARD_REQUEST: {
-        uint8_t *req = (uint8_t *)&msg[1];
-        uint8_t selection = *((uint8_t *)req);
-        uint32_t type = *((uint32_t *)(req + 4));
-
-        DPRINTF(1, "VD_AGENT_CLIPBOARD_REQUEST %d %d", selection, type);
-
-        vdagent_send_clipboard(vt, selection);
-        
-        break;
-    }
-    case VD_AGENT_CLIPBOARD: {
-        uint8_t *data = (uint8_t *)&msg[1];
-        uint8_t selection = data[0];
-        uint32_t type = *(uint32_t *)(data + 4);
-        int size = msg->size - 8;
-        DPRINTF(1, "VD_AGENT_CLIPBOARD %d %d %d", selection, type, size);
-
-        if (type == VD_AGENT_CLIPBOARD_UTF8_TEXT) {
-            int i;
-            for (i = 0; i < size; i++) {
-                if ((vt->ibuf_count + 1) < IBUFSIZE) {
-                    vt->ibuf[vt->ibuf_count++] = *(char *)(data + 8 + i);
-                } else {
-                    fprintf(stderr, "warning: input buffer overflow\n");
-                }
-            }
-            spiceterm_update_watch_mask(vt, TRUE);
-        }
-        break;
-    }
-    case VD_AGENT_CLIPBOARD_RELEASE: {
-        uint8_t *data = (uint8_t *)&msg[1];
-        uint8_t selection = data[0];
-        
-        DPRINTF(1, "VD_AGENT_CLIPBOARD_RELEASE %d", selection);
-     
-        break;
+        vdagent_grab_clipboard(vt);
     }
-    case VD_AGENT_MONITORS_CONFIG: {
-        VDAgentMonitorsConfig *list = (VDAgentMonitorsConfig *)&msg[1];
-        g_assert(list->num_of_monitors > 0);
-        DPRINTF(1, "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(1, "got uknown vdagent message type %d\n", msg->type);
-    }
-
-    return len;
-}
-
-static int
-vmc_read(SpiceCharDeviceInstance *sin, uint8_t *buf, int len)
-{
-    DPRINTF(1, "%d %d", len,  vdagent_write_buffer_pos);
-    g_assert(len >= 8);
-
-    if (!vdagent_write_buffer_pos) {
-        return 0;
-    }
-     
-    int size = (len >= vdagent_write_buffer_pos) ? vdagent_write_buffer_pos : len;
-    memcpy(buf, vdagent_write_buffer, size);
-    if (size < vdagent_write_buffer_pos) {
-        memmove(vdagent_write_buffer, vdagent_write_buffer + size, 
-                vdagent_write_buffer_pos - size);
-    }
-    vdagent_write_buffer_pos -= size;
-
-    DPRINTF(1, "RET %d %d", size,  vdagent_write_buffer_pos);
-    return size;
-}
-
-static void
-vmc_state(SpiceCharDeviceInstance *sin, int connected)
-{
-    /* IGNORE */
 }
 
-static SpiceCharDeviceInterface my_vdagent_sif = {
-    .base.type          = SPICE_INTERFACE_CHAR_DEVICE,
-    .base.description   = "spice virtual channel char device",
-    .base.major_version = SPICE_INTERFACE_CHAR_DEVICE_MAJOR,
-    .base.minor_version = SPICE_INTERFACE_CHAR_DEVICE_MINOR,
-    .state              = vmc_state,
-    .write              = vmc_write,
-    .read               = vmc_read,
-};
-
-static void
+void
 init_spiceterm(spiceTerm *vt, uint32_t width, uint32_t height)
 {
     int i;
@@ -2121,7 +1535,7 @@ init_spiceterm(spiceTerm *vt, uint32_t width, uint32_t height)
     vt->altcells = (TextCell *)calloc (sizeof (TextCell), vt->width*vt->height);
 }
 
-static void
+void
 spiceterm_resize(spiceTerm *vt, uint32_t width, uint32_t height)
 {
     width = (width/8)*8;
@@ -2144,31 +1558,6 @@ spiceterm_resize(spiceTerm *vt, uint32_t width, uint32_t 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);
-    
-    spice_screen->image_cache = g_hash_table_new(g_int_hash, g_int_equal);
-
-    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;
-}
-
 static gboolean
 master_error_callback(GIOChannel *channel, GIOCondition condition,
                       gpointer data)