Diff for /qemu/vnc.c between versions 1.1.1.2 and 1.1.1.3

version 1.1.1.2, 2018/04/24 16:42:51 version 1.1.1.3, 2018/04/24 16:45:06
Line 68  struct VncState Line 68  struct VncState
     int depth; /* internal VNC frame buffer byte per pixel */      int depth; /* internal VNC frame buffer byte per pixel */
     int has_resize;      int has_resize;
     int has_hextile;      int has_hextile;
       int has_pointer_type_change;
       int absolute;
       int last_x;
       int last_y;
   
       const char *display;
   
     Buffer output;      Buffer output;
     Buffer input;      Buffer input;
     kbd_layout_t *kbd_layout;      kbd_layout_t *kbd_layout;
Line 81  struct VncState Line 88  struct VncState
   
     VncReadEvent *read_handler;      VncReadEvent *read_handler;
     size_t read_handler_expect;      size_t read_handler_expect;
       /* input */
       uint8_t modifiers_state[256];
 };  };
   
   static VncState *vnc_state; /* needed for info vnc */
   
   void do_info_vnc(void)
   {
       if (vnc_state == NULL)
           term_printf("VNC server disabled\n");
       else {
           term_printf("VNC server active on: ");
           term_print_filename(vnc_state->display);
           term_printf("\n");
   
           if (vnc_state->csock == -1)
               term_printf("No client connected\n");
           else
               term_printf("Client connected\n");
       }
   }
   
 /* TODO  /* TODO
    1) Get the queue working for IO.     1) Get the queue working for IO.
    2) there is some weirdness when using the -S option (the screen is grey     2) there is some weirdness when using the -S option (the screen is grey
Line 165  static void vnc_framebuffer_update(VncSt Line 192  static void vnc_framebuffer_update(VncSt
   
 static void vnc_dpy_resize(DisplayState *ds, int w, int h)  static void vnc_dpy_resize(DisplayState *ds, int w, int h)
 {  {
       int size_changed;
     VncState *vs = ds->opaque;      VncState *vs = ds->opaque;
   
     ds->data = realloc(ds->data, w * h * vs->depth);      ds->data = realloc(ds->data, w * h * vs->depth);
Line 176  static void vnc_dpy_resize(DisplayState  Line 204  static void vnc_dpy_resize(DisplayState 
     }      }
   
     ds->depth = vs->depth * 8;      ds->depth = vs->depth * 8;
       size_changed = ds->width != w || ds->height != h;
     ds->width = w;      ds->width = w;
     ds->height = h;      ds->height = h;
     ds->linesize = w * vs->depth;      ds->linesize = w * vs->depth;
     if (vs->csock != -1 && vs->has_resize) {      if (vs->csock != -1 && vs->has_resize && size_changed) {
         vnc_write_u8(vs, 0);  /* msg id */          vnc_write_u8(vs, 0);  /* msg id */
         vnc_write_u8(vs, 0);          vnc_write_u8(vs, 0);
         vnc_write_u16(vs, 1); /* number of rects */          vnc_write_u16(vs, 1); /* number of rects */
