=?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