Merge pull request #5 from glyptodon/resize-with-dpi
GUAC-936: Use initial resolution for all future resizing of display.
This commit is contained in:
commit
7ef33e5901
@ -43,6 +43,7 @@ libguac_client_rdp_la_SOURCES = \
|
||||
rdp_settings.c \
|
||||
rdp_stream.c \
|
||||
rdp_svc.c \
|
||||
resolution.c \
|
||||
unicode.c
|
||||
|
||||
guacsvc_sources = \
|
||||
@ -95,6 +96,7 @@ noinst_HEADERS = \
|
||||
rdp_status.h \
|
||||
rdp_stream.h \
|
||||
rdp_svc.h \
|
||||
resolution.h \
|
||||
unicode.h
|
||||
|
||||
# Add compatibility layer for WinPR if not available
|
||||
|
@ -33,6 +33,7 @@
|
||||
#include "rdp_pointer.h"
|
||||
#include "rdp_stream.h"
|
||||
#include "rdp_svc.h"
|
||||
#include "resolution.h"
|
||||
|
||||
#ifdef HAVE_FREERDP_DISPLAY_UPDATE_SUPPORT
|
||||
#include "rdp_disp.h"
|
||||
@ -509,56 +510,6 @@ void __guac_rdp_client_load_keymap(guac_client* client,
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Reduces the resolution of the client to the given resolution in DPI if
|
||||
* doing so is reasonable. This function returns non-zero if the resolution
|
||||
* was successfully reduced to the given DPI, and zero if reduction failed.
|
||||
*/
|
||||
static int __guac_rdp_reduce_resolution(guac_client* client, int resolution) {
|
||||
|
||||
int width = client->info.optimal_width * resolution / client->info.optimal_resolution;
|
||||
int height = client->info.optimal_height * resolution / client->info.optimal_resolution;
|
||||
|
||||
/* Reduced resolution if result is reasonably sized */
|
||||
if (width*height >= GUAC_RDP_REASONABLE_AREA) {
|
||||
client->info.optimal_width = width;
|
||||
client->info.optimal_height = height;
|
||||
client->info.optimal_resolution = resolution;
|
||||
guac_client_log(client, GUAC_LOG_INFO,
|
||||
"Reducing resolution to %i DPI (%ix%i)", resolution, width, height);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* No reduction performed */
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Forces the client resolution to the given value, without checking whether
|
||||
* the resulting width and height are reasonable.
|
||||
*/
|
||||
static void __guac_rdp_force_resolution(guac_client* client, int resolution) {
|
||||
|
||||
int width = client->info.optimal_width * resolution / client->info.optimal_resolution;
|
||||
int height = client->info.optimal_height * resolution / client->info.optimal_resolution;
|
||||
|
||||
/* Do not force DPI to zero */
|
||||
if (resolution == 0) {
|
||||
guac_client_log(client, GUAC_LOG_WARNING,
|
||||
"Cowardly refusing to force resolution to %i DPI", resolution);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Reduced resolution if result is reasonably sized */
|
||||
client->info.optimal_width = width;
|
||||
client->info.optimal_height = height;
|
||||
client->info.optimal_resolution = resolution;
|
||||
guac_client_log(client, GUAC_LOG_INFO,
|
||||
"Resolution forced to %i DPI (%ix%i)", resolution, width, height);
|
||||
|
||||
}
|
||||
|
||||
int guac_client_init(guac_client* client, int argc, char** argv) {
|
||||
|
||||
rdp_guac_client_data* guac_client_data;
|
||||
@ -648,23 +599,22 @@ int guac_client_init(guac_client* client, int argc, char** argv) {
|
||||
if (argv[IDX_PORT][0] != '\0')
|
||||
settings->port = atoi(argv[IDX_PORT]);
|
||||
|
||||
guac_client_log(client, GUAC_LOG_INFO, "Client resolution is %ix%i at %i DPI",
|
||||
guac_client_log(client, GUAC_LOG_DEBUG,
|
||||
"Client resolution is %ix%i at %i DPI",
|
||||
client->info.optimal_width,
|
||||
client->info.optimal_height,
|
||||
client->info.optimal_resolution);
|
||||
|
||||
/* Use optimal resolution unless overridden */
|
||||
/* Use suggested resolution unless overridden */
|
||||
settings->resolution = guac_rdp_suggest_resolution(client);
|
||||
if (argv[IDX_DPI][0] != '\0')
|
||||
__guac_rdp_force_resolution(client, atoi(argv[IDX_DPI]));
|
||||
|
||||
/* If resolution not forced, attempt to reduce resolution for high DPI */
|
||||
else if (client->info.optimal_resolution > GUAC_RDP_NATIVE_RESOLUTION
|
||||
&& !__guac_rdp_reduce_resolution(client, GUAC_RDP_NATIVE_RESOLUTION)
|
||||
&& !__guac_rdp_reduce_resolution(client, GUAC_RDP_HIGH_RESOLUTION))
|
||||
guac_client_log(client, GUAC_LOG_INFO, "No reasonable lower resolution");
|
||||
settings->resolution = atoi(argv[IDX_DPI]);
|
||||
|
||||
/* Use optimal width unless overridden */
|
||||
settings->width = client->info.optimal_width;
|
||||
settings->width = client->info.optimal_width
|
||||
* settings->resolution
|
||||
/ client->info.optimal_resolution;
|
||||
|
||||
if (argv[IDX_WIDTH][0] != '\0')
|
||||
settings->width = atoi(argv[IDX_WIDTH]);
|
||||
|
||||
@ -680,7 +630,10 @@ int guac_client_init(guac_client* client, int argc, char** argv) {
|
||||
settings->width = settings->width & ~0x3;
|
||||
|
||||
/* Use optimal height unless overridden */
|
||||
settings->height = client->info.optimal_height;
|
||||
settings->height = client->info.optimal_height
|
||||
* settings->resolution
|
||||
/ client->info.optimal_resolution;
|
||||
|
||||
if (argv[IDX_HEIGHT][0] != '\0')
|
||||
settings->height = atoi(argv[IDX_HEIGHT]);
|
||||
|
||||
@ -692,6 +645,12 @@ int guac_client_init(guac_client* client, int argc, char** argv) {
|
||||
argv[IDX_WIDTH], settings->height);
|
||||
}
|
||||
|
||||
guac_client_log(client, GUAC_LOG_DEBUG,
|
||||
"Using resolution of %ix%i at %i DPI",
|
||||
settings->width,
|
||||
settings->height,
|
||||
settings->resolution);
|
||||
|
||||
/* Domain */
|
||||
settings->domain = NULL;
|
||||
if (argv[IDX_DOMAIN][0] != '\0')
|
||||
|
@ -480,6 +480,13 @@ int rdp_guac_client_size_handler(guac_client* client, int width, int height) {
|
||||
|
||||
freerdp* rdp_inst = guac_client_data->rdp_inst;
|
||||
|
||||
/* Convert client pixels to remote pixels */
|
||||
width = width * guac_client_data->settings.resolution
|
||||
/ client->info.optimal_resolution;
|
||||
|
||||
height = height * guac_client_data->settings.resolution
|
||||
/ client->info.optimal_resolution;
|
||||
|
||||
/* Send display update */
|
||||
pthread_mutex_lock(&(guac_client_data->rdp_lock));
|
||||
guac_rdp_disp_set_size(guac_client_data->disp, rdp_inst->context,
|
||||
|
@ -122,6 +122,12 @@ typedef struct guac_rdp_settings {
|
||||
*/
|
||||
int height;
|
||||
|
||||
/**
|
||||
* The DPI of the remote display to assume when converting between
|
||||
* client pixels and remote pixels.
|
||||
*/
|
||||
int resolution;
|
||||
|
||||
/**
|
||||
* Whether audio is enabled.
|
||||
*/
|
||||
|
60
src/protocols/rdp/resolution.c
Normal file
60
src/protocols/rdp/resolution.c
Normal file
@ -0,0 +1,60 @@
|
||||
/*
|
||||
* Copyright (C) 2014 Glyptodon LLC
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "client.h"
|
||||
#include "resolution.h"
|
||||
|
||||
#include <guacamole/client.h>
|
||||
|
||||
int guac_rdp_resolution_reasonable(guac_client* client, int resolution) {
|
||||
|
||||
int width = client->info.optimal_width;
|
||||
int height = client->info.optimal_height;
|
||||
|
||||
/* Convert client pixels to remote pixels */
|
||||
width = width * resolution / client->info.optimal_resolution;
|
||||
height = height * resolution / client->info.optimal_resolution;
|
||||
|
||||
/*
|
||||
* Resolution is reasonable if the same as the client optimal resolution
|
||||
* OR if the resulting display area is reasonable
|
||||
*/
|
||||
return client->info.optimal_resolution == resolution
|
||||
|| width*height >= GUAC_RDP_REASONABLE_AREA;
|
||||
|
||||
}
|
||||
|
||||
int guac_rdp_suggest_resolution(guac_client* client) {
|
||||
|
||||
/* Prefer RDP's native resolution */
|
||||
if (guac_rdp_resolution_reasonable(client, GUAC_RDP_NATIVE_RESOLUTION))
|
||||
return GUAC_RDP_NATIVE_RESOLUTION;
|
||||
|
||||
/* If native resolution is too tiny, try higher resolution */
|
||||
if (guac_rdp_resolution_reasonable(client, GUAC_RDP_HIGH_RESOLUTION))
|
||||
return GUAC_RDP_HIGH_RESOLUTION;
|
||||
|
||||
/* Fallback to client-suggested resolution */
|
||||
return client->info.optimal_resolution;
|
||||
|
||||
}
|
||||
|
49
src/protocols/rdp/resolution.h
Normal file
49
src/protocols/rdp/resolution.h
Normal file
@ -0,0 +1,49 @@
|
||||
/*
|
||||
* Copyright (C) 2014 Glyptodon LLC
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef GUAC_RDP_RESOLUTION_H
|
||||
#define GUAC_RDP_RESOLUTION_H
|
||||
|
||||
#include <guacamole/client.h>
|
||||
|
||||
/**
|
||||
* Returns whether the given resolution is reasonable for the given client,
|
||||
* based on arbitrary criteria for reasonability.
|
||||
*
|
||||
* @param client The guac_client to test the given resolution against.
|
||||
* @param resolution The resolution to test, in DPI.
|
||||
* @return Non-zero if the resolution is reasonable, zero otherwise.
|
||||
*/
|
||||
int guac_rdp_resolution_reasonable(guac_client* client, int resolution);
|
||||
|
||||
/**
|
||||
* Returns a reasonable resolution for the remote display, given the size and
|
||||
* resolution of a guac_client.
|
||||
*
|
||||
* @param client The guac_client whose size and resolution shall be used to
|
||||
* determine an appropriate remote display resolution.
|
||||
* @return A reasonable resolution for the remote display, in DPI.
|
||||
*/
|
||||
int guac_rdp_suggest_resolution(guac_client* client);
|
||||
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user