diff options
Diffstat (limited to 'vncviewer')
-rw-r--r-- | vncviewer/DesktopWindow.cxx | 5 | ||||
-rw-r--r-- | vncviewer/ServerDialog.cxx | 90 | ||||
-rw-r--r-- | vncviewer/ServerDialog.h | 4 | ||||
-rw-r--r-- | vncviewer/UserDialog.cxx | 3 | ||||
-rw-r--r-- | vncviewer/parameters.cxx | 32 | ||||
-rw-r--r-- | vncviewer/parameters.h | 6 |
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 |