diff options
-rw-r--r-- | xrandr.c | 377 | ||||
-rw-r--r-- | xrandr.man | 76 |
2 files changed, 453 insertions, 0 deletions
diff --git a/xrandr.c b/xrandr.c new file mode 100644 index 0000000..79af8dd --- /dev/null +++ b/xrandr.c @@ -0,0 +1,377 @@ +/* + * $XFree86: xc/programs/xrandr/xrandr.c,v 1.12 2002/11/01 20:04:00 keithp Exp $ + * + * Copyright © 2001 Keith Packard, member of The XFree86 Project, Inc. + * Copyright © 2002 Hewlett Pacard Company, Inc. + * + * 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 Keith Packard or HP not be used in + * advertising or publicity pertaining to distribution of the software without + * specific, written prior permission. Keith Packard and HP makes no + * representations about the suitability of this software for any purpose. It + * is provided "as is" without express or implied warranty. + * + * KEITH PACKARD and HP DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL KEITH PACKARD 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. + * + * Blame Jim Gettys for any bugs; he wrote most of the client side code, + * and part of the server code for randr. + */ + +#include <stdio.h> +#include <X11/Xlib.h> +#include <X11/Xlibint.h> +#include <X11/Xproto.h> +#include <X11/extensions/Xrandr.h> +#include <X11/extensions/Xrender.h> /* we share subpixel information */ +#include <string.h> +#include <stdlib.h> + +static char *program_name; + +static char *direction[5] = { + "normal", + "left", + "inverted", + "right", + "\n"}; + +/* subpixel order */ +static char *order[6] = { + "unknown", + "horizontal rgb", + "horizontal bgr", + "vertical rgb", + "vertical bgr", + "no subpixels"}; + + +static void +usage(void) +{ + fprintf(stderr, "usage: %s [options]\n", program_name); + fprintf(stderr, " where options are:\n"); + fprintf(stderr, " -display <display> or -d <display>\n"); + fprintf(stderr, " -help\n"); + fprintf(stderr, " -o <normal,inverted,left,right,0,1,2,3>\n"); + fprintf(stderr, " or --orientation <normal,inverted,left,right,0,1,2,3>\n"); + fprintf(stderr, " -q or --query\n"); + fprintf(stderr, " -s <size>/<width>x<height> or --size <size>/<width>x<height>\n"); + fprintf(stderr, " -r <rate> or --rate <rate>\n"); + fprintf(stderr, " -v or --version\n"); + fprintf(stderr, " -x (reflect in x)\n"); + fprintf(stderr, " -y (reflect in y)\n"); + fprintf(stderr, " --screen <screen>\n"); + fprintf(stderr, " --verbose\n"); + + exit(1); + /*NOTREACHED*/ +} + +int +main (int argc, char **argv) +{ + Display *dpy; + XRRScreenSize *sizes; + XRRScreenConfiguration *sc; + int nsize; + int nrate; + short *rates; + Window root; + Status status = RRSetConfigFailed; + int rot = -1; + int verbose = 0, query = 0; + Rotation rotation, current_rotation, rotations; + XEvent event; + XRRScreenChangeNotifyEvent *sce; + char *display_name = NULL; + int i, j; + SizeID current_size; + short current_rate; + int rate = -1; + int size = -1; + int dirind = 0; + int setit = 0; + int screen = -1; + int version = 0; + int event_base, error_base; + int reflection = 0; + int width = 0, height = 0; + int have_pixel_size = 0; + + program_name = argv[0]; + if (argc == 1) query = 1; + for (i = 1; i < argc; i++) { + if (!strcmp ("-display", argv[i]) || !strcmp ("-d", argv[i])) { + if (++i>=argc) usage (); + display_name = argv[i]; + continue; + } + if (!strcmp("-help", argv[i])) { + usage(); + continue; + } + if (!strcmp ("--verbose", argv[i])) { + verbose = 1; + continue; + } + + if (!strcmp ("-s", argv[i]) || !strcmp ("--size", argv[i])) { + if (++i>=argc) usage (); + if (sscanf (argv[i], "%dx%d", &width, &height) == 2) + have_pixel_size = 1; + else { + size = atoi (argv[i]); + if (size < 0) usage(); + } + setit = 1; + continue; + } + + if (!strcmp ("-r", argv[i]) || !strcmp ("--rate", argv[i])) { + if (++i>=argc) usage (); + rate = atoi (argv[i]); + if (rate < 0) usage(); + setit = 1; + continue; + } + + if (!strcmp ("-v", argv[i]) || !strcmp ("--version", argv[i])) { + version = 1; + continue; + } + + if (!strcmp ("-x", argv[i])) { + reflection |= RR_Reflect_X; + setit = 1; + continue; + } + if (!strcmp ("-y", argv[i])) { + reflection |= RR_Reflect_Y; + setit = 1; + continue; + } + if (!strcmp ("--screen", argv[i])) { + if (++i>=argc) usage (); + screen = atoi (argv[i]); + if (screen < 0) usage(); + continue; + } + if (!strcmp ("-q", argv[i]) || !strcmp ("--query", argv[i])) { + query = 1; + continue; + } + if (!strcmp ("-o", argv[i]) || !strcmp ("--orientation", argv[i])) { + char *endptr; + if (++i>=argc) usage (); + dirind = strtol(argv[i], &endptr, 0); + if (*endptr != '\0') { + for (dirind = 0; dirind < 4; dirind++) { + if (strcmp (direction[dirind], argv[i]) == 0) break; + } + if ((dirind < 0) || (dirind > 3)) usage(); + } + rot = dirind; + setit = 1; + continue; + } + usage(); + } + if (verbose) query = 1; + + dpy = XOpenDisplay (display_name); + + if (dpy == NULL) { + fprintf (stderr, "Can't open display %s\n", display_name); + exit (1); + } + if (screen < 0) + screen = DefaultScreen (dpy); + if (screen >= ScreenCount (dpy)) { + fprintf (stderr, "Invalid screen number %d (display has %d)\n", + screen, ScreenCount (dpy)); + exit (1); + } + + root = RootWindow (dpy, screen); + + sc = XRRGetScreenInfo (dpy, root); + + if (sc == NULL) + exit (1); + + current_size = XRRConfigCurrentConfiguration (sc, ¤t_rotation); + + sizes = XRRConfigSizes(sc, &nsize); + + if (have_pixel_size) { + for (size = 0; size < nsize; size++) + { + if (sizes[size].width == width && sizes[size].height == height) + break; + } + } + else if (size < 0) + size = current_size; + + if (size >= nsize) usage(); + + if (rot < 0) + { + for (rot = 0; rot < 4; rot++) + if (1 << rot == (current_rotation & 0xf)) + break; + } + + current_rate = XRRConfigCurrentRate (sc); + + if (rate < 0) + { + if (size == current_size) + rate = current_rate; + else + rate = 0; + } + + if (version) { + int major_version, minor_version; + XRRQueryVersion (dpy, &major_version, &minor_version); + printf("Server reports RandR version %d.%d\n", + major_version, minor_version); + } + + if (query) { + printf(" SZ: Pixels Physical Refresh\n"); + for (i = 0; i < nsize; i++) { + printf ("%c%-2d %5d x %-5d (%4dmm x%4dmm )", + i == current_size ? '*' : ' ', + i, sizes[i].width, sizes[i].height, + sizes[i].mwidth, sizes[i].mheight); + rates = XRRConfigRates (sc, i, &nrate); + if (nrate) printf (" "); + for (j = 0; j < nrate; j++) + printf ("%c%-4d", + i == current_size && rates[j] == current_rate ? '*' : ' ', + rates[j]); + printf ("\n"); + } + } + + rotations = XRRConfigRotations(sc, ¤t_rotation); + + rotation = 1 << rot ; + if (query) { + for (i = 0; i < 4; i ++) { + if ((current_rotation >> i) & 1) + printf("Current rotation - %s\n", direction[i]); + } + + printf("Current reflection - "); + if (current_rotation & (RR_Reflect_X|RR_Reflect_Y)) + { + if (current_rotation & RR_Reflect_X) printf ("X Axis "); + if (current_rotation & RR_Reflect_Y) printf ("Y Axis"); + } + else + printf ("none"); + printf ("\n"); + + + printf ("Rotations possible - "); + for (i = 0; i < 4; i ++) { + if ((rotations >> i) & 1) printf("%s ", direction[i]); + } + printf ("\n"); + + printf ("Reflections possible - "); + if (rotations & (RR_Reflect_X|RR_Reflect_Y)) + { + if (rotations & RR_Reflect_X) printf ("X Axis "); + if (rotations & RR_Reflect_Y) printf ("Y Axis"); + } + else + printf ("none"); + printf ("\n"); + } + + if (verbose) { + printf("Setting size to %d, rotation to %s\n", size, direction[rot]); + + printf ("Setting reflection on "); + if (reflection) + { + if (reflection & RR_Reflect_X) printf ("X Axis "); + if (reflection & RR_Reflect_Y) printf ("Y Axis"); + } + else + printf ("neither axis"); + printf ("\n"); + + if (reflection & RR_Reflect_X) printf("Setting reflection on X axis\n"); + + if (reflection & RR_Reflect_Y) printf("Setting reflection on Y axis\n"); + } + + /* we should test configureNotify on the root window */ + XSelectInput (dpy, root, StructureNotifyMask); + + if (setit) XRRSelectInput (dpy, root, + RRScreenChangeNotifyMask); + if (setit) status = XRRSetScreenConfigAndRate (dpy, sc, + DefaultRootWindow (dpy), + (SizeID) size, (Rotation) (rotation | reflection), rate, CurrentTime); + + XRRQueryExtension(dpy, &event_base, &error_base); + if (verbose && setit) { + if (status == RRSetConfigSuccess) + { + while (1) { + int spo; + XNextEvent(dpy, (XEvent *) &event); + + printf ("Event received, type = %d\n", event.type); + /* update Xlib's knowledge of the event */ + XRRUpdateConfiguration (&event); + if (event.type == ConfigureNotify) + printf("Received ConfigureNotify Event!\n"); + + switch (event.type - event_base) { + case RRScreenChangeNotify: + sce = (XRRScreenChangeNotifyEvent *) &event; + + printf("Got a screen change notify event!\n"); + printf(" window = %d\n root = %d\n size_index = %d\n rotation %d\n", + (int) sce->window, (int) sce->root, + sce->size_index, sce->rotation); + printf(" timestamp = %ld, config_timestamp = %ld\n", + sce->timestamp, sce->config_timestamp); + printf(" Rotation = %x\n", sce->rotation); + printf(" %d X %d pixels, %d X %d mm\n", + sce->width, sce->height, sce->mwidth, sce->mheight); + printf("Display width %d, height %d\n", + DisplayWidth(dpy, screen), DisplayHeight(dpy, screen)); + printf("Display widthmm %d, heightmm %d\n", + DisplayWidthMM(dpy, screen), DisplayHeightMM(dpy, screen)); + spo = sce->subpixel_order; + if ((spo < 0) || (spo > 5)) + printf ("Unknown subpixel order, value = %d\n", spo); + else printf ("new Subpixel rendering model is %s\n", order[spo]); + break; + default: + if (event.type != ConfigureNotify) + printf("unknown event received, type = %d!\n", event.type); + } + } + } + } + XRRFreeScreenConfigInfo(sc); + return(0); +} diff --git a/xrandr.man b/xrandr.man new file mode 100644 index 0000000..1e75aec --- /dev/null +++ b/xrandr.man @@ -0,0 +1,76 @@ +.\" +.\" Copyright © 2001 Keith Packard, member of The XFree86 Project, Inc. +.\" +.\" 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 Keith Packard not be used in +.\" advertising or publicity pertaining to distribution of the software without +.\" specific, written prior permission. Keith Packard makes no +.\" representations about the suitability of this software for any purpose. It +.\" is provided "as is" without express or implied warranty. +.\" +.\" KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, +.\" INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO +.\" EVENT SHALL KEITH PACKARD 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. +.\" +.\" +.\" $XFree86: xc/programs/xrandr/xrandr.man,v 1.4 2002/10/02 16:58:05 keithp Exp $ +.\" +.TH XRANDR 1 "Version 1.0" "XFree86" +.SH NAME +xrandr \- primitive command line interface to RandR extension +.SH SYNOPSIS +.B "xrandr" +[-help] [-display \fIdisplay\fP] +[-o \fIorientation\fP] +[-q] [-v] +[-s \fIsize\fP] +[-x] [-y] +[--screen \fIsnum\fP] +[--verbose] +.SH DESCRIPTION +.I Xrandr +is uses to set the screen size, orientation and/or reflection. +The +.I -s +option is a small integer index used to specify which size the screen should be set to. +To find out what sizes are available, use the +.I -q +option, which reports the sizes available, the current rotation, and +the possible rotations and reflections. +The default size is the first size specified in the list. +The +.I -o +option is used to specify the orientation of the screen, +and can be one of +\f"Inormal inverted left right 0 1 2 3"\fP. +.PP +The +.I -x +option instructs the server to reflect the screen on the X axis. +The +.I -y +option instructs the server to reflect the screen on the Y axis. +Reflection is applied after rotation. +.PP +The +.I -help +option prints out a usage summary. +The +.I --verbose +option tells you what xrandr is doing, selects for events, and tells you +when events are received to enable debugging. +.SH "SEE ALSO" +Xrandr(3) +.SH AUTHORS +Keith Packard, +XFree86 Core Team and Cambridge Research Laboratory, HP Labs, HP. +and +Jim Gettys, +Cambridge Research Laboratory, HP Labs, HP. |