ephyr: Move the host screen info into the kdrive screen private.

We can include xcb bits from the same place as server headers, so
there's no need to hide them any more.

Signed-off-by: Eric Anholt <eric@anholt.net>
Reviewed-by: Julien Cristau <jcristau@debian.org>
This commit is contained in:
Eric Anholt 2013-08-18 17:28:08 +02:00
parent 8dadc78e23
commit 847c856eff
5 changed files with 191 additions and 233 deletions

View File

@ -99,8 +99,9 @@ ephyrCardInit(KdCardInfo * card)
} }
Bool Bool
ephyrScreenInitialize(KdScreenInfo * screen, EphyrScrPriv * scrpriv) ephyrScreenInitialize(KdScreenInfo *screen)
{ {
EphyrScrPriv *scrpriv = screen->driver;
int width = 640, height = 480; int width = 640, height = 480;
CARD32 redMask, greenMask, blueMask; CARD32 redMask, greenMask, blueMask;
@ -117,7 +118,7 @@ ephyrScreenInitialize(KdScreenInfo * screen, EphyrScrPriv * scrpriv)
if (screen->fb.depth < hostx_get_depth() if (screen->fb.depth < hostx_get_depth()
&& (screen->fb.depth == 24 || screen->fb.depth == 16 && (screen->fb.depth == 24 || screen->fb.depth == 16
|| screen->fb.depth == 8)) { || screen->fb.depth == 8)) {
hostx_set_server_depth(screen, screen->fb.depth); scrpriv->server_depth = screen->fb.depth;
} }
else else
ErrorF ErrorF
@ -180,27 +181,6 @@ ephyrScreenInitialize(KdScreenInfo * screen, EphyrScrPriv * scrpriv)
return ephyrMapFramebuffer(screen); return ephyrMapFramebuffer(screen);
} }
Bool
ephyrScreenInit(KdScreenInfo * screen)
{
EphyrScrPriv *scrpriv;
scrpriv = calloc(1, sizeof(EphyrScrPriv));
if (!scrpriv)
return FALSE;
screen->driver = scrpriv;
if (!ephyrScreenInitialize(screen, scrpriv)) {
screen->driver = 0;
free(scrpriv);
return FALSE;
}
return TRUE;
}
void * void *
ephyrWindowLinear(ScreenPtr pScreen, ephyrWindowLinear(ScreenPtr pScreen,
CARD32 row, CARD32 row,

View File

@ -29,6 +29,7 @@
#include <unistd.h> #include <unistd.h>
#include <signal.h> #include <signal.h>
#include <libgen.h> #include <libgen.h>
#include <xcb/xcb_image.h>
#include "os.h" /* for OsSignal() */ #include "os.h" /* for OsSignal() */
#include "kdrive.h" #include "kdrive.h"
@ -61,10 +62,24 @@ typedef struct _ephyrFakexaPriv {
} EphyrFakexaPriv; } EphyrFakexaPriv;
typedef struct _ephyrScrPriv { typedef struct _ephyrScrPriv {
/* ephyr server info */
Rotation randr; Rotation randr;
Bool shadow; Bool shadow;
DamagePtr pDamage; DamagePtr pDamage;
EphyrFakexaPriv *fakexa; EphyrFakexaPriv *fakexa;
/* Host X window info */
xcb_window_t win;
xcb_window_t win_pre_existing; /* Set via -parent option like xnest */
xcb_window_t peer_win; /* Used for GL; should be at most one */
xcb_image_t *ximg;
int win_width, win_height;
int server_depth;
unsigned char *fb_data; /* only used when host bpp != server bpp */
xcb_shm_segment_info_t shminfo;
KdScreenInfo *screen;
int mynum; /* Screen number */
} EphyrScrPriv; } EphyrScrPriv;
extern KdCardFuncs ephyrFuncs; extern KdCardFuncs ephyrFuncs;
@ -80,10 +95,7 @@ Bool
ephyrCardInit(KdCardInfo * card); ephyrCardInit(KdCardInfo * card);
Bool Bool
ephyrScreenInit(KdScreenInfo * screen); ephyrScreenInitialize(KdScreenInfo *screen);
Bool
ephyrScreenInitialize(KdScreenInfo * screen, EphyrScrPriv * scrpriv);
Bool Bool
ephyrInitScreen(ScreenPtr pScreen); ephyrInitScreen(ScreenPtr pScreen);

View File

@ -147,6 +147,9 @@ processScreenArg(const char *screen_size, char *parent_id)
screen = KdScreenInfoAdd(card); screen = KdScreenInfoAdd(card);
KdParseScreen(screen, screen_size); KdParseScreen(screen, screen_size);
screen->driver = calloc(1, sizeof(EphyrScrPriv));
if (!screen->driver)
FatalError("Couldn't alloc screen private\n");
if (parent_id) { if (parent_id) {
p_id = strtol(parent_id, NULL, 0); p_id = strtol(parent_id, NULL, 0);
@ -369,7 +372,7 @@ ephyrCursorEnable(ScreenPtr pScreen)
KdCardFuncs ephyrFuncs = { KdCardFuncs ephyrFuncs = {
ephyrCardInit, /* cardinit */ ephyrCardInit, /* cardinit */
ephyrScreenInit, /* scrinit */ ephyrScreenInitialize, /* scrinit */
ephyrInitScreen, /* initScreen */ ephyrInitScreen, /* initScreen */
ephyrFinishInitScreen, /* finishInitScreen */ ephyrFinishInitScreen, /* finishInitScreen */
ephyrCreateResources, /* createRes */ ephyrCreateResources, /* createRes */

View File

@ -56,20 +56,6 @@
#include "ephyrlog.h" #include "ephyrlog.h"
#include "ephyr.h" #include "ephyr.h"
struct EphyrHostScreen {
Window win;
Window win_pre_existing; /* Set via -parent option like xnest */
Window peer_win; /* Used for GL; should be at most one */
xcb_image_t *ximg;
int win_width, win_height;
int server_depth;
unsigned char *fb_data; /* only used when host bpp != server bpp */
xcb_shm_segment_info_t shminfo;
KdScreenInfo *screen;
int mynum; /* Screen number */
};
struct EphyrHostXVars { struct EphyrHostXVars {
char *server_dpy_name; char *server_dpy_name;
xcb_connection_t *conn; xcb_connection_t *conn;
@ -83,7 +69,7 @@ struct EphyrHostXVars {
Bool have_shm; Bool have_shm;
int n_screens; int n_screens;
struct EphyrHostScreen *screens; KdScreenInfo **screens;
long damage_debug_msec; long damage_debug_msec;
@ -111,29 +97,15 @@ static void
#define host_depth_matches_server(_vars) (HostX.depth == (_vars)->server_depth) #define host_depth_matches_server(_vars) (HostX.depth == (_vars)->server_depth)
static struct EphyrHostScreen *
host_screen_from_screen_info(KdScreenInfo *screen)
{
int i;
for (i = 0; i < HostX.n_screens; i++) {
if (HostX.screens[i].screen == screen) {
return &HostX.screens[i];
}
}
return NULL;
}
int int
hostx_want_screen_size(KdScreenInfo *screen, int *width, int *height) hostx_want_screen_size(KdScreenInfo *screen, int *width, int *height)
{ {
struct EphyrHostScreen *host_screen = host_screen_from_screen_info(screen); EphyrScrPriv *scrpriv = screen->driver;
if (host_screen && if (scrpriv && (scrpriv->win_pre_existing != None ||
(host_screen->win_pre_existing != None ||
HostX.use_fullscreen == TRUE)) { HostX.use_fullscreen == TRUE)) {
*width = host_screen->win_width; *width = scrpriv->win_width;
*height = host_screen->win_height; *height = scrpriv->win_height;
return 1; return 1;
} }
@ -143,15 +115,16 @@ hostx_want_screen_size(KdScreenInfo *screen, int *width, int *height)
void void
hostx_add_screen(KdScreenInfo *screen, unsigned long win_id, int screen_num) hostx_add_screen(KdScreenInfo *screen, unsigned long win_id, int screen_num)
{ {
EphyrScrPriv *scrpriv = screen->driver;
int index = HostX.n_screens; int index = HostX.n_screens;
HostX.n_screens += 1; HostX.n_screens += 1;
HostX.screens = realloc(HostX.screens, HostX.screens = realloc(HostX.screens,
HostX.n_screens * sizeof(struct EphyrHostScreen)); HostX.n_screens * sizeof(HostX.screens[0]));
memset(&HostX.screens[index], 0, sizeof(struct EphyrHostScreen)); HostX.screens[index] = screen;
HostX.screens[index].screen = screen; scrpriv->screen = screen;
HostX.screens[index].win_pre_existing = win_id; scrpriv->win_pre_existing = win_id;
} }
void void
@ -163,25 +136,25 @@ hostx_set_display_name(char *name)
void void
hostx_set_screen_number(KdScreenInfo *screen, int number) hostx_set_screen_number(KdScreenInfo *screen, int number)
{ {
struct EphyrHostScreen *host_screen = host_screen_from_screen_info(screen); EphyrScrPriv *scrpriv = screen->driver;
if (host_screen) { if (scrpriv) {
host_screen->mynum = number; scrpriv->mynum = number;
hostx_set_win_title(host_screen->screen, ""); hostx_set_win_title(screen, "");
} }
} }
void void
hostx_set_win_title(KdScreenInfo *screen, const char *extra_text) hostx_set_win_title(KdScreenInfo *screen, const char *extra_text)
{ {
struct EphyrHostScreen *host_screen = host_screen_from_screen_info(screen); EphyrScrPriv *scrpriv = screen->driver;
if (!host_screen) if (!scrpriv)
return; return;
if (ephyrTitle) { if (ephyrTitle) {
xcb_icccm_set_wm_name(HostX.conn, xcb_icccm_set_wm_name(HostX.conn,
host_screen->win, scrpriv->win,
XCB_ATOM_STRING, XCB_ATOM_STRING,
8, 8,
strlen(ephyrTitle), strlen(ephyrTitle),
@ -193,10 +166,10 @@ hostx_set_win_title(KdScreenInfo *screen, const char *extra_text)
memset(buf, 0, BUF_LEN + 1); memset(buf, 0, BUF_LEN + 1);
snprintf(buf, BUF_LEN, "Xephyr on %s.%d %s", snprintf(buf, BUF_LEN, "Xephyr on %s.%d %s",
HostX.server_dpy_name, HostX.server_dpy_name,
host_screen->mynum, (extra_text != NULL) ? extra_text : ""); scrpriv->mynum, (extra_text != NULL) ? extra_text : "");
xcb_icccm_set_wm_name(HostX.conn, xcb_icccm_set_wm_name(HostX.conn,
host_screen->win, scrpriv->win,
XCB_ATOM_STRING, XCB_ATOM_STRING,
8, 8,
strlen(buf), strlen(buf),
@ -219,9 +192,9 @@ hostx_use_host_cursor(void)
int int
hostx_want_preexisting_window(KdScreenInfo *screen) hostx_want_preexisting_window(KdScreenInfo *screen)
{ {
struct EphyrHostScreen *host_screen = host_screen_from_screen_info(screen); EphyrScrPriv *scrpriv = screen->driver;
if (host_screen && host_screen->win_pre_existing) { if (scrpriv && scrpriv->win_pre_existing) {
return 1; return 1;
} }
else { else {
@ -261,9 +234,10 @@ hostx_set_fullscreen_hint(void)
free(reply); free(reply);
for (index = 0; index < HostX.n_screens; index++) { for (index = 0; index < HostX.n_screens; index++) {
EphyrScrPriv *scrpriv = HostX.screens[index]->driver;
xcb_change_property(HostX.conn, xcb_change_property(HostX.conn,
PropModeReplace, PropModeReplace,
HostX.screens[index].win, scrpriv->win,
atom_WINDOW_STATE, atom_WINDOW_STATE,
XCB_ATOM_ATOM, XCB_ATOM_ATOM,
32, 32,
@ -316,7 +290,7 @@ hostx_init(void)
char *class_hint; char *class_hint;
size_t class_len; size_t class_len;
const xcb_query_extension_reply_t *shm_rep; const xcb_query_extension_reply_t *shm_rep;
xcb_screen_t *screen; xcb_screen_t *xscreen;
attr = attr =
XCB_EVENT_MASK_BUTTON_PRESS XCB_EVENT_MASK_BUTTON_PRESS
@ -334,11 +308,11 @@ hostx_init(void)
exit(1); exit(1);
} }
screen = xcb_aux_get_screen(HostX.conn, HostX.screen); xscreen = xcb_aux_get_screen(HostX.conn, HostX.screen);
HostX.winroot = screen->root; HostX.winroot = xscreen->root;
HostX.gc = xcb_generate_id(HostX.conn); HostX.gc = xcb_generate_id(HostX.conn);
HostX.depth = screen->root_depth; HostX.depth = xscreen->root_depth;
HostX.visual = xcb_aux_find_visual_by_id(screen, screen->root_visual); HostX.visual = xcb_aux_find_visual_by_id(xscreen, xscreen->root_visual);
xcb_create_gc(HostX.conn, HostX.gc, HostX.winroot, 0, NULL); xcb_create_gc(HostX.conn, HostX.gc, HostX.winroot, 0, NULL);
cookie_WINDOW_STATE = xcb_intern_atom(HostX.conn, FALSE, cookie_WINDOW_STATE = xcb_intern_atom(HostX.conn, FALSE,
@ -350,19 +324,21 @@ hostx_init(void)
"_NET_WM_STATE_FULLSCREEN"); "_NET_WM_STATE_FULLSCREEN");
for (index = 0; index < HostX.n_screens; index++) { for (index = 0; index < HostX.n_screens; index++) {
struct EphyrHostScreen *host_screen = &HostX.screens[index]; KdScreenInfo *screen = HostX.screens[index];
EphyrScrPriv *scrpriv = screen->driver;
host_screen->win = xcb_generate_id(HostX.conn); scrpriv->win = xcb_generate_id(HostX.conn);
host_screen->server_depth = HostX.depth; scrpriv->server_depth = HostX.depth;
scrpriv->ximg = NULL;
if (host_screen->win_pre_existing != XCB_WINDOW_NONE) { if (scrpriv->win_pre_existing != XCB_WINDOW_NONE) {
xcb_get_geometry_reply_t *prewin_geom; xcb_get_geometry_reply_t *prewin_geom;
xcb_get_geometry_cookie_t cookie; xcb_get_geometry_cookie_t cookie;
xcb_generic_error_t *e = NULL; xcb_generic_error_t *e = NULL;
/* Get screen size from existing window */ /* Get screen size from existing window */
cookie = xcb_get_geometry(HostX.conn, cookie = xcb_get_geometry(HostX.conn,
host_screen->win_pre_existing); scrpriv->win_pre_existing);
prewin_geom = xcb_get_geometry_reply(HostX.conn, cookie, &e); prewin_geom = xcb_get_geometry_reply(HostX.conn, cookie, &e);
if (e) { if (e) {
@ -372,18 +348,18 @@ hostx_init(void)
exit (1); exit (1);
} }
host_screen->win_width = prewin_geom->width; scrpriv->win_width = prewin_geom->width;
host_screen->win_height = prewin_geom->height; scrpriv->win_height = prewin_geom->height;
free(prewin_geom); free(prewin_geom);
xcb_create_window(HostX.conn, xcb_create_window(HostX.conn,
XCB_COPY_FROM_PARENT, XCB_COPY_FROM_PARENT,
host_screen->win, scrpriv->win,
host_screen->win_pre_existing, scrpriv->win_pre_existing,
0,0, 0,0,
host_screen->win_width, scrpriv->win_width,
host_screen->win_height, scrpriv->win_height,
0, 0,
XCB_WINDOW_CLASS_COPY_FROM_PARENT, XCB_WINDOW_CLASS_COPY_FROM_PARENT,
XCB_COPY_FROM_PARENT, XCB_COPY_FROM_PARENT,
@ -393,7 +369,7 @@ hostx_init(void)
else { else {
xcb_create_window(HostX.conn, xcb_create_window(HostX.conn,
XCB_COPY_FROM_PARENT, XCB_COPY_FROM_PARENT,
host_screen->win, scrpriv->win,
HostX.winroot, HostX.winroot,
0,0,100,100, /* will resize */ 0,0,100,100, /* will resize */
0, 0,
@ -402,12 +378,12 @@ hostx_init(void)
XCB_CW_EVENT_MASK, XCB_CW_EVENT_MASK,
&attr); &attr);
hostx_set_win_title (host_screen->screen, hostx_set_win_title(screen,
"(ctrl+shift grabs mouse and keyboard)"); "(ctrl+shift grabs mouse and keyboard)");
if (HostX.use_fullscreen) { if (HostX.use_fullscreen) {
host_screen->win_width = screen->width_in_pixels; scrpriv->win_width = xscreen->width_in_pixels;
host_screen->win_height = screen->height_in_pixels; scrpriv->win_height = xscreen->height_in_pixels;
hostx_set_fullscreen_hint(); hostx_set_fullscreen_hint();
} }
@ -422,7 +398,7 @@ hostx_init(void)
strcpy(class_hint + strlen(ephyrResName) + 1, "Xephyr"); strcpy(class_hint + strlen(ephyrResName) + 1, "Xephyr");
xcb_change_property(HostX.conn, xcb_change_property(HostX.conn,
XCB_PROP_MODE_REPLACE, XCB_PROP_MODE_REPLACE,
host_screen->win, scrpriv->win,
XCB_ATOM_WM_CLASS, XCB_ATOM_WM_CLASS,
XCB_ATOM_STRING, XCB_ATOM_STRING,
8, 8,
@ -435,7 +411,7 @@ hostx_init(void)
if (!xcb_aux_parse_color("red", &red, &green, &blue)) { if (!xcb_aux_parse_color("red", &red, &green, &blue)) {
xcb_lookup_color_cookie_t c = xcb_lookup_color_cookie_t c =
xcb_lookup_color(HostX.conn, screen->default_colormap, 3, "red"); xcb_lookup_color(HostX.conn, xscreen->default_colormap, 3, "red");
xcb_lookup_color_reply_t *reply = xcb_lookup_color_reply_t *reply =
xcb_lookup_color_reply(HostX.conn, c, NULL); xcb_lookup_color_reply(HostX.conn, c, NULL);
red = reply->exact_red; red = reply->exact_red;
@ -446,7 +422,7 @@ hostx_init(void)
{ {
xcb_alloc_color_cookie_t c = xcb_alloc_color(HostX.conn, xcb_alloc_color_cookie_t c = xcb_alloc_color(HostX.conn,
screen->default_colormap, xscreen->default_colormap,
red, green, blue); red, green, blue);
xcb_alloc_color_reply_t *r = xcb_alloc_color_reply(HostX.conn, c, NULL); xcb_alloc_color_reply_t *r = xcb_alloc_color_reply(HostX.conn, c, NULL);
red = r->red; red = r->red;
@ -470,18 +446,17 @@ hostx_init(void)
0,0,0, 0,0,0,
1,1); 1,1);
for (index = 0; index < HostX.n_screens; index++) { for (index = 0; index < HostX.n_screens; index++) {
KdScreenInfo *screen = HostX.screens[index];
EphyrScrPriv *scrpriv = screen->driver;
xcb_change_window_attributes(HostX.conn, xcb_change_window_attributes(HostX.conn,
HostX.screens[index].win, scrpriv->win,
XCB_CW_CURSOR, XCB_CW_CURSOR,
&empty_cursor); &empty_cursor);
} }
xcb_free_pixmap(HostX.conn, cursor_pxm); xcb_free_pixmap(HostX.conn, cursor_pxm);
} }
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 */ /* Try to get share memory ximages for a little bit more speed */
shm_rep = xcb_get_extension_data(HostX.conn, &xcb_shm_id); shm_rep = xcb_get_extension_data(HostX.conn, &xcb_shm_id);
if (!shm_rep || !shm_rep->present || getenv("XEPHYR_NO_SHM")) { if (!shm_rep || !shm_rep->present || getenv("XEPHYR_NO_SHM")) {
@ -538,49 +513,40 @@ hostx_get_depth(void)
int int
hostx_get_server_depth(KdScreenInfo *screen) hostx_get_server_depth(KdScreenInfo *screen)
{ {
struct EphyrHostScreen *host_screen = host_screen_from_screen_info(screen); EphyrScrPriv *scrpriv = screen->driver;
return host_screen ? host_screen->server_depth : 0; return scrpriv ? scrpriv->server_depth : 0;
}
void
hostx_set_server_depth(KdScreenInfo *screen, int depth)
{
struct EphyrHostScreen *host_screen = host_screen_from_screen_info(screen);
if (host_screen)
host_screen->server_depth = depth;
} }
int int
hostx_get_bpp(KdScreenInfo *screen) hostx_get_bpp(KdScreenInfo *screen)
{ {
struct EphyrHostScreen *host_screen = host_screen_from_screen_info(screen); EphyrScrPriv *scrpriv = screen->driver;
if (!host_screen) if (!scrpriv)
return 0; return 0;
if (host_depth_matches_server (host_screen)) if (host_depth_matches_server(scrpriv))
return HostX.visual->bits_per_rgb_value; return HostX.visual->bits_per_rgb_value;
else else
return host_screen->server_depth; /*XXX correct ?*/ return scrpriv->server_depth; /*XXX correct ?*/
} }
void void
hostx_get_visual_masks(KdScreenInfo *screen, hostx_get_visual_masks(KdScreenInfo *screen,
CARD32 *rmsk, CARD32 *gmsk, CARD32 *bmsk) CARD32 *rmsk, CARD32 *gmsk, CARD32 *bmsk)
{ {
struct EphyrHostScreen *host_screen = host_screen_from_screen_info(screen); EphyrScrPriv *scrpriv = screen->driver;
if (!host_screen) if (!scrpriv)
return; return;
if (host_depth_matches_server(host_screen)) { if (host_depth_matches_server(scrpriv)) {
*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 (host_screen->server_depth == 16) { else if (scrpriv->server_depth == 16) {
/* Assume 16bpp 565 */ /* Assume 16bpp 565 */
*rmsk = 0xf800; *rmsk = 0xf800;
*gmsk = 0x07e0; *gmsk = 0x07e0;
@ -645,11 +611,10 @@ hostx_screen_init(KdScreenInfo *screen,
int width, int height, int buffer_height, int width, int height, int buffer_height,
int *bytes_per_line, int *bits_per_pixel) int *bytes_per_line, int *bits_per_pixel)
{ {
EphyrScrPriv *scrpriv = screen->driver;
Bool shm_success = FALSE; Bool shm_success = FALSE;
struct EphyrHostScreen *host_screen = host_screen_from_screen_info(screen); if (!scrpriv) {
if (!host_screen) {
fprintf(stderr, "%s: Error in accessing hostx data\n", __func__); fprintf(stderr, "%s: Error in accessing hostx data\n", __func__);
exit(1); exit(1);
} }
@ -657,27 +622,27 @@ hostx_screen_init(KdScreenInfo *screen,
EPHYR_DBG("host_screen=%p wxh=%dx%d, buffer_height=%d", EPHYR_DBG("host_screen=%p wxh=%dx%d, buffer_height=%d",
host_screen, width, height, buffer_height); host_screen, width, height, buffer_height);
if (host_screen->ximg != NULL) { if (scrpriv->ximg != NULL) {
/* Free up the image data if previously used /* Free up the image data if previously used
* i.ie called by server reset * i.ie called by server reset
*/ */
if (HostX.have_shm) { if (HostX.have_shm) {
xcb_shm_detach(HostX.conn, host_screen->shminfo.shmseg); xcb_shm_detach(HostX.conn, scrpriv->shminfo.shmseg);
xcb_image_destroy (host_screen->ximg); xcb_image_destroy(scrpriv->ximg);
shmdt(host_screen->shminfo.shmaddr); shmdt(scrpriv->shminfo.shmaddr);
shmctl(host_screen->shminfo.shmid, IPC_RMID, 0); shmctl(scrpriv->shminfo.shmid, IPC_RMID, 0);
} }
else { else {
free(host_screen->ximg->data); free(scrpriv->ximg->data);
host_screen->ximg->data = NULL; scrpriv->ximg->data = NULL;
xcb_image_destroy(host_screen->ximg); xcb_image_destroy(scrpriv->ximg);
} }
} }
if (HostX.have_shm) { if (HostX.have_shm) {
host_screen->ximg = xcb_image_create_native(HostX.conn, scrpriv->ximg = xcb_image_create_native(HostX.conn,
width, width,
buffer_height, buffer_height,
XCB_IMAGE_FORMAT_Z_PIXMAP, XCB_IMAGE_FORMAT_Z_PIXMAP,
@ -686,35 +651,35 @@ hostx_screen_init(KdScreenInfo *screen,
~0, ~0,
NULL); NULL);
host_screen->shminfo.shmid = scrpriv->shminfo.shmid =
shmget(IPC_PRIVATE, shmget(IPC_PRIVATE,
host_screen->ximg->stride * buffer_height, scrpriv->ximg->stride * buffer_height,
IPC_CREAT | 0777); IPC_CREAT | 0777);
host_screen->ximg->data = shmat(host_screen->shminfo.shmid, 0, 0); scrpriv->ximg->data = shmat(scrpriv->shminfo.shmid, 0, 0);
host_screen->shminfo.shmaddr = host_screen->ximg->data; scrpriv->shminfo.shmaddr = scrpriv->ximg->data;
if (host_screen->ximg->data == (uint8_t *) -1) { if (scrpriv->ximg->data == (uint8_t *) -1) {
EPHYR_DBG EPHYR_DBG
("Can't attach SHM Segment, falling back to plain XImages"); ("Can't attach SHM Segment, falling back to plain XImages");
HostX.have_shm = FALSE; HostX.have_shm = FALSE;
xcb_image_destroy (host_screen->ximg); xcb_image_destroy (scrpriv->ximg);
shmctl(host_screen->shminfo.shmid, IPC_RMID, 0); shmctl(scrpriv->shminfo.shmid, IPC_RMID, 0);
} }
else { else {
EPHYR_DBG("SHM segment attached %p", host_screen->shminfo.shmaddr); EPHYR_DBG("SHM segment attached %p", scrpriv->shminfo.shmaddr);
host_screen->shminfo.shmseg = xcb_generate_id(HostX.conn); scrpriv->shminfo.shmseg = xcb_generate_id(HostX.conn);
xcb_shm_attach(HostX.conn, xcb_shm_attach(HostX.conn,
host_screen->shminfo.shmseg, scrpriv->shminfo.shmseg,
host_screen->shminfo.shmid, scrpriv->shminfo.shmid,
FALSE); FALSE);
shm_success = TRUE; shm_success = TRUE;
} }
} }
if (!shm_success) { if (!shm_success) {
EPHYR_DBG("Creating image %dx%d for screen host_screen=%p\n", EPHYR_DBG("Creating image %dx%d for screen scrpriv=%p\n",
width, buffer_height, host_screen); width, buffer_height, scrpriv);
host_screen->ximg = xcb_image_create_native(HostX.conn, scrpriv->ximg = xcb_image_create_native(HostX.conn,
width, width,
buffer_height, buffer_height,
XCB_IMAGE_FORMAT_Z_PIXMAP, XCB_IMAGE_FORMAT_Z_PIXMAP,
@ -723,53 +688,53 @@ hostx_screen_init(KdScreenInfo *screen,
~0, ~0,
NULL); NULL);
host_screen->ximg->data = scrpriv->ximg->data =
malloc(host_screen->ximg->stride * buffer_height); malloc(scrpriv->ximg->stride * buffer_height);
} }
*bytes_per_line = host_screen->ximg->stride; *bytes_per_line = scrpriv->ximg->stride;
*bits_per_pixel = host_screen->ximg->bpp; *bits_per_pixel = scrpriv->ximg->bpp;
if (host_screen->win_pre_existing == None && !EphyrWantResize) { if (scrpriv->win_pre_existing == None && !EphyrWantResize) {
/* Ask the WM to keep our size static */ /* Ask the WM to keep our size static */
xcb_size_hints_t size_hints = {0}; xcb_size_hints_t size_hints = {0};
size_hints.max_width = size_hints.min_width = width; size_hints.max_width = size_hints.min_width = width;
size_hints.max_height = size_hints.min_height = height; size_hints.max_height = size_hints.min_height = height;
size_hints.flags = (XCB_ICCCM_SIZE_HINT_P_MIN_SIZE | size_hints.flags = (XCB_ICCCM_SIZE_HINT_P_MIN_SIZE |
XCB_ICCCM_SIZE_HINT_P_MAX_SIZE); XCB_ICCCM_SIZE_HINT_P_MAX_SIZE);
xcb_icccm_set_wm_normal_hints(HostX.conn, host_screen->win, xcb_icccm_set_wm_normal_hints(HostX.conn, scrpriv->win,
&size_hints); &size_hints);
} }
xcb_map_window(HostX.conn, host_screen->win); xcb_map_window(HostX.conn, scrpriv->win);
xcb_aux_sync(HostX.conn); xcb_aux_sync(HostX.conn);
host_screen->win_width = width; scrpriv->win_width = width;
host_screen->win_height = height; scrpriv->win_height = height;
if (host_depth_matches_server(host_screen)) { if (host_depth_matches_server(scrpriv)) {
EPHYR_DBG("Host matches server"); EPHYR_DBG("Host matches server");
return host_screen->ximg->data; return scrpriv->ximg->data;
} }
else { else {
EPHYR_DBG("server bpp %i", host_screen->server_depth >> 3); EPHYR_DBG("server bpp %i", scrpriv->server_depth >> 3);
host_screen->fb_data = scrpriv->fb_data =
malloc(width * buffer_height * (host_screen->server_depth >> 3)); malloc(width * buffer_height * (scrpriv->server_depth >> 3));
return host_screen->fb_data; return scrpriv->fb_data;
} }
} }
static void hostx_paint_debug_rect(struct EphyrHostScreen *host_screen, static void hostx_paint_debug_rect(KdScreenInfo *screen,
int x, int y, int width, int height); int x, int y, int width, int height);
void void
hostx_paint_rect(KdScreenInfo *screen, hostx_paint_rect(KdScreenInfo *screen,
int sx, int sy, int dx, int dy, int width, int height) int sx, int sy, int dx, int dy, int width, int height)
{ {
struct EphyrHostScreen *host_screen = host_screen_from_screen_info(screen); EphyrScrPriv *scrpriv = screen->driver;
EPHYR_DBG("painting in screen %d\n", host_screen->mynum); EPHYR_DBG("painting in screen %d\n", scrpriv->mynum);
/* /*
* Copy the image data updated by the shadow layer * Copy the image data updated by the shadow layer
@ -777,7 +742,7 @@ hostx_paint_rect(KdScreenInfo *screen,
*/ */
if (HostXWantDamageDebug) { if (HostXWantDamageDebug) {
hostx_paint_debug_rect(host_screen, dx, dy, width, height); hostx_paint_debug_rect(screen, dx, dy, width, height);
} }
/* /*
@ -792,23 +757,23 @@ hostx_paint_rect(KdScreenInfo *screen,
* ... and it will be slower than the matching depth case. * ... and it will be slower than the matching depth case.
*/ */
if (!host_depth_matches_server(host_screen)) { if (!host_depth_matches_server(scrpriv)) {
int x, y, idx, bytes_per_pixel = (host_screen->server_depth >> 3); int x, y, idx, bytes_per_pixel = (scrpriv->server_depth >> 3);
unsigned char r, g, b; unsigned char r, g, b;
unsigned long host_pixel; unsigned long host_pixel;
EPHYR_DBG("Unmatched host depth host_screen=%p\n", host_screen); EPHYR_DBG("Unmatched host depth scrpriv=%p\n", scrpriv);
for (y = sy; y < sy + height; y++) for (y = sy; y < sy + height; y++)
for (x = sx; x < sx + width; x++) { for (x = sx; x < sx + width; x++) {
idx = idx =
(host_screen->win_width * y * bytes_per_pixel) + (scrpriv->win_width * y * bytes_per_pixel) +
(x * bytes_per_pixel); (x * bytes_per_pixel);
switch (host_screen->server_depth) { switch (scrpriv->server_depth) {
case 16: case 16:
{ {
unsigned short pixel = unsigned short pixel =
*(unsigned short *) (host_screen->fb_data + idx); *(unsigned short *) (scrpriv->fb_data + idx);
r = ((pixel & 0xf800) >> 8); r = ((pixel & 0xf800) >> 8);
g = ((pixel & 0x07e0) >> 3); g = ((pixel & 0x07e0) >> 3);
@ -816,14 +781,14 @@ hostx_paint_rect(KdScreenInfo *screen,
host_pixel = (r << 16) | (g << 8) | (b); host_pixel = (r << 16) | (g << 8) | (b);
xcb_image_put_pixel(host_screen->ximg, x, y, host_pixel); xcb_image_put_pixel(scrpriv->ximg, x, y, host_pixel);
break; break;
} }
case 8: case 8:
{ {
unsigned char pixel = unsigned char pixel =
*(unsigned char *) (host_screen->fb_data + idx); *(unsigned char *) (scrpriv->fb_data + idx);
xcb_image_put_pixel(host_screen->ximg, x, y, xcb_image_put_pixel(scrpriv->ximg, x, y,
HostX.cmap[pixel]); HostX.cmap[pixel]);
break; break;
} }
@ -834,13 +799,13 @@ hostx_paint_rect(KdScreenInfo *screen,
} }
if (HostX.have_shm) { if (HostX.have_shm) {
xcb_image_shm_put(HostX.conn, host_screen->win, xcb_image_shm_put(HostX.conn, scrpriv->win,
HostX.gc, host_screen->ximg, HostX.gc, scrpriv->ximg,
host_screen->shminfo, scrpriv->shminfo,
sx, sy, dx, dy, width, height, FALSE); sx, sy, dx, dy, width, height, FALSE);
} }
else { else {
xcb_image_put(HostX.conn, host_screen->win, HostX.gc, host_screen->ximg, xcb_image_put(HostX.conn, scrpriv->win, HostX.gc, scrpriv->ximg,
dx, dy, 0); dx, dy, 0);
} }
@ -848,9 +813,10 @@ hostx_paint_rect(KdScreenInfo *screen,
} }
static void static void
hostx_paint_debug_rect(struct EphyrHostScreen *host_screen, hostx_paint_debug_rect(KdScreenInfo *screen,
int x, int y, int width, int height) int x, int y, int width, int height)
{ {
EphyrScrPriv *scrpriv = screen->driver;
struct timespec tspec; struct timespec tspec;
xcb_rectangle_t rect = { .x = x, .y = y, .width = width, .height = height }; xcb_rectangle_t rect = { .x = x, .y = y, .width = width, .height = height };
xcb_void_cookie_t cookie; xcb_void_cookie_t cookie;
@ -864,7 +830,7 @@ hostx_paint_debug_rect(struct EphyrHostScreen *host_screen,
/* fprintf(stderr, "Xephyr updating: %i+%i %ix%i\n", x, y, width, height); */ /* fprintf(stderr, "Xephyr updating: %i+%i %ix%i\n", x, y, width, height); */
cookie = xcb_poly_fill_rectangle_checked(HostX.conn, host_screen->win, cookie = xcb_poly_fill_rectangle_checked(HostX.conn, scrpriv->win,
HostX.gc, 1, &rect); HostX.gc, 1, &rect);
e = xcb_request_check(HostX.conn, cookie); e = xcb_request_check(HostX.conn, cookie);
free(e); free(e);
@ -887,23 +853,21 @@ hostx_load_keymap(void)
ephyrKeySyms.maxKeyCode = max_keycode; ephyrKeySyms.maxKeyCode = max_keycode;
} }
static struct EphyrHostScreen * static KdScreenInfo *
host_screen_from_window(Window w) screen_from_window(Window w)
{ {
int index = 0; int index = 0;
struct EphyrHostScreen *result = NULL;
for (index = 0; index < HostX.n_screens; index++) { for (index = 0; index < HostX.n_screens; index++) {
if (HostX.screens[index].win == w EphyrScrPriv *scrpriv = HostX.screens[index]->driver;
|| HostX.screens[index].peer_win == w if (scrpriv->win == w
|| HostX.screens[index].win_pre_existing == w) { || scrpriv->peer_win == w
result = &HostX.screens[index]; || scrpriv->win_pre_existing == w) {
goto out; return HostX.screens[index];
} }
} }
out: return NULL;
return result;
} }
int int
@ -948,8 +912,8 @@ hostx_get_event(EphyrHostXEvent * ev)
case XCB_EXPOSE: { case XCB_EXPOSE: {
xcb_expose_event_t *expose = (xcb_expose_event_t *)xev; xcb_expose_event_t *expose = (xcb_expose_event_t *)xev;
struct EphyrHostScreen *host_screen = KdScreenInfo *screen = screen_from_window(expose->window);
host_screen_from_window(expose->window); EphyrScrPriv *scrpriv = screen->driver;
/* Wait for the last expose event in a series of cliprects /* Wait for the last expose event in a series of cliprects
* to actually paint our screen. * to actually paint our screen.
@ -957,10 +921,10 @@ hostx_get_event(EphyrHostXEvent * ev)
if (expose->count != 0) if (expose->count != 0)
break; break;
if (host_screen) { if (scrpriv) {
hostx_paint_rect(host_screen->screen, 0, 0, 0, 0, hostx_paint_rect(screen, 0, 0, 0, 0,
host_screen->win_width, scrpriv->win_width,
host_screen->win_height); scrpriv->win_height);
} }
else { else {
EPHYR_LOG_ERROR("failed to get host screen\n"); EPHYR_LOG_ERROR("failed to get host screen\n");
@ -974,15 +938,14 @@ hostx_get_event(EphyrHostXEvent * ev)
case XCB_MOTION_NOTIFY: { case XCB_MOTION_NOTIFY: {
xcb_motion_notify_event_t *motion = (xcb_motion_notify_event_t *)xev; xcb_motion_notify_event_t *motion = (xcb_motion_notify_event_t *)xev;
struct EphyrHostScreen *host_screen = KdScreenInfo *screen = screen_from_window(motion->event);
host_screen_from_window(motion->event); EphyrScrPriv *scrpriv = screen->driver;
ev->type = EPHYR_EV_MOUSE_MOTION; ev->type = EPHYR_EV_MOUSE_MOTION;
ev->data.mouse_motion.x = motion->event_x; ev->data.mouse_motion.x = motion->event_x;
ev->data.mouse_motion.y = motion->event_y; ev->data.mouse_motion.y = motion->event_y;
ev->data.mouse_motion.window = motion->event; ev->data.mouse_motion.window = motion->event;
ev->data.mouse_motion.screen = ev->data.mouse_motion.screen = scrpriv ? scrpriv->mynum : -1;
(host_screen ? host_screen->mynum : -1);
free(xev); free(xev);
return 1; return 1;
} }
@ -1023,14 +986,14 @@ hostx_get_event(EphyrHostXEvent * ev)
if ((xcb_key_symbols_get_keysym(keysyms, key->detail, 0) == XK_Shift_L if ((xcb_key_symbols_get_keysym(keysyms, key->detail, 0) == XK_Shift_L
|| xcb_key_symbols_get_keysym(keysyms, key->detail, 0) == XK_Shift_R) || xcb_key_symbols_get_keysym(keysyms, key->detail, 0) == XK_Shift_R)
&& (key->state & XCB_MOD_MASK_CONTROL)) { && (key->state & XCB_MOD_MASK_CONTROL)) {
struct EphyrHostScreen *host_screen = KdScreenInfo *screen = screen_from_window(key->event);
host_screen_from_window(key->event); EphyrScrPriv *scrpriv = screen->driver;
if (grabbed_screen != -1) { if (grabbed_screen != -1) {
xcb_ungrab_keyboard(HostX.conn, XCB_TIME_CURRENT_TIME); xcb_ungrab_keyboard(HostX.conn, XCB_TIME_CURRENT_TIME);
xcb_ungrab_pointer(HostX.conn, XCB_TIME_CURRENT_TIME); xcb_ungrab_pointer(HostX.conn, XCB_TIME_CURRENT_TIME);
grabbed_screen = -1; grabbed_screen = -1;
hostx_set_win_title(host_screen->screen, hostx_set_win_title(screen,
"(ctrl+shift grabs mouse and keyboard)"); "(ctrl+shift grabs mouse and keyboard)");
} }
else { else {
@ -1038,7 +1001,7 @@ hostx_get_event(EphyrHostXEvent * ev)
xcb_grab_keyboard_cookie_t kbgrabc = xcb_grab_keyboard_cookie_t kbgrabc =
xcb_grab_keyboard(HostX.conn, xcb_grab_keyboard(HostX.conn,
TRUE, TRUE,
host_screen->win, scrpriv->win,
XCB_TIME_CURRENT_TIME, XCB_TIME_CURRENT_TIME,
XCB_GRAB_MODE_ASYNC, XCB_GRAB_MODE_ASYNC,
XCB_GRAB_MODE_ASYNC); XCB_GRAB_MODE_ASYNC);
@ -1046,11 +1009,11 @@ hostx_get_event(EphyrHostXEvent * ev)
xcb_grab_pointer_cookie_t pgrabc = xcb_grab_pointer_cookie_t pgrabc =
xcb_grab_pointer(HostX.conn, xcb_grab_pointer(HostX.conn,
TRUE, TRUE,
host_screen->win, scrpriv->win,
0, 0,
XCB_GRAB_MODE_ASYNC, XCB_GRAB_MODE_ASYNC,
XCB_GRAB_MODE_ASYNC, XCB_GRAB_MODE_ASYNC,
host_screen->win, scrpriv->win,
XCB_NONE, XCB_NONE,
XCB_TIME_CURRENT_TIME); XCB_TIME_CURRENT_TIME);
xcb_grab_pointer_reply_t *pgrabr; xcb_grab_pointer_reply_t *pgrabr;
@ -1065,9 +1028,9 @@ hostx_get_event(EphyrHostXEvent * ev)
xcb_ungrab_keyboard(HostX.conn, xcb_ungrab_keyboard(HostX.conn,
XCB_TIME_CURRENT_TIME); XCB_TIME_CURRENT_TIME);
} else { } else {
grabbed_screen = host_screen->mynum; grabbed_screen = scrpriv->mynum;
hostx_set_win_title hostx_set_win_title
(host_screen->screen, (screen,
"(ctrl+shift releases mouse and keyboard)"); "(ctrl+shift releases mouse and keyboard)");
} }
} }
@ -1087,14 +1050,13 @@ hostx_get_event(EphyrHostXEvent * ev)
case ConfigureNotify: case ConfigureNotify:
{ {
struct EphyrHostScreen *host_screen;
xcb_configure_notify_event_t *configure = xcb_configure_notify_event_t *configure =
(xcb_configure_notify_event_t *)xev; (xcb_configure_notify_event_t *)xev;
KdScreenInfo *screen = screen_from_window(configure->window);
EphyrScrPriv *scrpriv = screen->driver;
host_screen = host_screen_from_window(configure->window); if (!scrpriv ||
(scrpriv->win_pre_existing == None && !EphyrWantResize)) {
if (!host_screen ||
(host_screen->win_pre_existing == None && !EphyrWantResize)) {
free(xev); free(xev);
return 0; return 0;
} }
@ -1103,7 +1065,7 @@ hostx_get_event(EphyrHostXEvent * ev)
ev->data.configure.width = configure->width; ev->data.configure.width = configure->width;
ev->data.configure.height = configure->height; ev->data.configure.height = configure->height;
ev->data.configure.window = configure->window; ev->data.configure.window = configure->window;
ev->data.configure.screen = host_screen->mynum; ev->data.configure.screen = scrpriv->mynum;
free(xev); free(xev);
return 1; return 1;
@ -1131,11 +1093,13 @@ hostx_get_screen(void)
int int
hostx_get_window(int a_screen_number) hostx_get_window(int a_screen_number)
{ {
EphyrScrPriv *scrpriv;
if (a_screen_number < 0 || a_screen_number >= HostX.n_screens) { if (a_screen_number < 0 || a_screen_number >= HostX.n_screens) {
EPHYR_LOG_ERROR("bad screen number:%d\n", a_screen_number); EPHYR_LOG_ERROR("bad screen number:%d\n", a_screen_number);
return 0; return 0;
} }
return HostX.screens[a_screen_number].win; scrpriv = HostX.screens[a_screen_number]->driver;
return scrpriv->win;
} }
int int
@ -1228,6 +1192,8 @@ hostx_create_window(int a_screen_number,
xcb_screen_t *screen = xcb_aux_get_screen(HostX.conn, hostx_get_screen()); xcb_screen_t *screen = xcb_aux_get_screen(HostX.conn, hostx_get_screen());
xcb_visualtype_t *visual; xcb_visualtype_t *visual;
int depth = 0; int depth = 0;
EphyrScrPriv *scrpriv = HostX.screens[a_screen_number]->driver;
EPHYR_RETURN_VAL_IF_FAIL(screen && a_geometry, FALSE); EPHYR_RETURN_VAL_IF_FAIL(screen && a_geometry, FALSE);
EPHYR_LOG("enter\n"); EPHYR_LOG("enter\n");
@ -1264,8 +1230,8 @@ hostx_create_window(int a_screen_number,
XCB_WINDOW_CLASS_COPY_FROM_PARENT, XCB_WINDOW_CLASS_COPY_FROM_PARENT,
a_visual_id, winmask, attrs); a_visual_id, winmask, attrs);
if (HostX.screens[a_screen_number].peer_win == XCB_NONE) { if (scrpriv->peer_win == XCB_NONE) {
HostX.screens[a_screen_number].peer_win = win; scrpriv->peer_win = win;
} }
else { else {
EPHYR_LOG_ERROR("multiple peer windows created for same screen\n"); EPHYR_LOG_ERROR("multiple peer windows created for same screen\n");

View File

@ -177,9 +177,6 @@ int
int int
hostx_get_server_depth(KdScreenInfo *screen); hostx_get_server_depth(KdScreenInfo *screen);
void
hostx_set_server_depth(KdScreenInfo *screen, int depth);
int int
hostx_get_bpp(KdScreenInfo *screen); hostx_get_bpp(KdScreenInfo *screen);