From http://www.jwz.org/xscreensaver/xscreensaver-5.16.tar.gz
[xscreensaver] / driver / test-vp.c
1 /* test-xinerama.c --- playing with XF86VidModeGetViewPort
2  * xscreensaver, Copyright (c) 2004 Jamie Zawinski <jwz@jwz.org>
3  *
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
7  * copyright notice and this permission notice appear in supporting
8  * documentation.  No representations are made about the suitability of this
9  * software for any purpose.  It is provided "as is" without express or 
10  * implied warranty.
11  */
12
13 #ifdef HAVE_CONFIG_H
14 # include "config.h"
15 #endif
16
17 #include <stdlib.h>
18 #ifdef HAVE_UNISTD_H
19 # include <unistd.h>
20 #endif
21
22 #include <stdio.h>
23 #include <time.h>
24 #include <sys/time.h>
25
26 #include <X11/Xlib.h>
27 #include <X11/Xatom.h>
28 #include <X11/Intrinsic.h>
29
30 #include <X11/Xproto.h>
31 #include <X11/extensions/xf86vmode.h>
32 #include <X11/extensions/Xinerama.h>
33
34 char *progname = 0;
35 char *progclass = "XScreenSaver";
36
37 static const char *
38 blurb (void)
39 {
40   static char buf[255];
41   time_t now = time ((time_t *) 0);
42   char *ct = (char *) ctime (&now);
43   int n = strlen(progname);
44   if (n > 100) n = 99;
45   strncpy(buf, progname, n);
46   buf[n++] = ':';
47   buf[n++] = ' ';
48   strncpy(buf+n, ct+11, 8);
49   strcpy(buf+n+9, ": ");
50   return buf;
51 }
52
53
54 static Bool error_handler_hit_p = False;
55
56 static int
57 ignore_all_errors_ehandler (Display *dpy, XErrorEvent *error)
58 {
59   error_handler_hit_p = True;
60   return 0;
61 }
62
63
64 static int
65 screen_count (Display *dpy)
66 {
67   int n = ScreenCount(dpy);
68   int xn = 0;
69   int event_number, error_number;
70
71   if (!XineramaQueryExtension (dpy, &event_number, &error_number))
72     {
73       fprintf(stderr, "%s: XineramaQueryExtension(dpy, ...)    ==> False\n",
74               blurb());
75       goto DONE;
76     }
77   else
78     fprintf(stderr,   "%s: XineramaQueryExtension(dpy, ...)    ==> %d, %d\n",
79             blurb(), event_number, error_number);
80
81   if (!XineramaIsActive(dpy))
82     {
83       fprintf(stderr, "%s: XineramaIsActive(dpy)               ==> False\n",
84               blurb());
85       goto DONE;
86     }
87   else
88     {
89       int major, minor;
90       XineramaScreenInfo *xsi;
91       fprintf(stderr, "%s: XineramaIsActive(dpy)               ==> True\n",
92               blurb());
93       if (!XineramaQueryVersion(dpy, &major, &minor))
94         {
95           fprintf(stderr,
96                   "%s: XineramaQueryVersion(dpy, ...)      ==> False\n",
97                   blurb());
98           goto DONE;
99         }
100       else
101         fprintf(stderr,
102                 "%s: XineramaQueryVersion(dpy, ...)      ==> %d, %d\n",
103                 blurb(), major, minor);
104
105       xsi = XineramaQueryScreens (dpy, &xn);
106       if (xsi) XFree (xsi);
107     }
108
109  DONE:
110   fprintf (stderr, "\n");
111   fprintf (stderr, "%s: X client screens: %d\n", blurb(), n);
112   fprintf (stderr, "%s: Xinerama screens: %d\n", blurb(), xn);
113   fprintf (stderr, "\n");
114
115   if (xn > n) return xn;
116   else return n;
117 }
118
119
120 int
121 main (int argc, char **argv)
122 {
123   int event_number, error_number;
124   int major, minor;
125   int nscreens = 0;
126   int i;
127
128   XtAppContext app;
129   Widget toplevel_shell = XtAppInitialize (&app, progclass, 0, 0,
130                                            &argc, argv, 0, 0, 0);
131   Display *dpy = XtDisplay (toplevel_shell);
132   XtGetApplicationNameAndClass (dpy, &progname, &progclass);
133
134   if (!XF86VidModeQueryExtension(dpy, &event_number, &error_number))
135     {
136       fprintf(stderr, "%s: XF86VidModeQueryExtension(dpy, ...) ==> False\n",
137               blurb());
138       fprintf(stderr,
139               "%s: server does not support the XF86VidMode extension.\n",
140               blurb());
141       exit(1);
142     }
143   else
144     fprintf(stderr, "%s: XF86VidModeQueryExtension(dpy, ...) ==> %d, %d\n",
145             blurb(), event_number, error_number);
146
147   if (!XF86VidModeQueryVersion(dpy, &major, &minor))
148     {
149       fprintf(stderr, "%s: XF86VidModeQueryVersion(dpy, ...) ==> False\n",
150               blurb());
151       fprintf(stderr,
152               "%s: server didn't report XF86VidMode version numbers?\n",
153               blurb());
154     }
155   else
156     fprintf(stderr, "%s: XF86VidModeQueryVersion(dpy, ...)   ==> %d, %d\n",
157             blurb(), major, minor);
158
159   nscreens = screen_count (dpy);
160
161   for (i = 0; i < nscreens; i++)
162     {
163       int result = 0;
164       int x = 0, y = 0, dot = 0;
165       XF86VidModeModeLine ml = { 0, };
166       XErrorHandler old_handler;
167
168       XSync (dpy, False);
169       error_handler_hit_p = False;
170       old_handler = XSetErrorHandler (ignore_all_errors_ehandler);
171
172       result = XF86VidModeGetViewPort (dpy, i, &x, &y);
173
174       XSync (dpy, False);
175       XSetErrorHandler (old_handler);
176       XSync (dpy, False);
177
178       if (error_handler_hit_p)
179         {
180           fprintf(stderr,
181                   "%s: XF86VidModeGetViewPort(dpy, %d, ...) ==> X error\n",
182                   blurb(), i);
183           continue;
184         }
185
186       if (! result)
187         fprintf(stderr, "%s: XF86VidModeGetViewPort(dpy, %d, ...) ==> %d\n",
188                 blurb(), i, result);
189
190       result = XF86VidModeGetModeLine (dpy, i, &dot, &ml);
191       if (! result)
192         fprintf(stderr, "%s: XF86VidModeGetModeLine(dpy, %d, ...) ==> %d\n",
193                 blurb(), i, result);
194
195       fprintf (stderr, "%s:   screen %d: %dx%d; viewport: %dx%d+%d+%d\n",
196                blurb(), i,
197                DisplayWidth (dpy, i), DisplayHeight (dpy, i),
198                ml.hdisplay, ml.vdisplay, x, y
199                );
200
201       fprintf (stderr,
202                "%s:       hsync start %d; end %d; total %d; skew  %d;\n",
203                blurb(),
204                ml.hsyncstart, ml.hsyncend, ml.htotal, ml.hskew);
205       fprintf (stderr,
206                "%s:       vsync start %d; end %d; total %d; flags 0x%04x;\n",
207                blurb(),
208                ml.vsyncstart, ml.vsyncend, ml.vtotal, ml.flags);
209       fprintf (stderr, "\n");
210     }
211   XSync (dpy, False);
212   exit (0);
213 }