2 * Copyright © 2006 Keith Packard
4 * Permission to use, copy, modify, distribute, and sell this software and its
5 * documentation for any purpose is hereby granted without fee, provided that
6 * the above copyright notice appear in all copies and that both that copyright
7 * notice and this permission notice appear in supporting documentation, and
8 * that the name of the copyright holders not be used in advertising or
9 * publicity pertaining to distribution of the software without specific,
10 * written prior permission. The copyright holders make no representations
11 * about the suitability of this software for any purpose. It is provided "as
12 * is" without express or implied warranty.
14 * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
15 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
16 * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
17 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
18 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
19 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
25 #include <X11/Xlibint.h>
26 #include <X11/Xatom.h>
27 #include <X11/Xproto.h>
28 #include <X11/extensions/Xrandr.h>
29 #include <X11/extensions/Xrender.h> /* we share subpixel information */
33 static char *program_name;
35 static char *direction[5] = {
43 static char *order[6] = {
51 static char *connection[3] = {
54 "unknown connection"};
59 fprintf(stderr, "usage: %s [options]\n", program_name);
60 fprintf(stderr, " where options are:\n");
61 fprintf(stderr, " -display <display> or -d <display>\n");
62 fprintf(stderr, " -help\n");
63 fprintf(stderr, " -o <normal,inverted,left,right,0,1,2,3>\n");
64 fprintf(stderr, " or --orientation <normal,inverted,left,right,0,1,2,3>\n");
65 fprintf(stderr, " -q or --query\n");
66 fprintf(stderr, " -s <size>/<width>x<height> or --size <size>/<width>x<height>\n");
67 fprintf(stderr, " -r <rate> or --rate <rate>\n");
68 fprintf(stderr, " -v or --version\n");
69 fprintf(stderr, " -x (reflect in x)\n");
70 fprintf(stderr, " -y (reflect in y)\n");
71 fprintf(stderr, " --screen <screen>\n");
72 fprintf(stderr, " --verbose\n");
79 main (int argc, char **argv)
82 XRRScreenResources *sr;
84 XRRScreenConfiguration *sc;
89 Status status = RRSetConfigFailed;
91 int verbose = 0, query = 0;
92 Rotation rotation = RR_Rotate_0, current_rotation, rotations;
94 XRRScreenChangeNotifyEvent *sce;
95 char *display_name = NULL;
105 int event_base, error_base;
107 int width = 0, height = 0;
108 int mmwidth = 0, mmheight = 0;
110 int have_size = 0, have_mm_size = 0;
111 int major_version, minor_version;
112 RRMode mode = (RRMode) -1;
114 RROutput output = (RROutput) -1;
117 int minWidth, minHeight;
118 int maxWidth, maxHeight;
120 program_name = argv[0];
121 if (argc == 1) query = 1;
122 for (i = 1; i < argc; i++) {
123 if (!strcmp ("-display", argv[i]) || !strcmp ("-d", argv[i])) {
124 if (++i>=argc) usage ();
125 display_name = argv[i];
128 if (!strcmp("-help", argv[i])) {
132 if (!strcmp ("--verbose", argv[i])) {
137 if (!strcmp ("-s", argv[i]) || !strcmp ("--size", argv[i])) {
138 if (++i>=argc) usage ();
139 if (sscanf (argv[i], "%dx%d", &width, &height) == 2)
146 if (!strcmp ("-mm", argv[i]) || !strcmp ("--mm", argv[i])) {
147 if (++i>=argc) usage ();
148 if (sscanf (argv[i], "%dx%d", &mmwidth, &mmheight) == 2)
155 if (!strcmp ("-m", argv[i]) || !strcmp ("--mode", argv[i])) {
156 if (++i>=argc) usage ();
157 mode = strtoul (argv[i], NULL, 0);
161 if (!strcmp ("-c", argv[i]) || !strcmp ("--crtc", argv[i])) {
162 if (++i>=argc) usage ();
163 crtc = strtoul (argv[i], NULL, 0);
166 if (!strcmp ("-o", argv[i]) || !strcmp ("--output", argv[i])) {
167 if (++i>=argc) usage ();
168 output = strtoul (argv[i], NULL, 0);
172 if (!strcmp ("-v", argv[i]) || !strcmp ("--version", argv[i])) {
177 if (!strcmp ("-x", argv[i])) {
178 if (++i>=argc) usage ();
179 x = strtoul (argv[i], NULL, 0);
182 if (!strcmp ("-y", argv[i])) {
183 if (++i>=argc) usage ();
184 y = strtoul (argv[i], NULL, 0);
187 if (!strcmp ("--screen", argv[i])) {
188 if (++i>=argc) usage ();
189 screen = atoi (argv[i]);
190 if (screen < 0) usage();
193 if (!strcmp ("-q", argv[i]) || !strcmp ("--query", argv[i])) {
197 if (!strcmp ("-r", argv[i]) || !strcmp ("--rotation", argv[i])) {
199 if (++i>=argc) usage ();
200 dirind = strtol(argv[i], &endptr, 0);
201 if (*endptr != '\0') {
202 for (dirind = 0; dirind < 4; dirind++) {
203 if (strcmp (direction[dirind], argv[i]) == 0) break;
205 if ((dirind < 0) || (dirind > 3)) usage();
213 if (verbose) query = 1;
215 dpy = XOpenDisplay (display_name);
218 fprintf (stderr, "Can't open display %s\n", XDisplayName(display_name));
222 XRRQueryVersion (dpy, &major_version, &minor_version);
223 if (!(major_version > 1 || minor_version >= 2))
225 fprintf (stderr, "Randr version too old (need 1.2 or better)\n");
230 screen = DefaultScreen (dpy);
231 if (screen >= ScreenCount (dpy)) {
232 fprintf (stderr, "Invalid screen number %d (display has %d)\n",
233 screen, ScreenCount (dpy));
237 root = RootWindow (dpy, screen);
239 if (XRRGetScreenSizeRange (dpy, root, &minWidth, &minHeight,
240 &maxWidth, &maxHeight))
242 printf ("min screen size: %d x %d\n", minWidth, minHeight);
243 printf ("max screen size: %d x %d\n", maxWidth, maxHeight);
245 sr = XRRGetScreenResources (dpy, root);
247 printf ("timestamp: %ld\n", sr->timestamp);
248 printf ("configTimestamp: %ld\n", sr->configTimestamp);
249 for (i = 0; i < sr->ncrtc; i++) {
253 printf ("\tcrtc: 0x%x\n", sr->crtcs[i]);
254 xci = XRRGetCrtcInfo (dpy, sr, sr->crtcs[i]);
255 printf ("\t\t%dx%d +%u+%u\n",
256 xci->width, xci->height, xci->x, xci->y);
257 printf ("\t\tmode: 0x%x\n", xci->mode);
258 printf ("\t\toutputs:");
259 for (j = 0; j < xci->noutput; j++)
260 printf (" 0x%x", xci->outputs[j]);
262 printf ("\t\tpossible:");
263 for (j = 0; j < xci->npossible; j++)
264 printf (" 0x%x", xci->possible[j]);
267 for (i = 0; i < sr->noutput; i++) {
272 printf ("\toutput: 0x%x\n", sr->outputs[i]);
273 xoi = XRRGetOutputInfo (dpy, sr, sr->outputs[i]);
274 printf ("\t\tname: %s\n", xoi->name);
275 printf ("\t\ttimestamp: %d\n", xoi->timestamp);
276 printf ("\t\tcrtc: 0x%x\n", xoi->crtc);
277 printf ("\t\tconnection: %s\n", connection[xoi->connection]);
278 printf ("\t\tsubpixel_order: %s\n", order[xoi->subpixel_order]);
279 printf ("\t\tphysical_size: %5d x %5d\n", xoi->mm_width,xoi->mm_height);
280 printf ("\t\tmodes:");
281 for (j = 0; j < xoi->nmode; j++)
282 printf(" 0x%x%s", xoi->modes[j], j < xoi->npreferred ? "*" : "");
284 printf ("\t\tclones:");
285 for (j = 0; j < xoi->nclone; j++)
286 printf(" 0x%x", xoi->clones[j]);
289 props = XRRListOutputProperties (dpy, sr->outputs[i], &nprop);
290 printf ("\t\tproperties:\n");
291 for (j = 0; j < nprop; j++) {
294 unsigned long nitems, bytes_after;
297 XRRGetOutputProperty (dpy, sr->outputs[i], props[j],
298 0, 100, False, AnyPropertyType,
299 &actual_type, &actual_format,
300 &nitems, &bytes_after, &prop);
302 if (actual_type == XA_INTEGER && actual_format == 8) {
305 printf("\t\t\t%s:\n", XGetAtomName (dpy, props[j]));
306 for (k = 0; k < nitems; k++) {
309 printf("%02x", (unsigned char)prop[k]);
313 } else if (actual_format == 8) {
314 printf ("\t\t\t%s: %s%s\n", XGetAtomName (dpy, props[j]),
315 prop, bytes_after ? "..." : "");
317 printf ("\t\t\t%s: ????\n", XGetAtomName (dpy, props[j]));
321 XRRFreeOutputInfo (xoi);
323 for (i = 0; i < sr->nmode; i++) {
325 printf ("\tmode: 0x%04x", sr->modes[i].id);
326 printf (" %15.15s", sr->modes[i].name);
327 printf (" %5d x %5d", sr->modes[i].width, sr->modes[i].height);
328 if (sr->modes[i].hTotal && sr->modes[i].vTotal)
329 rate = ((double) sr->modes[i].dotClock /
330 ((double) sr->modes[i].hTotal * (double) sr->modes[i].vTotal));
333 printf (" %6.1fHz %6.1fMhz (with blanking: %d x %d)", rate,
334 (float)sr->modes[i].dotClock / 1000000,
335 sr->modes[i].hTotal, sr->modes[i].vTotal);
340 fprintf (stderr, "Cannot get screen resources\n");
348 mmwidth = DisplayWidthMM(dpy, screen);
349 mmheight = DisplayHeightMM(dpy, screen);
351 XRRSetScreenSize (dpy, root, width, height, mmwidth, mmheight);
365 output = sr->outputs[0];
371 if (mode != (RRMode) -1)
375 status = XRRSetCrtcConfig (dpy, sr, crtc, CurrentTime, x, y,
376 mode, rotation, &output, noutput);
377 printf ("status: %d\n", status);
381 XRRFreeScreenResources (sr);