=?n?q?=5BPATCH=20xrandr-utils=201/4=5D=20Refactor=20rotations=20into=20library?=

Bryce Harrington bryce at canonical.com
Wed Feb 15 16:10:40 PST 2012


This is perhaps the simplest way to refactor out the code, but I'm not
happy with it.  It adds three api calls when it seems like 2 ought to be
sufficient.  Also, one routine returns 0 on error, the other -1, and
that's no good.

Signed-off-by: Bryce Harrington <bryce at canonical.com>
---
 Makefile.am                          |    2 +-
 examples/Makefile.am                 |    9 ++-
 examples/xrandr.c                    |   61 ++++++----------
 include/X11/extensions/XrandrUtils.h |   11 +++
 man/XrandrUtils.man                  |   19 +++++
 src/XrandrUtils.c                    |   74 +++++++++++++++++++
 test/.gitignore                      |    1 +
 test/Makefile.am                     |    8 ++-
 test/rotations.c                     |  132 ++++++++++++++++++++++++++++++++++
 9 files changed, 274 insertions(+), 43 deletions(-)
 create mode 100644 test/rotations.c

diff --git a/Makefile.am b/Makefile.am
index f6bb4f9..0bb4033 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -19,7 +19,7 @@
 #  TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 #  PERFORMANCE OF THIS SOFTWARE.
 
-SUBDIRS = examples man src test
+SUBDIRS = src test examples man
 
 pkgconfigdir = $(libdir)/pkgconfig
 pkgconfig_DATA = xrandr-utils.pc
diff --git a/examples/Makefile.am b/examples/Makefile.am
index c993ccc..438e0b7 100644
--- a/examples/Makefile.am
+++ b/examples/Makefile.am
@@ -4,10 +4,17 @@ AM_CFLAGS = \
 	$(RANDR_UTILS_CFLAGS) \
 	$(MALLOC_ZERO_CFLAGS) \
 	$(CWARNFLAGS)
-xrandr_LDADD = @RANDR_UTILS_LIBS@
+
+RANDR_UTILS_LIB = $(top_builddir)/src/libXrandrUtils.la
+
+xrandr_LDADD = \
+	$(RANDR_UTILS_LIB) \
+	@RANDR_UTILS_LIBS@
 
 INCLUDES = -I$(top_srcdir)/include/X11/extensions
 
 xrandr_SOURCES =	\
         xrandr.c
 
+$(RANDR_UTILS_LIB):
+	@cd $(top_builddir)/src/ && $(MAKE) libXrandrUtils.la
diff --git a/examples/xrandr.c b/examples/xrandr.c
index a69eea3..c6ad767 100644
--- a/examples/xrandr.c
+++ b/examples/xrandr.c
@@ -51,13 +51,6 @@ static Bool	properties = False;
 static Bool	grab_server = True;
 static Bool	no_primary = False;
 
-static char *direction[5] = {
-    "normal", 
-    "left", 
-    "inverted", 
-    "right",
-    "\n"};
-
 static char *reflections[5] = {
     "normal", 
     "x", 
@@ -181,19 +174,6 @@ static inline double dmin (double x, double y)
 }
 
 static char *
