xf86-video-intel: tools/virtual.c
Chris Wilson
ickle at kemper.freedesktop.org
Mon Sep 2 04:43:48 PDT 2013
tools/virtual.c | 136 +++++++++++++++++++++++++++++++++++++++++---------------
1 file changed, 100 insertions(+), 36 deletions(-)
New commits:
commit 962460c0e1a22c3db9c1a25227eb9f1d1f1542d3
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Mon Sep 2 12:33:55 2013 +0100
intel-virtual-output: Probe and automatically enable sibling screens
Look for screens on the same display that we can enable automatically.
Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
diff --git a/tools/virtual.c b/tools/virtual.c
index d03f108..5d2932a 100644
--- a/tools/virtual.c
+++ b/tools/virtual.c
@@ -1429,10 +1429,8 @@ static int display_open(struct context *ctx, const char *name)
DBG(("%s(%s)\n", __func__, name));
dpy = XOpenDisplay(name);
- if (dpy == NULL) {
- fprintf(stderr, "Unable to connect to %s\n", name);
+ if (dpy == NULL)
return -ECONNREFUSED;
- }
/* Prevent cloning the same display twice */
for (n = 0; n < ctx->ndisplay; n++) {
@@ -1453,7 +1451,7 @@ static int bumblebee_open(struct context *ctx)
fd = socket(PF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0);
if (fd < 0)
- goto err;
+ return -ECONNREFUSED;
addr.sun_family = AF_UNIX;
strcpy(addr.sun_path, optarg && *optarg ? optarg : "/var/run/bumblebee.socket");
@@ -1462,10 +1460,8 @@ static int bumblebee_open(struct context *ctx)
/* Ask bumblebee to start the second server */
buf[0] = 'C';
- if (send(fd, &buf, 1, 0) != 1 || (len = recv(fd, &buf, 255, 0)) <= 0) {
- close(fd);
+ if (send(fd, &buf, 1, 0) != 1 || (len = recv(fd, &buf, 255, 0)) <= 0)
goto err;
- }
buf[len] = '\0';
/* Query the display name */
@@ -1476,7 +1472,7 @@ static int bumblebee_open(struct context *ctx)
close(fd);
if (strncmp(buf, "Value: ", 7))
- goto err;
+ return -ECONNREFUSED;
while (isspace(buf[--len]))
buf[len] = '\0';
@@ -1484,7 +1480,7 @@ static int bumblebee_open(struct context *ctx)
return display_open(ctx, buf+7);
err:
- fprintf(stderr, "Unable to connect to bumblebee\n");
+ close(fd);
return -ECONNREFUSED;
}
@@ -1916,15 +1912,49 @@ static void display_flush(struct display *display)
display->flush = 0;
}
+static int first_display_first_sibling(struct context *ctx)
+{
+ const char *str, *colon;
+ int dpy, scr, len;
+
+ str = DisplayString(ctx->display->dpy);
+ colon = strrchr(str, ':');
+ if (colon == NULL)
+ return -1;
+
+ if (sscanf(colon + 1, "%d.%d", &dpy, &scr) == 1)
+ scr = 0;
+
+ len = (colon - str) + 1;
+ memcpy(ctx->command, str, len);
+ len += sprintf(ctx->command + len, "%d.", dpy);
+ ctx->command_continuation = len;
+
+ return scr + 1;
+}
+
+static int first_display_sibling(struct context *ctx, int i)
+{
+ if (i < 0)
+ return 0;
+
+ sprintf(ctx->command + ctx->command_continuation, "%d", i);
+ return 1;
+}
+
+#define first_display_for_each_sibling(CTX, i) \
+ for (i = first_display_first_sibling(CTX); first_display_sibling(CTX, i); i++)
+
int main(int argc, char **argv)
{
struct context ctx;
const char *src_name = NULL;
uint64_t count;
int enable_timer = 0;
- int i, ret, daemonize = 1, bumblebee = 0, singleton = 1;
+ int daemonize = 1, bumblebee = 0, all = 0, singleton = 1;
+ int i, ret, open, fail;
- while ((i = getopt(argc, argv, "bd:fhS")) != -1) {
+ while ((i = getopt(argc, argv, "abd:fhS")) != -1) {
switch (i) {
case 'd':
src_name = optarg;
@@ -1935,6 +1965,9 @@ int main(int argc, char **argv)
case 'b':
bumblebee = 1;
break;
+ case 'a':
+ all = 1;
+ break;
case 'S':
singleton = 0;
break;
@@ -1952,8 +1985,11 @@ int main(int argc, char **argv)
XSetErrorHandler(_check_error_handler);
ret = add_fd(&ctx, display_open(&ctx, src_name));
- if (ret)
+ if (ret) {
+ fprintf(stderr, "Unable to connect to \"%s\".\n", src_name ?: getenv("DISPLAY") ?:
+ "<unspecified>, set either the DISPLAY environment variable or pass -d <display name> on the commandline");
return -ret;
+ }
if (singleton) {
XSelectInput(ctx.display->dpy, ctx.display->root, PropertyChangeMask);
@@ -1966,18 +2002,35 @@ int main(int argc, char **argv)
DBG(("No reply from singleton; assuming control\n"));
} else {
DBG(("%s: singleton active, sending open commands\n", DisplayString(ctx.display->dpy)));
- if (optind == argc || bumblebee) {
- ret = first_display_send_command(&ctx, 5000, "B");
- if (ret && ret != -EBUSY)
- return -ret;
- }
+
+ open = fail = 0;
for (i = optind; i < argc; i++) {
ret = first_display_send_command(&ctx, 5000, "C%s", argv[i]);
- if (ret && ret != -EBUSY)
- return -ret;
+ if (ret && ret != -EBUSY) {
+ fprintf(stderr, "Unable to connect to \"%s\".\n", argv[i]);
+ fail++;
+ } else
+ open++;
}
-
- return 0;
+ if (all || (optind == argc && open == 0)) {
+ first_display_for_each_sibling(&ctx, i) {
+ ret = first_display_send_command(&ctx, 5000, "C%s", ctx.command);
+ if (ret && ret != -EBUSY)
+ break;
+ else
+ open++;
+ }
+ }
+ if (bumblebee || (optind == argc && open == 0)) {
+ ret = first_display_send_command(&ctx, 5000, "B");
+ if (ret && ret != -EBUSY) {
+ if (bumblebee)
+ fprintf(stderr, "Unable to connect to bumblebee.\n");
+ fail++;
+ } else
+ open++;
+ }
+ return open || !fail ? 0 : ECONNREFUSED;
}
}
ret = first_display_register_as_singleton(&ctx);
@@ -1992,25 +2045,35 @@ int main(int argc, char **argv)
XRRSelectInput(ctx.display->dpy, ctx.display->root, RRScreenChangeNotifyMask);
XFixesSelectCursorInput(ctx.display->dpy, ctx.display->root, XFixesDisplayCursorNotifyMask);
- if (optind == argc || bumblebee) {
- ret = last_display_clone(&ctx, bumblebee_open(&ctx));
- if (ret) {
- if (!bumblebee) {
- usage(argv[0]);
- return 0;
- }
- return -ret;
- }
- }
-
+ open = fail = 0;
for (i = optind; i < argc; i++) {
ret = last_display_clone(&ctx, display_open(&ctx, argv[i]));
- if (ret) {
- if (ret == -EBUSY)
- continue;
- return -ret;
+ if (ret && ret != -EBUSY) {
+ fprintf(stderr, "Unable to connect to \"%s\".\n", argv[i]);
+ fail++;
+ } else
+ open++;
+ }
+ if (all || (optind == argc && open == 0)) {
+ first_display_for_each_sibling(&ctx, i) {
+ ret = last_display_clone(&ctx, display_open(&ctx, ctx.command));
+ if (ret && ret != -EBUSY)
+ break;
+ else
+ open++;
}
}
+ if (bumblebee || (optind == argc && open == 0)) {
+ ret = last_display_clone(&ctx, bumblebee_open(&ctx));
+ if (ret && ret != -EBUSY) {
+ if (bumblebee)
+ fprintf(stderr, "Unable to connect to bumblebee.\n");
+ fail++;
+ } else
+ open++;
+ }
+ if (open == 0)
+ return fail ? ECONNREFUSED : 0;
ret = add_fd(&ctx, record_mouse(&ctx));
if (ret) {
@@ -2021,6 +2084,7 @@ int main(int argc, char **argv)
if (daemonize && daemon(0, 0))
return EINVAL;
+ ctx.command_continuation = 0;
while (1) {
XEvent e;
int reconfigure = 0;
More information about the xorg-commit
mailing list