Line 622  static void vnc_write_u32(VncState *vs,  Line 651  static void vnc_write_u32(VncState *vs, 
   
 static void vnc_write_u16(VncState *vs, uint16_t value)  static void vnc_write_u16(VncState *vs, uint16_t value)
 {  {
     char buf[2];      uint8_t buf[2];
   
     buf[0] = (value >> 8) & 0xFF;      buf[0] = (value >> 8) & 0xFF;
     buf[1] = value & 0xFF;      buf[1] = value & 0xFF;
Line 641  static void vnc_flush(VncState *vs) Line 670  static void vnc_flush(VncState *vs)
         vnc_client_write(vs);          vnc_client_write(vs);
 }  }
   
 static uint8_t read_u8(char *data, size_t offset)  static uint8_t read_u8(uint8_t *data, size_t offset)
 {  {
     return data[offset];      return data[offset];
 }  }
   
 static uint16_t read_u16(char *data, size_t offset)  static uint16_t read_u16(uint8_t *data, size_t offset)
 {  {
     return ((data[offset] & 0xFF) << 8) | (data[offset + 1] & 0xFF);      return ((data[offset] & 0xFF) << 8) | (data[offset + 1] & 0xFF);
 }  }
   
 static int32_t read_s32(char *data, size_t offset)  static int32_t read_s32(uint8_t *data, size_t offset)
 {  {
     return (int32_t)((data[offset] << 24) | (data[offset + 1] << 16) |      return (int32_t)((data[offset] << 24) | (data[offset + 1] << 16) |
                      (data[offset + 2] << 8) | data[offset + 3]);                       (data[offset + 2] << 8) | data[offset + 3]);
 }  }
   
 static uint32_t read_u32(char *data, size_t offset)  static uint32_t read_u32(uint8_t *data, size_t offset)
 {  {
     return ((data[offset] << 24) | (data[offset + 1] << 16) |      return ((data[offset] << 24) | (data[offset + 1] << 16) |
             (data[offset + 2] << 8) | data[offset + 3]);              (data[offset + 2] << 8) | data[offset + 3]);
Line 667  static void client_cut_text(VncState *vs Line 696  static void client_cut_text(VncState *vs
 {  {
 }  }
   
   static void check_pointer_type_change(VncState *vs, int absolute)
   {
       if (vs->has_pointer_type_change && vs->absolute != absolute) {
           vnc_write_u8(vs, 0);
           vnc_write_u8(vs, 0);
           vnc_write_u16(vs, 1);
           vnc_framebuffer_update(vs, absolute, 0,
                                  vs->ds->width, vs->ds->height, -257);
           vnc_flush(vs);
       }
       vs->absolute = absolute;
   }
   
 static void pointer_event(VncState *vs, int button_mask, int x, int y)  static void pointer_event(VncState *vs, int button_mask, int x, int y)
 {  {
     int buttons = 0;      int buttons = 0;
Line 682  static void pointer_event(VncState *vs,  Line 724  static void pointer_event(VncState *vs, 
         dz = -1;          dz = -1;
     if (button_mask & 0x10)      if (button_mask & 0x10)
         dz = 1;          dz = 1;
               
     if (kbd_mouse_is_absolute()) {      if (vs->absolute) {
         kbd_mouse_event(x * 0x7FFF / vs->ds->width,          kbd_mouse_event(x * 0x7FFF / vs->ds->width,
                         y * 0x7FFF / vs->ds->height,                          y * 0x7FFF / vs->ds->height,
                         dz, buttons);                          dz, buttons);
       } else if (vs->has_pointer_type_change) {
           x -= 0x7FFF;
           y -= 0x7FFF;
   
           kbd_mouse_event(x, y, dz, buttons);
     } else {      } else {
         static int last_x = -1;          if (vs->last_x != -1)
         static int last_y = -1;              kbd_mouse_event(x - vs->last_x,
                               y - vs->last_y,
                               dz, buttons);
           vs->last_x = x;
           vs->last_y = y;
       }
   
         if (last_x != -1)      check_pointer_type_change(vs, kbd_mouse_is_absolute());
             kbd_mouse_event(x - last_x, y - last_y, dz, buttons);  }
   
         last_x = x;  static void reset_keys(VncState *vs)
         last_y = y;  {
       int i;
       for(i = 0; i < 256; i++) {
           if (vs->modifiers_state[i]) {
               if (i & 0x80)
                   kbd_put_keycode(0xe0);
               kbd_put_keycode(i | 0x80);
               vs->modifiers_state[i] = 0;
           }
     }      }
 }  }
   
Line 704  static void do_key_event(VncState *vs, i Line 764  static void do_key_event(VncState *vs, i
     int keycode;      int keycode;
   
     keycode = keysym2scancode(vs->kbd_layout, sym & 0xFFFF);      keycode = keysym2scancode(vs->kbd_layout, sym & 0xFFFF);
       
       /* QEMU console switch */
       switch(keycode) {
       case 0x2a:                          /* Left Shift */
       case 0x36:                          /* Right Shift */
       case 0x1d:                          /* Left CTRL */
       case 0x9d:                          /* Right CTRL */
       case 0x38:                          /* Left ALT */
       case 0xb8:                          /* Right ALT */
           if (down)
               vs->modifiers_state[keycode] = 1;
           else
               vs->modifiers_state[keycode] = 0;
           break;
       case 0x02 ... 0x0a: /* '1' to '9' keys */ 
           if (down && vs->modifiers_state[0x1d] && vs->modifiers_state[0x38]) {
               /* Reset the modifiers sent to the current console */
               reset_keys(vs);
               console_select(keycode - 0x02);
               return;
           }
           break;
       }
   
     if (keycode & 0x80)      if (is_graphic_console()) {
         kbd_put_keycode(0xe0);          if (keycode & 0x80)
     if (down)              kbd_put_keycode(0xe0);
         kbd_put_keycode(keycode & 0x7f);          if (down)
     else              kbd_put_keycode(keycode & 0x7f);
         kbd_put_keycode(keycode | 0x80);          else
               kbd_put_keycode(keycode | 0x80);
       } else {
           /* QEMU console emulation */
           if (down) {
               switch (keycode) {
               case 0x2a:                          /* Left Shift */
               case 0x36:                          /* Right Shift */
               case 0x1d:                          /* Left CTRL */
               case 0x9d:                          /* Right CTRL */
               case 0x38:                          /* Left ALT */
               case 0xb8:                          /* Right ALT */
                   break;
               case 0xc8:
                   kbd_put_keysym(QEMU_KEY_UP);
                   break;
               case 0xd0:
                   kbd_put_keysym(QEMU_KEY_DOWN);
                   break;
               case 0xcb:
                   kbd_put_keysym(QEMU_KEY_LEFT);
                   break;
               case 0xcd:
                   kbd_put_keysym(QEMU_KEY_RIGHT);
                   break;
               case 0xd3:
                   kbd_put_keysym(QEMU_KEY_DELETE);
                   break;
               case 0xc7:
                   kbd_put_keysym(QEMU_KEY_HOME);
                   break;
               case 0xcf:
                   kbd_put_keysym(QEMU_KEY_END);
                   break;
               case 0xc9:
                   kbd_put_keysym(QEMU_KEY_PAGEUP);
                   break;
               case 0xd1:
                   kbd_put_keysym(QEMU_KEY_PAGEDOWN);
                   break;
               default:
                   kbd_put_keysym(sym);
                   break;
               }
           }
       }
 }  }
   
 static void key_event(VncState *vs, int down, uint32_t sym)  static void key_event(VncState *vs, int down, uint32_t sym)
Line 744  static void set_encodings(VncState *vs,  Line 872  static void set_encodings(VncState *vs, 
   
     vs->has_hextile = 0;      vs->has_hextile = 0;
     vs->has_resize = 0;      vs->has_resize = 0;
       vs->has_pointer_type_change = 0;
       vs->absolute = -1;
     vs->ds->dpy_copy = NULL;      vs->ds->dpy_copy = NULL;
   
     for (i = n_encodings - 1; i >= 0; i--) {      for (i = n_encodings - 1; i >= 0; i--) {
Line 760  static void set_encodings(VncState *vs,  Line 890  static void set_encodings(VncState *vs, 
         case -223: /* DesktopResize */          case -223: /* DesktopResize */
             vs->has_resize = 1;              vs->has_resize = 1;
             break;              break;
           case -257:
               vs->has_pointer_type_change = 1;
               break;
         default:          default:
             break;              break;
         }          }
     }      }
   
       check_pointer_type_change(vs, kbd_mouse_is_absolute());
 }  }
   
 static int compute_nbits(unsigned int val)  static int compute_nbits(unsigned int val)
Line 1016  static void vnc_listen_read(void *opaque Line 1151  static void vnc_listen_read(void *opaque
     }      }
 }  }
   
 void vnc_display_init(DisplayState *ds, int display)  extern int parse_host_port(struct sockaddr_in *saddr, const char *str);
   
   void vnc_display_init(DisplayState *ds, const char *arg)
 {  {
     struct sockaddr_in addr;      struct sockaddr *addr;
       struct sockaddr_in iaddr;
   #ifndef _WIN32
       struct sockaddr_un uaddr;
   #endif
     int reuse_addr, ret;      int reuse_addr, ret;
       socklen_t addrlen;
       const char *p;
     VncState *vs;      VncState *vs;
   
     vs = qemu_mallocz(sizeof(VncState));      vs = qemu_mallocz(sizeof(VncState));
Line 1027  void vnc_display_init(DisplayState *ds,  Line 1170  void vnc_display_init(DisplayState *ds, 
         exit(1);          exit(1);
   
     ds->opaque = vs;      ds->opaque = vs;
       vnc_state = vs;
       vs->display = arg;
   
     vs->lsock = -1;      vs->lsock = -1;
     vs->csock = -1;      vs->csock = -1;
     vs->depth = 4;      vs->depth = 4;
       vs->last_x = -1;
       vs->last_y = -1;
   
     vs->ds = ds;      vs->ds = ds;
   
Line 1041  void vnc_display_init(DisplayState *ds,  Line 1188  void vnc_display_init(DisplayState *ds, 
     if (!vs->kbd_layout)      if (!vs->kbd_layout)
         exit(1);          exit(1);
   
     vs->lsock = socket(PF_INET, SOCK_STREAM, 0);      vs->ds->data = NULL;
     if (vs->lsock == -1) {      vs->ds->dpy_update = vnc_dpy_update;
         fprintf(stderr, "Could not create socket\n");      vs->ds->dpy_resize = vnc_dpy_resize;
         exit(1);      vs->ds->dpy_refresh = vnc_dpy_refresh;
     }  
   
     addr.sin_family = AF_INET;      memset(vs->dirty_row, 0xFF, sizeof(vs->dirty_row));
     addr.sin_port = htons(5900 + display);  
     memset(&addr.sin_addr, 0, sizeof(addr.sin_addr));      vnc_dpy_resize(vs->ds, 640, 400);
   
     reuse_addr = 1;  #ifndef _WIN32
     ret = setsockopt(vs->lsock, SOL_SOCKET, SO_REUSEADDR,      if (strstart(arg, "unix:", &p)) {
                      (const char *)&reuse_addr, sizeof(reuse_addr));          addr = (struct sockaddr *)&uaddr;
     if (ret == -1) {          addrlen = sizeof(uaddr);
         fprintf(stderr, "setsockopt() failed\n");  
         exit(1);          vs->lsock = socket(PF_UNIX, SOCK_STREAM, 0);
           if (vs->lsock == -1) {
               fprintf(stderr, "Could not create socket\n");
               exit(1);
           }
   
           uaddr.sun_family = AF_UNIX;
           memset(uaddr.sun_path, 0, 108);
           snprintf(uaddr.sun_path, 108, "%s", p);
   
           unlink(uaddr.sun_path);
       } else
   #endif
       {
           addr = (struct sockaddr *)&iaddr;
           addrlen = sizeof(iaddr);
   
           vs->lsock = socket(PF_INET, SOCK_STREAM, 0);
           if (vs->lsock == -1) {
               fprintf(stderr, "Could not create socket\n");
               exit(1);
           }
   
           if (parse_host_port(&iaddr, arg) < 0) {
               fprintf(stderr, "Could not parse VNC address\n");
               exit(1);
           }
               
           iaddr.sin_port = htons(ntohs(iaddr.sin_port) + 5900);
   
           reuse_addr = 1;
           ret = setsockopt(vs->lsock, SOL_SOCKET, SO_REUSEADDR,
                            (const char *)&reuse_addr, sizeof(reuse_addr));
           if (ret == -1) {
               fprintf(stderr, "setsockopt() failed\n");
               exit(1);
           }
     }      }
   
     if (bind(vs->lsock, (struct sockaddr *)&addr, sizeof(addr)) == -1) {      if (bind(vs->lsock, addr, addrlen) == -1) {
         fprintf(stderr, "bind() failed\n");          fprintf(stderr, "bind() failed\n");
         exit(1);          exit(1);
     }      }
Line 1073  void vnc_display_init(DisplayState *ds,  Line 1255  void vnc_display_init(DisplayState *ds, 
     if (ret == -1) {      if (ret == -1) {
         exit(1);          exit(1);
     }      }
   
     vs->ds->data = NULL;  
     vs->ds->dpy_update = vnc_dpy_update;  
     vs->ds->dpy_resize = vnc_dpy_resize;  
     vs->ds->dpy_refresh = vnc_dpy_refresh;  
   
     memset(vs->dirty_row, 0xFF, sizeof(vs->dirty_row));  
   
     vnc_dpy_resize(vs->ds, 640, 400);  
 }  }

Removed from v.1.1.1.2  
changed lines
  Added in v.1.1.1.3


unix.superglobalmegacorp.com