From 89dc44ae4550162fe12ce0dd68c5e7f072558fc7 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Sun, 1 Sep 2013 11:46:26 +0100 Subject: [PATCH] intel-virtual-output: Prevent cloning the same output twice And prevent cloning the localhost! The caveat is that the transport string (Display name) must match, so it still would be possible to connect to the same display with different transports (local sockets and TCP sockets for socket) and so cause confusion. Signed-off-by: Chris Wilson --- tools/virtual.c | 83 +++++++++++++++++++++++-------------------------- 1 file changed, 39 insertions(+), 44 deletions(-) diff --git a/tools/virtual.c b/tools/virtual.c index 8f828be5..af13e393 100644 --- a/tools/virtual.c +++ b/tools/virtual.c @@ -1382,9 +1382,24 @@ static int clone_init_depth(struct clone *clone) return 0; } -static int display_init_core(struct display *display) +static inline int is_power_of_2(unsigned long n) { - Display *dpy = display->dpy; + return n && ((n & (n - 1)) == 0); +} + +static int add_display(struct context *ctx, Display *dpy) +{ + struct display *display; + + if (is_power_of_2(ctx->ndisplay)) { + ctx->display = realloc(ctx->display, 2*ctx->ndisplay*sizeof(struct display)); + if (ctx->display == NULL) + return -ENOMEM; + } + + display = memset(&ctx->display[ctx->ndisplay++], 0, sizeof(struct display)); + + display->dpy = dpy; display->root = DefaultRootWindow(dpy); display->depth = DefaultDepth(dpy, DefaultScreen(dpy)); @@ -1403,54 +1418,38 @@ static int display_init_core(struct display *display) display->invisible_cursor = display_load_invisible_cursor(display); display->cursor = None; - return 0; -} - -static inline int is_power_of_2(unsigned long n) -{ - return n && ((n & (n - 1)) == 0); -} - -static struct display *add_display(struct context *ctx) -{ - if (is_power_of_2(ctx->ndisplay)) { - ctx->display = realloc(ctx->display, 2*ctx->ndisplay*sizeof(struct display)); - if (ctx->display == NULL) - return NULL; - } - - return memset(&ctx->display[ctx->ndisplay++], 0, sizeof(struct display)); + return ConnectionNumber(dpy); } static int display_open(struct context *ctx, const char *name) { - struct display *display; - int ret; - - display = add_display(ctx); - if (display == NULL) - return -ENOMEM; + Display *dpy; + int n; DBG(("%s(%s)\n", __func__, name)); - display->dpy = XOpenDisplay(name); - if (display->dpy == NULL) { + dpy = XOpenDisplay(name); + if (dpy == NULL) { fprintf(stderr, "Unable to connect to %s\n", name); return -ECONNREFUSED; } - ret = display_init_core(display); - if (ret) - return ret; + /* Prevent cloning the same display twice */ + for (n = 0; n < ctx->ndisplay; n++) { + if (strcmp(DisplayString(dpy), DisplayString(ctx->display[n].dpy)) == 0) { + XCloseDisplay(dpy); + return -EBUSY; + } + } - return ConnectionNumber(display->dpy); + return add_display(ctx, dpy); } static int bumblebee_open(struct context *ctx) { char buf[256]; struct sockaddr_un addr; - struct display *display; + Display *dpy; int fd, len; fd = socket(PF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0); @@ -1483,21 +1482,13 @@ static int bumblebee_open(struct context *ctx) while (isspace(buf[--len])) buf[len] = '\0'; - display = add_display(ctx); - if (display == NULL) - return -ENOMEM; - - display->dpy = XOpenDisplay(buf+7); - if (display->dpy == NULL) { + dpy = XOpenDisplay(buf+7); + if (dpy == NULL) { fprintf(stderr, "Unable to connect to bumblebee Xserver on %s\n", buf+7); return -ECONNREFUSED; } - len = display_init_core(display); - if (len) - return len; - - return ConnectionNumber(display->dpy); + return add_display(ctx, dpy); err: fprintf(stderr, "Unable to connect to bumblebee\n"); @@ -1729,8 +1720,12 @@ int main(int argc, char **argv) for (i = optind; i < argc; i++) { ret = add_fd(&ctx, display_open(&ctx, argv[i])); - if (ret) + if (ret) { + if (ret == -EBUSY) + continue; + return -ret; + } ret = last_display_add_clones(&ctx); if (ret)