diff options
author | Chris Wilson <chris@chris-wilson.co.uk> | 2013-09-02 22:37:23 +0100 |
---|---|---|
committer | Chris Wilson <chris@chris-wilson.co.uk> | 2013-09-02 22:42:48 +0100 |
commit | 13a28f607f0eb4b4906e856c3f75f53446f4f999 (patch) | |
tree | c247ae97ba47642206ff6e816e993fa471e7d341 /tools/virtual.c | |
parent | e6e6572ac8f15bfee204cdf6bee4661ee2c6ffbb (diff) |
intel-virtual-overlay: Try to shutdown gracefully
Attempt to clean up the VIRTUAL mess when we exit.
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Diffstat (limited to 'tools/virtual.c')
-rw-r--r-- | tools/virtual.c | 67 |
1 files changed, 65 insertions, 2 deletions
diff --git a/tools/virtual.c b/tools/virtual.c index c781f413..7655a7b0 100644 --- a/tools/virtual.c +++ b/tools/virtual.c @@ -48,6 +48,7 @@ #include <stdio.h> #include <stdlib.h> #include <stdint.h> +#include <signal.h> #include <getopt.h> #include <limits.h> #include <ctype.h> @@ -2287,9 +2288,64 @@ static int first_display_sibling(struct context *ctx, int i) return 1; } + #define first_display_for_each_sibling(CTX, i) \ for (i = first_display_first_sibling(CTX); first_display_sibling(CTX, i); i++) +static void context_cleanup(struct context *ctx) +{ + Display *dpy = ctx->display->dpy; + XRRScreenResources *res; + int i, j; + + res = _XRRGetScreenResourcesCurrent(dpy, ctx->display->root); + if (res == NULL) + return; + + for (i = 0; i < ctx->nclone; i++) { + struct clone *clone = &ctx->clones[i]; + XRROutputInfo *output; + + assert(clone->src.display == ctx->display); + + output = XRRGetOutputInfo(dpy, res, clone->src.rr_output); + if (output == NULL) + continue; + + if (output->crtc) + XRRSetCrtcConfig(dpy, res, output->crtc, CurrentTime, + 0, 0, None, RR_Rotate_0, NULL, 0); + + for (j = 0; j < output->nmode; j++) + XRRDeleteOutputMode(dpy, clone->src.rr_output, output->modes[j]); + + XRRFreeOutputInfo(output); + } + + for (i = 0; i < res->nmode; i++) { + if (strncmp(res->modes[i].name, "VIRTUAL", 7) == 0) { + XRRDestroyMode(dpy, res->modes[i].id); + continue; + } + + if (strcmp(res->modes[i].name, "ClaimVirtualHead") == 0) { + XRRDestroyMode(dpy, res->modes[i].id); + continue; + } + } + + XRRFreeScreenResources(res); + + XCloseDisplay(dpy); +} + +static int done; + +static void signal_handler(int sig) +{ + done = sig; +} + int main(int argc, char **argv) { struct context ctx; @@ -2298,6 +2354,8 @@ int main(int argc, char **argv) int daemonize = 1, bumblebee = 0, all = 0, singleton = 1; int i, ret, open, fail; + signal(SIGPIPE, SIG_IGN); + while ((i = getopt(argc, argv, "abd:fhS")) != -1) { switch (i) { case 'd': @@ -2432,8 +2490,12 @@ int main(int argc, char **argv) if (daemonize && daemon(0, 0)) return EINVAL; + signal(SIGHUP, signal_handler); + signal(SIGINT, signal_handler); + signal(SIGTERM, signal_handler); + ctx.command_continuation = 0; - while (1) { + while (!done) { XEvent e; int reconfigure = 0; @@ -2558,5 +2620,6 @@ int main(int argc, char **argv) XPending(ctx.record); } - return EINVAL; + context_cleanup(&ctx); + return 0; } |