-rotation_name (Rotation rotation)
-{
-    int	i;
-
-    if ((rotation & 0xf) == 0)
-	return "normal";
-    for (i = 0; i < 4; i++)
-	if (rotation & (1 << i))
-	    return direction[i];
-    return "invalid rotation";
-}
-
-static char *
 reflection_name (Rotation rotation)
 {
     rotation &= (RR_Reflect_X|RR_Reflect_Y);
@@ -1132,7 +1112,7 @@ set_output_info (output_t *output, RROutput xid, XRROutputInfo *output_info)
     if (!output_can_use_rotation (output, output->rotation))
 	fatal ("output %s cannot use rotation \"%s\" reflection \"%s\"\n",
 	       output->output.string,
-	       rotation_name (output->rotation),
+	       XRURotationName (output->rotation),
 	       reflection_name (output->rotation));
 
     /* set gamma */
@@ -2246,10 +2226,9 @@ main (int argc, char **argv)
 	    if (++i>=argc) usage ();
 	    dirind = strtol(argv[i], &endptr, 10);
 	    if (argv[i] == endptr) {
-		for (dirind = 0; dirind < 4; dirind++) {
-		    if (strcmp (direction[dirind], argv[i]) == 0) break;
-		}
-		if ((dirind < 0) || (dirind > 3))  usage();
+		dirind = XRUGetRotationIndex(argv[i]);
+		if ((dirind < 0) || (dirind > 3))
+		    usage();
 	    }
 	    rot = dirind;
 	    setit = True;
@@ -2310,11 +2289,9 @@ main (int argc, char **argv)
 	}
 	if (!strcmp ("--rotation", argv[i]) || !strcmp ("--rotate", argv[i])) {
 	    if (++i>=argc) usage ();
-	    if (!output) usage();
-	    for (dirind = 0; dirind < 4; dirind++) {
-		if (strcmp (direction[dirind], argv[i]) == 0) break;
-	    }
-	    if (dirind == 4)
+	    if (!output) usage ();
+	    dirind = XRUGetRotationIndex(argv[i]);
+	    if ((dirind < 0) || (dirind > 3))
 		usage ();
 	    output->rotation &= ~0xf;
 	    output->rotation |= 1 << dirind;
@@ -2323,10 +2300,10 @@ main (int argc, char **argv)
 	}
 	if (!strcmp ("--reflect", argv[i]) || !strcmp ("--reflection", argv[i])) {
 	    if (++i>=argc) usage ();
-	    if (!output) usage();
+	    if (!output) usage ();
 	    for (dirind = 0; dirind < 4; dirind++) {
-		if (strcmp (reflections[dirind], argv[i]) == 0) break;
-	    }
+                if (strcmp (reflections[dirind], argv[i]) == 0) break;
+            }
 	    if (dirind == 4)
 		usage ();
 	    output->rotation &= ~(RR_Reflect_X|RR_Reflect_Y);
@@ -2938,8 +2915,8 @@ main (int argc, char **argv)
 		    printf (" (0x%x)", (int)mode->id);
 		if (output->rotation != RR_Rotate_0 || verbose)
 		{
-		    printf (" %s", 
-			    rotation_name (output->rotation));
+		    printf (" %s",
+			    XRURotationName (output->rotation));
 		    if (output->rotation & (RR_Reflect_X|RR_Reflect_Y))
 			printf (" %s", reflection_name (output->rotation));
 		}
@@ -2951,7 +2928,8 @@ main (int argc, char **argv)
 		for (i = 0; i < 4; i ++) {
 		    if ((rotations >> i) & 1) {
 			if (!first) printf (" "); first = False;
-			printf("%s", direction[i]);
+			rotation = XRUGetRotation(i);
+			printf("%s", XRURotationName(rotation));
 		    }
 		}
 		if (rotations & RR_Reflect_X)
@@ -3311,14 +3289,17 @@ main (int argc, char **argv)
     rotation = 1 << rot ;
     if (query) {
     	printf("Current rotation - %s\n",
-	       rotation_name (current_rotation));
+	       XRURotationName (current_rotation));
 
 	printf("Current reflection - %s\n",
 	       reflection_name (current_rotation));
 
 	printf ("Rotations possible - ");
 	for (i = 0; i < 4; i ++) {
-	    if ((rotations >> i) & 1)  printf("%s ", direction[i]);
+	    if ((rotations >> i) & 1) {
+		rotation = XRUGetRotation(i);
+		printf("%s ", XRURotationName(rotation));
+	    }
 	}
 	printf ("\n");
 
@@ -3333,8 +3314,8 @@ main (int argc, char **argv)
 	printf ("\n");
     }
 
