...
 
Commits (74)
......@@ -83,11 +83,16 @@ appimage:build:
artifacts:
name: "Remmina-x86_64.AppImage"
expose_as: "Download AppImage"
paths:
- $BUILD_FOLDER/Remmina-x86_64.AppImage
expire_in: 7 days
only:
refs:
- web
- merge_requests
- tags
- web
- schedules
flatpak:test:
image: remmina/ubuntu:18.04
......@@ -108,7 +113,7 @@ flatpak:test:
expose_as: "Download flatpak from the flatpak artifact folder"
paths:
- flatpak/$BUNDLE
expire_in: 10 days
expire_in: 7 days
cache:
paths:
- flatpak/.flatpak-builder/cache
......
# Changelog
## v1.4.7
[full changelog](https://gitlab.com/Remmina/Remmina/compare/v1.4.6...v1.4.7)
* Allow compilation with libwinpr (freerdp) pre commit 8c5d96784d [!2083](https://gitlab.com/Remmina/Remmina/merge_requests/2083) *@giox069*
* Bug fixing v1.4.6 [!2082](https://gitlab.com/Remmina/Remmina/merge_requests/2082) *@antenore*
* Spelling: Automatic negotiation [!2084](https://gitlab.com/Remmina/Remmina/merge_requests/2084) *@kingu*
* Spelling: GNOME Shell, opt-in desc, comments [!2085](https://gitlab.com/Remmina/Remmina/merge_requests/2085) *@kingu*
* Memory leaks fixes [!2086](https://gitlab.com/Remmina/Remmina/merge_requests/2086) *@antenore*
* RDP: Replacing deprecated freerdp function VeryfyCertificate [!2087](https://gitlab.com/Remmina/Remmina/merge_requests/2087) *@antenore*
## v1.4.6
[full changelog](https://gitlab.com/Remmina/Remmina/compare/v1.4.5...v1.4.6)
......
......@@ -212,7 +212,7 @@ endif()
set(WITH_LIBRARY_VERSIONING "ON")
set(REMMINA_VERSION_MAJOR "1")
set(REMMINA_VERSION_MINOR "4")
set(REMMINA_VERSION_REVISION "6")
set(REMMINA_VERSION_REVISION "7")
#set(REMMINA_VERSION_SUFFIX "1")
#set(REMMINA_VERSION "${REMMINA_VERSION_MAJOR}.${REMMINA_VERSION_MINOR}.${REMMINA_VERSION_REVISION}.${REMMINA_VERSION_SUFFIX}")
set(REMMINA_VERSION "${REMMINA_VERSION_MAJOR}.${REMMINA_VERSION_MINOR}.${REMMINA_VERSION_REVISION}")
......
......@@ -38,7 +38,7 @@ PROJECT_NAME = "Remmina - The GTK+ Remote Desktop Client"
# could be handy for archiving the generated documentation or if some version
# control system is used.
PROJECT_NUMBER = v1.4.6
PROJECT_NUMBER = v1.4.7
# Using the PROJECT_BRIEF tag one can provide an optional one line description
# for a project that appears at the top of each page and should give viewer a
......
......@@ -3,12 +3,12 @@
.Os
.Sh NAME
.Nm gnome-session-remmina
.Nd Gnome Shell session script for Remmina
.Nd GNOME Shell session script for Remmina
.Sh DESCRIPTION
.Nm
This script is part of the Remmina kiosk mode.
If you have a freedesktop compliant Login Manager, a Remmina Kiosk mode will be
added in the list of the available sessions.
If you have a freedesktop compliant Login Manager, a Remmina kiosk mode will be
added in the list of available sessions.
.Sh SEE ALSO
.Xr remmina 1
.Sh AUTHORS
......
......@@ -16,7 +16,7 @@
<summary xml:lang="fr">Client de contrôle de bureau à distance</summary>
<content_rating type="oars-1.1" />
<releases>
<release version="1.4.6" date="2020-06-09"/>
<release version="1.4.7" date="2020-06-19"/>
</releases>
<description>
<p>
......
......@@ -3,19 +3,19 @@
.Os
.Sh NAME
.Nm remmina-gnome
.Nd Script file to start common Gnome Shell interfaces
.Nd Script file to start common GNOME Shell interfaces
.Sh DESCRIPTION
.Nm
This script is part of the Remmina kiosk mode.
If you have a freedesktop compliant Login Manager, a Remmina Kiosk mode will be
added in the list of the available sessions.
If you have a freedesktop compliant Login Manager, a Remmina kiosk mode will be
added in the list of available sessions.
.Sh USAGE
Ports from the range 5901-5999 map directly to VNC displays numbered 1-99.
Ports from the 5901-5999 range map directly to VNC displays numbered 1-99.
For example, to connect to server at 192.168.0.1 to the screen :1, in the
address field we simply write the IP address 192.168.0.1.
For example, to connect to server at 192.168.0.1 to the screen :1,
write the IP address 192.168.0.1 in the address field.
To connect to display number :2 we may refer to the display number by writing
To connect to display number :2, refer to the display number by writing
the address as 192.168.0.1:2. Another way is to refer to the port by specifying
the address as 192.168.0.1:5902.
.Sh SEE ALSO
......
......@@ -35,9 +35,9 @@
<script type="text/javascript">
new Chartkick.BarChart(
"multiple-bar-stacked", [
{ name: "Translated", data: [["ar.po",230],["ast.po",163],["bg.po",243],["bn.po",12],["br.po",0],["bs.po",163],["ca.po",671],["[email protected]",671],["cs.po",686],["da.po",684],["de.po",686],["el.po",186],["en_AU.po",666],["en_GB.po",666],["eo.po",0],["es.po",681],["es_VE.po",284],["et.po",102],["eu.po",240],["fa.po",86],["fi.po",661],["fr.po",686],["gl.po",172],["he.po",686],["hi.po",0],["hr.po",686],["hu.po",665],["id.po",680],["ie.po",269],["it.po",686],["ja.po",676],["kk.po",53],["km.po",55],["kn.po",11],["ko.po",581],["lt.po",163],["lv.po",163],["mr.po",15],["ms.po",165],["my.po",13],["nb.po",498],["nl.po",339],["oc.po",164],["pl.po",686],["pt.po",318],["pt_BR.po",686],["pt_PT.po",262],["ro.po",170],["ru.po",681],["shn.po",0],["si.po",36],["sk.po",594],["sl.po",165],["sq.po",86],["sr.po",114],["sv.po",307],["te.po",14],["th.po",89],["tr.po",686],["ug.po",160],["uk.po",686],["[email protected]",245],["zh_CN.po",560],["zh_TW.po",452]] },
{ name: "Fuzzy", data: [["ar.po",19],["ast.po",120],["bg.po",91],["bn.po",12],["br.po",0],["bs.po",120],["ca.po",10],["[email protected]",10],["cs.po",0],["da.po",1],["de.po",0],["el.po",121],["en_AU.po",10],["en_GB.po",10],["eo.po",0],["es.po",1],["es_VE.po",190],["et.po",61],["eu.po",4],["fa.po",9],["fi.po",13],["fr.po",0],["gl.po",120],["he.po",0],["hi.po",0],["hr.po",0],["hu.po",10],["id.po",1],["ie.po",117],["it.po",0],["ja.po",0],["kk.po",81],["km.po",37],["kn.po",4],["ko.po",63],["lt.po",120],["lv.po",120],["mr.po",4],["ms.po",120],["my.po",12],["nb.po",187],["nl.po",73],["oc.po",119],["pl.po",0],["pt.po",79],["pt_BR.po",0],["pt_PT.po",104],["ro.po",120],["ru.po",1],["shn.po",0],["si.po",17],["sk.po",51],["sl.po",120],["sq.po",50],["sr.po",93],["sv.po",358],["te.po",3],["th.po",93],["tr.po",0],["ug.po",123],["uk.po",0],["[email protected]",144],["zh_CN.po",76],["zh_TW.po",169]] },
{ name: "Untranslated", data: [["ar.po",437],["ast.po",403],["bg.po",352],["bn.po",662],["br.po",686],["bs.po",403],["ca.po",5],["[email protected]",5],["cs.po",0],["da.po",1],["de.po",0],["el.po",379],["en_AU.po",10],["en_GB.po",10],["eo.po",686],["es.po",4],["es_VE.po",212],["et.po",523],["eu.po",442],["fa.po",591],["fi.po",12],["fr.po",0],["gl.po",394],["he.po",0],["hi.po",686],["hr.po",0],["hu.po",11],["id.po",5],["ie.po",300],["it.po",0],["ja.po",10],["kk.po",552],["km.po",594],["kn.po",671],["ko.po",42],["lt.po",403],["lv.po",403],["mr.po",667],["ms.po",401],["my.po",661],["nb.po",1],["nl.po",274],["oc.po",403],["pl.po",0],["pt.po",289],["pt_BR.po",0],["pt_PT.po",320],["ro.po",396],["ru.po",4],["shn.po",686],["si.po",633],["sk.po",41],["sl.po",401],["sq.po",550],["sr.po",479],["sv.po",21],["te.po",669],["th.po",504],["tr.po",0],["ug.po",403],["uk.po",0],["[email protected]",297],["zh_CN.po",50],["zh_TW.po",65]] }
{ name: "Translated", data: [["ar.po",230],["ast.po",163],["bg.po",243],["bn.po",12],["br.po",0],["bs.po",163],["ca.po",670],["[email protected]",670],["ckb.po",0],["cs.po",685],["da.po",686],["de.po",686],["el.po",186],["en_AU.po",665],["en_GB.po",665],["eo.po",0],["es.po",686],["es_VE.po",284],["et.po",102],["eu.po",240],["fa.po",90],["fi.po",660],["fr.po",685],["gl.po",172],["he.po",686],["hi.po",0],["hr.po",686],["hu.po",664],["id.po",680],["ie.po",269],["it.po",685],["ja.po",676],["kk.po",53],["km.po",55],["kn.po",11],["ko.po",581],["lt.po",163],["lv.po",163],["mr.po",15],["ms.po",165],["my.po",13],["nb.po",503],["nl.po",338],["oc.po",164],["pl.po",686],["pt.po",318],["pt_BR.po",686],["pt_PT.po",262],["ro.po",170],["ru.po",685],["shn.po",0],["si.po",36],["sk.po",594],["sl.po",165],["sq.po",86],["sr.po",114],["sv.po",307],["te.po",14],["th.po",89],["tr.po",686],["ug.po",160],["uk.po",686],["[email protected]",245],["zh_CN.po",560],["zh_TW.po",452]] },
{ name: "Fuzzy", data: [["ar.po",19],["ast.po",120],["bg.po",91],["bn.po",12],["br.po",0],["bs.po",120],["ca.po",11],["[email protected]",11],["ckb.po",0],["cs.po",1],["da.po",0],["de.po",0],["el.po",122],["en_AU.po",11],["en_GB.po",11],["eo.po",0],["es.po",0],["es_VE.po",191],["et.po",61],["eu.po",4],["fa.po",7],["fi.po",14],["fr.po",1],["gl.po",120],["he.po",0],["hi.po",0],["hr.po",0],["hu.po",11],["id.po",1],["ie.po",118],["it.po",1],["ja.po",0],["kk.po",81],["km.po",37],["kn.po",4],["ko.po",63],["lt.po",120],["lv.po",120],["mr.po",4],["ms.po",120],["my.po",12],["nb.po",183],["nl.po",74],["oc.po",119],["pl.po",0],["pt.po",79],["pt_BR.po",0],["pt_PT.po",104],["ro.po",121],["ru.po",1],["shn.po",0],["si.po",17],["sk.po",51],["sl.po",120],["sq.po",50],["sr.po",94],["sv.po",358],["te.po",3],["th.po",93],["tr.po",0],["ug.po",123],["uk.po",0],["[email protected]",144],["zh_CN.po",76],["zh_TW.po",169]] },
{ name: "Untranslated", data: [["ar.po",437],["ast.po",403],["bg.po",352],["bn.po",662],["br.po",686],["bs.po",403],["ca.po",5],["[email protected]",5],["ckb.po",686],["cs.po",0],["da.po",0],["de.po",0],["el.po",378],["en_AU.po",10],["en_GB.po",10],["eo.po",686],["es.po",0],["es_VE.po",211],["et.po",523],["eu.po",442],["fa.po",589],["fi.po",12],["fr.po",0],["gl.po",394],["he.po",0],["hi.po",686],["hr.po",0],["hu.po",11],["id.po",5],["ie.po",299],["it.po",0],["ja.po",10],["kk.po",552],["km.po",594],["kn.po",671],["ko.po",42],["lt.po",403],["lv.po",403],["mr.po",667],["ms.po",401],["my.po",661],["nb.po",0],["nl.po",274],["oc.po",403],["pl.po",0],["pt.po",289],["pt_BR.po",0],["pt_PT.po",320],["ro.po",395],["ru.po",0],["shn.po",686],["si.po",633],["sk.po",41],["sl.po",401],["sq.po",550],["sr.po",478],["sv.po",21],["te.po",669],["th.po",504],["tr.po",0],["ug.po",403],["uk.po",0],["[email protected]",297],["zh_CN.po",50],["zh_TW.po",65]] }
],
{ max: 686, stacked: true }
);
......
......@@ -58,7 +58,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
<property name="can_focus">False</property>
<property name="icon_name">org.remmina.Remmina</property>
<signal name="delete-event" handler="remmina_main_on_delete_event" swapped="no"/>
<signal name="destroy" handler="remmina_main_destroy" swapped="no"/>
<signal name="destroy" handler="remmina_main_on_destroy_event" swapped="no"/>
<signal name="drag-data-received" handler="remmina_main_on_drag_data_received" swapped="no"/>
<signal name="show" handler="remmina_main_on_show" swapped="no"/>
<signal name="window-state-event" handler="remmina_main_on_window_state_event" swapped="no"/>
......
......@@ -346,6 +346,7 @@ static gboolean remmina_rdp_event_delayed_monitor_layout(RemminaProtocolWidget*
rfi->delayed_monitor_layout_handler = 0;
gint gpwidth, gpheight, prevwidth, prevheight;
REMMINA_PLUGIN_DEBUG("Sending preconfigured monitor layout");
if (rfi->dispcontext && rfi->dispcontext->SendMonitorLayout) {
remmina_rdp_settings_get_orientation_scale_prefs(&desktopOrientation, &desktopScaleFactor, &deviceScaleFactor);
gtk_widget_get_allocation(GTK_WIDGET(gp), &a);
......
......@@ -50,8 +50,9 @@ void remmina_rdp_monitor_get (rfContext *rfi, gchar **monitorids, guint32 *maxwi
GdkMonitor *monitor;
GdkDisplay *display = gdk_display_get_default ();
GdkRectangle geometry;
GdkRectangle destgeom;
GdkRectangle geometry = { 0, 0, 0, 0 };
GdkRectangle tempgeom = { 0, 0, 0, 0 };
GdkRectangle destgeom = { 0, 0, 0, 0 };
n_monitors = gdk_display_get_n_monitors(display);
......@@ -103,10 +104,9 @@ void remmina_rdp_monitor_get (rfContext *rfi, gchar **monitorids, guint32 *maxwi
*maxheight = MIN(*maxheight, geometry.height);
g_debug("maxw and maxh: %ux%u", *maxwidth, *maxheight);
#endif
if (destgeom.width && destgeom.height) {
gdk_rectangle_union(&geometry, &destgeom, &destgeom);
} else
destgeom = geometry;
gdk_rectangle_union(&tempgeom, &geometry, &destgeom);
//tempgeom = destgeom;
memcpy(&tempgeom, &destgeom, sizeof tempgeom);
count++;
}
rfi->settings->MonitorCount = count;
......
......@@ -93,6 +93,103 @@ static char remmina_rdp_plugin_default_drive_name[] = "RemminaDisk";
static BOOL gfx_h264_available = FALSE;
/* Compatibility: these functions have been introduced with https://github.com/FreeRDP/FreeRDP/commit/8c5d96784d
* and are missing on older FreeRDP, so we add them here.
* They should be removed from here after all distributed versions of FreeRDP (libwinpr) will have
* CommandLineParseCommaSeparatedValuesEx() onboard.
*
* (C) Copyright goes to the FreeRDP authors.
*/
static char** remmina_rdp_CommandLineParseCommaSeparatedValuesEx(const char* name, const char* list, size_t* count)
{
char** p;
char* str;
size_t nArgs;
size_t index;
size_t nCommas;
size_t prefix, len;
nCommas = 0;
if (count == NULL)
return NULL;
*count = 0;
if (!list)
{
if (name)
{
size_t len = strlen(name);
p = (char**)calloc(2UL + len, sizeof(char*));
if (p)
{
char* dst = (char*)&p[1];
p[0] = dst;
sprintf_s(dst, len + 1, "%s", name);
*count = 1;
return p;
}
}
return NULL;
}
{
const char* it = list;
while ((it = strchr(it, ',')) != NULL)
{
it++;
nCommas++;
}
}
nArgs = nCommas + 1;
if (name)
nArgs++;
prefix = (nArgs + 1UL) * sizeof(char*);
len = strlen(list);
p = (char**)calloc(len + prefix + 1, sizeof(char*));
if (!p)
return NULL;
str = &((char*)p)[prefix];
memcpy(str, list, len);
if (name)
p[0] = (char*)name;
for (index = name ? 1 : 0; index < nArgs; index++)
{
char* comma = strchr(str, ',');
p[index] = str;
if (comma)
{
str = comma + 1;
*comma = '\0';
}
}
*count = nArgs;
return p;
}
static char** remmina_rdp_CommandLineParseCommaSeparatedValues(const char* list, size_t* count)
{
return remmina_rdp_CommandLineParseCommaSeparatedValuesEx(NULL, list, count);
}
/*
* End of CommandLineParseCommaSeparatedValuesEx() compatibility and copyright
*/
static BOOL rf_process_event_queue(RemminaProtocolWidget *gp)
{
TRACE_CALL(__func__);
......@@ -155,6 +252,7 @@ static BOOL rf_process_event_queue(RemminaProtocolWidget *gp)
if (!dcml)
break;
for (gint i = 0; i < rfi->settings->MonitorCount; i++) {
REMMINA_PLUGIN_DEBUG ("Sending diplay layout n° %d", i);
dcml[i].Flags = (rfi->settings->MonitorDefArray[i].is_primary ? DISPLAY_CONTROL_MONITOR_PRIMARY :0);
dcml[i].Left = rfi->settings->MonitorDefArray[i].x;
dcml[i].Width = rfi->settings->MonitorDefArray[i].width;
......@@ -680,6 +778,25 @@ static BOOL remmina_rdp_gw_authenticate(freerdp *instance, char **username, char
return True;
}
static DWORD remmina_rdp_verify_certificate_ex(freerdp* instance, const char* host, UINT16 port,
const char* common_name, const char* subject,
const char* issuer, const char* fingerprint, DWORD flags)
{
TRACE_CALL(__func__);
gint status;
rfContext *rfi;
RemminaProtocolWidget *gp;
rfi = (rfContext *)instance->context;
gp = rfi->protocol_widget;
status = remmina_plugin_service->protocol_plugin_init_certificate(gp, subject, issuer, fingerprint);
if (status == GTK_RESPONSE_OK)
return 1;
return 0;
}
static DWORD remmina_rdp_verify_certificate(freerdp *instance, const char *common_name, const char *subject,
const char *issuer, const char *fingerprint, BOOL host_mismatch)
......@@ -699,6 +816,29 @@ static DWORD remmina_rdp_verify_certificate(freerdp *instance, const char *commo
return 0;
}
static DWORD remmina_rdp_verify_changed_certificate_ex(freerdp* instance, const char* host, UINT16 port,
const char* common_name, const char* subject,
const char* issuer, const char* fingerprint,
const char* old_subject, const char* old_issuer,
const char* old_fingerprint, DWORD flags)
{
TRACE_CALL(__func__);
gint status;
rfContext *rfi;
RemminaProtocolWidget *gp;
rfi = (rfContext *)instance->context;
gp = rfi->protocol_widget;
status = remmina_plugin_service->protocol_plugin_changed_certificate(gp, subject, issuer, fingerprint, old_fingerprint);
if (status == GTK_RESPONSE_OK)
return 1;
return 0;
}
static DWORD remmina_rdp_verify_changed_certificate(freerdp *instance,
const char *common_name, const char *subject, const char *issuer,
const char *new_fingerprint, const char *old_subject, const char *old_issuer, const char *old_fingerprint)
......@@ -914,7 +1054,6 @@ int remmina_rdp_set_printers(void *user_data, unsigned flags, cups_dest_t *dest)
* dest->options);
* @endcode
*/
const char *model = NULL;
RemminaFile *remminafile = remmina_plugin_service->protocol_plugin_get_file(gp);
const gchar *s = remmina_plugin_service->file_get_string(remminafile, "printer_overrides");
......@@ -954,8 +1093,7 @@ int remmina_rdp_set_printers(void *user_data, unsigned flags, cups_dest_t *dest)
}
} else {
/* We set to a default driver*/
model = _strdup("MS Publisher Imagesetter");
printer->DriverName = _strdup(model);
printer->DriverName = _strdup("MS Publisher Imagesetter");
}
REMMINA_PLUGIN_DEBUG("Printer Driver: %s", printer->DriverName);
......@@ -1358,7 +1496,7 @@ static gboolean remmina_rdp_main(RemminaProtocolWidget *gp)
char **p;
size_t count;
p = CommandLineParseCommaSeparatedValuesEx("audin", g_strdup(cs), &count);
p = remmina_rdp_CommandLineParseCommaSeparatedValuesEx("audin", g_strdup(cs), &count);
freerdp_client_add_dynamic_channel(rfi->settings, count, p);
rfi->settings->AudioCapture = TRUE;
......@@ -1369,7 +1507,7 @@ static gboolean remmina_rdp_main(RemminaProtocolWidget *gp)
if (cs != NULL && cs[0] != '\0') {
char **p;
size_t count;
p = CommandLineParseCommaSeparatedValuesEx("urbdrc", g_strdup(cs), &count);
p = remmina_rdp_CommandLineParseCommaSeparatedValuesEx("urbdrc", g_strdup(cs), &count);
freerdp_client_add_dynamic_channel(rfi->settings, count, p);
g_free(p);
}
......@@ -1378,7 +1516,7 @@ static gboolean remmina_rdp_main(RemminaProtocolWidget *gp)
if (cs != NULL && cs[0] != '\0') {
char **p;
size_t count;
p = CommandLineParseCommaSeparatedValues(g_strdup(cs), &count);
p = remmina_rdp_CommandLineParseCommaSeparatedValues(g_strdup(cs), &count);
freerdp_client_add_static_channel(rfi->settings, count, p);
g_free(p);
}
......@@ -1387,7 +1525,7 @@ static gboolean remmina_rdp_main(RemminaProtocolWidget *gp)
if (cs != NULL && cs[0] != '\0') {
char **p;
size_t count;
p = CommandLineParseCommaSeparatedValues(g_strdup(cs), &count);
p = remmina_rdp_CommandLineParseCommaSeparatedValues(g_strdup(cs), &count);
freerdp_client_add_dynamic_channel(rfi->settings, count, p);
g_free(p);
}
......@@ -1815,8 +1953,10 @@ static void remmina_rdp_init(RemminaProtocolWidget *gp)
instance->PostDisconnect = remmina_rdp_post_disconnect;
instance->Authenticate = remmina_rdp_authenticate;
instance->GatewayAuthenticate = remmina_rdp_gw_authenticate;
instance->VerifyCertificate = remmina_rdp_verify_certificate;
instance->VerifyChangedCertificate = remmina_rdp_verify_changed_certificate;
//instance->VerifyCertificate = remmina_rdp_verify_certificate;
instance->VerifyCertificateEx = remmina_rdp_verify_certificate_ex;
//instance->VerifyChangedCertificate = remmina_rdp_verify_changed_certificate;
instance->VerifyChangedCertificateEx = remmina_rdp_verify_changed_certificate_ex;
instance->ContextSize = sizeof(rfContext);
freerdp_context_new(instance);
......@@ -2051,7 +2191,7 @@ static gpointer sound_list[] =
/* Array of key/value pairs for security */
static gpointer security_list[] =
{
"", N_("Automatically negotiate"),
"", N_("Automatic negotiation"),
"nla", N_("NLA protocol security"),
"tls", N_("TLS protocol security"),
"rdp", N_("RDP protocol security"),
......@@ -2108,7 +2248,7 @@ static const RemminaProtocolSetting remmina_rdp_basic_settings[] =
{ REMMINA_PROTOCOL_SETTING_TYPE_PASSWORD, "password", N_("Password"), FALSE, NULL, NULL },
{ REMMINA_PROTOCOL_SETTING_TYPE_TEXT, "domain", N_("Domain"), FALSE, NULL, NULL },
{ REMMINA_PROTOCOL_SETTING_TYPE_CHECK, "multimon", N_("Enable multi monitor"), FALSE, NULL, NULL },
{ REMMINA_PROTOCOL_SETTING_TYPE_TEXT, "monitorids", N_("Monitor ID list"), FALSE, NULL, N_("Comma separated list of monitor IDs (0,1,2,4)") },
{ REMMINA_PROTOCOL_SETTING_TYPE_TEXT, "monitorids", N_("Monitor ID list"), FALSE, NULL, N_("Comma separated list of monitor IDs (0,1,2,4)") },
{ REMMINA_PROTOCOL_SETTING_TYPE_RESOLUTION, "resolution", NULL, FALSE, NULL, NULL },
{ REMMINA_PROTOCOL_SETTING_TYPE_SELECT, "colordepth", N_("Colour depth"), FALSE, colordepth_list, NULL },
{ REMMINA_PROTOCOL_SETTING_TYPE_FOLDER, "sharefolder", N_("Share folder"), FALSE, NULL, NULL },
......
......@@ -42,17 +42,18 @@
#include <gdk/gdkx.h>
static RemminaPluginService *remmina_plugin_service = NULL;
#define REMMINA_PLUGIN_DEBUG(fmt, ...) remmina_plugin_service->_remmina_debug(__func__, fmt, ##__VA_ARGS__)
static void remmina_plugin_tool_init(RemminaProtocolWidget *gp)
{
TRACE_CALL(__func__);
remmina_plugin_service->_debug("[%s] Plugin init", PLUGIN_NAME);
REMMINA_PLUGIN_DEBUG("[%s] Plugin init", PLUGIN_NAME);
}
static gboolean remmina_plugin_tool_open_connection(RemminaProtocolWidget *gp)
{
TRACE_CALL(__func__);
remmina_plugin_service->_debug("[%s] Plugin open connection", PLUGIN_NAME);
REMMINA_PLUGIN_DEBUG("[%s] Plugin open connection", PLUGIN_NAME);
GtkDialog *dialog;
dialog = GTK_DIALOG(gtk_message_dialog_new(NULL, GTK_DIALOG_MODAL | GTK_DIALOG_USE_HEADER_BAR,
......@@ -65,7 +66,7 @@ static gboolean remmina_plugin_tool_open_connection(RemminaProtocolWidget *gp)
static gboolean remmina_plugin_tool_close_connection(RemminaProtocolWidget *gp)
{
TRACE_CALL(__func__);
remmina_plugin_service->_debug("[%s] Plugin close connection", PLUGIN_NAME);
REMMINA_PLUGIN_DEBUG("[%s] Plugin close connection", PLUGIN_NAME);
remmina_plugin_service->protocol_plugin_emit_signal(gp, "disconnect");
return FALSE;
}
......
......@@ -62,3 +62,4 @@ es_VE
eo
fa
br
ckb
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
......@@ -39,6 +39,7 @@ apps:
- ssh-keys
- ssh-public-keys
- removable-media
- unity7
winpr-makecert:
command: winpr-makecert
......
......@@ -2173,6 +2173,7 @@ static void rcw_multimon_action_monitor (GSimpleAction *action, GVariant *varian
g_debug ("Loading monitor list from saved profile");
cnnwin->priv->monitors = g_strdup(remmina_file_get_string(cnnobj->remmina_file, "monitors"));
//if (remmina_file_get_int(cnnobj->remmina_file, "multimon", 0) == 1)
//cnnwin->priv->monitors = g_strdup(remmina_pref.monitors);
g_debug ("Monitor list is %s", cnnwin->priv->monitors);
......@@ -2978,7 +2979,7 @@ static gboolean rcw_on_configure(GtkWidget *widget, GdkEventConfigure *event,
if (gtk_widget_get_window(GTK_WIDGET(cnnwin))
&& cnnwin->priv->view_mode == SCROLLED_WINDOW_MODE)
/* Under Gnome shell we receive this configure_event BEFORE a window
/* Under GNOME Shell we receive this configure_event BEFORE a window
* is really unmaximized, so we must read its new state and dimensions
* later, not now */
cnnwin->priv->acs_eventsourceid = g_timeout_add(500, rcw_after_configure_scrolled, cnnobj);
......@@ -3163,6 +3164,7 @@ static gboolean rcw_map_event_fullscreen(GtkWidget *widget, GdkEvent *event, gpo
target_monitor);
} else {
REMMINA_DEBUG("Fullscreen managed by WM or by the user, as per settings");
gdk_window_set_fullscreen_mode (gtk_widget_get_window(widget), GDK_FULLSCREEN_ON_ALL_MONITORS);
gtk_window_fullscreen(GTK_WINDOW(widget));
}
#else
......@@ -3992,7 +3994,7 @@ static gboolean rcw_hostkey_func(RemminaProtocolWidget *gp, guint keyval, gboole
* priv is now invalid. So we can no longer use priv here */
cnnobj->cnnwin->priv->hostkey_activated = FALSE;
/* Trap all key presses when hostkey is pressed */
/* Trap all keypresses when hostkey is pressed */
return TRUE;
}
......@@ -4060,7 +4062,7 @@ void rco_on_connect(RemminaProtocolWidget *gp, RemminaConnectionObject *cnnobj)
if (remmina_pref.periodic_usage_stats_permitted) {
REMMINA_DEBUG("Stats are allowed, we save the last successful connection date");
remmina_file_set_string(cnnobj->remmina_file, "last_success", last_success);
REMMINA_DEBUG("Last connection was made on %s.", last_success);
REMMINA_DEBUG("Last connection made on %s.", last_success);
}
REMMINA_DEBUG("Saving credentials");
......@@ -4195,7 +4197,7 @@ static void rpw_size_allocated_on_connection(GtkWidget *w, GdkRectangle *allocat
/* Disconnect signal handler to avoid to be called again after a normal resize */
g_signal_handler_disconnect(w, gp->cnnobj->deferred_open_size_allocate_handler);
/* Allow extra 100ms for size allocation (do we really need it?) */
/* Allow extra 100 ms for size allocation (do we really need it?) */
g_timeout_add(100, open_connection_last_stage, gp);
return;
......@@ -4241,7 +4243,7 @@ GtkWidget *rcw_open_from_file_full(RemminaFile *remminafile, GCallback disconnec
GTK_MESSAGE_ERROR, GTK_BUTTONS_CLOSE, "%s", msg);
gtk_dialog_run(GTK_DIALOG(dialog));
gtk_widget_destroy(dialog);
/* We should destroy cnnobj->proto and cnnobj now… ToDo: fix this leak */
/* We should destroy cnnobj->proto and cnnobj now… TODO: Fix this leak */
return NULL;
}
......@@ -4342,7 +4344,7 @@ GtkWidget *rcw_open_from_file_full(RemminaFile *remminafile, GCallback disconnec
if (remmina_protocol_widget_has_error((RemminaProtocolWidget *)cnnobj->proto)) {
printf("OK, an error occurred in initializing the protocol plugin before connecting. The error is %s.\n"
"ToDo: Put this string as error to show", remmina_protocol_widget_get_error_message((RemminaProtocolWidget *)cnnobj->proto));
"TODO: Put this string as an error to show", remmina_protocol_widget_get_error_message((RemminaProtocolWidget *)cnnobj->proto));
return cnnobj->proto;
}
......
......@@ -98,6 +98,9 @@ void remmina_exec_exitremmina()
/* Remove systray menu */
remmina_icon_destroy();
/* close/destroy main window struct and window */
remmina_main_destroy();
/* Exit from Remmina */
g_application_quit(g_application_get_default());
}
......
......@@ -410,6 +410,7 @@ remmina_file_load(const gchar *filename)
upgrade_sshkeys_202001(remminafile);
}
g_strfreev(keys);
} else {
REMMINA_DEBUG ("Unable to load remmina profile file %s: cannot find key name= in section remmina.\n", filename);
remminafile = NULL;
......
......@@ -278,6 +278,7 @@ GNode *remmina_file_manager_get_group_tree(void)
TRACE_CALL(__func__);
gchar filename[MAX_PATH_LEN];
GDir *dir;
g_autofree gchar *datadir = NULL;
const gchar *name;
RemminaFile *remminafile;
const gchar *group;
......@@ -285,14 +286,15 @@ GNode *remmina_file_manager_get_group_tree(void)
root = g_node_new(NULL);
dir = g_dir_open(remmina_file_get_datadir(), 0, NULL);
datadir = g_strdup(remmina_file_get_datadir());
dir = g_dir_open(datadir, 0, NULL);
if (dir == NULL)
return root;
while ((name = g_dir_read_name(dir)) != NULL) {
if (!g_str_has_suffix(name, ".remmina"))
continue;
g_snprintf(filename, MAX_PATH_LEN, "%s/%s", remmina_file_get_datadir(), name);
g_snprintf(filename, MAX_PATH_LEN, "%s/%s", datadir, name);
remminafile = remmina_file_load(filename);
if (remminafile) {
group = remmina_file_get_string(remminafile, "group");
......
......@@ -381,7 +381,7 @@ gboolean remmina_icon_is_available(void)
if (remmina_pref.disable_tray_icon)
return FALSE;
/* Special treatmen under Gnome Shell */
/* Special treatmen under GNOME Shell */
if ((gsversion = remmina_sysinfo_get_gnome_shell_version()) != NULL) {
if (sscanf(gsversion, "%u.%u", &gsv_maj, &gsv_min) == 2)
gsv_seq = gsv_maj << 16 | gsv_min << 8;
......@@ -391,17 +391,17 @@ gboolean remmina_icon_is_available(void)
gshell_has_legacyTray = FALSE;
if (gsv_seq >= 0x031000 && gsv_seq <= 0x031800)
/* Gnome shell from 3.16 to 3.24, Status Icon (GtkStatusIcon) is visible on the drawer
/* GNOME Shell from 3.16 to 3.24, Status Icon (GtkStatusIcon) is visible in the drawer
* at the bottom left of the screen */
gshell_has_legacyTray = TRUE;
#ifdef HAVE_LIBAPPINDICATOR
/** Gnome Shell with compiled in LIBAPPINDICATOR:
/** GNOME Shell with compiled in LIBAPPINDICATOR:
* ensure have also a working appindicator extension available.
*/
if (remmina_sysinfo_is_appindicator_available())
/* No libappindicator extension for gnome shell, no remmina_icon */
/* No libappindicator extension for GNOME Shell, no remmina_icon */
return TRUE;
else if (gshell_has_legacyTray)
return TRUE;
......@@ -409,12 +409,12 @@ gboolean remmina_icon_is_available(void)
return FALSE;
#endif
/* Gnome Shell without LIBAPPINDICATOR */
/* GNOME Shell without LIBAPPINDICATOR */
if (gshell_has_legacyTray)
return TRUE;
else
/* Gnome shell < 3.16, Status Icon (GtkStatusIcon) is hidden
* on the message tray */
/* GNOME Shell < 3.16, Status Icon (GtkStatusIcon) is hidden
* in the message tray */
return FALSE;
}
return TRUE;
......@@ -441,9 +441,9 @@ void remmina_icon_init(void)
if (sni_supported) {
strcat(msg, "your desktop does support it");
#ifdef HAVE_LIBAPPINDICATOR
strcat(msg, " and libappindicator is compiled in remmina. Good!");
strcat(msg, " and libappindicator is compiled in Remmina. Good.");
#else
strcat(msg, ", but you did not compile remmina with cmake’s -DWITH_APPINDICATOR=on");
strcat(msg, ", but you did not compile Remmina with CMake’s -DWITH_APPINDICATOR=on");
#endif
} else {
#ifdef HAVE_LIBAPPINDICATOR
......@@ -457,7 +457,7 @@ void remmina_icon_init(void)
remmina_icon.gsversion = remmina_sysinfo_get_gnome_shell_version();
if (remmina_icon.gsversion != NULL)
printf("Running under Gnome Shell version %s\n", remmina_icon.gsversion);
printf("Running under GNOME Shell version %s\n", remmina_icon.gsversion);
if (!remmina_icon.icon && !remmina_pref.disable_tray_icon) {
#ifdef HAVE_LIBAPPINDICATOR
......
......@@ -201,15 +201,20 @@ void _remmina_debug(const gchar *fun, const gchar *fmt, ...)
va_start(args, fmt);
text = g_strdup_vprintf(fmt, args);
va_end(args);
g_autofree gchar *buf = g_strconcat("(", fun, ") - ", text, NULL);
g_free(text);
g_debug ("%s", g_strdup(buf));
g_debug ("%s", buf);
buf = g_strconcat (buf, "\n", NULL);
/* freed in remmina_log_print_real */
gchar *bufn = g_strconcat(buf, "\n", NULL);
if (!log_window)
if (!log_window) {
free(bufn);
return;
IDLE_ADD(remmina_log_print_real, g_strdup(buf));
}
IDLE_ADD(remmina_log_print_real, bufn);
}
void remmina_log_printf(const gchar *fmt, ...)
......
......@@ -168,13 +168,39 @@ static void remmina_main_save_expanded_group(void)
*/
void remmina_main_save_before_destroy()
{
TRACE_CALL(__func__);
if (!remminamain || !remminamain->window)
return;
remmina_main_save_size();
remmina_main_save_expanded_group();
g_free(remmina_pref.expanded_group);
remmina_pref.expanded_group = remmina_string_array_to_string(remminamain->priv->expanded_group);
remmina_pref_save();
}
void remmina_main_destroy()
{
TRACE_CALL(__func__);
if (remminamain) {
if (remminamain->window)
gtk_widget_destroy(GTK_WIDGET(remminamain->window));
g_object_unref(remminamain->builder);
remmina_string_array_free(remminamain->priv->expanded_group);
remminamain->priv->expanded_group = NULL;
if (remminamain->priv->file_model)
g_object_unref(G_OBJECT(remminamain->priv->file_model));
g_object_unref(G_OBJECT(remminamain->priv->file_model_filter));
g_free(remminamain->priv->selected_filename);
g_free(remminamain->priv->selected_name);
g_free(remminamain->priv);
g_free(remminamain);
remminamain = NULL;
}
}
/**
* Try to exit remmina after a delete window event
*/
......@@ -190,47 +216,34 @@ gboolean remmina_main_on_delete_event(GtkWidget *widget, GdkEvent *event, gpoint
TRACE_CALL(__func__);
remmina_main_save_before_destroy();
/* Forget the main window: it has been deleted */
remminamain->window = NULL;
g_idle_add(remmina_main_dexit, NULL);
return FALSE;
}
/**
* Called after the main window is destroyed, will cleanup remminamain object and related data
*/
static gboolean remmina_main_rmodestroy(gpointer data)
gboolean remmina_main_idle_destroy(gpointer data)
{
g_free(remmina_pref.expanded_group);
remmina_pref.expanded_group = remmina_string_array_to_string(remminamain->priv->expanded_group);
remmina_string_array_free(remminamain->priv->expanded_group);
remminamain->priv->expanded_group = NULL;
if (remminamain->priv->file_model)
g_object_unref(G_OBJECT(remminamain->priv->file_model));
TRACE_CALL(__func__);
g_object_unref(G_OBJECT(remminamain->priv->file_model_filter));
g_object_unref(remminamain->builder);
g_free(remminamain->priv->selected_filename);
g_free(remminamain->priv->selected_name);
g_free(remminamain->priv);
g_free(remminamain);
remminamain = NULL;
return FALSE;
if (remminamain)
remmina_main_destroy();
return G_SOURCE_REMOVE;
}
/**
* Called when the main window is destroyed via a call from gtk_widget_destroy()
* Called when the remminamain->window widget is destroyed (glade event handler)
*/
void remmina_main_destroy()
void remmina_main_on_destroy_event()
{
TRACE_CALL(__func__);
if (remminamain) {
/* Schedule remminamain object destruction after
* GTK will finish to destroy the main window */
if (remminamain->window)
remmina_main_save_before_destroy();
g_idle_add(remmina_main_rmodestroy, NULL);
/* Invalidate remminamain->window to avoid multiple destructions */
remminamain->window = NULL;
/* Destroy remminamain struct, later. We can't destroy
important objects like the builder now */
g_idle_add(remmina_main_idle_destroy, NULL);
}
}
......
......@@ -93,14 +93,15 @@ struct _RemminaMainPriv {
G_BEGIN_DECLS
/* Create the main Remmina window */
/* Create the remminamain struct and the remmina main Remmina window */
GtkWidget *remmina_main_new(void);
/* Get the current main window or NULL if not initialized */
/* Get the current main GTK window or NULL if not initialized */
GtkWindow *remmina_main_get_window(void);