]> git.proxmox.com Git - spiceterm.git/commitdiff
use modified input channel extension with utf8
authorDietmar Maurer <dietmar@proxmox.com>
Wed, 16 Oct 2013 10:19:00 +0000 (12:19 +0200)
committerDietmar Maurer <dietmar@proxmox.com>
Wed, 16 Oct 2013 10:19:00 +0000 (12:19 +0200)
spiceterm.c

index 83eb4c8249366cc6ac467ab5b9ff188fbba63020..3031606f4ae31dcb4210b6b4482531991c4f336e 100644 (file)
@@ -1353,166 +1353,212 @@ spiceterm_respond_unichar2(spiceTerm *vt, gunichar2 uc)
     }
 }
 
-static void
-spiceterm_push_keysym(spiceTerm *vt, uint32_t keySym, uint32_t flags)
+static uint8_t
+my_kbd_get_leds(SpiceKbdInstance *sin)
 {
-    static int control = 0;
-    static int shift = 0;
-    char *esc = NULL;
-
-    gunichar2 uc = 0;
+    return 0;
+}
 
-    DPRINTF(1, "flags=%d keySym=%08x", flags, keySym);
+#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)
 
-    if (flags & SPICE_KEYBOARD_FLAG_DOWN) {
-        if (keySym == GDK_KEY_Shift_L || keySym == GDK_KEY_Shift_R) {
-            shift = 1;
-        } if (keySym == GDK_KEY_Control_L || keySym == GDK_KEY_Control_R) {
-            control = 1;
-        } else if (vt->ibuf_count < (IBUFSIZE - 32)) {
+static int kbd_flags = 0;
+static void
+my_kbd_push_key(SpiceKbdInstance *sin, uint8_t frag)
+{
+    spiceTerm *vt = SPICE_CONTAINEROF(sin, spiceTerm, keyboard_sin);
 
-            if (control) {
-                if(keySym >= 'a' && keySym <= 'z')
-                    uc = keySym - 'a' + 1;
-                else if (keySym >= 'A' && keySym <= 'Z')
-                    uc = keySym - 'A' + 1;
-                else
-                    uc = 0;
+    char *esc = NULL; // used to send special keys
 
-            } else {
-                switch (keySym) {
-                case GDK_KEY_Escape:
-                    uc = 27; break;
-                case GDK_KEY_Return:
-                    uc = '\r'; break;
-                case GDK_KEY_BackSpace:
-                    uc = 8; break;
-                case GDK_KEY_Tab:
-                    uc = '\t'; break;
-                case GDK_KEY_Delete: /* kdch1 */
-                case GDK_KEY_KP_Delete:
-                    esc = "[3~";break;
-                case GDK_KEY_Home: /* khome */
-                case GDK_KEY_KP_Home:
-                    esc = "OH";break;
-                case GDK_KEY_End:
-                case GDK_KEY_KP_End: /* kend */
-                    esc = "OF";break;
-                case GDK_KEY_Insert: /* kich1 */
-                case GDK_KEY_KP_Insert:
-                    esc = "[2~";break;
-                case GDK_KEY_Up:
-                case GDK_KEY_KP_Up:  /* kcuu1 */
-                    esc = "OA";break;
-                case GDK_KEY_Down: /* kcud1 */
-                case GDK_KEY_KP_Down:
-                    esc = "OB";break;
-                case GDK_KEY_Right:
-                case GDK_KEY_KP_Right: /* kcuf1 */
-                    esc = "OC";break;
-                case GDK_KEY_Left:
-                case GDK_KEY_KP_Left: /* kcub1 */
-                    esc = "OD";break;
-                case GDK_KEY_Page_Up:
-                    if (shift) {
-                        spiceterm_virtual_scroll (vt, -vt->height/2);
-                        goto ret;
-                    }
-                    esc = "[5~";break;
-                case GDK_KEY_Page_Down:
-                    if (shift) {
-                        spiceterm_virtual_scroll (vt, vt->height/2);
-                        goto ret;
-                    }
-                    esc = "[6~";break;
-                case GDK_KEY_F1:
-                    esc = "OP";break;
-                case GDK_KEY_F2:
-                    esc = "OQ";break;
-                case GDK_KEY_F3:
-                    esc = "OR";break;
-                case GDK_KEY_F4:
-                    esc = "OS";break;
-                case GDK_KEY_F5:
-                    esc = "[15~";break;
-                case GDK_KEY_F6:
-                    esc = "[17~";break;
-                case GDK_KEY_F7:
-                    esc = "[18~";break;
-                case GDK_KEY_F8:
-                    esc = "[19~";break;
-                case GDK_KEY_F9:
-                    esc = "[20~";break;
-                case GDK_KEY_F10:
-                    esc = "[21~";break;
-                case GDK_KEY_F11:
-                    esc = "[23~";break;
-                case GDK_KEY_F12:
-                    esc = "[24~";break;
-                default:
-                    if (keySym < 0x100) {
-                        uc = keySym;
-                    }
-                    break;
-                }
-            }
+    static int e0_mode = 0;
 
-            DPRINTF(1, "escape=%s unicode=%08x\n", esc, uc);
+    DPRINTF(1, "enter frag=%02x flags=%08x", frag, kbd_flags);
 
-            if (vt->y_displ != vt->y_base) {
-                vt->y_displ = vt->y_base;
-                spiceterm_refresh(vt);
+    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);
             }
-
-            if (esc) {
-                spiceterm_respond_esc(vt, esc);
-            } else if (uc > 0) {
-                spiceterm_respond_unichar2(vt, uc);
+            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;
         }
-    }
-
-ret:
-
-    if (flags & SPICE_KEYBOARD_FLAG_UP) {
-        if (keySym == GDK_KEY_Shift_L || keySym == GDK_KEY_Shift_R) {
-            shift = 0;
-        } else if (keySym == GDK_KEY_Control_L || keySym == GDK_KEY_Control_R) {
-            control = 0;
+    } 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;
         }
     }
 
