Add support to Xephyr for lower depths than hosts
This commit is contained in:
parent
e494e24c50
commit
81a3b6fe27
|
@ -85,9 +85,18 @@ ephyrScreenInitialize (KdScreenInfo *screen, EphyrScrPriv *scrpriv)
|
||||||
|
|
||||||
|
|
||||||
if (screen->fb[0].depth && screen->fb[0].depth != hostx_get_depth())
|
if (screen->fb[0].depth && screen->fb[0].depth != hostx_get_depth())
|
||||||
ErrorF("\nXephyr screen depth must match hosts, ignoring.\n");
|
{
|
||||||
|
if (screen->fb[0].depth < hostx_get_depth()
|
||||||
|
&& (screen->fb[0].depth == 24 || screen->fb[0].depth == 16
|
||||||
|
|| screen->fb[0].depth == 8))
|
||||||
|
{
|
||||||
|
hostx_set_server_depth(screen->fb[0].depth);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
ErrorF("\nXephyr: requested screen depth not supported, setting to match hosts.\n");
|
||||||
|
}
|
||||||
|
|
||||||
screen->fb[0].depth = hostx_get_depth();
|
screen->fb[0].depth = hostx_get_server_depth();
|
||||||
screen->rate = 72;
|
screen->rate = 72;
|
||||||
|
|
||||||
if (screen->fb[0].depth <= 8)
|
if (screen->fb[0].depth <= 8)
|
||||||
|
@ -98,6 +107,13 @@ ephyrScreenInitialize (KdScreenInfo *screen, EphyrScrPriv *scrpriv)
|
||||||
(1 << PseudoColor) |
|
(1 << PseudoColor) |
|
||||||
(1 << TrueColor) |
|
(1 << TrueColor) |
|
||||||
(1 << DirectColor));
|
(1 << DirectColor));
|
||||||
|
|
||||||
|
screen->fb[0].redMask = 0x00;
|
||||||
|
screen->fb[0].greenMask = 0x00;
|
||||||
|
screen->fb[0].blueMask = 0x00;
|
||||||
|
screen->fb[0].depth = 8;
|
||||||
|
screen->fb[0].bitsPerPixel = 8;
|
||||||
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -601,6 +617,10 @@ ephyrCardFini (KdCardInfo *card)
|
||||||
void
|
void
|
||||||
ephyrGetColors (ScreenPtr pScreen, int fb, int n, xColorItem *pdefs)
|
ephyrGetColors (ScreenPtr pScreen, int fb, int n, xColorItem *pdefs)
|
||||||
{
|
{
|
||||||
|
/* XXX Not sure if this is right */
|
||||||
|
|
||||||
|
EPHYR_DBG("mark");
|
||||||
|
|
||||||
while (n--)
|
while (n--)
|
||||||
{
|
{
|
||||||
pdefs->red = 0;
|
pdefs->red = 0;
|
||||||
|
@ -608,11 +628,33 @@ ephyrGetColors (ScreenPtr pScreen, int fb, int n, xColorItem *pdefs)
|
||||||
pdefs->blue = 0;
|
pdefs->blue = 0;
|
||||||
pdefs++;
|
pdefs++;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
ephyrPutColors (ScreenPtr pScreen, int fb, int n, xColorItem *pdefs)
|
ephyrPutColors (ScreenPtr pScreen, int fb, int n, xColorItem *pdefs)
|
||||||
{
|
{
|
||||||
|
int min, max, p;
|
||||||
|
|
||||||
|
/* XXX Not sure if this is right */
|
||||||
|
|
||||||
|
min = 256;
|
||||||
|
max = 0;
|
||||||
|
|
||||||
|
while (n--)
|
||||||
|
{
|
||||||
|
p = pdefs->pixel;
|
||||||
|
if (p < min)
|
||||||
|
min = p;
|
||||||
|
if (p > max)
|
||||||
|
max = p;
|
||||||
|
|
||||||
|
hostx_set_cmap_entry(p,
|
||||||
|
pdefs->red >> 8,
|
||||||
|
pdefs->green >> 8,
|
||||||
|
pdefs->blue >> 8);
|
||||||
|
pdefs++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Mouse calls */
|
/* Mouse calls */
|
||||||
|
|
|
@ -55,16 +55,20 @@ struct EphyrHostXVars
|
||||||
Window win_pre_existing; /* Set via -parent option like xnest */
|
Window win_pre_existing; /* Set via -parent option like xnest */
|
||||||
GC gc;
|
GC gc;
|
||||||
int depth;
|
int depth;
|
||||||
|
int server_depth;
|
||||||
XImage *ximg;
|
XImage *ximg;
|
||||||
int win_width, win_height;
|
int win_width, win_height;
|
||||||
Bool use_host_cursor;
|
Bool use_host_cursor;
|
||||||
Bool have_shm;
|
Bool have_shm;
|
||||||
long damage_debug_msec;
|
long damage_debug_msec;
|
||||||
|
|
||||||
|
unsigned char *fb_data; /* only used when host bpp != server bpp */
|
||||||
|
unsigned long cmap[256];
|
||||||
|
|
||||||
XShmSegmentInfo shminfo;
|
XShmSegmentInfo shminfo;
|
||||||
};
|
};
|
||||||
|
|
||||||
static EphyrHostXVars HostX = { 0,0,0,0,0,0,0,0,0,0,0,0,0,0 }; /* defaults */
|
static EphyrHostXVars HostX = { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; /* memset? */
|
||||||
|
|
||||||
static int HostXWantDamageDebug = 0;
|
static int HostXWantDamageDebug = 0;
|
||||||
|
|
||||||
|
@ -83,6 +87,9 @@ extern int monitorResolution;
|
||||||
static int trapped_error_code = 0;
|
static int trapped_error_code = 0;
|
||||||
static int (*old_error_handler) (Display *d, XErrorEvent *e);
|
static int (*old_error_handler) (Display *d, XErrorEvent *e);
|
||||||
|
|
||||||
|
#define host_depth_matches_server() (HostX.depth == HostX.server_depth)
|
||||||
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
error_handler(Display *display,
|
error_handler(Display *display,
|
||||||
XErrorEvent *error)
|
XErrorEvent *error)
|
||||||
|
@ -188,13 +195,7 @@ hostx_init(void)
|
||||||
HostX.depth = DefaultDepth(HostX.dpy, HostX.screen);
|
HostX.depth = DefaultDepth(HostX.dpy, HostX.screen);
|
||||||
HostX.visual = DefaultVisual(HostX.dpy, HostX.screen);
|
HostX.visual = DefaultVisual(HostX.dpy, HostX.screen);
|
||||||
|
|
||||||
/* old way of getting dpi
|
HostX.server_depth = HostX.depth;
|
||||||
HostX.mm_per_pixel_vertical = (double)DisplayHeightMM(HostX.dpy, HostX.screen)
|
|
||||||
/ DisplayHeight(HostX.dpy, HostX.screen);
|
|
||||||
|
|
||||||
HostX.mm_per_pixel_horizontal = (double)DisplayWidthMM(HostX.dpy, HostX.screen)
|
|
||||||
/ DisplayWidth(HostX.dpy, HostX.screen);
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (HostX.win_pre_existing != None)
|
if (HostX.win_pre_existing != None)
|
||||||
{
|
{
|
||||||
|
@ -235,7 +236,6 @@ hostx_init(void)
|
||||||
XStoreName(HostX.dpy, HostX.win, "Xephyr");
|
XStoreName(HostX.dpy, HostX.win, "Xephyr");
|
||||||
}
|
}
|
||||||
|
|
||||||
HostX.gc = XCreateGC(HostX.dpy, HostX.winroot, 0, NULL);
|
|
||||||
|
|
||||||
XParseColor(HostX.dpy, DefaultColormap(HostX.dpy,HostX.screen), "red", &col);
|
XParseColor(HostX.dpy, DefaultColormap(HostX.dpy,HostX.screen), "red", &col);
|
||||||
XAllocColor(HostX.dpy, DefaultColormap(HostX.dpy, HostX.screen), &col);
|
XAllocColor(HostX.dpy, DefaultColormap(HostX.dpy, HostX.screen), &col);
|
||||||
|
@ -309,10 +309,25 @@ hostx_get_depth (void)
|
||||||
return HostX.depth;
|
return HostX.depth;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
hostx_get_server_depth (void)
|
||||||
|
{
|
||||||
|
return HostX.server_depth;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
hostx_set_server_depth(int depth)
|
||||||
|
{
|
||||||
|
HostX.server_depth = depth;
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
hostx_get_bpp(void)
|
hostx_get_bpp(void)
|
||||||
{
|
{
|
||||||
|
if (host_depth_matches_server())
|
||||||
return HostX.visual->bits_per_rgb;
|
return HostX.visual->bits_per_rgb;
|
||||||
|
else
|
||||||
|
return HostX.server_depth; /* XXX correct ? */
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -320,11 +335,36 @@ hostx_get_visual_masks (unsigned long *rmsk,
|
||||||
unsigned long *gmsk,
|
unsigned long *gmsk,
|
||||||
unsigned long *bmsk)
|
unsigned long *bmsk)
|
||||||
{
|
{
|
||||||
|
if (host_depth_matches_server())
|
||||||
|
{
|
||||||
*rmsk = HostX.visual->red_mask;
|
*rmsk = HostX.visual->red_mask;
|
||||||
*gmsk = HostX.visual->green_mask;
|
*gmsk = HostX.visual->green_mask;
|
||||||
*bmsk = HostX.visual->blue_mask;
|
*bmsk = HostX.visual->blue_mask;
|
||||||
|
}
|
||||||
|
else if (HostX.server_depth == 16)
|
||||||
|
{
|
||||||
|
/* Assume 16bpp 565 */
|
||||||
|
*rmsk = 0xf800;
|
||||||
|
*gmsk = 0x07e0;
|
||||||
|
*bmsk = 0x001f;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
*rmsk = 0x0;
|
||||||
|
*gmsk = 0x0;
|
||||||
|
*bmsk = 0x0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
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 */
|
||||||
|
HostX.cmap[idx] = (r << 16) | (g << 8) | (b);
|
||||||
|
}
|
||||||
|
|
||||||
void*
|
void*
|
||||||
hostx_screen_init (int width, int height)
|
hostx_screen_init (int width, int height)
|
||||||
|
@ -422,7 +462,17 @@ hostx_screen_init (int width, int height)
|
||||||
HostX.win_width = width;
|
HostX.win_width = width;
|
||||||
HostX.win_height = height;
|
HostX.win_height = height;
|
||||||
|
|
||||||
|
if (host_depth_matches_server())
|
||||||
|
{
|
||||||
|
EPHYR_DBG("Host matches server");
|
||||||
return HostX.ximg->data;
|
return HostX.ximg->data;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
EPHYR_DBG("server bpp %i", HostX.server_depth>>3);
|
||||||
|
HostX.fb_data = malloc(width*height*(HostX.server_depth>>3));
|
||||||
|
return HostX.fb_data;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -440,6 +490,56 @@ hostx_paint_rect(int sx, int sy,
|
||||||
hostx_paint_debug_rect(dx, dy, width, height);
|
hostx_paint_debug_rect(dx, dy, width, height);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If the depth of the ephyr server is less than that of the host,
|
||||||
|
* the kdrive fb does not point to the ximage data but to a buffer
|
||||||
|
* ( fb_data ), we shift the various bits from this onto the XImage
|
||||||
|
* so they match the host.
|
||||||
|
*
|
||||||
|
* Note, This code is pretty new ( and simple ) so may break on
|
||||||
|
* endian issues, 32 bpp host etc.
|
||||||
|
* Not sure if 8bpp case is right either.
|
||||||
|
* ... and it will be slower than the matching depth case.
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (!host_depth_matches_server())
|
||||||
|
{
|
||||||
|
int x,y,idx, bytes_per_pixel = (HostX.server_depth>>3);
|
||||||
|
unsigned char r,g,b;
|
||||||
|
unsigned long host_pixel;
|
||||||
|
|
||||||
|
for (x=sx; x<sx+width; x++)
|
||||||
|
for (y=sy; y<sy+height; y++)
|
||||||
|
{
|
||||||
|
idx = (HostX.win_width*y*bytes_per_pixel)+(x*bytes_per_pixel);
|
||||||
|
|
||||||
|
switch (HostX.server_depth)
|
||||||
|
{
|
||||||
|
case 16:
|
||||||
|
{
|
||||||
|
unsigned short pixel = *(unsigned short*)(HostX.fb_data+idx);
|
||||||
|
|
||||||
|
r = ((pixel & 0xf800) >> 8);
|
||||||
|
g = ((pixel & 0x07e0) >> 3);
|
||||||
|
b = ((pixel & 0x001f) << 3);
|
||||||
|
|
||||||
|
host_pixel = (r << 16) | (g << 8) | (b);
|
||||||
|
|
||||||
|
XPutPixel(HostX.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]);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (HostX.have_shm)
|
if (HostX.have_shm)
|
||||||
{
|
{
|
||||||
XShmPutImage(HostX.dpy, HostX.win, HostX.gc, HostX.ximg,
|
XShmPutImage(HostX.dpy, HostX.win, HostX.gc, HostX.ximg,
|
||||||
|
|
|
@ -103,6 +103,12 @@ hostx_init(void);
|
||||||
int
|
int
|
||||||
hostx_get_depth (void);
|
hostx_get_depth (void);
|
||||||
|
|
||||||
|
int
|
||||||
|
hostx_get_server_depth (void);
|
||||||
|
|
||||||
|
void
|
||||||
|
hostx_set_server_depth(int depth);
|
||||||
|
|
||||||
int
|
int
|
||||||
hostx_get_bpp(void);
|
hostx_get_bpp(void);
|
||||||
|
|
||||||
|
@ -110,6 +116,11 @@ void
|
||||||
hostx_get_visual_masks (unsigned long *rmsk,
|
hostx_get_visual_masks (unsigned long *rmsk,
|
||||||
unsigned long *gmsk,
|
unsigned long *gmsk,
|
||||||
unsigned long *bmsk);
|
unsigned long *bmsk);
|
||||||
|
void
|
||||||
|
hostx_set_cmap_entry(unsigned char idx,
|
||||||
|
unsigned char r,
|
||||||
|
unsigned char g,
|
||||||
|
unsigned char b);
|
||||||
|
|
||||||
void*
|
void*
|
||||||
hostx_screen_init (int width, int height);
|
hostx_screen_init (int width, int height);
|
||||||
|
|
Loading…
Reference in New Issue