winex11.drv: Preliminary support for Xinerama.
This commit is contained in:
parent
7d00b0504e
commit
3c305f9db9
|
@ -39,6 +39,7 @@ C_SRCS = \
|
|||
xdnd.c \
|
||||
xfont.c \
|
||||
xim.c \
|
||||
xinerama.c \
|
||||
xrandr.c \
|
||||
xrender.c \
|
||||
xvidmode.c
|
||||
|
|
|
@ -1154,7 +1154,7 @@ static BOOL BITBLT_GetVisRectangles( X11DRV_PDEVICE *physDevDst, INT xDst, INT y
|
|||
GetObjectW( physDevSrc->bitmap->hbitmap, sizeof(bm), &bm );
|
||||
SetRect( &clipRect, 0, 0, bm.bmWidth, bm.bmHeight );
|
||||
}
|
||||
else SetRect( &clipRect, 0, 0, screen_width, screen_height );
|
||||
else clipRect = virtual_screen_rect;
|
||||
if (!IntersectRect( visRectSrc, &rect, &clipRect ))
|
||||
return FALSE;
|
||||
|
||||
|
|
|
@ -141,6 +141,7 @@ void X11DRV_init_desktop( Window win, unsigned int width, unsigned int height )
|
|||
max_height = screen_height;
|
||||
screen_width = width;
|
||||
screen_height = height;
|
||||
xinerama_init();
|
||||
|
||||
/* initialize the available resolutions */
|
||||
dd_modes = X11DRV_Settings_SetHandlers("desktop",
|
||||
|
|
|
@ -110,8 +110,11 @@ BOOL X11DRV_is_window_rect_mapped( const RECT *rect )
|
|||
if (IsRectEmpty( rect )) return FALSE;
|
||||
|
||||
/* don't map if rect is off-screen */
|
||||
if (rect->left >= (int)screen_width || rect->top >= (int)screen_height) return FALSE;
|
||||
if (rect->right < 0 || rect->bottom < 0) return FALSE;
|
||||
if (rect->left >= virtual_screen_rect.right ||
|
||||
rect->top >= virtual_screen_rect.bottom ||
|
||||
rect->right <= virtual_screen_rect.left ||
|
||||
rect->bottom <= virtual_screen_rect.top)
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
@ -335,7 +338,7 @@ static void systray_dock_window( Display *display, struct x11drv_win_data *data
|
|||
* For more information on this problem, see
|
||||
* http://standards.freedesktop.org/xembed-spec/latest/ar01s04.html */
|
||||
|
||||
SetWindowPos( data->hwnd, NULL, screen_width + 1, screen_height + 1,
|
||||
SetWindowPos( data->hwnd, NULL, virtual_screen_rect.right + 1, virtual_screen_rect.bottom + 1,
|
||||
0, 0, SWP_NOZORDER | SWP_NOSIZE );
|
||||
|
||||
/* set XEMBED protocol data on the window */
|
||||
|
@ -938,7 +941,6 @@ static struct x11drv_win_data *alloc_win_data( Display *display, HWND hwnd )
|
|||
/* fill in the desktop X window id in the x11drv_win_data structure */
|
||||
static void get_desktop_xwin( Display *display, struct x11drv_win_data *data )
|
||||
{
|
||||
RECT rect;
|
||||
Window win = (Window)GetPropA( data->hwnd, whole_window_prop );
|
||||
|
||||
if (win)
|
||||
|
@ -967,8 +969,8 @@ static void get_desktop_xwin( Display *display, struct x11drv_win_data *data )
|
|||
SetPropA( data->hwnd, whole_window_prop, (HANDLE)root_window );
|
||||
SetPropA( data->hwnd, visual_id_prop, (HANDLE)visualid );
|
||||
data->whole_window = root_window;
|
||||
SetRect( &rect, 0, 0, screen_width, screen_height );
|
||||
X11DRV_set_window_pos( data->hwnd, 0, &rect, &rect, SWP_NOZORDER, NULL );
|
||||
X11DRV_set_window_pos( data->hwnd, 0, &virtual_screen_rect, &virtual_screen_rect,
|
||||
SWP_NOZORDER, NULL );
|
||||
if (root_window != DefaultRootWindow( display ))
|
||||
{
|
||||
data->managed = TRUE;
|
||||
|
|
|
@ -1253,6 +1253,7 @@ void X11DRV_handle_desktop_resize( unsigned int width, unsigned int height )
|
|||
|
||||
screen_width = width;
|
||||
screen_height = height;
|
||||
xinerama_init();
|
||||
TRACE("desktop %p change to (%dx%d)\n", hwnd, width, height);
|
||||
SetRect( &rect, 0, 0, width, height );
|
||||
data->lock_changes++;
|
||||
|
@ -1665,7 +1666,7 @@ void X11DRV_SysCommandSizeMove( HWND hwnd, WPARAM wParam )
|
|||
else
|
||||
{
|
||||
parent = 0;
|
||||
SetRect(&mouseRect, 0, 0, GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN));
|
||||
mouseRect = virtual_screen_rect;
|
||||
}
|
||||
origRect = sizingRect;
|
||||
|
||||
|
|
|
@ -526,12 +526,14 @@ extern Window root_window;
|
|||
extern unsigned int screen_width;
|
||||
extern unsigned int screen_height;
|
||||
extern unsigned int screen_depth;
|
||||
extern RECT virtual_screen_rect;
|
||||
extern unsigned int text_caps;
|
||||
extern int use_xkb;
|
||||
extern int use_take_focus;
|
||||
extern int use_primary_selection;
|
||||
extern int managed_mode;
|
||||
extern int private_color_map;
|
||||
extern int primary_monitor;
|
||||
extern int copy_default_colors;
|
||||
extern int alloc_system_colors;
|
||||
extern int xrender_error_base;
|
||||
|
@ -686,6 +688,7 @@ extern void X11DRV_sync_window_position( Display *display, struct x11drv_win_dat
|
|||
extern BOOL X11DRV_set_window_pos( HWND hwnd, HWND insert_after, const RECT *rectWindow,
|
||||
const RECT *rectClient, UINT swp_flags, const RECT *validRects );
|
||||
extern void X11DRV_set_wm_hints( Display *display, struct x11drv_win_data *data );
|
||||
extern void xinerama_init(void);
|
||||
|
||||
extern void X11DRV_init_desktop( Window win, unsigned int width, unsigned int height );
|
||||
extern void X11DRV_handle_desktop_resize(unsigned int width, unsigned int height);
|
||||
|
|
|
@ -69,6 +69,7 @@ Visual *visual;
|
|||
unsigned int screen_width;
|
||||
unsigned int screen_height;
|
||||
unsigned int screen_depth;
|
||||
RECT virtual_screen_rect;
|
||||
Window root_window;
|
||||
int dxgrab = 0;
|
||||
int usexvidmode = 1;
|
||||
|
@ -78,6 +79,7 @@ int use_take_focus = 1;
|
|||
int use_primary_selection = 0;
|
||||
int managed_mode = 1;
|
||||
int private_color_map = 0;
|
||||
int primary_monitor = 0;
|
||||
int client_side_with_core = 1;
|
||||
int client_side_with_render = 1;
|
||||
int client_side_antialias_with_core = 1;
|
||||
|
@ -358,6 +360,9 @@ static void setup_options(void)
|
|||
if (!get_config_key( hkey, appkey, "PrivateColorMap", buffer, sizeof(buffer) ))
|
||||
private_color_map = IS_OPTION_TRUE( buffer[0] );
|
||||
|
||||
if (!get_config_key( hkey, appkey, "PrimaryMonitor", buffer, sizeof(buffer) ))
|
||||
primary_monitor = atoi( buffer );
|
||||
|
||||
if (!get_config_key( hkey, appkey, "CopyDefaultColors", buffer, sizeof(buffer) ))
|
||||
copy_default_colors = atoi(buffer);
|
||||
|
||||
|
@ -429,6 +434,7 @@ static BOOL process_attach(void)
|
|||
screen_width = WidthOfScreen( screen );
|
||||
screen_height = HeightOfScreen( screen );
|
||||
|
||||
xinerama_init();
|
||||
X11DRV_Settings_Init();
|
||||
|
||||
#ifdef HAVE_LIBXXF86VM
|
||||
|
|
|
@ -0,0 +1,156 @@
|
|||
/*
|
||||
* Xinerama support
|
||||
*
|
||||
* Copyright 2006 Alexandre Julliard
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include "wine/port.h"
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stdlib.h>
|
||||
#include <X11/Xlib.h>
|
||||
#ifdef HAVE_X11_EXTENSIONS_XINERAMA_H
|
||||
#include <X11/extensions/Xinerama.h>
|
||||
#endif
|
||||
#include "wine/library.h"
|
||||
#include "x11drv.h"
|
||||
#include "wine/debug.h"
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(x11drv);
|
||||
|
||||
static MONITORINFOEXW default_monitor =
|
||||
{
|
||||
sizeof(default_monitor), /* cbSize */
|
||||
{ 0, 0, 0, 0 }, /* rcMonitor */
|
||||
{ 0, 0, 0, 0 }, /* rcWork */
|
||||
MONITORINFOF_PRIMARY, /* dwFlags */
|
||||
{ '\\','\\','.','\\','D','I','S','P','L','A','Y','1',0 } /* szDevice */
|
||||
};
|
||||
|
||||
static MONITORINFOEXW *monitors;
|
||||
static int nb_monitors;
|
||||
|
||||
static inline MONITORINFOEXW *get_primary(void)
|
||||
{
|
||||
/* default to 0 if specified primary is invalid */
|
||||
int idx = primary_monitor;
|
||||
if (idx >= nb_monitors) idx = 0;
|
||||
return &monitors[idx];
|
||||
}
|
||||
|
||||
#ifdef HAVE_LIBXINERAMA
|
||||
|
||||
#define MAKE_FUNCPTR(f) static typeof(f) * p##f
|
||||
|
||||
MAKE_FUNCPTR(XineramaQueryExtension);
|
||||
MAKE_FUNCPTR(XineramaQueryScreens);
|
||||
|
||||
static void load_xinerama(void)
|
||||
{
|
||||
void *handle;
|
||||
|
||||
if (!(handle = wine_dlopen(SONAME_LIBXINERAMA, RTLD_NOW, NULL, 0)))
|
||||
{
|
||||
WARN( "failed to open %s\n", SONAME_LIBXINERAMA );
|
||||
return;
|
||||
}
|
||||
pXineramaQueryExtension = wine_dlsym( handle, "XineramaQueryExtension", NULL, 0 );
|
||||
if (!pXineramaQueryExtension) WARN( "XineramaQueryScreens not found\n" );
|
||||
pXineramaQueryScreens = wine_dlsym( handle, "XineramaQueryScreens", NULL, 0 );
|
||||
if (!pXineramaQueryScreens) WARN( "XineramaQueryScreens not found\n" );
|
||||
}
|
||||
|
||||
static int query_screens(void)
|
||||
{
|
||||
int i, count, event_base, error_base;
|
||||
XineramaScreenInfo *screens;
|
||||
|
||||
if (!monitors) /* first time around */
|
||||
load_xinerama();
|
||||
|
||||
if (!pXineramaQueryExtension || !pXineramaQueryScreens ||
|
||||
!pXineramaQueryExtension( gdi_display, &event_base, &error_base ) ||
|
||||
!(screens = pXineramaQueryScreens( gdi_display, &count ))) return 0;
|
||||
|
||||
if (monitors != &default_monitor) HeapFree( GetProcessHeap(), 0, monitors );
|
||||
if ((monitors = HeapAlloc( GetProcessHeap(), 0, count * sizeof(*monitors) )))
|
||||
{
|
||||
nb_monitors = count;
|
||||
for (i = 0; i < nb_monitors; i++)
|
||||
{
|
||||
/* FIXME: for now, force primary to be the screen that starts at (0,0) origin */
|
||||
if (!screens[i].x_org && !screens[i].y_org) primary_monitor = i;
|
||||
|
||||
monitors[i].cbSize = sizeof( monitors[i] );
|
||||
monitors[i].rcMonitor.left = screens[i].x_org;
|
||||
monitors[i].rcMonitor.top = screens[i].y_org;
|
||||
monitors[i].rcMonitor.right = screens[i].x_org + screens[i].width;
|
||||
monitors[i].rcMonitor.bottom = screens[i].y_org + screens[i].height;
|
||||
monitors[i].rcWork = monitors[i].rcMonitor;
|
||||
monitors[i].dwFlags = 0;
|
||||
/* FIXME: using the same device name for all monitors for now */
|
||||
lstrcpyW( monitors[i].szDevice, default_monitor.szDevice );
|
||||
}
|
||||
|
||||
get_primary()->dwFlags |= MONITORINFOF_PRIMARY;
|
||||
|
||||
for (i = 0; i < nb_monitors; i++)
|
||||
TRACE( "monitor %d: %s%s\n",
|
||||
i, wine_dbgstr_rect(&monitors[i].rcMonitor),
|
||||
(monitors[i].dwFlags & MONITORINFOF_PRIMARY) ? " (primary)" : "" );
|
||||
}
|
||||
else count = 0;
|
||||
|
||||
XFree( screens );
|
||||
return count;
|
||||
}
|
||||
|
||||
#else /* HAVE_LIBXINERAMA */
|
||||
|
||||
static inline int query_screens(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* HAVE_LIBXINERAMA */
|
||||
|
||||
void xinerama_init(void)
|
||||
{
|
||||
MONITORINFOEXW *primary;
|
||||
|
||||
wine_tsx11_lock();
|
||||
|
||||
SetRect( &virtual_screen_rect, 0, 0, screen_width, screen_height );
|
||||
|
||||
if (root_window != DefaultRootWindow( gdi_display ) || !query_screens())
|
||||
{
|
||||
default_monitor.rcWork = default_monitor.rcMonitor = virtual_screen_rect;
|
||||
nb_monitors = 1;
|
||||
monitors = &default_monitor;
|
||||
}
|
||||
|
||||
primary = get_primary();
|
||||
/* coordinates (0,0) have to point to the primary monitor origin */
|
||||
OffsetRect( &virtual_screen_rect, -primary->rcMonitor.left, -primary->rcMonitor.top );
|
||||
screen_width = primary->rcMonitor.right - primary->rcMonitor.left;
|
||||
screen_height = primary->rcMonitor.bottom - primary->rcMonitor.top;
|
||||
TRACE( "virtual size: %s primary size: %dx%d\n",
|
||||
wine_dbgstr_rect(&virtual_screen_rect), screen_width, screen_height );
|
||||
|
||||
wine_tsx11_unlock();
|
||||
}
|
Loading…
Reference in New Issue