diff --git a/common/xrdp_client_info.h b/common/xrdp_client_info.h index d1ce1e1e..f003ee2a 100644 --- a/common/xrdp_client_info.h +++ b/common/xrdp_client_info.h @@ -110,6 +110,7 @@ struct xrdp_client_info int multimon; /* 0 = deny , 1 = allow */ int monitorCount; /* number of monitors detected (max = 16) */ struct monitor_info minfo[16]; /* client monitor data */ + struct monitor_info minfo_wm[16]; /* client monitor data, non-negative values */ int keyboard_type; int keyboard_subtype; diff --git a/libxrdp/xrdp_sec.c b/libxrdp/xrdp_sec.c index 3857e2d1..3e9cef66 100644 --- a/libxrdp/xrdp_sec.c +++ b/libxrdp/xrdp_sec.c @@ -1873,15 +1873,16 @@ xrdp_sec_process_mcs_data_monitors(struct xrdp_sec *self, struct stream *s) int y1; int x2; int y2; + int got_primary; struct xrdp_client_info *client_info = (struct xrdp_client_info *)NULL; client_info = &(self->rdp_layer->client_info); - DEBUG(("processing monitors data, allow_multimon is %d", client_info->multimon)); + LLOGLN(10, ("xrdp_sec_process_mcs_data_monitors: processing monitors data, allow_multimon is %d", client_info->multimon)); /* this is an option set in xrdp.ini */ if (client_info->multimon != 1) /* are multi-monitors allowed ? */ { - DEBUG(("[INFO] xrdp_sec_process_mcs_data_monitors: multimon is not " + LLOGLN(0, ("[INFO] xrdp_sec_process_mcs_data_monitors: multimon is not " "allowed, skipping")); return 0; } @@ -1889,7 +1890,7 @@ xrdp_sec_process_mcs_data_monitors(struct xrdp_sec *self, struct stream *s) //verify flags - must be 0x0 if (flags != 0) { - DEBUG(("[ERROR] xrdp_sec_process_mcs_data_monitors: flags MUST be " + LLOGLN(0, ("[ERROR] xrdp_sec_process_mcs_data_monitors: flags MUST be " "zero, detected: %d", flags)); return 1; } @@ -1897,12 +1898,12 @@ xrdp_sec_process_mcs_data_monitors(struct xrdp_sec *self, struct stream *s) //verify monitorCount - max 16 if (monitorCount > 16) { - DEBUG(("[ERROR] xrdp_sec_process_mcs_data_monitors: max allowed " + LLOGLN(0, ("[ERROR] xrdp_sec_process_mcs_data_monitors: max allowed " "monitors is 16, detected: %d", monitorCount)); return 1; } - g_writeln("monitorCount= %d", monitorCount); // for debugging only + LLOGLN(10, ("xrdp_sec_process_mcs_data_monitors: monitorCount= %d", monitorCount)); client_info->monitorCount = monitorCount; @@ -1910,6 +1911,7 @@ xrdp_sec_process_mcs_data_monitors(struct xrdp_sec *self, struct stream *s) y1 = 0; x2 = 0; y2 = 0; + got_primary = 0; /* Add client_monitor_data to client_info struct, will later pass to X11rdp */ for (index = 0; index < monitorCount; index++) { @@ -1933,16 +1935,51 @@ xrdp_sec_process_mcs_data_monitors(struct xrdp_sec *self, struct stream *s) y2 = MAX(y2, client_info->minfo[index].bottom); } - g_writeln("got a monitor: left= %d, top= %d, right= %d, bottom= %d, is_primary?= %d", client_info->minfo[index].left, - client_info->minfo[index].top, client_info->minfo[index].right, client_info->minfo[index].bottom, client_info->minfo[index].is_primary); + if (client_info->minfo[index].is_primary) + { + got_primary = 1; + } + + LLOGLN(10, ("xrdp_sec_process_mcs_data_monitors: got a monitor [%d]: left= %d, top= %d, right= %d, bottom= %d, is_primary?= %d", + index, + client_info->minfo[index].left, + client_info->minfo[index].top, + client_info->minfo[index].right, + client_info->minfo[index].bottom, + client_info->minfo[index].is_primary)); } + if (!got_primary) + { + /* no primary monitor was set, choose the leftmost monitor as primary */ + for (index = 0; index < monitorCount; index++) + { + if (client_info->minfo[index].left == x1 && + client_info->minfo[index].top == y1) + { + client_info->minfo[index].is_primary = 1; + break; + } + } + } + + /* set wm geometry */ if ((x2 > x1) && (y2 > y1)) { client_info->width = (x2 - x1) + 1; client_info->height = (y2 - y1) + 1; } + /* keep a copy of non negative monitor info values for xrdp_wm usage */ + for (index = 0; index < monitorCount; index++) + { + client_info->minfo_wm[index].left = client_info->minfo[index].left - x1; + client_info->minfo_wm[index].top = client_info->minfo[index].top - y1; + client_info->minfo_wm[index].right = client_info->minfo[index].right - x1; + client_info->minfo_wm[index].bottom = client_info->minfo[index].bottom - y1; + client_info->minfo_wm[index].is_primary = client_info->minfo[index].is_primary; + } + return 0; } diff --git a/xrdp/xrdp_login_wnd.c b/xrdp/xrdp_login_wnd.c index 337ec236..c9fca912 100644 --- a/xrdp/xrdp_login_wnd.c +++ b/xrdp/xrdp_login_wnd.c @@ -618,14 +618,18 @@ xrdp_login_wnd_create(struct xrdp_wm *self) int log_width; int log_height; int regular; - int i = 0; - int primaryxoffset = 0; - int primaryyoffset = 0; + int primary_x_offset; + int primary_y_offset; + int index; + int x; + int y; + int cx; + int cy; globals = &self->xrdp_config->cfg_globals; - primaryxoffset = self->screen->width / 2; - primaryyoffset = self->screen->height / 2; + primary_x_offset = self->screen->width / 2; + primary_y_offset = self->screen->height / 2; log_width = globals->ls_width; log_height = globals->ls_height; @@ -648,12 +652,17 @@ xrdp_login_wnd_create(struct xrdp_wm *self) /* multimon scenario, draw login window on primary monitor */ if (self->client_info->monitorCount > 1) { - for (i = 0; i < self->client_info->monitorCount; ++i) + for (index = 0; index < self->client_info->monitorCount; index++) { - if (self->client_info->minfo[i].is_primary) + if (self->client_info->minfo_wm[index].is_primary) { - primaryxoffset = self->screen->width - (self->client_info->minfo[i].right / 2) - 1; - primaryyoffset = self->screen->height - (self->client_info->minfo[i].bottom / 2) - 1; + x = self->client_info->minfo_wm[index].left; + y = self->client_info->minfo_wm[index].top; + cx = self->client_info->minfo_wm[index].right; + cy = self->client_info->minfo_wm[index].bottom; + + primary_x_offset = x + ((cx - x) / 2); + primary_y_offset = y + ((cy - y) / 2); break; } } @@ -667,11 +676,8 @@ xrdp_login_wnd_create(struct xrdp_wm *self) self->login_window->owner = self->screen; self->login_window->bg_color = globals->ls_bg_color; - self->login_window->left = primaryxoffset - - self->login_window->width / 2; - - self->login_window->top = primaryyoffset - - self->login_window->height / 2; + self->login_window->left = primary_x_offset - self->login_window->width / 2; + self->login_window->top = primary_y_offset - self->login_window->height / 2; self->login_window->notify = xrdp_wm_login_notify; diff --git a/xrdp/xrdp_wm.c b/xrdp/xrdp_wm.c index 8ce18bb6..3b223902 100644 --- a/xrdp/xrdp_wm.c +++ b/xrdp/xrdp_wm.c @@ -1884,9 +1884,9 @@ xrdp_wm_show_log(struct xrdp_wm *self) int h; int xoffset; int yoffset; - int i; - int primaryxoffset = 0; - int primaryyoffset = 0; + int index; + int primary_x_offset; + int primary_y_offset; if (self->hide_log_window) @@ -1916,15 +1916,18 @@ xrdp_wm_show_log(struct xrdp_wm *self) yoffset = 2; } + primary_x_offset = 0; + primary_y_offset = 0; + /* multimon scenario, draw log window on primary monitor */ if (self->client_info->monitorCount > 1) { - for (i = 0; i < self->client_info->monitorCount; ++i) + for (index = 0; index < self->client_info->monitorCount; index++) { - if (self->client_info->minfo[i].is_primary) + if (self->client_info->minfo_wm[index].is_primary) { - primaryxoffset = self->screen->width - self->client_info->minfo[i].right - 1; - primaryyoffset = self->screen->height - self->client_info->minfo[i].bottom - 1; + primary_x_offset = self->client_info->minfo_wm[index].left; + primary_y_offset = self->client_info->minfo_wm[index].top; break; } } @@ -1937,8 +1940,8 @@ xrdp_wm_show_log(struct xrdp_wm *self) self->log_wnd->parent = self->screen; self->log_wnd->owner = self->screen; self->log_wnd->bg_color = self->grey; - self->log_wnd->left = primaryxoffset + xoffset; - self->log_wnd->top = primaryyoffset + yoffset; + self->log_wnd->left = primary_x_offset + xoffset; + self->log_wnd->top = primary_y_offset + yoffset; set_string(&(self->log_wnd->caption1), "Connection Log"); /* ok button */ but = xrdp_bitmap_create(DEFAULT_BUTTON_W, DEFAULT_BUTTON_H, self->screen->bpp, WND_TYPE_BUTTON, self);