xfreerdp: start handling multiple monitors in xf_monitor.c

This commit is contained in:
Marc-André Moreau 2011-08-30 20:59:42 -04:00
parent 9d7fce9194
commit b56962d254
7 changed files with 160 additions and 66 deletions

View File

@ -341,7 +341,7 @@ void rail_recv_handshake_order(rdpRailOrder* rail_order, STREAM* s)
rail_order->sysparam.keyboardPref = False;
rail_order->sysparam.params |= SPI_MASK_SET_DRAG_FULL_WINDOWS;
rail_order->sysparam.dragFullWindows = True;
rail_order->sysparam.dragFullWindows = False;
rail_order->sysparam.params |= SPI_MASK_SET_KEYBOARD_CUES;
rail_order->sysparam.keyboardCues = False;

View File

@ -29,6 +29,8 @@ add_executable(xfreerdp
xf_event.h
xf_keyboard.c
xf_keyboard.h
xf_monitor.c
xf_monitor.h
xf_window.c
xf_window.h
xfreerdp.c

106
client/X11/xf_monitor.c Normal file
View File

@ -0,0 +1,106 @@
/**
* FreeRDP: A Remote Desktop Protocol Client
* X11 Monitor Handling
*
* Copyright 2011 Marc-Andre Moreau <marcandre.moreau@gmail.com>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#ifdef WITH_XINERAMA
#include <X11/extensions/Xinerama.h>
#endif
#include "xf_monitor.h"
/* See MSDN Section on Multiple Display Monitors: http://msdn.microsoft.com/en-us/library/dd145071 */
boolean xf_detect_monitors(xfInfo* xfi, rdpSettings* settings)
{
int i;
VIRTUAL_SCREEN* vscreen;
#ifdef WITH_XINERAMA
int ignored, ignored2;
XineramaScreenInfo* screen_info = NULL;
#endif
vscreen = &xfi->vscreen;
xf_GetWorkArea(xfi);
if (settings->workarea)
{
settings->width = xfi->workArea.width;
settings->height = xfi->workArea.height;
}
if (settings->fullscreen != True && settings->workarea != True)
return True;
#ifdef WITH_XINERAMA
if (XineramaQueryExtension(xfi->display, &ignored, &ignored2))
{
if (XineramaIsActive(xfi->display))
{
screen_info = XineramaQueryScreens(xfi->display, &vscreen->nmonitors);
if (vscreen->nmonitors > 16)
vscreen->nmonitors = 0;
vscreen->monitors = xzalloc(sizeof(MONITOR_INFO) * vscreen->nmonitors);
if (vscreen->nmonitors)
{
for (i = 0; i < vscreen->nmonitors; i++)
{
vscreen->monitors[i].area.left = screen_info[i].x_org;
vscreen->monitors[i].area.top = screen_info[i].y_org;
vscreen->monitors[i].area.right = screen_info[i].x_org + screen_info[i].width - 1;
vscreen->monitors[i].area.bottom = screen_info[i].y_org + screen_info[i].height - 1;
if ((screen_info[i].x_org == 0) && (screen_info[i].y_org == 0))
vscreen->monitors[i].primary = True;
}
}
XFree(screen_info);
}
}
#endif
settings->num_monitors = vscreen->nmonitors;
settings->width = 0;
settings->height = 0;
for (i = 0; i < vscreen->nmonitors; i++)
{
settings->monitors[i].x = vscreen->monitors[i].area.left;
settings->monitors[i].y = vscreen->monitors[i].area.top;
settings->monitors[i].width = vscreen->monitors[i].area.right - vscreen->monitors[i].area.left + 1;
settings->monitors[i].height = vscreen->monitors[i].area.bottom - vscreen->monitors[i].area.top + 1;
settings->monitors[i].is_primary = vscreen->monitors[i].primary;
settings->width += settings->monitors[i].width;
settings->height = settings->monitors[i].height;
}
return True;
}

47
client/X11/xf_monitor.h Normal file
View File

@ -0,0 +1,47 @@
/**
* FreeRDP: A Remote Desktop Protocol Client
* X11 Monitor Handling
*
* Copyright 2011 Marc-Andre Moreau <marcandre.moreau@gmail.com>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef __XF_MONITOR_H
#define __XF_MONITOR_H
#include <freerdp/freerdp.h>
#include <freerdp/rail/rail.h>
struct _MONITOR_INFO
{
RECTANGLE_16 area;
RECTANGLE_16 workarea;
boolean primary;
};
typedef struct _MONITOR_INFO MONITOR_INFO;
struct _VIRTUAL_SCREEN
{
int nmonitors;
RECTANGLE_16 area;
RECTANGLE_16 workarea;
MONITOR_INFO* monitors;
};
typedef struct _VIRTUAL_SCREEN VIRTUAL_SCREEN;
#include "xfreerdp.h"
boolean xf_detect_monitors(xfInfo* xfi, rdpSettings* settings);
#endif /* __XF_MONITOR_H */

View File

@ -260,11 +260,6 @@ void xf_process_rail_get_sysparams_event(xfInfo* xfi, rdpChanMan* chanman, RDP_E
sysparam->workArea.right = xfi->workArea.x + xfi->workArea.width;
sysparam->workArea.bottom = xfi->workArea.y + xfi->workArea.height;
sysparam->displayChange.left = xfi->workArea.x;
sysparam->displayChange.top = xfi->workArea.y;
sysparam->displayChange.right = xfi->workArea.x + xfi->workArea.width;
sysparam->displayChange.bottom = xfi->workArea.y + xfi->workArea.height;
sysparam->taskbarPos.left = 0;
sysparam->taskbarPos.top = 0;
sysparam->taskbarPos.right = 0;

View File

@ -41,6 +41,7 @@
#include "xf_gdi.h"
#include "xf_rail.h"
#include "xf_event.h"
#include "xf_monitor.h"
#include "xf_keyboard.h"
#include "xfreerdp.h"
@ -235,11 +236,6 @@ boolean xf_pre_connect(freerdp* instance)
xfInfo* xfi;
rdpSettings* settings;
#ifdef WITH_XINERAMA
int n, ignored, ignored2;
XineramaScreenInfo* screen_info = NULL;
#endif
xfi = (xfInfo*) xzalloc(sizeof(xfInfo));
SET_XFI(instance, xfi);
@ -316,61 +312,7 @@ boolean xf_pre_connect(freerdp* instance)
xfi->remote_app = settings->remote_app;
xfi->fullscreen = settings->fullscreen;
xf_GetWorkArea(xfi);
if (settings->workarea)
{
settings->width = xfi->workArea.width;
settings->height = xfi->workArea.height;
}
if (settings->fullscreen != True && settings->workarea != True)
return True;
#ifdef WITH_XINERAMA
if (XineramaQueryExtension(xfi->display, &ignored, &ignored2))
{
if (XineramaIsActive(xfi->display))
{
screen_info = XineramaQueryScreens(xfi->display, &settings->num_monitors);
if (settings->num_monitors > 16)
settings->num_monitors = 0;
settings->width = 0;
settings->height = 0;
if (settings->num_monitors)
{
for (n = 0; n < settings->num_monitors; n++)
{
if (settings->workarea)
{
settings->monitors[n].x = screen_info[n].x_org;
settings->monitors[n].y = screen_info[n].y_org;
settings->monitors[n].width = screen_info[n].width;
settings->monitors[n].height = xfi->workArea.height;
settings->width += settings->monitors[n].width;
settings->height = settings->monitors[n].height;
}
else
{
settings->monitors[n].x = screen_info[n].x_org;
settings->monitors[n].y = screen_info[n].y_org;
settings->monitors[n].width = screen_info[n].width;
settings->monitors[n].height = screen_info[n].height;
settings->width += settings->monitors[n].width;
settings->height = settings->monitors[n].height;
}
settings->monitors[n].is_primary = screen_info[n].x_org == 0 && screen_info[n].y_org == 0;
}
}
XFree(screen_info);
}
}
#endif
xf_detect_monitors(xfi, settings);
return True;
}

View File

@ -31,6 +31,7 @@
typedef struct xf_info xfInfo;
#include "xf_window.h"
#include "xf_monitor.h"
#define SET_XFI(_instance, _xfi) (_instance)->param1 = _xfi
#define GET_XFI(_instance) ((xfInfo*) ((_instance)->param1))
@ -87,6 +88,7 @@ struct xf_info
XModifierKeymap* modifier_map;
XSetWindowAttributes attribs;
boolean complex_regions;
VIRTUAL_SCREEN vscreen;
Atom _NET_WM_ICON;
Atom _MOTIF_WM_HINTS;