aboutsummaryrefslogtreecommitdiffstats
path: root/vncviewer
diff options
context:
space:
mode:
Diffstat (limited to 'vncviewer')
-rw-r--r--vncviewer/DesktopWindow.cxx5
-rw-r--r--vncviewer/ServerDialog.cxx90
-rw-r--r--vncviewer/ServerDialog.h4
-rw-r--r--vncviewer/UserDialog.cxx3
-rw-r--r--vncviewer/parameters.cxx32
-rw-r--r--vncviewer/parameters.h6
6 files changed, 99 insertions, 41 deletions
diff --git a/vncviewer/DesktopWindow.cxx b/vncviewer/DesktopWindow.cxx
index 2d363781..584debd1 100644
--- a/vncviewer/DesktopWindow.cxx
+++ b/vncviewer/DesktopWindow.cxx
@@ -245,6 +245,11 @@ DesktopWindow::DesktopWindow(int w, int h, const char *name,
DesktopWindow::~DesktopWindow()
{
+ // Don't leave any dangling grabs as they are not automatically
+ // cleaned up on all platforms
+ ungrabPointer();
+ 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 --git a/vncviewer/ServerDialog.cxx b/vncviewer/ServerDialog.cxx
index d51b8713..67082a9e 100644
--- a/vncviewer/ServerDialog.cxx
+++ b/vncviewer/ServerDialog.cxx
@@ -37,9 +37,12 @@
#include <os/os.h>
#include <rfb/Exception.h>
+#include <rfb/Hostname.h>
#include <rfb/LogWriter.h>
+#include <rfb/util.h>
#include "fltk/layout.h"
+#include "fltk/util.h"
#include "ServerDialog.h"
#include "OptionsDialog.h"
#include "i18n.h"
@@ -131,13 +134,12 @@ void ServerDialog::run(const char* servername, char *newservername)
dialog.show();
try {
- size_t i;
-
dialog.loadServerHistory();
dialog.serverName->clear();
- for(i = 0; i < dialog.serverHistory.size(); ++i)
- dialog.serverName->add(dialog.serverHistory[i].c_str());
+ for (const string& entry : dialog.serverHistory)
+ fltk_menu_add(dialog.serverName->menubutton(),
+ entry.c_str(), 0, nullptr);
} catch (Exception& e) {
vlog.error("%s", e.str());
fl_alert(_("Unable to load the server history:\n\n%s"),
@@ -291,13 +293,12 @@ void ServerDialog::handleConnect(Fl_Widget* /*widget*/, void *data)
e.str());
}
+ // avoid duplicates in the history
+ dialog->serverHistory.remove(servername);
+ dialog->serverHistory.insert(dialog->serverHistory.begin(), servername);
+
try {
- vector<string>::iterator elem = std::find(dialog->serverHistory.begin(), dialog->serverHistory.end(), servername);
- // avoid duplicates in the history
- if(dialog->serverHistory.end() == elem) {
- dialog->serverHistory.insert(dialog->serverHistory.begin(), servername);
- dialog->saveServerHistory();
- }
+ dialog->saveServerHistory();
} catch (Exception& e) {
vlog.error("%s", e.str());
fl_alert(_("Unable to save the server history:\n\n%s"),
@@ -306,14 +307,42 @@ void ServerDialog::handleConnect(Fl_Widget* /*widget*/, void *data)
}
+static bool same_server(const string& a, const string& b)
+{
+ string hostA, hostB;
+ int portA, portB;
+
+#ifndef WIN32
+ if ((a.find("/") != string::npos) || (b.find("/") != string::npos))
+ return a == b;
+#endif
+
+ try {
+ getHostAndPort(a.c_str(), &hostA, &portA);
+ getHostAndPort(b.c_str(), &hostB, &portB);
+ } catch (Exception& e) {
+ return false;
+ }
+
+ if (hostA != hostB)
+ return false;
+
+ if (portA != portB)
+ return false;
+
+ return true;
+}
+
+
void ServerDialog::loadServerHistory()
{
+ list<string> rawHistory;
+
serverHistory.clear();
#ifdef _WIN32
- loadHistoryFromRegKey(serverHistory);
- return;
-#endif
+ rawHistory = loadHistoryFromRegKey();
+#else
const char* stateDir = os::getvncstatedir();
if (stateDir == nullptr)
@@ -329,8 +358,8 @@ void ServerDialog::loadServerHistory()
// no history file
return;
}
- throw Exception(_("Could not open \"%s\": %s"),
- filepath, strerror(errno));
+ std::string msg = format(_("Could not open \"%s\""), filepath);
+ throw rdr::SystemException(msg.c_str(), errno);
}
int lineNr = 0;
@@ -344,8 +373,9 @@ void ServerDialog::loadServerHistory()
break;
fclose(f);
- throw Exception(_("Failed to read line %d in file %s: %s"),
- lineNr, filepath, strerror(errno));
+ std::string msg = format(_("Failed to read line %d in "
+ "file \"%s\""), lineNr, filepath);
+ throw rdr::SystemException(msg.c_str(), errno);
}
int len = strlen(line);
@@ -368,10 +398,19 @@ void ServerDialog::loadServerHistory()
if (len == 0)
continue;
- serverHistory.push_back(line);
+ rawHistory.push_back(line);
}
fclose(f);
+#endif
+
+ // Filter out duplicates, even if they have different formats
+ for (const string& entry : rawHistory) {
+ if (std::find_if(serverHistory.begin(), serverHistory.end(),
+ [&entry](const string& s) { return same_server(s, entry); }) != serverHistory.end())
+ continue;
+ serverHistory.push_back(entry);
+ }
}
void ServerDialog::saveServerHistory()
@@ -390,13 +429,18 @@ void ServerDialog::saveServerHistory()
/* Write server history to file */
FILE* f = fopen(filepath, "w+");
- if (!f)
- throw Exception(_("Could not open \"%s\": %s"),
- filepath, strerror(errno));
+ if (!f) {
+ std::string msg = format(_("Could not open \"%s\""), filepath);
+ throw rdr::SystemException(msg.c_str(), errno);
+ }
// Save the last X elements to the config file.
- for(size_t idx=0; idx < serverHistory.size() && idx <= SERVER_HISTORY_SIZE; idx++)
- fprintf(f, "%s\n", serverHistory[idx].c_str());
+ size_t count = 0;
+ for (const string& entry : serverHistory) {
+ if (++count > SERVER_HISTORY_SIZE)
+ break;
+ fprintf(f, "%s\n", entry.c_str());
+ }
fclose(f);
}
diff --git a/vncviewer/ServerDialog.h b/vncviewer/ServerDialog.h
index a76a58cf..de330b59 100644
--- a/vncviewer/ServerDialog.h
+++ b/vncviewer/ServerDialog.h
@@ -21,7 +21,7 @@
#include <FL/Fl_Window.H>
#include <string>
-#include <vector>
+#include <list>
class Fl_Widget;
class Fl_Input_Choice;
@@ -49,7 +49,7 @@ private:
protected:
Fl_Input_Choice *serverName;
- std::vector<std::string> serverHistory;
+ std::list<std::string> serverHistory;
std::string usedDir;
};
diff --git a/vncviewer/UserDialog.cxx b/vncviewer/UserDialog.cxx
index 13821a9c..6ea67d6d 100644
--- a/vncviewer/UserDialog.cxx
+++ b/vncviewer/UserDialog.cxx
@@ -21,6 +21,7 @@
#endif
#include <assert.h>
+#include <errno.h>
#include <stdio.h>
#include <string.h>
@@ -114,7 +115,7 @@ void UserDialog::getUserPasswd(bool secure_, std::string* user,
fp = fopen(passwordFileName, "rb");
if (!fp)
- throw rfb::Exception(_("Opening password file failed"));
+ throw rdr::SystemException(_("Opening password file failed"), errno);
obfPwd.resize(fread(obfPwd.data(), 1, obfPwd.size(), fp));
fclose(fp);
diff --git a/vncviewer/parameters.cxx b/vncviewer/parameters.cxx
index 2e8ad7a1..4bbf7a7f 100644
--- a/vncviewer/parameters.cxx
+++ b/vncviewer/parameters.cxx
@@ -36,6 +36,7 @@
#include <rfb/Exception.h>
#include <rfb/LogWriter.h>
#include <rfb/SecurityClient.h>
+#include <rfb/util.h>
#include <FL/fl_utf8.h>
@@ -417,7 +418,7 @@ static void removeValue(const char* _name, HKEY* hKey) {
}
}
-void saveHistoryToRegKey(const vector<string>& serverHistory) {
+void saveHistoryToRegKey(const list<string>& serverHistory) {
HKEY hKey;
LONG res = RegCreateKeyExW(HKEY_CURRENT_USER,
L"Software\\TigerVNC\\vncviewer\\history", 0, nullptr,
@@ -432,9 +433,11 @@ void saveHistoryToRegKey(const vector<string>& serverHistory) {
char indexString[3];
try {
- while(index < serverHistory.size() && index <= SERVER_HISTORY_SIZE) {
+ for (const string& entry : serverHistory) {
+ if (index > SERVER_HISTORY_SIZE)
+ break;
snprintf(indexString, 3, "%d", index);
- setKeyString(indexString, serverHistory[index].c_str(), &hKey);
+ setKeyString(indexString, entry.c_str(), &hKey);
index++;
}
} catch (Exception& e) {
@@ -502,8 +505,9 @@ static void saveToReg(const char* servername) {
throw rdr::SystemException(_("Failed to close registry key"), res);
}
-void loadHistoryFromRegKey(vector<string>& serverHistory) {
+list<string> loadHistoryFromRegKey() {
HKEY hKey;
+ list<string> serverHistory;
LONG res = RegOpenKeyExW(HKEY_CURRENT_USER,
L"Software\\TigerVNC\\vncviewer\\history", 0,
@@ -511,7 +515,7 @@ void loadHistoryFromRegKey(vector<string>& serverHistory) {
if (res != ERROR_SUCCESS) {
if (res == ERROR_FILE_NOT_FOUND) {
// The key does not exist, defaults will be used.
- return;
+ return serverHistory;
}
throw rdr::SystemException(_("Failed to open registry key"), res);
@@ -542,6 +546,8 @@ void loadHistoryFromRegKey(vector<string>& serverHistory) {
res = RegCloseKey(hKey);
if (res != ERROR_SUCCESS)
throw rdr::SystemException(_("Failed to close registry key"), res);
+
+ return serverHistory;
}
static void getParametersFromReg(VoidParameter* parameters[],
@@ -640,9 +646,10 @@ void saveViewerParameters(const char *filename, const char *servername) {
/* Write parameters to file */
FILE* f = fopen(filepath, "w+");
- if (!f)
- throw Exception(_("Could not open \"%s\": %s"),
- filepath, strerror(errno));
+ if (!f) {
+ std::string msg = format(_("Could not open \"%s\""), filepath);
+ throw rdr::SystemException(msg.c_str(), errno);
+ }
fprintf(f, "%s\n", IDENTIFIER_STRING);
fprintf(f, "\n");
@@ -747,8 +754,8 @@ char* loadViewerParameters(const char *filename) {
if (!f) {
if (!filename)
return nullptr; // Use defaults.
- throw Exception(_("Could not open \"%s\": %s"),
- filepath, strerror(errno));
+ std::string msg = format(_("Could not open \"%s\""), filepath);
+ throw rdr::SystemException(msg.c_str(), errno);
}
int lineNr = 0;
@@ -761,8 +768,9 @@ char* loadViewerParameters(const char *filename) {
break;
fclose(f);
- throw Exception(_("Failed to read line %d in file %s: %s"),
- lineNr, filepath, strerror(errno));
+ std::string msg = format(_("Failed to read line %d in "
+ "file \"%s\""), lineNr, filepath);
+ throw rdr::SystemException(msg.c_str(), errno);
}
if (strlen(line) == (sizeof(line) - 1)) {
diff --git a/vncviewer/parameters.h b/vncviewer/parameters.h
index df7bc420..a25c932d 100644
--- a/vncviewer/parameters.h
+++ b/vncviewer/parameters.h
@@ -24,7 +24,7 @@
#include "MonitorIndicesParameter.h"
#ifdef _WIN32
-#include <vector>
+#include <list>
#include <string>
#endif
@@ -84,8 +84,8 @@ void saveViewerParameters(const char *filename, const char *servername=nullptr);
char* loadViewerParameters(const char *filename);
#ifdef _WIN32
-void loadHistoryFromRegKey(std::vector<std::string>& serverHistory);
-void saveHistoryToRegKey(const std::vector<std::string>& serverHistory);
+std::list<std::string> loadHistoryFromRegKey();
+void saveHistoryToRegKey(const std::list<std::string>& serverHistory);
#endif
#endif