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
|
||||
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;
|
||||
}
|
||||
|
||||
*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);
|
||||
|
@ -227,7 +226,7 @@ ephyrMapFramebuffer (KdScreenInfo *screen)
|
|||
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
|
||||
|
@ -330,13 +329,13 @@ ephyrInternalDamageRedisplay (ScreenPtr pScreen)
|
|||
|
||||
while (nbox--)
|
||||
{
|
||||
hostx_paint_rect(pbox->x1, pbox->y1,
|
||||
hostx_paint_rect(screen,
|
||||
pbox->x1, pbox->y1,
|
||||
pbox->x1, pbox->y1,
|
||||
pbox->x2 - pbox->x1,
|
||||
pbox->y2 - pbox->y1);
|
||||
pbox++;
|
||||
}
|
||||
|
||||
DamageEmpty (scrpriv->pDamage);
|
||||
}
|
||||
}
|
||||
|
@ -435,7 +434,7 @@ ephyrRandRGetInfo (ScreenPtr pScreen, Rotation *rotations)
|
|||
|
||||
*rotations = RR_Rotate_All|RR_Reflect_All;
|
||||
|
||||
if (!hostx_want_preexisting_window()
|
||||
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;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
|
@ -754,18 +808,36 @@ ephyrPoll(void)
|
|||
{
|
||||
case EPHYR_EV_MOUSE_MOTION:
|
||||
if (!ephyrMouse ||
|
||||
!((EphyrPointerPrivate *)ephyrMouse->driverPrivate)->enabled)
|
||||
!((EphyrPointerPrivate *)ephyrMouse->driverPrivate)->enabled) {
|
||||
EPHYR_DBG ("skipping mouse motion:%d\n", ephyrCurScreen) ;
|
||||
continue;
|
||||
}
|
||||
{
|
||||
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,16 +102,57 @@ 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)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -198,8 +241,10 @@ miPointerSpriteFuncRec EphyrPointerSpriteFuncs = {
|
|||
Bool
|
||||
ephyrCursorInit(ScreenPtr pScreen)
|
||||
{
|
||||
miPointerInitialize(pScreen, &EphyrPointerSpriteFuncs,
|
||||
&kdPointerScreenFuncs, FALSE);
|
||||
miPointerInitialize(pScreen,
|
||||
&EphyrPointerSpriteFuncs,
|
||||
&ephyrPointerScreenFuncs,
|
||||
FALSE);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
|
|
@ -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,19 +140,39 @@ 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;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
hostx_add_screen (EphyrScreenInfo screen,
|
||||
unsigned long win_id,
|
||||
int screen_num)
|
||||
{
|
||||
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_display_name (char *name)
|
||||
{
|
||||
|
@ -135,15 +180,31 @@ hostx_set_display_name(char *name)
|
|||
}
|
||||
|
||||
void
|
||||
hostx_set_win_title(char *extra_text)
|
||||
hostx_set_screen_number(EphyrScreenInfo screen, int number)
|
||||
{
|
||||
char buf[256];
|
||||
struct EphyrHostScreen *host_screen = host_screen_from_screen_info (screen);
|
||||
if (host_screen) {
|
||||
host_screen->mynum = number;
|
||||
hostx_set_win_title (host_screen->info, "") ;
|
||||
}}
|
||||
|
||||
snprintf(buf, 256, "Xephyr on %s %s",
|
||||
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];
|
||||
|
||||
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, HostX.win, buf);
|
||||
XStoreName (HostX.dpy, host_screen->win, buf);
|
||||
}
|
||||
|
||||
int
|
||||
|
@ -159,13 +220,19 @@ hostx_use_host_cursor(void)
|
|||
}
|
||||
|
||||
int
|
||||
hostx_want_preexisting_window(void)
|
||||
hostx_want_preexisting_window (EphyrScreenInfo screen)
|
||||
{
|
||||
struct EphyrHostScreen *host_screen = host_screen_from_screen_info (screen);
|
||||
|
||||
if (host_screen && host_screen->win_pre_existing)
|
||||
{
|
||||
if (HostX.win_pre_existing)
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
hostx_use_fullscreen (void)
|
||||
|
@ -183,24 +250,23 @@ static 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,
|
||||
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)
|
||||
{
|
||||
|
@ -211,7 +277,8 @@ 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
|
||||
|
@ -221,6 +288,7 @@ hostx_init(void)
|
|||
Cursor empty_cursor;
|
||||
Pixmap cursor_pxm;
|
||||
XColor col;
|
||||
int index;
|
||||
|
||||
attr.event_mask =
|
||||
ButtonPressMask
|
||||
|
@ -244,9 +312,12 @@ hostx_init(void)
|
|||
HostX.depth = DefaultDepth(HostX.dpy, HostX.screen);
|
||||
HostX.visual = DefaultVisual(HostX.dpy, HostX.screen);
|
||||
|
||||
HostX.server_depth = HostX.depth;
|
||||
for (index = 0 ; index < HostX.n_screens ; index++)
|
||||
{
|
||||
struct EphyrHostScreen *host_screen = &HostX.screens[index];
|
||||
|
||||
if (HostX.win_pre_existing != None)
|
||||
host_screen->server_depth = HostX.depth;
|
||||
if (host_screen->win_pre_existing != None)
|
||||
{
|
||||
Status result;
|
||||
XWindowAttributes prewin_attr;
|
||||
|
@ -256,7 +327,7 @@ hostx_init(void)
|
|||
hostx_errors_trap();
|
||||
|
||||
result = XGetWindowAttributes (HostX.dpy,
|
||||
HostX.win_pre_existing,
|
||||
host_screen->win_pre_existing,
|
||||
&prewin_attr);
|
||||
|
||||
|
||||
|
@ -266,12 +337,14 @@ hostx_init(void)
|
|||
exit (1);
|
||||
}
|
||||
|
||||
HostX.win_width = prewin_attr.width;
|
||||
HostX.win_height = prewin_attr.height;
|
||||
host_screen->win_width = prewin_attr.width;
|
||||
host_screen->win_height = prewin_attr.height;
|
||||
|
||||
HostX.win = XCreateWindow(HostX.dpy,
|
||||
HostX.win_pre_existing,
|
||||
0,0,HostX.win_width,HostX.win_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,
|
||||
|
@ -281,7 +354,7 @@ hostx_init(void)
|
|||
}
|
||||
else
|
||||
{
|
||||
HostX.win = XCreateWindow(HostX.dpy,
|
||||
host_screen->win = XCreateWindow (HostX.dpy,
|
||||
HostX.winroot,
|
||||
0,0,100,100, /* will resize */
|
||||
0,
|
||||
|
@ -291,20 +364,24 @@ hostx_init(void)
|
|||
CWEventMask,
|
||||
&attr);
|
||||
|
||||
hostx_set_win_title("( ctrl+shift grabs mouse and keyboard )");
|
||||
hostx_set_win_title (host_screen->info,
|
||||
"(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);
|
||||
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);
|
||||
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 ())
|
||||
|
@ -315,12 +392,19 @@ hostx_init(void)
|
|||
empty_cursor = XCreatePixmapCursor (HostX.dpy,
|
||||
cursor_pxm, cursor_pxm,
|
||||
&col, &col, 1, 1);
|
||||
XDefineCursor (HostX.dpy, HostX.win, empty_cursor);
|
||||
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"))
|
||||
|
@ -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())
|
||||
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,
|
||||
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;
|
||||
|
@ -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, int buffer_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,
|
||||
host_screen->ximg = XShmCreateImage (HostX.dpy, HostX.visual, HostX.depth,
|
||||
ZPixmap, NULL, &host_screen->shminfo,
|
||||
width, buffer_height );
|
||||
|
||||
HostX.shminfo.shmid = shmget(IPC_PRIVATE,
|
||||
HostX.ximg->bytes_per_line * buffer_height,
|
||||
host_screen->shminfo.shmid =
|
||||
shmget(IPC_PRIVATE,
|
||||
host_screen->ximg->bytes_per_line * buffer_height,
|
||||
IPC_CREAT|0777);
|
||||
HostX.shminfo.shmaddr = HostX.ximg->data = shmat(HostX.shminfo.shmid,
|
||||
0, 0);
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
@ -510,7 +621,9 @@ hostx_screen_init (int width, int height, int buffer_height)
|
|||
{
|
||||
bitmap_pad = ( HostX.depth > 16 )? 32 : (( HostX.depth > 8 )? 16 : 8 );
|
||||
|
||||
HostX.ximg = XCreateImage( HostX.dpy,
|
||||
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,
|
||||
|
@ -519,45 +632,54 @@ hostx_screen_init (int width, int height, int buffer_height)
|
|||
bitmap_pad,
|
||||
0);
|
||||
|
||||
HostX.ximg->data = malloc( HostX.ximg->bytes_per_line * buffer_height );
|
||||
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,
|
||||
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
|
||||
|
@ -565,7 +687,7 @@ hostx_paint_rect(int sx, int sy,
|
|||
|
||||
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);
|
||||
idx = (host_screen->win_width*y*bytes_per_pixel)+(x*bytes_per_pixel);
|
||||
|
||||
switch (HostX.server_depth)
|
||||
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,20 +743,22 @@ hostx_paint_rect(int sx, int sy,
|
|||
|
||||
if (HostX.have_shm)
|
||||
{
|
||||
XShmPutImage(HostX.dpy, HostX.win, HostX.gc, HostX.ximg,
|
||||
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,
|
||||
XPutImage (HostX.dpy, host_screen->win, HostX.gc, host_screen->ximg,
|
||||
sx, sy, dx, dy, width, height);
|
||||
}
|
||||
|
||||
XSync (HostX.dpy, False);
|
||||
}
|
||||
|
||||
void
|
||||
hostx_paint_debug_rect(int x, int y,
|
||||
static void
|
||||
hostx_paint_debug_rect (struct EphyrHostScreen *host_screen,
|
||||
int x, int y,
|
||||
int width, int height)
|
||||
{
|
||||
struct timespec tspec;
|
||||
|
@ -646,7 +771,7 @@ 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);
|
||||
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... */
|
||||
|
@ -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))
|
||||
{
|
||||
|
@ -712,13 +852,25 @@ hostx_get_event(EphyrHostXEvent *ev)
|
|||
/* Not so great event compression, but works ok */
|
||||
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:
|
||||
{
|
||||
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 )");
|
||||
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);
|
||||
|
|
|
@ -40,7 +40,7 @@
|
|||
|
||||
typedef struct EphyrHostXVars EphyrHostXVars;
|
||||
typedef struct EphyrHostXEvent EphyrHostXEvent;
|
||||
|
||||
typedef void* EphyrScreenInfo ;
|
||||
typedef enum EphyrHostXEventType
|
||||
{
|
||||
EPHYR_EV_MOUSE_MOTION,
|
||||
|
@ -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,
|
||||
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