-    spiceterm_update_watch_mask(vt, TRUE);
-}
+    if (esc) {
+        DPRINTF(1, "escape=%s", esc);
+        spiceterm_respond_esc(vt, esc);
 
-static uint8_t
-my_kbd_get_leds(SpiceKbdInstance *sin)
-{
-    return 0;
-}
-
-static void
-my_kbd_push_key(SpiceKbdInstance *sin, uint8_t frag)
-{
-    // spiceTerm *vt = SPICE_CONTAINEROF(sin, spiceTerm, keyboard_sin);
+        if (vt->y_displ != vt->y_base) {
+            vt->y_displ = vt->y_base;
+            spiceterm_refresh(vt);
+        }
 
-    /* we no not need this */
+        spiceterm_update_watch_mask(vt, TRUE);
+    }
 
+    DPRINTF(1, "leave frag=%02x flags=%08x", frag, kbd_flags);
     return;
 }
 
 static void
-my_kbd_push_x11_keysym(SpiceKbdInstance *sin, uint32_t keysym, uint32_t flags,
-                       uint8_t code_len, uint8_t *code)
+my_kbd_push_utf8(SpiceKbdInstance *sin, uint32_t size, uint8_t *data)
 {
     spiceTerm *vt = SPICE_CONTAINEROF(sin, spiceTerm, keyboard_sin);
 
-    DPRINTF(1, "flags=%d keySym=%08x code_len=%d", flags, keysym, code_len);
+    DPRINTF(1, " size=%d data[0]=%02x", size, data[0]);
 
-    if (keysym) {
-        spiceterm_push_keysym(vt, keysym, flags);
+    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;
+        }
+    } 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);
+    }
+
+    spiceterm_update_watch_mask(vt, TRUE);
+
     return;
 }
 
@@ -1523,7 +1569,7 @@ static SpiceKbdInterface my_keyboard_sif = {
     .base.minor_version = SPICE_INTERFACE_KEYBOARD_MINOR,
     .push_scan_freg     = my_kbd_push_key,
     .get_leds           = my_kbd_get_leds,
-    .push_x11_keysym    = my_kbd_push_x11_keysym,
+    .push_utf8          = my_kbd_push_utf8,
 };
 
 
@@ -1958,14 +2004,14 @@ vmc_write(SpiceCharDeviceInstance *sin, const uint8_t *buf, int len)
         uint8_t *data = (uint8_t *)&msg[1];
         uint8_t selection = data[0];
         
-        DPRINTF(0, "VD_AGENT_CLIPBOARD_RELEASE %d", selection);
+        DPRINTF(1, "VD_AGENT_CLIPBOARD_RELEASE %d", selection);
      
         break;
     }
     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, 
+        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);
@@ -1974,7 +2020,7 @@ vmc_write(SpiceCharDeviceInstance *sin, const uint8_t *buf, int len)
         break;
     }
     default:
-        DPRINTF(0, "got uknown vdagent message type %d\n", msg->type);
+        DPRINTF(1, "got uknown vdagent message type %d\n", msg->type);
     }
 
     return len;