summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKeith Packard <keithp@keithp.com>2013-02-28 11:23:31 -0800
committerKeith Packard <keithp@keithp.com>2013-02-28 11:25:39 -0800
commitd927ec1c20adf33d3c579285f5b251e623f7d79f (patch)
tree03f6b755f3d9cbf88ab857afc6d05cd1a130222e
Autotool
Signed-off-by: Keith Packard <keithp@keithp.com>
-rw-r--r--Makefile.am20
-rwxr-xr-xautogen.sh14
-rw-r--r--configure.ac21
-rw-r--r--x-on-resize.c216
4 files changed, 271 insertions, 0 deletions
diff --git a/Makefile.am b/Makefile.am
new file mode 100644
index 0000000..978f26f
--- /dev/null
+++ b/Makefile.am
@@ -0,0 +1,20 @@
+bin_PROGRAMS = x-on-resize
+
+AM_CFLAGS = $(XONRESIZE_CFLAGS) $(CWARNFLAGS)
+
+x_on_resize_LDADD = $(XONRESIZE_LIBS)
+
+x_on_resize_SOURCES = \
+ x-on-resize.c
+
+MAINTAINERCLEANFILES = ChangeLog INSTALL
+
+.PHONY: ChangeLog INSTALL
+
+INSTALL:
+ $(INSTALL_CMD)
+
+ChangeLog:
+ $(CHANGELOG_CMD)
+
+dist-hook: ChangeLog INSTALL
diff --git a/autogen.sh b/autogen.sh
new file mode 100755
index 0000000..fc34bd5
--- /dev/null
+++ b/autogen.sh
@@ -0,0 +1,14 @@
+#! /bin/sh
+
+srcdir=`dirname $0`
+test -z "$srcdir" && srcdir=.
+
+ORIGDIR=`pwd`
+cd $srcdir
+
+autoreconf -v --install || exit 1
+cd $ORIGDIR || exit $?
+
+if test -z "$NOCONFIGURE"; then
+ $srcdir/configure "$@"
+fi
diff --git a/configure.ac b/configure.ac
new file mode 100644
index 0000000..12b8d54
--- /dev/null
+++ b/configure.ac
@@ -0,0 +1,21 @@
+AC_PREREQ([2.60])
+AC_INIT([x-on-resize], [0.1],
+ [https://bugs.freedesktop.org/enter_bug.cgi?product=xorg], [x-on-resize])
+AC_CONFIG_SRCDIR([Makefile.am])
+AC_CONFIG_HEADERS([config.h])
+
+# Initialize Automake
+AM_INIT_AUTOMAKE([foreign dist-bzip2])
+
+# Require X.Org macros 1.8 or later for MAN_SUBSTS set by XORG_MANPAGE_SECTIONS
+m4_ifndef([XORG_MACROS_VERSION],
+ [m4_fatal([must install xorg-macros 1.8 or later before running autoconf/autogen])])
+XORG_MACROS_VERSION(1.8)
+XORG_DEFAULT_OPTIONS
+
+# Checks for pkg-config packages
+PKG_CHECK_MODULES(XONRESIZE, xrandr x11)
+
+AC_CONFIG_FILES([
+ Makefile])
+AC_OUTPUT
diff --git a/x-on-resize.c b/x-on-resize.c
new file mode 100644
index 0000000..93715a4
--- /dev/null
+++ b/x-on-resize.c
@@ -0,0 +1,216 @@
+/*
+ * Copyright © 2011 Keith Packard <keithp@keithp.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <getopt.h>
+#include <unistd.h>
+#include <X11/Xlib.h>
+#include <X11/extensions/Xrandr.h>
+
+struct output_info {
+ struct output_info *next;
+ RROutput output;
+ XRROutputInfo *info;
+};
+
+static struct output_info *output_info;
+
+static struct output_info *
+find_output_info (RROutput output)
+{
+ struct output_info *oi;
+
+ for (oi = output_info; oi; oi = oi->next)
+ if (oi->output == output)
+ return oi;
+ return NULL;
+}
+
+static void
+clear_output_info (RROutput output)
+{
+ struct output_info *oi, **prev;
+
+ for (prev = &output_info; (oi = *prev); prev = &(oi->next))
+ if (oi->output == output) {
+ XRRFreeOutputInfo (oi->info);
+ *prev = oi->next;
+ free (oi);
+ break;
+ }
+}
+
+/*
+ * Check to see if the monitor attached to an output
+ * is the same
+ */
+static int
+same_monitor(XRROutputInfo *a, XRROutputInfo *b)
+{
+ int m;
+
+ if (a->connection != b->connection)
+ return 0;
+ if (a->nmode != b->nmode)
+ return 0;
+ if (a->npreferred != b->npreferred)
+ return 0;
+ for (m = 0; m < a->nmode; m++)
+ if (a->modes[m] != b->modes[m])
+ return 0;
+ return 1;
+}
+
+static int
+check_output (Display *dpy, XRRScreenResources *resources, RROutput output)
+{
+ XRROutputInfo *info;
+ struct output_info *oi;
+
+ info = XRRGetOutputInfo (dpy, resources, output);
+ if (!info) {
+ clear_output_info(output);
+ return 0;
+ }
+ oi = find_output_info(output);
+ if (oi) {
+ int same = same_monitor(oi->info, info);
+ XRRFreeOutputInfo(oi->info);
+ oi->info = info;
+ return same;
+ }
+ oi = calloc(1, sizeof (struct output_info));
+ oi->output = output;
+ oi->info = info;
+ oi->next = output_info;
+ output_info = oi;
+ return 0;
+}
+
+
+int
+main (int argc, char **argv)
+{
+ Display *dpy;
+ int event_base, error_base;
+ int major, minor;
+ XEvent ev;
+ XRRNotifyEvent *nev;
+ char *config = NULL;
+ char *resize = NULL;
+ char *display = NULL;
+ int c, o;
+ int start = 0;
+ XRRScreenResources *resources;
+
+ static struct option opts[] = {
+ { "config", 1, NULL, 'c' },
+ { "resize", 1, NULL, 'r' },
+ { "start", 0, NULL, 's' },
+ { "display", 1, NULL, 'd' },
+ { "help", 0, NULL, 'h' },
+ { 0, 0, NULL, 0 }
+ };
+
+ while ((c = getopt_long(argc, argv, "c:r:d:hs", opts, NULL)) != -1) {
+ switch (c) {
+ case 'c':
+ config = optarg;
+ break;
+ case 'r':
+ resize = optarg;
+ break;
+ case 'd':
+ display = optarg;
+ break;
+ case 's':
+ start = 1;
+ break;
+ case 'h':
+ default:
+ fprintf(stderr, "Usage: %s --display <display> --config <config> --resize <resize> --start\n", argv[0]);
+ exit(1);
+ break;
+ }
+ }
+
+ dpy = XOpenDisplay(display);
+ if (!dpy) {
+ fprintf(stderr, "XOpenDisplay %s failed\n", XDisplayName(display));
+ exit(1);
+ }
+ if (!XRRQueryExtension (dpy, &event_base, &error_base) ||
+ !XRRQueryVersion (dpy, &major, &minor))
+ {
+ fprintf (stderr, "RandR extension missing on %s\n", XDisplayName(display));
+ exit (1);
+ }
+ XRRSelectInput(dpy, RootWindow(dpy, 0), RROutputChangeNotifyMask);
+ XSelectInput(dpy, RootWindow(dpy, 0), StructureNotifyMask);
+
+ /* Get current configuration */
+ resources = XRRGetScreenResourcesCurrent(dpy, RootWindow(dpy, 0));
+ for (o = 0; o < resources->noutput; o++)
+ (void) check_output(dpy, resources, resources->outputs[o]);
+ XRRFreeScreenResources (resources);
+
+ if (start) {
+ if (config)
+ system(config);
+ else
+ printf("config\n");
+ }
+ for (;;) {
+ int configed = 0;
+ int resized = 0;
+
+ do {
+ XNextEvent(dpy, &ev);
+ switch (ev.type - event_base) {
+ case RRNotify:
+ nev = (XRRNotifyEvent *) &ev;
+ if (nev->subtype == RRNotify_OutputChange) {
+ XRROutputChangeNotifyEvent *noev = (XRROutputChangeNotifyEvent *) nev;
+ resources = XRRGetScreenResources(dpy, RootWindow(dpy, 0));
+ if (!check_output(dpy, resources, noev->output))
+ configed = 1;
+ XRRFreeScreenResources (resources);
+ }
+ break;
+ }
+ switch (ev.type) {
+ case ConfigureNotify:
+ resized = 1;
+ break;
+ }
+ usleep(100000);
+ } while (XEventsQueued(dpy, QueuedAfterFlush));
+ if (configed) {
+ if (config)
+ system(config);
+ else
+ printf ("config\n");
+ }
+ if (resized) {
+ if (resize)
+ system(resize);
+ else
+ printf ("resize\n");
+ }
+ }
+}