-    if (verbose) { 
-	printf("Setting size to %d, rotation to %s\n",  size, direction[rot]);
+    if (verbose) {
+	printf("Setting size to %d, rotation to %s\n",  size, XRURotationName(rotation));
 
 	printf ("Setting reflection on ");
 	if (reflection)
diff --git a/include/X11/extensions/XrandrUtils.h b/include/X11/extensions/XrandrUtils.h
index 7542713..c48de2e 100644
--- a/include/X11/extensions/XrandrUtils.h
+++ b/include/X11/extensions/XrandrUtils.h
@@ -28,6 +28,8 @@
 #ifndef _XRANDR_UTILS_H_
 #define _XRANDR_UTILS_H_
 
+#include <X11/extensions/randr.h>
+
 typedef enum {
   relation_left_of,
   relation_right_of,
@@ -44,4 +46,13 @@ typedef struct {
   int     x, y;
 } XRUPoint;
 
+const char *
+XRURotationName(Rotation rotation);
+
+int
+XRUGetRotationIndex(char * rotation_name);
+
+Rotation
+XRUGetRotation(int dirind);
+
 #endif /* _XRANDR_UTILS_H_ */
diff --git a/man/XrandrUtils.man b/man/XrandrUtils.man
index bea2776..0fd1a46 100644
--- a/man/XrandrUtils.man
+++ b/man/XrandrUtils.man
@@ -33,6 +33,25 @@ typedef struct {
 typedef struct {
   int     x, y;
 } XRUPoint;
+
+/**
+ * Return string name for the given rotation,
+ * or "invalid rotation" on error.
+ */
+const char * XRURotationName(Rotation rotation);
+
+/**
+ * Look up rotation name and return an index number,
+ * or -1 if name could not be found.
+ */
+int XRUGetRotationIndex(char * rotation_name);
+
+/**
+ * Return the Rotation matching the given index,
+ * or 0 if not valid.
+ */
+Rotation XRUGetRotation(int dirind);
+
 .sp
 .fi
 
diff --git a/src/XrandrUtils.c b/src/XrandrUtils.c
index e69de29..a00ad1c 100644
--- a/src/XrandrUtils.c
+++ b/src/XrandrUtils.c
@@ -0,0 +1,74 @@
+/*
+ * Copyright © 2001 Keith Packard, member of The XFree86 Project, Inc.
+ * Copyright © 2002 Hewlett Packard Company, Inc.
+ * Copyright © 2006 Intel Corporation
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that copyright
+ * notice and this permission notice appear in supporting documentation, and
+ * that the name of the copyright holders not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission.  The copyright holders make no representations
+ * about the suitability of this software for any purpose.  It is provided "as
+ * is" without express or implied warranty.
+ *
+ * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
+ * OF THIS SOFTWARE.
+ *
+ * Thanks to Jim Gettys who wrote most of the client side code,
+ * and part of the server code for randr.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <string.h>
+#include <X11/extensions/randr.h>
+
+#include "XrandrUtils.h"
+
+static /* const */ char * ru_direction[5] = {
+    "normal",
+    "left",
+    "inverted",
+    "right",
+    "\n"};
+const char *
+XRURotationName(Rotation rotation)
+{
+    int i;
+
+    if ((rotation & 0xf) == 0)
+        return "normal";
+    for (i = 0; i < 4; i++)
+        if (rotation & (1 << i))
+            return ru_direction[i];
+    return "invalid rotation";
+}
+
+int
+XRUGetRotationIndex(char * rotation_name)
+{
+    int dirind;
+    if (!rotation_name)
+	return -1;
+    for (dirind = 0; dirind < 4; dirind++)
+	if (strcmp (ru_direction[dirind], rotation_name) == 0)
+	    return dirind;
+    return -1;
+}
+
+Rotation
+XRUGetRotation(int dirind)
+{
+    if ((dirind < 0) || (dirind > 3))
+	return 0;
+    return (1 << dirind);
+}
diff --git a/test/.gitignore b/test/.gitignore
index 953f2c7..3819c8e 100644
--- a/test/.gitignore
+++ b/test/.gitignore
@@ -1,2 +1,3 @@
 geometry
 xrandr
+rotations
diff --git a/test/Makefile.am b/test/Makefile.am
index bcd59ab..9c11fda 100644
--- a/test/Makefile.am
+++ b/test/Makefile.am
@@ -1,4 +1,4 @@
-check_PROGRAMS = geometry
+check_PROGRAMS = geometry rotations
 
 TESTS = $(check_PROGRAMS)
 
@@ -9,6 +9,12 @@ AM_CFLAGS = \
 
 INCLUDES = -I$(top_srcdir)/include/X11/extensions
 
+RANDR_UTIL_LIB = $(top_builddir)/src/libXrandrUtils.la
+
 TEST_LDADD = @RANDR_UTILS_LIBS@
 
 geometry_LDADD = $(TEST_LDADD)
+rotations_LDADD = $(TEST_LDADD) $(RANDR_UTIL_LIB)
+
+$(RANDR_UTIL_LIB):
+	@cd $(top_builddir)/src/ && $(MAKE) libXrandrUtils.la
diff --git a/test/rotations.c b/test/rotations.c
new file mode 100644
index 0000000..e96a0b5
--- /dev/null
+++ b/test/rotations.c
@@ -0,0 +1,132 @@
+/**
+ * Copyright © 2011 Canonical, Ltd.
+ *
+ *  Permission is hereby granted, free of charge, to any person obtaining a
+ *  copy of this software and associated documentation files (the "Software"),
+ *  to deal in the Software without restriction, including without limitation
+ *  the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ *  and/or sell copies of the Software, and to permit persons to whom the
+ *  Software is furnished to do so, subject to the following conditions:
+ *
+ *  The above copyright notice and this permission notice (including the next
+ *  paragraph) shall be included in all copies or substantial portions of the
+ *  Software.
+ *
+ *  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ *  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ *  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ *  THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ *  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *  FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ *  DEALINGS IN THE SOFTWARE.
+ */
+
+/**
+ * Test rotation and rotation name helper functions.
+ */
+
+#include <string.h>
+#include <assert.h>
+#include <stdio.h>
+
+#include "XrandrUtils.h"
+
+/**
+ * Lookup rotation names
+ */
+static void rotation_names(void)
+{
+    Rotation normal   = RR_Rotate_0;
+    Rotation left     = RR_Rotate_90;
+    Rotation inverted = RR_Rotate_180;
+    Rotation right    = RR_Rotate_270;
+
+    assert(0 == strcmp("normal",   XRURotationName( normal )));
+    assert(0 == strcmp("left",     XRURotationName( left )));
+    assert(0 == strcmp("inverted", XRURotationName( inverted )));
+    assert(0 == strcmp("right",    XRURotationName( right )));
+
+    assert(0 == strcmp("left",     XRURotationName( left | right )));
+}
+
+/**
+ * Verify that out of range name lookups produce an appropriate value or error
+ */
+static void rotation_names_invalid(void)
+{
+    assert(0 == strcmp("normal", XRURotationName((Rotation) 0 )));
+    assert(0 == strcmp("normal", XRURotationName((Rotation) 1 << 5 )));
+}
+
+/**
+ * Lookup rotation indexes by their string name
+ */
+static void rotation_indexes_by_name(void)
+{
+    assert(0 == XRUGetRotationIndex("normal"));
+    assert(1 == XRUGetRotationIndex("left"));
+    assert(2 == XRUGetRotationIndex("inverted"));
+    assert(3 == XRUGetRotationIndex("right"));
+}
+
+/**
+ * Verify garbage name lookups produce an appropriate error
+ */
+static void rotation_indexes_by_invalid_name(void)
+{
+    assert(-1 == XRUGetRotationIndex(NULL));
+    assert(-1 == XRUGetRotationIndex(""));
+    assert(-1 == XRUGetRotationIndex(" "));
+    assert(-1 == XRUGetRotationIndex("riight"));
+    assert(-1 == XRUGetRotationIndex("invalid"));
+    assert(-1 == XRUGetRotationIndex("NORMAL"));
+    assert(-1 == XRUGetRotationIndex("uni©ode"));
+}
+
+/**
+ * Check unterminated string behavior
+ */
+static void rotation_indexes_by_unterminated_name(void)
+{
+    char left_unterminated[5] = "left";
+    left_unterminated[4] = ' ';
+
+    assert(-1 == XRUGetRotationIndex(left_unterminated));
+}
+
+/**
+ * Lookup rotations by index
+ */
+static void rotations_by_index(void)
+{
+    assert(RR_Rotate_0   == XRUGetRotation(0));
+    assert(RR_Rotate_90  == XRUGetRotation(1));
+    assert(RR_Rotate_180 == XRUGetRotation(2));
+    assert(RR_Rotate_270 == XRUGetRotation(3));
+}
+
+/**
+ * Verify out of range indexes produce appropriate errors
+ */
+static void rotations_by_invalid_index(void)
+{
+    assert(0 == XRUGetRotation(-1));
+    assert(0 == XRUGetRotation( 4));
+    assert(0 == XRUGetRotation(42));
+    assert(0 == XRUGetRotation(-100));
+}
+
+int main(int argc, char** argv)
+{
+    rotation_names();
+    rotation_names_invalid();
+
+    rotation_indexes_by_name();
+    rotation_indexes_by_invalid_name();
+    rotation_indexes_by_unterminated_name();
+
+    rotations_by_index();
+    rotations_by_invalid_index();
+
+    return 0;
+}
-- 
1.7.9



More information about the xorg-devel mailing list