]> git.proxmox.com Git - spiceterm.git/blobdiff - spiceterm.c
use gdk keysyms instead of utf
[spiceterm.git] / spiceterm.c
index 7985ebb70bf74c2cad9b63c0a03f9942899c1577..bc24a18b83b7a4b623053ed04a0555c27e6a0da4 100644 (file)
@@ -25,7 +25,7 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <unistd.h>
-#include <sys/types.h> 
+#include <sys/types.h>
 #include <sys/socket.h>
 #include <arpa/inet.h>
 #include <netdb.h>
@@ -45,6 +45,7 @@
 #include <spice/macros.h>
 #include <spice/qxl_dev.h>
 
+#include <gdk/gdkkeysyms.h>
 #include "test_display_base.h"
 
 /* define this for debugging */
@@ -67,13 +68,6 @@ static int idle_timeout = 1;
 unsigned char color_table[] = { 0, 4, 2, 6, 1, 5, 3, 7,
                                8,12,10,14, 9,13,11,15 };
 
-/* the default colour table, for VGA+ colour systems */
-int default_red[] = {0x00,0xaa,0x00,0xaa,0x00,0xaa,0x00,0xaa,
-    0x55,0xff,0x55,0xff,0x55,0xff,0x55,0xff};
-int default_grn[] = {0x00,0x00,0xaa,0x55,0x00,0x00,0xaa,0xaa,
-    0x55,0x55,0xff,0xff,0x55,0x55,0xff,0xff};
-int default_blu[] = {0x00,0x00,0x00,0x00,0xaa,0xaa,0xaa,0xaa,
-    0x55,0x55,0x55,0x55,0xff,0xff,0xff,0xff};
 
 static void
 print_usage (const char *msg)
@@ -110,8 +104,8 @@ ucs2_to_utf8 (unicode c, char *out)
 static void
 draw_char_at (vncTerm *vt, int x, int y, unicode ch, TextAttributes attrib)
 {
-    if (x < 0 || y < 0 || x >= vt->width || y >= vt->height) { 
-        return; 
+    if (x < 0 || y < 0 || x >= vt->width || y >= vt->height) {
+        return;
     }
 
 
@@ -1141,7 +1135,7 @@ vncterm_putchar (vncTerm *vt, unicode ch)
       break;
     case 7:  /* alert aka. bell */
         // fixme:
-        //rfbSendBell(vt->screen); 
+        //rfbSendBell(vt->screen);
       break;
     case 8:  /* backspace */
       if (vt->cx > 0)
@@ -1272,6 +1266,7 @@ vncterm_puts (vncTerm *vt, const char *buf, int len)
     }
 
     vncterm_show_cursor (vt, 1);
+
     return len;
 }
 
@@ -1468,17 +1463,158 @@ static void my_kbd_push_key(SpiceKbdInstance *sin, uint8_t frag)
 {
     vncTerm *vt = SPICE_CONTAINEROF(sin, vncTerm, keyboard_sin);
 
+    return;
+
     printf("MYKEYCODE %x\n", frag);
 
     if (vt->ibuf_count < (IBUFSIZE - 32)) {
 
         char keySym = 'A'; // fixme;
         vt->ibuf[vt->ibuf_count++] = keySym;
-        
+
         vt->screen->core->watch_update_mask(vt->screen->mwatch, SPICE_WATCH_EVENT_READ|SPICE_WATCH_EVENT_WRITE);
     }
 }
 
