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())
|
||||
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;
|
||||
|
||||
if (screen->fb[0].depth <= 8)
|
||||
|
@ -98,6 +107,13 @@ ephyrScreenInitialize (KdScreenInfo *screen, EphyrScrPriv *scrpriv)
|
|||
(1 << PseudoColor) |
|
||||
(1 << TrueColor) |
|
||||
(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
|
||||
{
|
||||
|
@ -601,18 +617,44 @@ ephyrCardFini (KdCardInfo *card)
|
|||
void
|
||||
ephyrGetColors (ScreenPtr pScreen, int fb, int n, xColorItem *pdefs)
|
||||
{
|
||||
while (n--)
|
||||
/* XXX Not sure if this is right */
|
||||
|
||||
EPHYR_DBG("mark");
|
||||
|
||||
while (n--)
|
||||
{
|
||||
pdefs->red = 0;
|
||||
pdefs->green = 0;
|
||||
pdefs->blue = 0;
|
||||
pdefs++;
|
||||
pdefs->red = 0;
|
||||
pdefs->green = 0;
|
||||
pdefs->blue = 0;
|
||||
pdefs++;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
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 */
|
||||
|
|
|
@ -55,16 +55,20 @@ struct EphyrHostXVars
|
|||
Window win_pre_existing; /* Set via -parent option like xnest */
|
||||
GC gc;
|
||||
int depth;
|
||||
int server_depth;
|
||||
XImage *ximg;
|
||||
int win_width, win_height;
|
||||
Bool use_host_cursor;
|
||||
Bool have_shm;
|
||||
long damage_debug_msec;
|
||||
|
||||
unsigned char *fb_data; /* only used when host bpp != server bpp */
|
||||
unsigned long cmap[256];
|
||||
|
||||
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;
|
||||
|
||||
|
@ -83,6 +87,9 @@ extern int monitorResolution;
|
|||
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)
|
||||
|
||||
|
||||
static int
|
||||
error_handler(Display *display,
|
||||
XErrorEvent *error)
|
||||
|
@ -187,15 +194,9 @@ hostx_init(void)
|
|||
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;
|
||||
|
||||
/* old way of getting dpi
|
||||
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)
|
||||
{
|
||||
Status result;
|
||||
|
@ -226,7 +227,7 @@ hostx_init(void)
|
|||
HostX.winroot,
|
||||
0,0,100,100, /* will resize */
|
||||
0,
|
||||
CopyFromParent,
|
||||
CopyFromParent,
|
||||
CopyFromParent,
|
||||
CopyFromParent,
|
||||
CWEventMask,
|
||||
|
@ -235,7 +236,6 @@ hostx_init(void)
|
|||
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);
|
||||
XAllocColor(HostX.dpy, DefaultColormap(HostX.dpy, HostX.screen), &col);
|
||||
|
@ -309,22 +309,62 @@ hostx_get_depth (void)
|
|||
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
|
||||
hostx_get_bpp(void)
|
||||
{
|
||||
return HostX.visual->bits_per_rgb;
|
||||
if (host_depth_matches_server())
|
||||
return HostX.visual->bits_per_rgb;
|
||||
else
|
||||
return HostX.server_depth; /* XXX correct ? */
|
||||
}
|
||||
|
||||
void
|
||||
hostx_get_visual_masks (unsigned long *rmsk,
|
||||
unsigned long *gmsk,
|
||||
unsigned long *bmsk)
|
||||
unsigned long *gmsk,
|
||||
unsigned long *bmsk)
|
||||
{
|
||||
*rmsk = HostX.visual->red_mask;
|
||||
*gmsk = HostX.visual->green_mask;
|
||||
*bmsk = HostX.visual->blue_mask;
|
||||
if (host_depth_matches_server())
|
||||
{
|
||||
*rmsk = HostX.visual->red_mask;
|
||||
*gmsk = HostX.visual->green_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*
|
||||
hostx_screen_init (int width, int height)
|
||||
|
@ -422,7 +462,17 @@ hostx_screen_init (int width, int height)
|
|||
HostX.win_width = width;
|
||||
HostX.win_height = height;
|
||||
|
||||
return HostX.ximg->data;
|
||||
if (host_depth_matches_server())
|
||||
{
|
||||
EPHYR_DBG("Host matches server");
|
||||
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
|
||||
|
@ -440,10 +490,60 @@ hostx_paint_rect(int sx, int sy,
|
|||
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)
|
||||
{
|
||||
XShmPutImage(HostX.dpy, HostX.win, HostX.gc, HostX.ximg,
|
||||
sx, sy, dx, dy, width, height, False);
|
||||
sx, sy, dx, dy, width, height, False);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -103,6 +103,12 @@ hostx_init(void);
|
|||
int
|
||||
hostx_get_depth (void);
|
||||
|
||||
int
|
||||
hostx_get_server_depth (void);
|
||||
|
||||
void
|
||||
hostx_set_server_depth(int depth);
|
||||
|
||||
int
|
||||
hostx_get_bpp(void);
|
||||
|
||||
|
@ -110,6 +116,11 @@ void
|
|||
hostx_get_visual_masks (unsigned long *rmsk,
|
||||
unsigned long *gmsk,
|
||||
unsigned long *bmsk);
|
||||
void
|
||||
hostx_set_cmap_entry(unsigned char idx,
|
||||
unsigned char r,
|
||||
unsigned char g,
|
||||
unsigned char b);
|
||||
|
||||
void*
|
||||
hostx_screen_init (int width, int height);
|
||||
|
|
Loading…
Reference in New Issue