xserver: Branch 'master' - 2 commits
Dodji Seketeli
dodji at kemper.freedesktop.org
Tue Oct 2 04:52:43 PDT 2007
dix/events.c | 55 +++
hw/kdrive/ephyr/ephyr.c | 164 +++++++----
hw/kdrive/ephyr/ephyr.h | 2
hw/kdrive/ephyr/ephyrinit.c | 59 +++
hw/kdrive/ephyr/hostx.c | 654 +++++++++++++++++++++++++++-----------------
hw/kdrive/ephyr/hostx.h | 39 +-
hw/kdrive/ephyr/os.c | 8
include/dix.h | 3
mi/mipointer.c | 1
9 files changed, 669 insertions(+), 316 deletions(-)
New commits:
diff-tree e5e6514ffa0fd132e0cc1b15b94119e6e8755f43 (from 81692b628f41cb64329f3cccc0503fb216a2b8e3)
Author: Andrew Christan <andrew.christian at nokia.com>
Date: Tue Oct 2 13:25:51 2007 +0200
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 at 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.
diff --git a/hw/kdrive/ephyr/ephyr.c b/hw/kdrive/ephyr/ephyr.c
index e8001df..c5cb21a 100644
--- a/hw/kdrive/ephyr/ephyr.c
+++ b/hw/kdrive/ephyr/ephyr.c
@@ -34,6 +34,7 @@
#include "ephyr.h"
#include "inputstr.h"
+#include "scrnintstr.h"
extern int KdTsPhyScreen;
KdKeyboardInfo *ephyrKbd;
@@ -83,7 +84,7 @@ ephyrScreenInitialize (KdScreenInfo *scr
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 *scr
&& (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 *scr
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 *scree
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 *scree
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, sh
* 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
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, Ro
{ 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 st
}
}
+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;
diff --git a/hw/kdrive/ephyr/ephyr.h b/hw/kdrive/ephyr/ephyr.h
index f49d920..1c9b4f8 100644
--- a/hw/kdrive/ephyr/ephyr.h
+++ b/hw/kdrive/ephyr/ephyr.h
@@ -71,6 +71,8 @@ extern KdCardFuncs ephyrFuncs;
extern KdKeyboardInfo *ephyrKbd;
extern KdPointerInfo *ephyrMouse;
+extern miPointerScreenFuncRec ephyrPointerScreenFuncs;
+
Bool
ephyrInitialize (KdCardInfo *card, EphyrPriv *priv);
diff --git a/hw/kdrive/ephyr/ephyrinit.c b/hw/kdrive/ephyr/ephyrinit.c
index a76da03..6874609 100644
--- a/hw/kdrive/ephyr/ephyrinit.c
+++ b/hw/kdrive/ephyr/ephyrinit.c
@@ -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 EphyrPointerSprit
Bool
ephyrCursorInit(ScreenPtr pScreen)
{
- miPointerInitialize(pScreen, &EphyrPointerSpriteFuncs,
- &kdPointerScreenFuncs, FALSE);
+ miPointerInitialize(pScreen,
+ &EphyrPointerSpriteFuncs,
+ &ephyrPointerScreenFuncs,
+ FALSE);
return TRUE;
}
diff --git a/hw/kdrive/ephyr/hostx.c b/hw/kdrive/ephyr/hostx.c
index 36d3cbd..81678d9 100644
--- a/hw/kdrive/ephyr/hostx.c
+++ b/hw/kdrive/ephyr/hostx.c
@@ -47,33 +47,44 @@
* to get clobbered.
*/
+struct EphyrHostScreen
+{
+ Window win;
+ Window win_pre_existing; /* Set via -parent option like xnest */
+ XImage *ximg;
+ int win_width, win_height;
+ int server_depth;
+ unsigned char *fb_data; /* only used when host bpp != server bpp */
+ XShmSegmentInfo shminfo;
+
+ void *info; /* Pointer to the screen this is associated with */
+ int mynum; /* Screen number */
+};
+
struct EphyrHostXVars
{
char *server_dpy_name;
Display *dpy;
int screen;
Visual *visual;
- Window win, winroot;
- Window win_pre_existing; /* Set via -parent option like xnest */
+ Window winroot;
GC gc;
int depth;
- int server_depth;
- XImage *ximg;
- int win_width, win_height;
Bool use_host_cursor;
Bool use_fullscreen;
Bool have_shm;
+ int n_screens;
+ struct EphyrHostScreen *screens;
+
long damage_debug_msec;
- unsigned char *fb_data; /* only used when host bpp != server bpp */
unsigned long cmap[256];
-
- XShmSegmentInfo shminfo;
};
/* memset ( missing> ) instead of below */
-static EphyrHostXVars HostX = { "?", 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
+/*static EphyrHostXVars HostX = { "?", 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};*/
+static EphyrHostXVars HostX;
static int HostXWantDamageDebug = 0;
@@ -89,8 +100,22 @@ hostx_set_fullscreen_hint(void);
static int trapped_error_code = 0;
static int (*old_error_handler) (Display *d, XErrorEvent *e);
-#define host_depth_matches_server() (HostX.depth == HostX.server_depth)
+#define host_depth_matches_server(_vars) (HostX.depth == (_vars)->server_depth)
+static struct EphyrHostScreen *
+host_screen_from_screen_info (EphyrScreenInfo *screen)
+{
+ int i;
+
+ for (i = 0 ; i < HostX.n_screens ; i++)
+ {
+ if ( HostX.screens[i].info == screen)
+ {
+ return &HostX.screens[i];
+ }
+ }
+ return NULL;
+}
static int
error_handler(Display *display,
@@ -115,13 +140,16 @@ hostx_errors_untrap(void)
}
int
-hostx_want_screen_size(int *width, int *height)
+hostx_want_screen_size (EphyrScreenInfo screen, int *width, int *height )
{
- if (HostX.win_pre_existing != None
- || HostX.use_fullscreen == True)
+ struct EphyrHostScreen *host_screen = host_screen_from_screen_info (screen);
+
+ if (host_screen &&
+ (host_screen->win_pre_existing != None ||
+ HostX.use_fullscreen == True))
{
- *width = HostX.win_width;
- *height = HostX.win_height;
+ *width = host_screen->win_width;
+ *height = host_screen->win_height;
return 1;
}
@@ -129,100 +157,140 @@ hostx_want_screen_size(int *width, int *
}
void
-hostx_set_display_name(char *name)
+hostx_add_screen (EphyrScreenInfo screen,
+ unsigned long win_id,
+ int screen_num)
{
- HostX.server_dpy_name = strdup(name);
+ int index = HostX.n_screens;
+
+ HostX.n_screens += 1;
+ HostX.screens = realloc (HostX.screens,
+ HostX.n_screens * sizeof(struct EphyrHostScreen));
+ memset (&HostX.screens[index], 0, sizeof (struct EphyrHostScreen));
+
+ HostX.screens[index].info = screen;
+ HostX.screens[index].win_pre_existing = win_id;
}
+
void
-hostx_set_win_title(char *extra_text)
+hostx_set_display_name (char *name)
{
- char buf[256];
+ HostX.server_dpy_name = strdup (name);
+}
- snprintf(buf, 256, "Xephyr on %s %s",
- HostX.server_dpy_name,
- (extra_text != NULL) ? extra_text : "");
+void
+hostx_set_screen_number(EphyrScreenInfo screen, int number)
+{
+ struct EphyrHostScreen *host_screen = host_screen_from_screen_info (screen);
+ if (host_screen) {
+ host_screen->mynum = number;
+ hostx_set_win_title (host_screen->info, "") ;
+ }}
+
+void
+hostx_set_win_title (EphyrScreenInfo screen, char *extra_text)
+{
+ struct EphyrHostScreen *host_screen = host_screen_from_screen_info (screen);
+#define BUF_LEN 256
+ char buf[BUF_LEN+1];
- XStoreName(HostX.dpy, HostX.win, buf);
+ if (!host_screen)
+ return;
+
+ memset (buf, 0, BUF_LEN+1) ;
+ snprintf (buf, BUF_LEN, "Xephyr on %s.%d %s",
+ HostX.server_dpy_name,
+ host_screen->mynum,
+ (extra_text != NULL) ? extra_text : "");
+
+ XStoreName (HostX.dpy, host_screen->win, buf);
}
int
-hostx_want_host_cursor(void)
+hostx_want_host_cursor (void)
{
return HostX.use_host_cursor;
}
void
-hostx_use_host_cursor(void)
+hostx_use_host_cursor (void)
{
HostX.use_host_cursor = True;
}
int
-hostx_want_preexisting_window(void)
+hostx_want_preexisting_window (EphyrScreenInfo screen)
{
- if (HostX.win_pre_existing)
- return 1;
+ struct EphyrHostScreen *host_screen = host_screen_from_screen_info (screen);
+
+ if (host_screen && host_screen->win_pre_existing)
+ {
+ return 1;
+ }
else
+ {
return 0;
+ }
}
void
-hostx_use_fullscreen(void)
+hostx_use_fullscreen (void)
{
HostX.use_fullscreen = True;
}
int
-hostx_want_fullscreen(void)
+hostx_want_fullscreen (void)
{
return HostX.use_fullscreen;
}
static void
-hostx_set_fullscreen_hint(void)
+hostx_set_fullscreen_hint (void)
{
Atom atom_WINDOW_STATE, atom_WINDOW_STATE_FULLSCREEN;
+ int index;
atom_WINDOW_STATE
= XInternAtom(HostX.dpy, "_NET_WM_STATE", False);
atom_WINDOW_STATE_FULLSCREEN
= XInternAtom(HostX.dpy, "_NET_WM_STATE_FULLSCREEN",False);
- XChangeProperty(HostX.dpy, HostX.win,
- atom_WINDOW_STATE, XA_ATOM, 32,
- PropModeReplace,
- (unsigned char *)&atom_WINDOW_STATE_FULLSCREEN, 1);
+ for (index = 0 ; index < HostX.n_screens ; index++)
+ {
+ XChangeProperty (HostX.dpy, HostX.screens[index].win,
+ atom_WINDOW_STATE, XA_ATOM, 32,
+ PropModeReplace,
+ (unsigned char *)&atom_WINDOW_STATE_FULLSCREEN, 1);
+ }
}
-void
-hostx_use_preexisting_window(unsigned long win_id)
-{
- HostX.win_pre_existing = win_id;
-}
static void
-hostx_toggle_damage_debug(void)
+hostx_toggle_damage_debug (void)
{
HostXWantDamageDebug ^= 1;
}
-void
-hostx_handle_signal(int signum)
+void
+hostx_handle_signal (int signum)
{
hostx_toggle_damage_debug();
- EPHYR_DBG("Signal caught. Damage Debug:%i\n", HostXWantDamageDebug);
+ EPHYR_DBG ("Signal caught. Damage Debug:%i\n",
+ HostXWantDamageDebug);
}
int
-hostx_init(void)
+hostx_init (void)
{
XSetWindowAttributes attr;
Cursor empty_cursor;
Pixmap cursor_pxm;
XColor col;
+ int index;
- attr.event_mask =
+ attr.event_mask =
ButtonPressMask
|ButtonReleaseMask
|PointerMotionMask
@@ -233,126 +301,142 @@ hostx_init(void)
EPHYR_DBG("mark");
if ((HostX.dpy = XOpenDisplay(getenv("DISPLAY"))) == NULL)
- {
- fprintf(stderr, "\nXephyr cannot open host display. Is DISPLAY set?\n");
- exit(1);
- }
+ {
+ fprintf(stderr, "\nXephyr cannot open host display. Is DISPLAY set?\n");
+ exit(1);
+ }
HostX.screen = DefaultScreen(HostX.dpy);
HostX.winroot = RootWindow(HostX.dpy, HostX.screen);
HostX.gc = XCreateGC(HostX.dpy, HostX.winroot, 0, NULL);
HostX.depth = DefaultDepth(HostX.dpy, HostX.screen);
- HostX.visual = DefaultVisual(HostX.dpy, HostX.screen);
-
- HostX.server_depth = HostX.depth;
-
- if (HostX.win_pre_existing != None)
- {
- Status result;
- XWindowAttributes prewin_attr;
-
- /* Get screen size from existing window */
-
- hostx_errors_trap();
-
- result = XGetWindowAttributes(HostX.dpy,
- HostX.win_pre_existing,
- &prewin_attr);
-
-
- if (hostx_errors_untrap() || !result)
- {
- fprintf(stderr, "\nXephyr -parent window' does not exist!\n");
- exit(1);
- }
-
- HostX.win_width = prewin_attr.width;
- HostX.win_height = prewin_attr.height;
+ HostX.visual = DefaultVisual(HostX.dpy, HostX.screen);
- HostX.win = XCreateWindow(HostX.dpy,
- HostX.win_pre_existing,
- 0,0,HostX.win_width,HostX.win_height,
- 0,
- CopyFromParent,
- CopyFromParent,
- CopyFromParent,
- CWEventMask,
- &attr);
- }
- else
+ for (index = 0 ; index < HostX.n_screens ; index++)
{
- HostX.win = XCreateWindow(HostX.dpy,
- HostX.winroot,
- 0,0,100,100, /* will resize */
- 0,
- CopyFromParent,
- CopyFromParent,
- CopyFromParent,
- CWEventMask,
- &attr);
+ struct EphyrHostScreen *host_screen = &HostX.screens[index];
- hostx_set_win_title("( ctrl+shift grabs mouse and keyboard )");
-
- if (HostX.use_fullscreen)
- {
- HostX.win_width = DisplayWidth(HostX.dpy, HostX.screen);
- HostX.win_height = DisplayHeight(HostX.dpy, HostX.screen);
-
- hostx_set_fullscreen_hint();
- }
+ host_screen->server_depth = HostX.depth;
+ if (host_screen->win_pre_existing != None)
+ {
+ Status result;
+ XWindowAttributes prewin_attr;
+
+ /* Get screen size from existing window */
+
+ hostx_errors_trap();
+
+ result = XGetWindowAttributes (HostX.dpy,
+ host_screen->win_pre_existing,
+ &prewin_attr);
+
+
+ if (hostx_errors_untrap() || !result)
+ {
+ fprintf (stderr, "\nXephyr -parent window' does not exist!\n");
+ exit (1);
+ }
+
+ host_screen->win_width = prewin_attr.width;
+ host_screen->win_height = prewin_attr.height;
+
+ host_screen->win = XCreateWindow (HostX.dpy,
+ host_screen->win_pre_existing,
+ 0,0,
+ host_screen->win_width,
+ host_screen->win_height,
+ 0,
+ CopyFromParent,
+ CopyFromParent,
+ CopyFromParent,
+ CWEventMask,
+ &attr);
+ }
+ else
+ {
+ host_screen->win = XCreateWindow (HostX.dpy,
+ HostX.winroot,
+ 0,0,100,100, /* will resize */
+ 0,
+ CopyFromParent,
+ CopyFromParent,
+ CopyFromParent,
+ CWEventMask,
+ &attr);
+
+ hostx_set_win_title (host_screen->info,
+ "(ctrl+shift grabs mouse and keyboard)");
+
+ if (HostX.use_fullscreen)
+ {
+ host_screen->win_width = DisplayWidth(HostX.dpy, HostX.screen);
+ host_screen->win_height = DisplayHeight(HostX.dpy, HostX.screen);
+
+ hostx_set_fullscreen_hint();
+ }
+ }
}
- XParseColor(HostX.dpy, DefaultColormap(HostX.dpy,HostX.screen), "red", &col);
- XAllocColor(HostX.dpy, DefaultColormap(HostX.dpy, HostX.screen), &col);
- XSetForeground(HostX.dpy, HostX.gc, col.pixel);
+ XParseColor (HostX.dpy, DefaultColormap (HostX.dpy,HostX.screen),
+ "red", &col);
+ XAllocColor (HostX.dpy, DefaultColormap (HostX.dpy, HostX.screen),
+ &col);
+ XSetForeground (HostX.dpy, HostX.gc, col.pixel);
- if (!hostx_want_host_cursor())
+ if (!hostx_want_host_cursor ())
{
/* Ditch the cursor, we provide our 'own' */
cursor_pxm = XCreatePixmap (HostX.dpy, HostX.winroot, 1, 1, 1);
memset (&col, 0, sizeof (col));
- empty_cursor = XCreatePixmapCursor (HostX.dpy,
- cursor_pxm, cursor_pxm,
- &col, &col, 1, 1);
- XDefineCursor (HostX.dpy, HostX.win, empty_cursor);
+ empty_cursor = XCreatePixmapCursor (HostX.dpy,
+ cursor_pxm, cursor_pxm,
+ &col, &col, 1, 1);
+ for ( index = 0 ; index < HostX.n_screens ; index++ )
+ {
+ XDefineCursor (HostX.dpy,
+ HostX.screens[index].win,
+ empty_cursor);
+ }
XFreePixmap (HostX.dpy, cursor_pxm);
}
- HostX.ximg = NULL;
-
+ for (index = 0 ; index < HostX.n_screens ; index++)
+ {
+ HostX.screens[index].ximg = NULL;
+ }
/* Try to get share memory ximages for a little bit more speed */
- if (!XShmQueryExtension(HostX.dpy) || getenv("XEPHYR_NO_SHM"))
+ if (!XShmQueryExtension(HostX.dpy) || getenv("XEPHYR_NO_SHM"))
{
fprintf(stderr, "\nXephyr unable to use SHM XImages\n");
HostX.have_shm = False;
- }
- else
- {
+ }
+ else
+ {
/* Really really check we have shm - better way ?*/
- XShmSegmentInfo shminfo;
+ XShmSegmentInfo shminfo;
- HostX.have_shm = True;
+ HostX.have_shm = True;
- shminfo.shmid=shmget(IPC_PRIVATE, 1, IPC_CREAT|0777);
- shminfo.shmaddr=shmat(shminfo.shmid,0,0);
- shminfo.readOnly=True;
+ shminfo.shmid=shmget(IPC_PRIVATE, 1, IPC_CREAT|0777);
+ shminfo.shmaddr=shmat(shminfo.shmid,0,0);
+ shminfo.readOnly=True;
- hostx_errors_trap();
-
- XShmAttach(HostX.dpy, &shminfo);
- XSync(HostX.dpy, False);
+ hostx_errors_trap();
- if (hostx_errors_untrap())
- {
- fprintf(stderr, "\nXephyr unable to use SHM XImages\n");
- HostX.have_shm = False;
- }
+ XShmAttach(HostX.dpy, &shminfo);
+ XSync(HostX.dpy, False);
- shmdt(shminfo.shmaddr);
- shmctl(shminfo.shmid, IPC_RMID, 0);
- }
+ if (hostx_errors_untrap())
+ {
+ fprintf(stderr, "\nXephyr unable to use SHM XImages\n");
+ HostX.have_shm = False;
+ }
+
+ shmdt(shminfo.shmaddr);
+ shmctl(shminfo.shmid, IPC_RMID, 0);
+}
XFlush(HostX.dpy);
@@ -360,10 +444,10 @@ hostx_init(void)
HostX.damage_debug_msec = 20000; /* 1/50 th of a second */
- if (getenv("XEPHYR_PAUSE"))
+ if (getenv ("XEPHYR_PAUSE"))
{
- HostX.damage_debug_msec = strtol(getenv("XEPHYR_PAUSE"), NULL, 0);
- EPHYR_DBG("pause is %li\n", HostX.damage_debug_msec);
+ HostX.damage_debug_msec = strtol (getenv ("XEPHYR_PAUSE"), NULL, 0);
+ EPHYR_DBG ("pause is %li\n", HostX.damage_debug_msec);
}
return 1;
@@ -376,38 +460,54 @@ hostx_get_depth (void)
}
int
-hostx_get_server_depth (void)
+hostx_get_server_depth (EphyrScreenInfo screen)
{
- return HostX.server_depth;
+ struct EphyrHostScreen *host_screen = host_screen_from_screen_info (screen);
+
+ return (host_screen ? host_screen->server_depth : 0);
}
void
-hostx_set_server_depth(int depth)
+hostx_set_server_depth (EphyrScreenInfo screen, int depth)
{
- HostX.server_depth = depth;
+ struct EphyrHostScreen *host_screen = host_screen_from_screen_info (screen);
+
+ if (host_screen)
+ host_screen->server_depth = depth;
}
int
-hostx_get_bpp(void)
+hostx_get_bpp (EphyrScreenInfo screen)
{
- if (host_depth_matches_server())
- return HostX.visual->bits_per_rgb;
+ struct EphyrHostScreen *host_screen = host_screen_from_screen_info (screen);
+
+ if (!host_screen)
+ return 0;
+
+ if (host_depth_matches_server (host_screen))
+ return HostX.visual->bits_per_rgb;
else
- return HostX.server_depth; /* XXX correct ? */
+ return host_screen->server_depth; /*XXX correct ?*/
}
void
-hostx_get_visual_masks (CARD32 *rmsk,
- CARD32 *gmsk,
+hostx_get_visual_masks (EphyrScreenInfo screen,
+ CARD32 *rmsk,
+ CARD32 *gmsk,
CARD32 *bmsk)
{
- if (host_depth_matches_server())
+ struct EphyrHostScreen *host_screen = host_screen_from_screen_info (screen);
+
+ if (!host_screen)
+ return;
+
+ if (host_depth_matches_server(host_screen))
{
*rmsk = HostX.visual->red_mask;
*gmsk = HostX.visual->green_mask;
*bmsk = HostX.visual->blue_mask;
}
- else if (HostX.server_depth == 16)
+ else if (host_screen->server_depth == 16)
{
/* Assume 16bpp 565 */
*rmsk = 0xf800;
@@ -423,9 +523,9 @@ hostx_get_visual_masks (CARD32 *rmsk,
}
void
-hostx_set_cmap_entry(unsigned char idx,
- unsigned char r,
- unsigned char g,
+hostx_set_cmap_entry(unsigned char idx,
+ unsigned char r,
+ unsigned char g,
unsigned char b)
{
/* XXX Will likely break for 8 on 16, not sure if this is correct */
@@ -445,15 +545,25 @@ hostx_set_cmap_entry(unsigned char idx,
* by fakexa for storing offscreen pixmap data.
*/
void*
-hostx_screen_init (int width, int height, int buffer_height)
+hostx_screen_init (EphyrScreenInfo screen,
+ int width, int height,
+ int buffer_height)
{
int bitmap_pad;
Bool shm_success = False;
XSizeHints *size_hints;
- EPHYR_DBG("mark");
+ struct EphyrHostScreen *host_screen = host_screen_from_screen_info (screen);
+ if (!host_screen)
+ {
+ fprintf (stderr, "%s: Error in accessing hostx data\n", __func__ );
+ exit(1);
+ }
- if (HostX.ximg != NULL)
+ EPHYR_DBG ("host_screen=%p wxh=%dx%d, buffer_height=%d",
+ host_screen, width, height, buffer_height);
+
+ if (host_screen->ximg != NULL)
{
/* Free up the image data if previously used
* i.ie called by server reset
@@ -461,47 +571,48 @@ hostx_screen_init (int width, int height
if (HostX.have_shm)
{
- XShmDetach(HostX.dpy, &HostX.shminfo);
- XDestroyImage (HostX.ximg);
- shmdt(HostX.shminfo.shmaddr);
- shmctl(HostX.shminfo.shmid, IPC_RMID, 0);
+ XShmDetach(HostX.dpy, &host_screen->shminfo);
+ XDestroyImage (host_screen->ximg);
+ shmdt(host_screen->shminfo.shmaddr);
+ shmctl(host_screen->shminfo.shmid, IPC_RMID, 0);
}
else
{
- if (HostX.ximg->data)
+ if (host_screen->ximg->data)
{
- free(HostX.ximg->data);
- HostX.ximg->data = NULL;
+ free(host_screen->ximg->data);
+ host_screen->ximg->data = NULL;
}
- XDestroyImage(HostX.ximg);
+ XDestroyImage(host_screen->ximg);
}
}
if (HostX.have_shm)
{
- HostX.ximg = XShmCreateImage(HostX.dpy, HostX.visual, HostX.depth,
- ZPixmap, NULL, &HostX.shminfo,
- width, buffer_height );
-
- HostX.shminfo.shmid = shmget(IPC_PRIVATE,
- HostX.ximg->bytes_per_line * buffer_height,
- IPC_CREAT|0777);
- HostX.shminfo.shmaddr = HostX.ximg->data = shmat(HostX.shminfo.shmid,
- 0, 0);
+ host_screen->ximg = XShmCreateImage (HostX.dpy, HostX.visual, HostX.depth,
+ ZPixmap, NULL, &host_screen->shminfo,
+ width, buffer_height );
+
+ host_screen->shminfo.shmid =
+ shmget(IPC_PRIVATE,
+ host_screen->ximg->bytes_per_line * buffer_height,
+ IPC_CREAT|0777);
+ host_screen->ximg->data = shmat(host_screen->shminfo.shmid, 0, 0);
+ host_screen->shminfo.shmaddr = host_screen->ximg->data;
- if (HostX.ximg->data == (char *)-1)
+ if (host_screen->ximg->data == (char *)-1)
{
EPHYR_DBG("Can't attach SHM Segment, falling back to plain XImages");
HostX.have_shm = False;
- XDestroyImage(HostX.ximg);
- shmctl(HostX.shminfo.shmid, IPC_RMID, 0);
+ XDestroyImage(host_screen->ximg);
+ shmctl(host_screen->shminfo.shmid, IPC_RMID, 0);
}
else
{
- EPHYR_DBG("SHM segment attached");
- HostX.shminfo.readOnly = False;
- XShmAttach(HostX.dpy, &HostX.shminfo);
+ EPHYR_DBG("SHM segment attached %p", host_screen->shminfo.shmaddr);
+ host_screen->shminfo.readOnly = False;
+ XShmAttach(HostX.dpy, &host_screen->shminfo);
shm_success = True;
}
}
@@ -509,63 +620,74 @@ hostx_screen_init (int width, int height
if (!shm_success)
{
bitmap_pad = ( HostX.depth > 16 )? 32 : (( HostX.depth > 8 )? 16 : 8 );
-
- HostX.ximg = XCreateImage( HostX.dpy,
- HostX.visual,
- HostX.depth,
- ZPixmap, 0, 0,
- width,
- buffer_height,
- bitmap_pad,
- 0);
- HostX.ximg->data = malloc( HostX.ximg->bytes_per_line * buffer_height );
- }
+ EPHYR_DBG("Creating image %dx%d for screen host_screen=%p\n",
+ width, buffer_height, host_screen );
+ host_screen->ximg = XCreateImage (HostX.dpy,
+ HostX.visual,
+ HostX.depth,
+ ZPixmap, 0, 0,
+ width,
+ buffer_height,
+ bitmap_pad,
+ 0);
+ host_screen->ximg->data =
+ malloc (host_screen->ximg->bytes_per_line * buffer_height);
+ }
- XResizeWindow(HostX.dpy, HostX.win, width, height);
+ XResizeWindow (HostX.dpy, host_screen->win, width, height);
/* Ask the WM to keep our size static */
size_hints = XAllocSizeHints();
size_hints->max_width = size_hints->min_width = width;
size_hints->max_height = size_hints->min_height = height;
size_hints->flags = PMinSize|PMaxSize;
- XSetWMNormalHints(HostX.dpy, HostX.win, size_hints);
+ XSetWMNormalHints(HostX.dpy, host_screen->win, size_hints);
XFree(size_hints);
- XMapWindow(HostX.dpy, HostX.win);
+ XMapWindow(HostX.dpy, host_screen->win);
XSync(HostX.dpy, False);
- HostX.win_width = width;
- HostX.win_height = height;
+ host_screen->win_width = width;
+ host_screen->win_height = height;
- if (host_depth_matches_server())
+ if (host_depth_matches_server(host_screen))
{
EPHYR_DBG("Host matches server");
- return HostX.ximg->data;
+ return host_screen->ximg->data;
}
else
{
- EPHYR_DBG("server bpp %i", HostX.server_depth>>3);
- HostX.fb_data = malloc(width*buffer_height*(HostX.server_depth>>3));
- return HostX.fb_data;
+ EPHYR_DBG("server bpp %i", host_screen->server_depth>>3);
+ host_screen->fb_data = malloc(width*buffer_height*(host_screen->server_depth>>3));
+ return host_screen->fb_data;
}
}
+static void hostx_paint_debug_rect (struct EphyrHostScreen *host_screen,
+ int x, int y,
+ int width, int height);
+
void
-hostx_paint_rect(int sx, int sy,
- int dx, int dy,
- int width, int height)
+hostx_paint_rect (EphyrScreenInfo screen,
+ int sx, int sy,
+ int dx, int dy,
+ int width, int height)
{
- /*
+ struct EphyrHostScreen *host_screen = host_screen_from_screen_info (screen);
+
+ EPHYR_DBG ("painting in screen %d\n", host_screen->mynum) ;
+
+ /*
* Copy the image data updated by the shadow layer
* on to the window
*/
if (HostXWantDamageDebug)
{
- hostx_paint_debug_rect(dx, dy, width, height);
+ hostx_paint_debug_rect(host_screen, dx, dy, width, height);
}
/*
@@ -580,22 +702,23 @@ hostx_paint_rect(int sx, int sy,
* ... and it will be slower than the matching depth case.
*/
- if (!host_depth_matches_server())
+ if (!host_depth_matches_server(host_screen))
{
- int x,y,idx, bytes_per_pixel = (HostX.server_depth>>3);
+ int x,y,idx, bytes_per_pixel = (host_screen->server_depth>>3);
unsigned char r,g,b;
unsigned long host_pixel;
+ EPHYR_DBG("Unmatched host depth host_screen=%p\n", host_screen);
for (y=sy; y<sy+height; y++)
for (x=sx; x<sx+width; x++)
{
- idx = (HostX.win_width*y*bytes_per_pixel)+(x*bytes_per_pixel);
-
- switch (HostX.server_depth)
+ idx = (host_screen->win_width*y*bytes_per_pixel)+(x*bytes_per_pixel);
+
+ switch (host_screen->server_depth)
{
case 16:
{
- unsigned short pixel = *(unsigned short*)(HostX.fb_data+idx);
+ unsigned short pixel = *(unsigned short*)(host_screen->fb_data+idx);
r = ((pixel & 0xf800) >> 8);
g = ((pixel & 0x07e0) >> 3);
@@ -603,13 +726,13 @@ hostx_paint_rect(int sx, int sy,
host_pixel = (r << 16) | (g << 8) | (b);
- XPutPixel(HostX.ximg, x, y, host_pixel);
+ XPutPixel(host_screen->ximg, x, y, host_pixel);
break;
}
case 8:
{
- unsigned char pixel = *(unsigned char*)(HostX.fb_data+idx);
- XPutPixel(HostX.ximg, x, y, HostX.cmap[pixel]);
+ unsigned char pixel = *(unsigned char*)(host_screen->fb_data+idx);
+ XPutPixel(host_screen->ximg, x, y, HostX.cmap[pixel]);
break;
}
default:
@@ -620,21 +743,23 @@ hostx_paint_rect(int sx, int sy,
if (HostX.have_shm)
{
- XShmPutImage(HostX.dpy, HostX.win, HostX.gc, HostX.ximg,
- sx, sy, dx, dy, width, height, False);
+ XShmPutImage (HostX.dpy, host_screen->win,
+ HostX.gc, host_screen->ximg,
+ sx, sy, dx, dy, width, height, False);
}
else
{
- XPutImage(HostX.dpy, HostX.win, HostX.gc, HostX.ximg,
- sx, sy, dx, dy, width, height);
+ XPutImage (HostX.dpy, host_screen->win, HostX.gc, host_screen->ximg,
+ sx, sy, dx, dy, width, height);
}
- XSync(HostX.dpy, False);
+ XSync (HostX.dpy, False);
}
-void
-hostx_paint_debug_rect(int x, int y,
- int width, int height)
+static void
+hostx_paint_debug_rect (struct EphyrHostScreen *host_screen,
+ int x, int y,
+ int width, int height)
{
struct timespec tspec;
@@ -646,8 +771,8 @@ hostx_paint_debug_rect(int x, int y,
/* fprintf(stderr, "Xephyr updating: %i+%i %ix%i\n", x, y, width, height); */
- XFillRectangle(HostX.dpy, HostX.win, HostX.gc, x, y, width,height);
- XSync(HostX.dpy, False);
+ XFillRectangle (HostX.dpy, host_screen->win, HostX.gc, x, y, width,height);
+ XSync (HostX.dpy, False);
/* nanosleep seems to work better than usleep for me... */
nanosleep(&tspec, NULL);
@@ -660,14 +785,14 @@ hostx_load_keymap(void)
int host_width, min_keycode, max_keycode, width;
int i,j;
- XDisplayKeycodes(HostX.dpy, &min_keycode, &max_keycode);
+ XDisplayKeycodes (HostX.dpy, &min_keycode, &max_keycode);
- EPHYR_DBG("min: %d, max: %d", min_keycode, max_keycode);
+ EPHYR_DBG ("min: %d, max: %d", min_keycode, max_keycode);
- keymap = XGetKeyboardMapping(HostX.dpy,
- min_keycode,
- max_keycode - min_keycode + 1,
- &host_width);
+ keymap = XGetKeyboardMapping (HostX.dpy,
+ min_keycode,
+ max_keycode - min_keycode + 1,
+ &host_width);
/* Try and copy the hosts keymap into our keymap to avoid loads
* of messing around.
@@ -688,7 +813,7 @@ hostx_load_keymap(void)
ephyrKeySyms.map[(i*width)+j] = (CARD32) keymap[(i*host_width) + j];
EPHYR_DBG("keymap width, host:%d kdrive:%d", host_width, width);
-
+
ephyrKeySyms.minKeyCode = min_keycode;
ephyrKeySyms.maxKeyCode = max_keycode;
ephyrKeySyms.mapWidth = width;
@@ -696,11 +821,26 @@ hostx_load_keymap(void)
XFree(keymap);
}
+static struct EphyrHostScreen *
+host_screen_from_window (Window w)
+{
+ int index;
+
+ for (index = 0 ; index < HostX.n_screens ; index++)
+ {
+ if (HostX.screens[index].win == w)
+ {
+ return &HostX.screens[index];
+ }
+ }
+ return NULL;
+}
+
int
hostx_get_event(EphyrHostXEvent *ev)
{
XEvent xev;
- static Bool grabbed;
+ static int grabbed_screen = -1;
if (XPending(HostX.dpy))
{
@@ -710,15 +850,27 @@ hostx_get_event(EphyrHostXEvent *ev)
{
case Expose:
/* Not so great event compression, but works ok */
- while (XCheckTypedWindowEvent(HostX.dpy, xev.xexpose.window,
+ while (XCheckTypedWindowEvent(HostX.dpy, xev.xexpose.window,
Expose, &xev));
- hostx_paint_rect(0, 0, 0, 0, HostX.win_width, HostX.win_height);
+ {
+ struct EphyrHostScreen *host_screen =
+ host_screen_from_window (xev.xexpose.window);
+ hostx_paint_rect (host_screen->info, 0, 0, 0, 0,
+ host_screen->win_width,
+ host_screen->win_height);
+ }
return 0;
case MotionNotify:
- ev->type = EPHYR_EV_MOUSE_MOTION;
- ev->data.mouse_motion.x = xev.xmotion.x;
- ev->data.mouse_motion.y = xev.xmotion.y;
+ {
+ struct EphyrHostScreen *host_screen =
+ host_screen_from_window (xev.xmotion.window);
+
+ ev->type = EPHYR_EV_MOUSE_MOTION;
+ ev->data.mouse_motion.x = xev.xmotion.x;
+ ev->data.mouse_motion.y = xev.xmotion.y;
+ ev->data.mouse_motion.screen = (host_screen ? host_screen->mynum : -1);
+ }
return 1;
case ButtonPress:
@@ -750,29 +902,35 @@ hostx_get_event(EphyrHostXEvent *ev)
|| XKeycodeToKeysym(HostX.dpy,xev.xkey.keycode,0) == XK_Shift_R)
&& (xev.xkey.state & ControlMask))
{
- if (grabbed)
+ struct EphyrHostScreen *host_screen =
+ host_screen_from_window (xev.xexpose.window);
+
+ if (grabbed_screen != -1)
{
XUngrabKeyboard (HostX.dpy, CurrentTime);
XUngrabPointer (HostX.dpy, CurrentTime);
- grabbed = False;
- hostx_set_win_title("( ctrl+shift grabs mouse and keyboard )");
- }
- else
+ grabbed_screen = -1;
+ hostx_set_win_title (host_screen->info,
+ "(ctrl+shift grabs mouse and keyboard)");
+ }
+ else
{
/* Attempt grab */
- if (XGrabKeyboard (HostX.dpy, HostX.win, True,
+ if (XGrabKeyboard (HostX.dpy, host_screen->win, True,
GrabModeAsync,
GrabModeAsync,
CurrentTime) == 0)
{
- if (XGrabPointer (HostX.dpy, HostX.win, True,
+ if (XGrabPointer (HostX.dpy, host_screen->win, True,
NoEventMask,
GrabModeAsync,
GrabModeAsync,
- HostX.win, None, CurrentTime) == 0)
+ host_screen->win, None, CurrentTime) == 0)
{
- grabbed = True;
- hostx_set_win_title("( ctrl+shift releases mouse and keyboard )");
+ grabbed_screen = host_screen->mynum;
+ hostx_set_win_title
+ (host_screen->info,
+ "(ctrl+shift releases mouse and keyboard)");
}
else /* Failed pointer grabm ungrab keyboard */
XUngrabKeyboard (HostX.dpy, CurrentTime);
diff --git a/hw/kdrive/ephyr/hostx.h b/hw/kdrive/ephyr/hostx.h
index 4d5f37f..93765d0 100644
--- a/hw/kdrive/ephyr/hostx.h
+++ b/hw/kdrive/ephyr/hostx.h
@@ -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);
@@ -119,25 +120,32 @@ 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);
diff --git a/hw/kdrive/ephyr/os.c b/hw/kdrive/ephyr/os.c
index 1a42495..b58daae 100644
--- a/hw/kdrive/ephyr/os.c
+++ b/hw/kdrive/ephyr/os.c
@@ -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();
}
diff-tree 81692b628f41cb64329f3cccc0503fb216a2b8e3 (from dc90d500085dd74e90073be008fc514bd97b160a)
Author: Dodji Seketeli <dodji at openedhand.com>
Date: Tue Oct 2 13:11:28 2007 +0200
Fix #12650: "windows not receiving mouse events in multiple screens context"
* dix/events.c, include/dix.h:
(UpdateSpriteForScreen): added this to update the mouse sprite context
when we switch from a pScreen to another.
* mi/mipointer.c:
(miPointerWarpCursor): as we are switching to a new pScreen,
don't forget to update the mouse sprite context.
diff --git a/dix/events.c b/dix/events.c
index 7b4cab0..61dd534 100644
--- a/dix/events.c
+++ b/dix/events.c
@@ -2352,6 +2352,61 @@ DefineInitialRootWindow(WindowPtr win)
#endif
}
+/**
+ * Update the mouse sprite info when the server switches from a pScreen to another.
+ * Otherwise, the pScreen of the mouse sprite is never updated when we switch
+ * from a pScreen to another. Never updating the pScreen of the mouse sprite
+ * implies that windows that are in pScreen whose pScreen->myNum >0 will never
+ * get pointer events. This is because in CheckMotion(), sprite.hotPhys.pScreen
+ * always points to the first pScreen it has been set by
+ * DefineInitialRootWindow().
+ *
+ * Calling this function is useful for use cases where the server
+ * has more than one pScreen.
+ * This function is similar to DefineInitialRootWindow() but it does not
+ * reset the mouse pointer position.
+ * @param win must be the new pScreen we are switching to.
+ */
+void
+UpdateSpriteForScreen(ScreenPtr pScreen)
+{
+ WindowPtr win = NULL;
+ if (!pScreen)
+ return ;
+ win = WindowTable[pScreen->myNum];
+
+ sprite.hotPhys.pScreen = pScreen;
+ sprite.hot = sprite.hotPhys;
+ sprite.hotLimits.x2 = pScreen->width;
+ sprite.hotLimits.y2 = pScreen->height;
+#ifdef XEVIE
+ xeviewin =
+#endif
+ sprite.win = win;
+ sprite.current = wCursor (win);
+ sprite.current->refcnt++;
+ spriteTraceGood = 1;
+ ROOT = win;
+ (*pScreen->CursorLimits) (pScreen,
+ sprite.current,
+ &sprite.hotLimits,
+ &sprite.physLimits);
+ sprite.confined = FALSE;
+ (*pScreen->ConstrainCursor) (pScreen, &sprite.physLimits);
+ (*pScreen->DisplayCursor) (pScreen, sprite.current);
+
+#ifdef PANORAMIX
+ if(!noPanoramiXExtension) {
+ sprite.hotLimits.x1 = -panoramiXdataPtr[0].x;
+ sprite.hotLimits.y1 = -panoramiXdataPtr[0].y;
+ sprite.hotLimits.x2 = PanoramiXPixWidth - panoramiXdataPtr[0].x;
+ sprite.hotLimits.y2 = PanoramiXPixHeight - panoramiXdataPtr[0].y;
+ sprite.physLimits = sprite.hotLimits;
+ sprite.screen = pScreen;
+ }
+#endif
+}
+
/*
* This does not take any shortcuts, and even ignores its argument, since
* it does not happen very often, and one has to walk up the tree since
diff --git a/include/dix.h b/include/dix.h
index c1d609a..6a67d14 100644
--- a/include/dix.h
+++ b/include/dix.h
@@ -415,6 +415,9 @@ extern int DeliverDeviceEvents(
extern void DefineInitialRootWindow(
WindowPtr /* win */);
+extern void UpdateSpriteForScreen(
+ ScreenPtr /* pScreen */);
+
extern void WindowHasNewCursor(
WindowPtr /* pWin */);
diff --git a/mi/mipointer.c b/mi/mipointer.c
index b86a26a..24ff4cc 100644
--- a/mi/mipointer.c
+++ b/mi/mipointer.c
@@ -262,6 +262,7 @@ miPointerWarpCursor (pScreen, x, y)
miPointer.y = y;
miPointer.pScreen = pScreen;
}
+ UpdateSpriteForScreen (pScreen) ;
}
/*
More information about the xorg-commit
mailing list