summaryrefslogtreecommitdiff
path: root/tools/virtual.c
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2013-09-02 22:37:23 +0100
committerChris Wilson <chris@chris-wilson.co.uk>2013-09-02 22:42:48 +0100
commit13a28f607f0eb4b4906e856c3f75f53446f4f999 (patch)
treec247ae97ba47642206ff6e816e993fa471e7d341 /tools/virtual.c
parente6e6572ac8f15bfee204cdf6bee4661ee2c6ffbb (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.c67
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;
}