diff -ru tigervnc-1.9.0.orig/vncviewer/CConn.cxx tigervnc-1.9.0/vncviewer/CConn.cxx
--- tigervnc-1.9.0.orig/vncviewer/CConn.cxx	2018-07-16 23:08:55.000000000 +0900
+++ tigervnc-1.9.0/vncviewer/CConn.cxx	2018-08-21 00:01:45.785380000 +0900
@@ -297,6 +297,14 @@
   } catch (rdr::EndOfStream& e) {
     vlog.info("%s", e.str());
     exit_vncviewer();
+  } catch (rdr::SystemException& e) {
+    vlog.error("%s", e.str());
+    if (e.err == WSAECONNRESET) {
+      recursing = false;
+      throw;
+    }
+    else if (!should_exit())
+      exit_vncviewer(e.str());
   } catch (rdr::Exception& e) {
     vlog.error("%s", e.str());
     // Somebody might already have requested us to terminate, and
diff -ru tigervnc-1.9.0.orig/vncviewer/DesktopWindow.cxx tigervnc-1.9.0/vncviewer/DesktopWindow.cxx
--- tigervnc-1.9.0.orig/vncviewer/DesktopWindow.cxx	2018-07-16 23:08:55.000000000 +0900
+++ tigervnc-1.9.0/vncviewer/DesktopWindow.cxx	2018-08-21 02:09:47.391163140 +0900
@@ -190,6 +190,8 @@
 
 DesktopWindow::~DesktopWindow()
 {
+  if (this->fullscreen_active() && fullscreenSystemKeys)
+    this->ungrabKeyboard();
   // Unregister all timeouts in case they get a change tro trigger
   // again later when this object is already gone.
   Fl::remove_timeout(handleGrab, this);
diff -ru tigervnc-1.9.0.orig/vncviewer/OptionsDialog.cxx tigervnc-1.9.0/vncviewer/OptionsDialog.cxx
--- tigervnc-1.9.0.orig/vncviewer/OptionsDialog.cxx	2018-07-16 23:08:55.000000000 +0900
+++ tigervnc-1.9.0/vncviewer/OptionsDialog.cxx	2018-08-22 16:52:09.798435000 +0900
@@ -271,6 +271,7 @@
   sendPrimaryCheckbox->value(sendPrimary);
 #endif
   systemKeysCheckbox->value(fullscreenSystemKeys);
+  emulate3ButtonsCheckbox->value(emulate3Buttons);
 
   menuKeyChoice->value(0);
 
@@ -384,6 +385,7 @@
   sendPrimary.setParam(sendPrimaryCheckbox->value());
 #endif
   fullscreenSystemKeys.setParam(systemKeysCheckbox->value());
+  emulate3Buttons.setParam(emulate3ButtonsCheckbox->value());
 
   if (menuKeyChoice->value() == 0)
     menuKey.setParam("");
@@ -732,6 +734,12 @@
                                                     _("Pass system keys directly to server (full screen)")));
   ty += CHECK_HEIGHT + TIGHT_MARGIN;
 
+  emulate3ButtonsCheckbox = new Fl_Check_Button(LBLRIGHT(tx, ty,
+														 CHECK_MIN_WIDTH,
+														 CHECK_HEIGHT,
+														 _("Emulate the 3 buttons")));
+  ty += CHECK_HEIGHT + TIGHT_MARGIN;
+
   menuKeyChoice = new Fl_Choice(LBLLEFT(tx, ty, 150, CHOICE_HEIGHT, _("Menu key")));
 
   fltk_menu_add(menuKeyChoice, _("None"), 0, NULL, (void*)0, FL_MENU_DIVIDER);
diff -ru tigervnc-1.9.0.orig/vncviewer/OptionsDialog.h tigervnc-1.9.0/vncviewer/OptionsDialog.h
--- tigervnc-1.9.0.orig/vncviewer/OptionsDialog.h	2018-07-16 23:08:55.000000000 +0900
+++ tigervnc-1.9.0/vncviewer/OptionsDialog.h	2018-08-22 16:08:39.021975000 +0900
@@ -116,6 +116,7 @@
   Fl_Check_Button *sendPrimaryCheckbox;
 #endif
   Fl_Check_Button *systemKeysCheckbox;
+  Fl_Check_Button *emulate3ButtonsCheckbox;
   Fl_Choice *menuKeyChoice;
 
   /* Screen */
diff -ru tigervnc-1.9.0.orig/vncviewer/parameters.cxx tigervnc-1.9.0/vncviewer/parameters.cxx
--- tigervnc-1.9.0.orig/vncviewer/parameters.cxx	2018-07-16 23:08:55.000000000 +0900
+++ tigervnc-1.9.0/vncviewer/parameters.cxx	2018-08-22 15:55:51.771022000 +0900
@@ -146,6 +146,10 @@
                                    "Pass special keys (like Alt+Tab) directly "
                                    "to the server when in full screen mode.",
                                    true);
+BoolParameter emulate3Buttons("Emulate3Buttons",
+							  "Emulate push the left+right buttons to the "
+							  "middle button.",
+							  true);
 
 #ifndef WIN32
 StringParameter via("via", "Gateway to tunnel via", "");
@@ -182,7 +186,8 @@
 #endif
   &menuKey,
   &fullscreenSystemKeys,
-  &alertOnFatalError
+  &alertOnFatalError,
+  &emulate3Buttons
 };
 
 // Encoding Table
diff -ru tigervnc-1.9.0.orig/vncviewer/parameters.h tigervnc-1.9.0/vncviewer/parameters.h
--- tigervnc-1.9.0.orig/vncviewer/parameters.h	2018-07-16 23:08:55.000000000 +0900
+++ tigervnc-1.9.0/vncviewer/parameters.h	2018-08-22 15:56:47.984623000 +0900
@@ -62,6 +62,7 @@
 
 extern rfb::BoolParameter fullscreenSystemKeys;
 extern rfb::BoolParameter alertOnFatalError;
