Xephyr: add "multiscreen" suport
* This patch adds multiscreen support to Xephyr. For instance, the command line : "Xephyr :4 -ac -screen 320x240 -screen 640x480" will launch with two "screens" - namely two main windows. The first main window represents a screen that has the number :4.0, with a geometry of 320x240 pixels, and the second one represents a screen that has the number :4.1 with a geometry of 640x480. The command line: "DISPLAY=:4.1 xclock" will launch the xclock program on the second screen, for intance. * this patch was edited by Dodji Seketeli <dodji@openedhand.com> for: - better style compliance with the rest of the Xephyr code - make sure Xephyr could be launched with no -screen option. By default that creates a default screen of 640x480 pixel like before - display full titles on the windows - with insctructions to grab keyboard and mouse - like before.
This commit is contained in:
parent
81692b628f
commit
e5e6514ffa
|
@ -34,6 +34,7 @@
|
|||
#include "ephyr.h"
|
||||
|
||||
#include "inputstr.h"
|
||||
#include "scrnintstr.h"
|
||||
|
||||
extern int KdTsPhyScreen;
|
||||
KdKeyboardInfo *ephyrKbd;
|
||||
|
@ -83,7 +84,7 @@ ephyrScreenInitialize (KdScreenInfo *screen, EphyrScrPriv *scrpriv)
|
|||
int width = 640, height = 480;
|
||||
unsigned long redMask, greenMask, blueMask;
|
||||
|
||||
if (hostx_want_screen_size(&width, &height)
|
||||
if (hostx_want_screen_size(screen, &width, &height)
|
||||
|| !screen->width || !screen->height)
|
||||
{
|
||||
screen->width = width;
|
||||
|
@ -99,13 +100,13 @@ ephyrScreenInitialize (KdScreenInfo *screen, EphyrScrPriv *scrpriv)
|
|||
&& (screen->fb[0].depth == 24 || screen->fb[0].depth == 16
|
||||
|| screen->fb[0].depth == 8))
|
||||
{
|
||||
hostx_set_server_depth(screen->fb[0].depth);
|
||||
hostx_set_server_depth(screen, screen->fb[0].depth);
|
||||
}
|
||||
else
|
||||
else
|
||||
ErrorF("\nXephyr: requested screen depth not supported, setting to match hosts.\n");
|
||||
}
|
||||
|
||||
screen->fb[0].depth = hostx_get_server_depth();
|
||||
screen->fb[0].depth = hostx_get_server_depth(screen);
|
||||
screen->rate = 72;
|
||||
|
||||
if (screen->fb[0].depth <= 8)
|
||||
|
@ -146,7 +147,7 @@ ephyrScreenInitialize (KdScreenInfo *screen, EphyrScrPriv *scrpriv)
|
|||
screen->fb[0].bitsPerPixel = 32;
|
||||
}
|
||||
|
||||
hostx_get_visual_masks (&redMask, &greenMask, &blueMask);
|
||||
hostx_get_visual_masks (screen, &redMask, &greenMask, &blueMask);
|
||||
|
||||
screen->fb[0].redMask = (Pixel) redMask;
|
||||
screen->fb[0].greenMask = (Pixel) greenMask;
|
||||
|
@ -194,9 +195,7 @@ ephyrWindowLinear (ScreenPtr pScreen,
|
|||
EphyrPriv *priv = pScreenPriv->card->driver;
|
||||
|
||||
if (!pScreenPriv->enabled)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
return 0;
|
||||
|
||||
*size = priv->bytes_per_line;
|
||||
return priv->base + row * priv->bytes_per_line + offset;
|
||||
|
@ -210,8 +209,8 @@ ephyrMapFramebuffer (KdScreenInfo *screen)
|
|||
KdPointerMatrix m;
|
||||
int buffer_height;
|
||||
|
||||
EPHYR_DBG(" screen->width: %d, screen->height: %d",
|
||||
screen->width, screen->height);
|
||||
EPHYR_DBG("screen->width: %d, screen->height: %d index=%d",
|
||||
screen->width, screen->height, screen->mynum);
|
||||
|
||||
KdComputePointerMatrix (&m, scrpriv->randr, screen->width, screen->height);
|
||||
KdSetPointerMatrix (&m);
|
||||
|
@ -226,8 +225,8 @@ ephyrMapFramebuffer (KdScreenInfo *screen)
|
|||
buffer_height = screen->height;
|
||||
else
|
||||
buffer_height = 3 * screen->height;
|
||||
|
||||
priv->base = hostx_screen_init (screen->width, screen->height, buffer_height);
|
||||
|
||||
priv->base = hostx_screen_init (screen, screen->width, screen->height, buffer_height);
|
||||
|
||||
screen->memory_base = (CARD8 *) (priv->base);
|
||||
screen->memory_size = priv->bytes_per_line * buffer_height;
|
||||
|
@ -304,7 +303,7 @@ ephyrShadowUpdate (ScreenPtr pScreen, shadowBufPtr pBuf)
|
|||
* pBuf->pDamage regions
|
||||
*/
|
||||
shadowUpdateRotatePacked(pScreen, pBuf);
|
||||
hostx_paint_rect(0,0,0,0, screen->width, screen->height);
|
||||
hostx_paint_rect(screen, 0,0,0,0, screen->width, screen->height);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -314,29 +313,29 @@ ephyrInternalDamageRedisplay (ScreenPtr pScreen)
|
|||
KdScreenInfo *screen = pScreenPriv->screen;
|
||||
EphyrScrPriv *scrpriv = screen->driver;
|
||||
RegionPtr pRegion;
|
||||
|
||||
|
||||
if (!scrpriv || !scrpriv->pDamage)
|
||||
return;
|
||||
|
||||
|
||||
pRegion = DamageRegion (scrpriv->pDamage);
|
||||
|
||||
|
||||
if (REGION_NOTEMPTY (pScreen, pRegion))
|
||||
{
|
||||
int nbox;
|
||||
BoxPtr pbox;
|
||||
|
||||
|
||||
nbox = REGION_NUM_RECTS (pRegion);
|
||||
pbox = REGION_RECTS (pRegion);
|
||||
|
||||
|
||||
while (nbox--)
|
||||
{
|
||||
hostx_paint_rect(pbox->x1, pbox->y1,
|
||||
pbox->x1, pbox->y1,
|
||||
pbox->x2 - pbox->x1,
|
||||
pbox->y2 - pbox->y1);
|
||||
pbox++;
|
||||
}
|
||||
|
||||
{
|
||||
hostx_paint_rect(screen,
|
||||
pbox->x1, pbox->y1,
|
||||
pbox->x1, pbox->y1,
|
||||
pbox->x2 - pbox->x1,
|
||||
pbox->y2 - pbox->y1);
|
||||
pbox++;
|
||||
}
|
||||
DamageEmpty (scrpriv->pDamage);
|
||||
}
|
||||
}
|
||||
|
@ -432,11 +431,11 @@ ephyrRandRGetInfo (ScreenPtr pScreen, Rotation *rotations)
|
|||
{ 160, 160 },
|
||||
{ 0, 0 }
|
||||
};
|
||||
|
||||
|
||||
*rotations = RR_Rotate_All|RR_Reflect_All;
|
||||
|
||||
if (!hostx_want_preexisting_window()
|
||||
&& !hostx_want_fullscreen()) /* only if no -parent switch */
|
||||
|
||||
if (!hostx_want_preexisting_window (screen)
|
||||
&& !hostx_want_fullscreen ()) /* only if no -parent switch */
|
||||
{
|
||||
while (sizes[n].width != 0 && sizes[n].height != 0)
|
||||
{
|
||||
|
@ -586,9 +585,7 @@ ephyrRandRInit (ScreenPtr pScreen)
|
|||
rrScrPrivPtr pScrPriv;
|
||||
|
||||
if (!RRScreenInit (pScreen))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
return FALSE;
|
||||
|
||||
pScrPriv = rrGetScrPriv(pScreen);
|
||||
pScrPriv->rrGetInfo = ephyrRandRGetInfo;
|
||||
|
@ -606,6 +603,12 @@ ephyrCreateColormap (ColormapPtr pmap)
|
|||
Bool
|
||||
ephyrInitScreen (ScreenPtr pScreen)
|
||||
{
|
||||
KdScreenPriv(pScreen);
|
||||
KdScreenInfo *screen = pScreenPriv->screen;
|
||||
|
||||
EPHYR_DBG ("pScreen->myNum:%d\n", pScreen->myNum) ;
|
||||
hostx_set_screen_number (screen, pScreen->myNum);
|
||||
hostx_set_win_title (screen, "(ctrl+shift grabs mouse and keyboard)") ;
|
||||
pScreen->CreateColormap = ephyrCreateColormap;
|
||||
return TRUE;
|
||||
}
|
||||
|
@ -634,7 +637,8 @@ ephyrCreateResources (ScreenPtr pScreen)
|
|||
KdScreenInfo *screen = pScreenPriv->screen;
|
||||
EphyrScrPriv *scrpriv = screen->driver;
|
||||
|
||||
EPHYR_DBG("mark");
|
||||
EPHYR_DBG("mark pScreen=%p mynum=%d shadow=%d",
|
||||
pScreen, pScreen->myNum, scrpriv->shadow);
|
||||
|
||||
if (scrpriv->shadow)
|
||||
return KdShadowSet (pScreen,
|
||||
|
@ -743,6 +747,56 @@ ephyrUpdateModifierState(unsigned int state)
|
|||
}
|
||||
}
|
||||
|
||||
static void
|
||||
ephyrBlockSigio (void)
|
||||
{
|
||||
sigset_t set;
|
||||
|
||||
sigemptyset (&set);
|
||||
sigaddset (&set, SIGIO);
|
||||
sigprocmask (SIG_BLOCK, &set, 0);
|
||||
}
|
||||
|
||||
static void
|
||||
ephyrUnblockSigio (void)
|
||||
{
|
||||
sigset_t set;
|
||||
|
||||
sigemptyset (&set);
|
||||
sigaddset (&set, SIGIO);
|
||||
sigprocmask (SIG_UNBLOCK, &set, 0);
|
||||
}
|
||||
|
||||
static Bool
|
||||
ephyrCursorOffScreen(ScreenPtr *ppScreen, int *x, int *y)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
ephyrCrossScreen (ScreenPtr pScreen, Bool entering)
|
||||
{
|
||||
}
|
||||
|
||||
int ephyrCurScreen; /*current event screen*/
|
||||
|
||||
static void
|
||||
ephyrWarpCursor (ScreenPtr pScreen, int x, int y)
|
||||
{
|
||||
ephyrBlockSigio ();
|
||||
ephyrCurScreen = pScreen->myNum;
|
||||
miPointerWarpCursor (pScreen, x, y);
|
||||
ephyrUnblockSigio ();
|
||||
}
|
||||
|
||||
miPointerScreenFuncRec ephyrPointerScreenFuncs =
|
||||
{
|
||||
ephyrCursorOffScreen,
|
||||
ephyrCrossScreen,
|
||||
ephyrWarpCursor
|
||||
};
|
||||
|
||||
|
||||
void
|
||||
ephyrPoll(void)
|
||||
{
|
||||
|
@ -751,21 +805,39 @@ ephyrPoll(void)
|
|||
while (hostx_get_event(&ev))
|
||||
{
|
||||
switch (ev.type)
|
||||
{
|
||||
case EPHYR_EV_MOUSE_MOTION:
|
||||
{
|
||||
case EPHYR_EV_MOUSE_MOTION:
|
||||
if (!ephyrMouse ||
|
||||
!((EphyrPointerPrivate *)ephyrMouse->driverPrivate)->enabled)
|
||||
!((EphyrPointerPrivate *)ephyrMouse->driverPrivate)->enabled) {
|
||||
EPHYR_DBG ("skipping mouse motion:%d\n", ephyrCurScreen) ;
|
||||
continue;
|
||||
KdEnqueuePointerEvent(ephyrMouse, mouseState,
|
||||
ev.data.mouse_motion.x,
|
||||
ev.data.mouse_motion.y,
|
||||
0);
|
||||
break;
|
||||
|
||||
case EPHYR_EV_MOUSE_PRESS:
|
||||
}
|
||||
{
|
||||
if (ephyrCurScreen != ev.data.mouse_motion.screen)
|
||||
{
|
||||
EPHYR_DBG ("warping mouse cursor:%d\n", ephyrCurScreen) ;
|
||||
ephyrWarpCursor(screenInfo.screens[ev.data.mouse_motion.screen],
|
||||
ev.data.mouse_motion.x,
|
||||
ev.data.mouse_motion.y );
|
||||
}
|
||||
else
|
||||
{
|
||||
EPHYR_DBG ("enqueuing mouse motion:%d\n", ephyrCurScreen) ;
|
||||
KdEnqueuePointerEvent(ephyrMouse, mouseState,
|
||||
ev.data.mouse_motion.x,
|
||||
ev.data.mouse_motion.y,
|
||||
0);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case EPHYR_EV_MOUSE_PRESS:
|
||||
if (!ephyrMouse ||
|
||||
!((EphyrPointerPrivate *)ephyrMouse->driverPrivate)->enabled)
|
||||
!((EphyrPointerPrivate *)ephyrMouse->driverPrivate)->enabled) {
|
||||
EPHYR_DBG ("skipping mouse press:%d\n", ephyrCurScreen) ;
|
||||
continue;
|
||||
}
|
||||
EPHYR_DBG ("enqueuing mouse press:%d\n", ephyrCurScreen) ;
|
||||
ephyrUpdateModifierState(ev.key_state);
|
||||
mouseState |= ev.data.mouse_down.button_num;
|
||||
KdEnqueuePointerEvent(ephyrMouse, mouseState|KD_MOUSE_DELTA, 0, 0, 0);
|
||||
|
@ -777,6 +849,7 @@ ephyrPoll(void)
|
|||
continue;
|
||||
ephyrUpdateModifierState(ev.key_state);
|
||||
mouseState &= ~ev.data.mouse_up.button_num;
|
||||
EPHYR_DBG ("enqueuing mouse release:%d\n", ephyrCurScreen) ;
|
||||
KdEnqueuePointerEvent(ephyrMouse, mouseState|KD_MOUSE_DELTA, 0, 0, 0);
|
||||
break;
|
||||
|
||||
|
@ -792,7 +865,6 @@ ephyrPoll(void)
|
|||
if (!ephyrKbd ||
|
||||
!((EphyrKbdPrivate *)ephyrKbd->driverPrivate)->enabled)
|
||||
continue;
|
||||
ephyrUpdateModifierState(ev.key_state);
|
||||
KdEnqueueKeyboardEvent (ephyrKbd, ev.data.key_up.scancode, TRUE);
|
||||
break;
|
||||
|
||||
|
|
|
@ -71,6 +71,8 @@ extern KdCardFuncs ephyrFuncs;
|
|||
extern KdKeyboardInfo *ephyrKbd;
|
||||
extern KdPointerInfo *ephyrMouse;
|
||||
|
||||
extern miPointerScreenFuncRec ephyrPointerScreenFuncs;
|
||||
|
||||
Bool
|
||||
ephyrInitialize (KdCardInfo *card, EphyrPriv *priv);
|
||||
|
||||
|
|
|
@ -33,6 +33,8 @@ extern Bool EphyrWantGrayScale;
|
|||
extern Bool kdHasPointer;
|
||||
extern Bool kdHasKbd;
|
||||
|
||||
void processScreenArg (char *screen_size, char *parent_id) ;
|
||||
|
||||
void
|
||||
InitCard (char *name)
|
||||
{
|
||||
|
@ -100,19 +102,60 @@ ddxUseMsg (void)
|
|||
exit(1);
|
||||
}
|
||||
|
||||
void
|
||||
processScreenArg (char *screen_size, char *parent_id)
|
||||
{
|
||||
KdCardInfo *card;
|
||||
static int card_exists;
|
||||
|
||||
InitCard (0); /*Put each screen on a separate card*/
|
||||
card = KdCardInfoLast ();
|
||||
|
||||
if (card)
|
||||
{
|
||||
KdScreenInfo *screen;
|
||||
unsigned long p_id = 0;
|
||||
|
||||
screen = KdScreenInfoAdd (card);
|
||||
KdParseScreen (screen, screen_size);
|
||||
|
||||
if (parent_id)
|
||||
{
|
||||
p_id = strtol (parent_id, NULL, 0);
|
||||
}
|
||||
EPHYR_DBG ("screen number:%d\n", screen->mynum) ;
|
||||
hostx_add_screen (screen, p_id, screen->mynum);
|
||||
}
|
||||
else
|
||||
{
|
||||
ErrorF("No matching card found!\n");
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
ddxProcessArgument (int argc, char **argv, int i)
|
||||
{
|
||||
EPHYR_DBG("mark");
|
||||
EPHYR_DBG("mark argv[%d]='%s'", i, argv[i] );
|
||||
|
||||
if (!strcmp (argv[i], "-parent"))
|
||||
{
|
||||
if(i+1 < argc)
|
||||
if(i+1 < argc)
|
||||
{
|
||||
hostx_use_preexisting_window(strtol(argv[i+1], NULL, 0));
|
||||
processScreenArg ("100x100", argv[i+1]);
|
||||
return 2;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
UseMsg();
|
||||
exit(1);
|
||||
}
|
||||
else if (!strcmp (argv[i], "-screen"))
|
||||
{
|
||||
if ((i+1) < argc)
|
||||
{
|
||||
processScreenArg (argv[i+1], NULL);
|
||||
return 2;
|
||||
}
|
||||
|
||||
UseMsg();
|
||||
exit(1);
|
||||
}
|
||||
|
@ -198,8 +241,10 @@ miPointerSpriteFuncRec EphyrPointerSpriteFuncs = {
|
|||
Bool
|
||||
ephyrCursorInit(ScreenPtr pScreen)
|
||||
{
|
||||
miPointerInitialize(pScreen, &EphyrPointerSpriteFuncs,
|
||||
&kdPointerScreenFuncs, FALSE);
|
||||
miPointerInitialize(pScreen,
|
||||
&EphyrPointerSpriteFuncs,
|
||||
&ephyrPointerScreenFuncs,
|
||||
FALSE);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -40,8 +40,8 @@
|
|||
|
||||
typedef struct EphyrHostXVars EphyrHostXVars;
|
||||
typedef struct EphyrHostXEvent EphyrHostXEvent;
|
||||
|
||||
typedef enum EphyrHostXEventType
|
||||
typedef void* EphyrScreenInfo ;
|
||||
typedef enum EphyrHostXEventType
|
||||
{
|
||||
EPHYR_EV_MOUSE_MOTION,
|
||||
EPHYR_EV_MOUSE_PRESS,
|
||||
|
@ -68,6 +68,7 @@ struct EphyrHostXEvent
|
|||
struct mouse_motion {
|
||||
int x;
|
||||
int y;
|
||||
int screen;
|
||||
} mouse_motion;
|
||||
|
||||
struct mouse_down {
|
||||
|
@ -92,7 +93,7 @@ struct EphyrHostXEvent
|
|||
};
|
||||
|
||||
int
|
||||
hostx_want_screen_size(int *width, int *height);
|
||||
hostx_want_screen_size(EphyrScreenInfo screen, int *width, int *height);
|
||||
|
||||
int
|
||||
hostx_want_host_cursor(void);
|
||||
|
@ -107,7 +108,7 @@ int
|
|||
hostx_want_fullscreen(void);
|
||||
|
||||
int
|
||||
hostx_want_preexisting_window(void);
|
||||
hostx_want_preexisting_window(EphyrScreenInfo screen);
|
||||
|
||||
void
|
||||
hostx_use_preexisting_window(unsigned long win_id);
|
||||
|
@ -118,26 +119,33 @@ hostx_handle_signal(int signum);
|
|||
int
|
||||
hostx_init(void);
|
||||
|
||||
void
|
||||
hostx_add_screen(EphyrScreenInfo screen, unsigned long win_id, int screen_num);
|
||||
|
||||
void
|
||||
hostx_set_display_name(char *name);
|
||||
|
||||
void
|
||||
hostx_set_win_title(char *extra_text);
|
||||
hostx_set_screen_number(EphyrScreenInfo screen, int number);
|
||||
|
||||
void
|
||||
hostx_set_win_title(EphyrScreenInfo screen, char *extra_text);
|
||||
|
||||
int
|
||||
hostx_get_depth (void);
|
||||
|
||||
int
|
||||
hostx_get_server_depth (void);
|
||||
hostx_get_server_depth (EphyrScreenInfo screen);
|
||||
|
||||
void
|
||||
hostx_set_server_depth(int depth);
|
||||
hostx_set_server_depth(EphyrScreenInfo screen, int depth);
|
||||
|
||||
int
|
||||
hostx_get_bpp(void);
|
||||
hostx_get_bpp(void *info);
|
||||
|
||||
void
|
||||
hostx_get_visual_masks (CARD32 *rmsk,
|
||||
hostx_get_visual_masks (void *info,
|
||||
CARD32 *rmsk,
|
||||
CARD32 *gmsk,
|
||||
CARD32 *bmsk);
|
||||
void
|
||||
|
@ -147,15 +155,16 @@ hostx_set_cmap_entry(unsigned char idx,
|
|||
unsigned char b);
|
||||
|
||||
void*
|
||||
hostx_screen_init (int width, int height, int buffer_height);
|
||||
hostx_screen_init (EphyrScreenInfo screen,
|
||||
int width, int height,
|
||||
int buffer_height);
|
||||
|
||||
void
|
||||
hostx_paint_rect(int sx, int sy,
|
||||
int dx, int dy,
|
||||
hostx_paint_rect(EphyrScreenInfo screen,
|
||||
int sx, int sy,
|
||||
int dx, int dy,
|
||||
int width, int height);
|
||||
void
|
||||
hostx_paint_debug_rect(int x, int y,
|
||||
int width, int height);
|
||||
|
||||
|
||||
void
|
||||
hostx_load_keymap(void);
|
||||
|
|
|
@ -31,6 +31,14 @@
|
|||
static int
|
||||
EphyrInit (void)
|
||||
{
|
||||
/*
|
||||
* make sure at least one screen
|
||||
* has been added to the system.
|
||||
*/
|
||||
if (!KdCardInfoLast ())
|
||||
{
|
||||
processScreenArg ("640x480", NULL) ;
|
||||
}
|
||||
return hostx_init();
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user