Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/neutrinolabs/xrdp.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormatt335672 <30179339+matt335672@users.noreply.github.com>2022-08-11 16:42:53 +0300
committermatt335672 <30179339+matt335672@users.noreply.github.com>2022-09-06 11:42:14 +0300
commita417ab0542be1375a70aa8158b9ed990760a263a (patch)
tree5b181672283a9beb106cef00ee89b51afa3ff6cf
parentd0c8e28d273c9fb849ba27ac68ca84deabe4a32a (diff)
Add font control variables to xrdp.ini
This commit adds the variables fv1_select and default_dpi to xrdp.ini. These variables allow for a different font to be loaded, depending on the DPI of the login screen.
-rw-r--r--docs/man/xrdp.ini.5.in16
-rw-r--r--xrdp/xrdp.h11
-rw-r--r--xrdp/xrdp.ini.in23
-rw-r--r--xrdp/xrdp_font.c138
-rw-r--r--xrdp/xrdp_login_wnd.c86
-rw-r--r--xrdp/xrdp_types.h3
-rw-r--r--xrdp/xrdp_wm.c4
7 files changed, 263 insertions, 18 deletions
diff --git a/docs/man/xrdp.ini.5.in b/docs/man/xrdp.ini.5.in
index 581fcac9..b680dcba 100644
--- a/docs/man/xrdp.ini.5.in
+++ b/docs/man/xrdp.ini.5.in
@@ -125,12 +125,12 @@ separator as the password supplied by the user and treats it as autologon. If no
defaults to \fBfalse\fP.
.TP
-\domain_user_separator\fP=\separator\fP
+\fBdomain_user_separator\fP=\fBseparator\fP
If specified the domain name supplied by the client is appended to the username separated
by \fBseparator\fP.
.TP
-\enable_token_login\fP=\fI[true|false]\fP
+\fBenable_token_login\fP=\fI[true|false]\fP
If set to \fB1\fP, \fBtrue\fP or \fByes\fP, \fBxrdp\fP requires clients to include username and
password initial connection phase. In other words, xrdp doesn't allow clients to show login
screen if set to true. If not specified, defaults to \fBfalse\fP.
@@ -212,6 +212,18 @@ These options override the colors used internally by \fBxrdp\fP(8) to draw the l
Colors are defined using a hexadecimal (hex) notation for the combination of Red, Green, and Blue color values (RGB).
The lowest value that can be given to one of the light sources is 0 (hex 00).
The highest value is 255 (hex FF).
+.TP
+\fBfv1_select\fP=\fI130:sans-18.fv1,0:sans-10.fv1\fP
+Selects a default fv1 font.
+This parameter is a comma-separated list of DPI:name pairs. The list
+is scanned from left-to-right. The font used is the first font whose DPI
+value is less-than-or-equal to the vertical DPI of the monitor used for
+the login screen.
+.TP
+\fBdefault_dpi\fP=\fI96\fP
+Default DPI used for a monitor if the client does not send physical
+size information.
+
.SH "LOGGING"
The following parameters can be used in the \fB[Logging]\fR section:
diff --git a/xrdp/xrdp.h b/xrdp/xrdp.h
index a769f987..ae4bf062 100644
--- a/xrdp/xrdp.h
+++ b/xrdp/xrdp.h
@@ -343,7 +343,7 @@ xrdp_painter_line(struct xrdp_painter *self,
/* xrdp_font.c */
struct xrdp_font *
-xrdp_font_create(struct xrdp_wm *wm);
+xrdp_font_create(struct xrdp_wm *wm, unsigned int dpi);
void
xrdp_font_delete(struct xrdp_font *self);
int
@@ -387,6 +387,14 @@ int
get_keymaps(int keylayout, struct xrdp_keymap *keymap);
/* xrdp_login_wnd.c */
+/**
+ * Gets the DPI of the login (primary) monitor
+ *
+ * @param self xrdp_wm instance
+ * @return DPI of primary monitor, or 0 if unavailable.
+ */
+unsigned int
+xrdp_login_wnd_get_monitor_dpi(struct xrdp_wm *self);
int
xrdp_login_wnd_create(struct xrdp_wm *self);
int
@@ -394,7 +402,6 @@ load_xrdp_config(struct xrdp_config *config, const char *xrdp_ini, int bpp);
void
xrdp_login_wnd_scale_config_values(struct xrdp_wm *self);
-
/* xrdp_bitmap_compress.c */
int
xrdp_bitmap_compress(char *in_data, int width, int height,
diff --git a/xrdp/xrdp.ini.in b/xrdp/xrdp.ini.in
index 3c60a5f2..48329f91 100644
--- a/xrdp/xrdp.ini.in
+++ b/xrdp/xrdp.ini.in
@@ -107,6 +107,17 @@ grey=dedede
#background=626c72
;
+; Select a default fv1 font
+;
+; This parameter is a comma-separated list of DPI:name pairs.
+; The list is scanned from left-to-right. The font used is the first
+; font whose DPI value is less-than-or-equal to the vertical DPI of
+; the monitor used for the login screen.
+#fv1_select=130:sans-18.fv1,0:sans-10.fv1
+; Default DPI used for a monitor when that information is unknown
+#default_dpi=96
+
+;
; configure login screen
;
@@ -118,6 +129,10 @@ ls_top_window_bg_color=009cb5
; width and height of login screen
;
+; When the sans-10.fv1 font is selected, these values are in pixels.
+; For other fonts, these values (and other size values) will be scaled
+; appropriately to preserve the proportions of the login screen.
+;
; The default height allows for about 5 fields to be comfortably displayed
; above the buttons at the bottom. To display more fields, make <ls_height>
; larger, and also increase <ls_btn_ok_y_pos> and <ls_btn_cancel_y_pos>
@@ -147,15 +162,15 @@ ls_bg_color=dedede
; For transform values, see 'ls_background_transform'. The logo width and
; logo height are ignored for a transform of 'none'.
ls_logo_filename=
-#ls_logo_transform=none
-#ls_logo_width=240
-#ls_logo_height=140
+ls_logo_transform=scale
+ls_logo_width=240
+ls_logo_height=140
ls_logo_x_pos=55
ls_logo_y_pos=50
; for positioning labels such as username, password etc
ls_label_x_pos=30
-ls_label_width=65
+ls_label_width=68
; for positioning text and combo boxes next to above labels
ls_input_x_pos=110
diff --git a/xrdp/xrdp_font.c b/xrdp/xrdp_font.c
index 5813b361..6fe81d8c 100644
--- a/xrdp/xrdp_font.c
+++ b/xrdp/xrdp_font.c
@@ -24,8 +24,11 @@
#include <config_ac.h>
#endif
+#include <ctype.h>
+
#include "xrdp.h"
#include "log.h"
+#include "string_calls.h"
#if 0 /* not used */
static char w_char[] =
@@ -50,8 +53,92 @@ static char w_char[] =
#endif
/*****************************************************************************/
+/**
+ * Parses the fv1_select configuration value to get the font to use,
+ * based on the DPI of the primary monitor
+ *
+ * @param globals Configuration globals
+ * @param dpi DPI of primary monitor. If not known, a suitable
+ * default should be passed in here.
+ * @param[out] font_name Name of font to use
+ * @param[in] font_name_len Length of font name buffer
+ */
+static void
+get_font_name_from_dpi(const struct xrdp_cfg_globals *globals,
+ unsigned int dpi,
+ char *font_name, int font_name_len)
+{
+ int bad_selector = 0;
+
+ font_name[0] = '\0';
+
+ const char *fv1_select = globals->fv1_select;
+ if (fv1_select == NULL || fv1_select[0] == '\0')
+ {
+ fv1_select = DEFAULT_FV1_SELECT;
+ }
+
+ const char *p = fv1_select;
+
+ while (p != NULL)
+ {
+ /* DPI value must be next in string */
+ if (!isdigit(*p))
+ {
+ bad_selector = 1;
+ break;
+ }
+ unsigned int field_dpi = g_atoi(p);
+ if (field_dpi <= dpi)
+ {
+ /* Use this font */
+ p = g_strchr(p, ':');
+ if (p == NULL)
+ {
+ bad_selector = 1;
+ }
+ else
+ {
+ ++p;
+ const char *q = g_strchr(p, ',');
+ if (q == NULL)
+ {
+ q = p + g_strlen(p);
+ }
+ if (q - p > (font_name_len - 1))
+ {
+ q = p + font_name_len - 1;
+ }
+ g_memcpy(font_name, p, q - p);
+ font_name[q - p] = '\0';
+ }
+ break;
+ }
+ else
+ {
+ p = g_strchr(p, ',');
+ if (p != NULL)
+ {
+ ++p;
+ }
+ }
+ }
+
+ if (bad_selector)
+ {
+ LOG(LOG_LEVEL_WARNING, "Unable to parse fv1_select configuration");
+ }
+
+ if (font_name[0] == '\0')
+ {
+ LOG(LOG_LEVEL_WARNING, "Loading default font " DEFAULT_FONT_NAME);
+ g_snprintf(font_name, font_name_len, DEFAULT_FONT_NAME);
+ }
+}
+
+/*****************************************************************************/
struct xrdp_font *
-xrdp_font_create(struct xrdp_wm *wm)
+xrdp_font_create(struct xrdp_wm *wm, unsigned int dpi)
{
struct xrdp_font *self;
struct stream *s;
@@ -62,17 +149,52 @@ xrdp_font_create(struct xrdp_wm *wm)
int datasize;
int file_size;
struct xrdp_font_char *f;
+ const char *file_path;
+ char file_path_buff[256];
int min_descender;
- char file_path[256];
-
+ char font_name[256];
+ const struct xrdp_cfg_globals *globals = &wm->xrdp_config->cfg_globals;
LOG_DEVEL(LOG_LEVEL_TRACE, "in xrdp_font_create");
- g_snprintf(file_path, 255, "%s/%s", XRDP_SHARE_PATH, DEFAULT_FONT_NAME);
+
+ if (dpi == 0)
+ {
+ LOG(LOG_LEVEL_WARNING, "No DPI value is available to find login font");
+ dpi = globals->default_dpi;
+ LOG(LOG_LEVEL_WARNING, "Using the default_dpi of %u", dpi);
+ }
+ get_font_name_from_dpi(globals, dpi, font_name, sizeof(font_name));
+
+ if (font_name[0] == '/')
+ {
+ /* User specified absolute path */
+ file_path = font_name;
+ }
+ else
+ {
+ g_snprintf(file_path_buff, sizeof(file_path_buff),
+ XRDP_SHARE_PATH "/%s",
+ font_name);
+ file_path = file_path_buff;
+ }
if (!g_file_exist(file_path))
{
- LOG(LOG_LEVEL_ERROR, "xrdp_font_create: error font file [%s] does not exist",
- file_path);
- return 0;
+ /* Try to fall back to the default */
+ const char *default_file_path = XRDP_SHARE_PATH "/" DEFAULT_FONT_NAME;
+ if (g_file_exist(default_file_path))
+ {
+ LOG(LOG_LEVEL_WARNING,
+ "xrdp_font_create: font file [%s] does not exist - using [%s]",
+ file_path, default_file_path);
+ file_path = default_file_path;
+ }
+ else
+ {
+ LOG(LOG_LEVEL_ERROR,
+ "xrdp_font_create: Can't load either [%s] or [%s]",
+ file_path, default_file_path);
+ return 0;
+ }
}
file_size = g_file_get_size(file_path);
@@ -150,7 +272,6 @@ xrdp_font_create(struct xrdp_wm *wm)
{
LOG(LOG_LEVEL_ERROR, "error in xrdp_font_create");
}
-
index++;
}
@@ -161,7 +282,6 @@ xrdp_font_create(struct xrdp_wm *wm)
self->body_height = -self->font_items[32].baseline + 1;
}
}
-
}
free_stream(s);
diff --git a/xrdp/xrdp_login_wnd.c b/xrdp/xrdp_login_wnd.c
index d11287c5..5afd730c 100644
--- a/xrdp/xrdp_login_wnd.c
+++ b/xrdp/xrdp_login_wnd.c
@@ -669,6 +669,81 @@ xrdp_wm_login_fill_in_combo(struct xrdp_wm *self, struct xrdp_bitmap *b)
}
/******************************************************************************/
+unsigned int
+xrdp_login_wnd_get_monitor_dpi(struct xrdp_wm *self)
+{
+ unsigned int result = 0;
+ const struct display_size_description *display_sizes =
+ &self->client_info->display_sizes;
+ unsigned int height_pixels = 0;
+ unsigned int height_mm = 0;
+
+ unsigned int i;
+
+ /* Look at the monitor data first */
+ for (i = 0; i < display_sizes->monitorCount; ++i)
+ {
+ const struct monitor_info *mi = &display_sizes->minfo_wm[i];
+ {
+ if (mi->is_primary)
+ {
+ height_pixels = mi->bottom - mi->top + 1;
+ height_mm = mi->physical_height;
+ break;
+ }
+ }
+ }
+
+ /* No primary monitor, or values not defined - use the desktop size */
+ if (height_mm == 0)
+ {
+ height_pixels = display_sizes->session_height;
+ height_mm = self->client_info->session_physical_height;
+
+ if (height_mm == 0)
+ {
+ LOG(LOG_LEVEL_WARNING,
+ "No information is available to determine login screen DPI");
+ }
+ else if (height_pixels < 768)
+ {
+ /* A bug was encountered with mstsc.exe version
+ 10.0.19041.1682 where the full physical monitor size was
+ sent in TS_UD_CS_CORE when the desktop size was set to
+ less than the screen size.
+ To generate the bug, make a connection with a full-screen
+ single window, cancel the login, and reconnect at
+ (e.g.) 800x600.
+ We can't detect that exact situation here, but if the
+ session height is so small as to likely be in a window
+ (rather than full screen), we should ignore the physical
+ size */
+ LOG(LOG_LEVEL_WARNING,
+ "Ignoring unlikely physical session size %u "
+ "for height of %u pixels", height_mm, height_pixels);
+ height_mm = 0;
+ }
+ }
+
+ if (height_mm != 0)
+ {
+ /*
+ * DPI = height_pixels / (height_mm / 25.4)
+ * = (height_pixels * 25.4) / height_mm
+ * = (height_pixels * 127) / (height_mm * 5)
+ */
+ result = (height_pixels * 127 ) / (height_mm * 5);
+ LOG(LOG_LEVEL_INFO,
+ "Login screen monitor height is %u pixels over %u mm (%u DPI)",
+ height_pixels,
+ height_mm,
+ result);
+ }
+ return result;
+}
+
+
+/******************************************************************************/
int
xrdp_login_wnd_create(struct xrdp_wm *self)
{
@@ -989,6 +1064,7 @@ load_xrdp_config(struct xrdp_config *config, const char *xrdp_ini, int bpp)
/* set default values in case we can't get them from xrdp.ini file */
globals->ini_version = 1;
+ globals->default_dpi = 96;
globals->ls_top_window_bg_color = HCOLOR(bpp, xrdp_wm_htoi("009cb5"));
globals->ls_bg_color = HCOLOR(bpp, xrdp_wm_htoi("dedede"));
@@ -1217,6 +1293,16 @@ load_xrdp_config(struct xrdp_config *config, const char *xrdp_ini, int bpp)
}
/* login screen values */
+ else if (g_strcmp(n, "default_dpi") == 0)
+ {
+ globals->default_dpi = g_atoi(v);
+ }
+
+ else if (g_strcmp(n, "fv1_select") == 0)
+ {
+ g_strncpy(globals->fv1_select, v, sizeof(globals->fv1_select) - 1);
+ }
+
else if (g_strncmp(n, "ls_top_window_bg_color", 64) == 0)
{
globals->ls_top_window_bg_color = HCOLOR(bpp, xrdp_wm_htoi(v));
diff --git a/xrdp/xrdp_types.h b/xrdp/xrdp_types.h
index 12f75e0c..98b7b08c 100644
--- a/xrdp/xrdp_types.h
+++ b/xrdp/xrdp_types.h
@@ -606,6 +606,7 @@ struct xrdp_bitmap
#define NUM_FONTS 0x4e00
#define DEFAULT_FONT_NAME "sans-10.fv1"
#define DEFAULT_FONT_PIXEL_SIZE 16
+#define DEFAULT_FV1_SELECT "130:sans-18.fv1,0:" DEFAULT_FONT_NAME
#define DEFAULT_BUTTON_MARGIN_H 12
#define DEFAULT_BUTTON_MARGIN_W 12
@@ -726,6 +727,8 @@ struct xrdp_cfg_globals
int background;
/* login screen */
+ unsigned int default_dpi; /* Default DPI to use if nothing from client */
+ char fv1_select[256]; /* Selection string for fv1 font */
int ls_top_window_bg_color; /* top level window background color */
int ls_bg_color; /* background color */
char ls_background_image[256]; /* background image file name */
diff --git a/xrdp/xrdp_wm.c b/xrdp/xrdp_wm.c
index 0076ef44..61261a97 100644
--- a/xrdp/xrdp_wm.c
+++ b/xrdp/xrdp_wm.c
@@ -569,6 +569,7 @@ xrdp_wm_init(struct xrdp_wm *self)
char default_section_name[256];
char section_name[256];
char autorun_name[256];
+ int dpi;
LOG(LOG_LEVEL_DEBUG, "in xrdp_wm_init: ");
@@ -576,7 +577,8 @@ xrdp_wm_init(struct xrdp_wm *self)
self->screen->bpp);
/* Load the font */
- self->default_font = xrdp_font_create(self);
+ dpi = xrdp_login_wnd_get_monitor_dpi(self);
+ self->default_font = xrdp_font_create(self, dpi);
/* Scale the login screen values */
xrdp_login_wnd_scale_config_values(self);