+static void my_kbd_push_keyval(SpiceKbdInstance *sin, uint32_t keySym, int flags)
+{
+    vncTerm *vt = SPICE_CONTAINEROF(sin, vncTerm, keyboard_sin);
+    static int control = 0;
+    static int shift = 0;
+    char *esc = NULL;
+
+    //fprintf (stderr, "KEYEVENT:%d: %08x\n", flags, keySym);fflush (stderr);
+    if (flags & 1) {
+        fprintf(stderr, "KEYPRESS: %08x\n", keySym);fflush (stderr);
+
+        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)) {
+
+            if (control) {
+                if(keySym >= 'a' && keySym <= 'z')
+                    keySym -= 'a' -1;
+                else if (keySym >= 'A' && keySym <= 'Z')
+                    keySym -= 'A'-1;
+                else
+                    keySym=0xffff;
+            } else {
+                switch (keySym) {
+                case GDK_KEY_Escape:
+                    keySym=27; break;
+                case GDK_KEY_Return:
+                    keySym='\r'; break;
+                case GDK_KEY_BackSpace:
+                    keySym=8; break;
+                case GDK_KEY_Tab:
+                    keySym='\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) {
+                        vncterm_virtual_scroll (vt, -vt->height/2);
+                        return;
+                    }
+                    esc = "[5~";break;
+                case GDK_KEY_Page_Down:
+                    if (shift) {
+                        vncterm_virtual_scroll (vt, vt->height/2);
+                        return;
+                    }
+                    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:
+                    break;
+                }
+            }
+
+#ifdef DEBUG
+            fprintf(stderr, "KEYPRESS OUT:%s: %d\n", esc, keySym); fflush (stderr);
+#endif
+
+            if (vt->y_displ != vt->y_base) {
+                vt->y_displ = vt->y_base;
+                vncterm_refresh (vt);
+            }
+            
+            if (esc) {
+                vncterm_respond_esc(vt, esc);
+            } else if(keySym < 0x100) {
+                if (vt->utf8) {
+                    gchar buf[10];
+                    gint len = g_unichar_to_utf8(keySym, buf);
+
+                    if (len > 0) {
+                        int i;
+                        for (i = 0; i < len; i++) {
+                            vt->ibuf[vt->ibuf_count++] = buf[i];
+                        }
+                    }
+                } else {
+                    vt->ibuf[vt->ibuf_count++] = (char)keySym;
+                }
+            }
+            vt->screen->core->watch_update_mask(vt->screen->mwatch, 
+                                                SPICE_WATCH_EVENT_READ|SPICE_WATCH_EVENT_WRITE);
+       }
+    }
+
+    if (flags & 2) { // 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;
+        }
+    }
+}
+
 static uint8_t my_kbd_get_leds(SpiceKbdInstance *sin)
 {
     return 0;
@@ -1489,6 +1625,7 @@ static SpiceKbdInterface my_keyboard_sif = {
     .base.description   = "spiceterm keyboard device",
     .base.major_version = SPICE_INTERFACE_KEYBOARD_MAJOR,
     .base.minor_version = SPICE_INTERFACE_KEYBOARD_MINOR,
+    .push_keyval        = my_kbd_push_keyval,
     .push_scan_freg     = my_kbd_push_key,
     .get_leds           = my_kbd_get_leds,
 };
@@ -1507,10 +1644,10 @@ create_vncterm (int argc, char** argv, int maxx, int maxy)
   test_add_agent_interface(test->server);
 
   vncTerm *vt = (vncTerm *)calloc (sizeof(vncTerm), 1);
+
   vt->keyboard_sin.base.sif = &my_keyboard_sif.base;
   spice_server_add_interface(test->server, &vt->keyboard_sin.base);
+
   /*
   rfbColourMap *cmap =&screen->colourMap;
   cmap->data.bytes = malloc (16*3);
@@ -1599,9 +1736,9 @@ static void master_watch(int master, int event, void *opaque)
         vncterm_puts (vt, buffer, c);
     } else {
         if (vt->ibuf_count > 0) {
-            printf ("DEBUG: WRITE %d %d\n", vt->ibuf[0], vt->ibuf_count);
+            printf ("DEBUG: WRITE %x %d\n", vt->ibuf[0], vt->ibuf_count);
             write (master, vt->ibuf, vt->ibuf_count);
-            vt->ibuf_count = 0; // fixme: what if not all data written          
+            vt->ibuf_count = 0; // fixme: what if not all data written
         }
         vt->screen->core->watch_update_mask(vt->screen->mwatch, SPICE_WATCH_EVENT_READ);
     }
@@ -1647,7 +1784,7 @@ main (int argc, char** argv)
 
   setenv ("TERM", TERM, 1);
 
-  printf("EXEC: %s\n", command);  
+  printf("EXEC: %s\n", command);
 
   pid = forkpty (&master, ptyname, NULL, &dimensions);
   if(!pid) {
@@ -1671,7 +1808,7 @@ main (int argc, char** argv)
 
 
   vt->screen->mwatch = vt->screen->core->watch_add(
-      master, SPICE_WATCH_EVENT_READ /* |SPICE_WATCH_EVENT_WRITE */, 
+      master, SPICE_WATCH_EVENT_READ /* |SPICE_WATCH_EVENT_WRITE */,
       master_watch, vt);
 
   basic_event_loop_mainloop();