+extern rfb::BoolParameter emulate3Buttons;
 
 #ifndef WIN32
 extern rfb::StringParameter via;
diff -ru tigervnc-1.9.0.orig/vncviewer/UserDialog.cxx tigervnc-1.9.0/vncviewer/UserDialog.cxx
--- tigervnc-1.9.0.orig/vncviewer/UserDialog.cxx	2018-07-16 23:08:55.000000000 +0900
+++ tigervnc-1.9.0/vncviewer/UserDialog.cxx	2018-08-21 01:30:28.082912789 +0900
@@ -93,6 +93,16 @@
     return;
   }
 
+  static char *keep_username = NULL;
+  static char *keep_passwd = NULL;
+
+ if (keep_passwd) {
+    if (user)
+      *user = strDup(keep_username);
+    *password = strDup(keep_passwd);
+	return;
+ }
+ else {
   Fl_Window *win;
   Fl_Box *banner;
   Fl_Input *username;
@@ -168,15 +178,19 @@
   while (win->shown()) Fl::wait();
 
   if (ret_val == 0) {
-    if (user)
+    if (user) {
       *user = strDup(username->value());
+      keep_username = strDup(username->value());
+    }
     *password = strDup(passwd->value());
+    keep_passwd = strDup(passwd->value());
   }
 
   delete win;
 
   if (ret_val != 0)
     throw rfb::Exception(_("Authentication cancelled"));
+ }
 }
 
 bool UserDialog::showMsgBox(int flags, const char* title, const char* text)
diff -ru tigervnc-1.9.0.orig/vncviewer/Viewport.cxx tigervnc-1.9.0/vncviewer/Viewport.cxx
--- tigervnc-1.9.0.orig/vncviewer/Viewport.cxx	2018-07-16 23:08:55.000000000 +0900
+++ tigervnc-1.9.0/vncviewer/Viewport.cxx	2018-08-22 16:54:35.582411000 +0900
@@ -594,12 +594,16 @@
   case FL_MOVE:
   case FL_MOUSEWHEEL:
     buttonMask = 0;
+    if (emulate3Buttons && Fl::event_button1() && Fl::event_button3())
+      buttonMask |= 2;
+    else {
     if (Fl::event_button1())
       buttonMask |= 1;
     if (Fl::event_button2())
       buttonMask |= 2;
     if (Fl::event_button3())
       buttonMask |= 4;
+    }
 
     if (event == FL_MOUSEWHEEL) {
       wheelMask = 0;
@@ -1143,6 +1147,15 @@
     int keycode = code_map_keycode_to_qnum[xevent->xkey.keycode];
     if (keycode == 0)
         keycode = 0x100 | xevent->xkey.keycode;
+    if (!fullscreen_active() || !fullscreenSystemKeys) {
+      char key;
+      KeySym keysym;
+      XLookupString(&xevent->xkey, &str, 1, &keysym, NULL);
+      if (keysym == XK_Tab) {
+        self->handleKeyRelease(0x38); //LALT release.
+        self->handleKeyRelease(0xb8); //RALT release.
+      }
+    }
     self->handleKeyRelease(keycode);
     return 1;
   }
diff -ru tigervnc-1.9.0.orig/vncviewer/vncviewer.cxx tigervnc-1.9.0/vncviewer/vncviewer.cxx
--- tigervnc-1.9.0.orig/vncviewer/vncviewer.cxx	2018-07-16 23:08:55.000000000 +0900
+++ tigervnc-1.9.0/vncviewer/vncviewer.cxx	2018-08-21 00:29:58.562119000 +0900
@@ -573,6 +573,9 @@
 
   Socket *sock = NULL;
 
+ while (1) {
+  try {
+
 #ifndef WIN32
   /* Specifying -via and -listen together is nonsense */
   if (listenMode && strlen(via.getValueStr()) > 0) {
@@ -651,12 +654,20 @@
 #endif
   }
 
-  CConn *cc = new CConn(vncServerName, sock);
+  CConn cc(vncServerName, sock);
 
   while (!exitMainloop)
     run_mainloop();
 
-  delete cc;
+  // delete cc;
+
+  } catch (rdr::SystemException& e) {
+    sock = NULL;
+    fl_message("%s", e.str());
+    continue;
+  }
+  break;
+ }
 
   if (exitError != NULL && alertOnFatalError)
     fl_alert("%s", exitError);
diff -ru tigervnc-1.9.0.orig/vncviewer/win32.c tigervnc-1.9.0/vncviewer/win32.c
--- tigervnc-1.9.0.orig/vncviewer/win32.c	2018-07-16 23:08:55.000000000 +0900
+++ tigervnc-1.9.0/vncviewer/win32.c	2018-08-14 23:04:33.105167000 +0900
@@ -143,7 +143,11 @@
   { VK_PAUSE,               XK_Pause,       NoSymbol },
   { VK_CAPITAL,             XK_Caps_Lock,   NoSymbol },
   /* FIXME: IME keys */
+  { VK_KANA,                XK_Hiragana,    XK_Katakana },
+  { VK_KANJI,               XK_Zenkaku_Hankaku, NoSymbol },
   { VK_ESCAPE,              XK_Escape,      NoSymbol },
+  { VK_CONVERT,             XK_Henkan,      NoSymbol },
+  { VK_NONCONVERT,          XK_Muhenkan,    NoSymbol },
   { VK_PRIOR,               XK_KP_Prior,    XK_Prior },
   { VK_NEXT,                XK_KP_Next,     XK_Next },
   { VK_END,                 XK_KP_End,      XK_End },
