dga.c revision f672524f
1/* $XFree86: xc/programs/xf86dga/dga.c,v 3.19 2001/10/28 03:34:32 tsi Exp $ */
2
3#include <X11/Xlib.h>
4#include <X11/Xutil.h>
5#include <X11/extensions/Xxf86dga.h>
6#include <sys/time.h>
7#include <ctype.h>
8#include <errno.h>
9#include <stdio.h>
10#include <stdlib.h>
11#include <string.h>
12#include <signal.h>
13#include <unistd.h>
14
15
16#define MINMAJOR 0
17#define MINMINOR 0
18
19/* copied from xf86Io.c */
20static int
21GetTimeInMillis(void)
22{
23    struct timeval  tp;
24
25    gettimeofday(&tp, NULL);
26    return(tp.tv_sec * 1000) + (tp.tv_usec / 1000);
27}
28
29int
30main(int argc, char *argv[])
31{
32    int MajorVersion, MinorVersion;
33    int EventBase, ErrorBase;
34    Display *dis;
35    int i, bpp;
36    char *addr;
37    int width, bank, banks, ram;
38    XEvent event;
39    Colormap cmap = 0;
40    Visual *vis;
41    int flags;
42
43    if (geteuid()) {
44	fprintf(stderr, "Must be suid root\n");
45	exit(1);
46    }
47
48    if ( (dis = XOpenDisplay(NULL)) == NULL )
49    {
50        (void) fprintf( stderr, " cannot connect to X server %s\n",
51                       XDisplayName(NULL));
52        exit( -1 );
53    }
54
55
56    if (!XF86DGAQueryVersion(dis, &MajorVersion, &MinorVersion))
57    {
58        fprintf(stderr, "Unable to query video extension version\n");
59        exit(2);
60    }
61
62    if (!XF86DGAQueryExtension(dis, &EventBase, &ErrorBase)) {
63        fprintf(stderr, "Unable to query video extension information\n");
64        exit(2);
65    }
66
67    /* Fail if the extension version in the server is too old */
68    if (MajorVersion < MINMAJOR ||
69        (MajorVersion == MINMAJOR && MinorVersion < MINMINOR)) {
70        fprintf(stderr,
71                "Xserver is running an old XFree86-DGA version"
72                " (%d.%d)\n", MajorVersion, MinorVersion);
73        fprintf(stderr, "Minimum required version is %d.%d\n",
74                MINMAJOR, MINMINOR);
75        exit(2);
76    }
77
78    XF86DGAQueryDirectVideo(dis, DefaultScreen(dis), &flags);
79    if (!(flags & XF86DGADirectPresent)) {
80      fprintf(stderr, "Xserver driver doesn't support DirectVideo on screen %d\n", DefaultScreen(dis) );
81      exit(2);
82    }
83
84   XGrabKeyboard(dis, DefaultRootWindow(dis), True, GrabModeAsync,
85		 GrabModeAsync,  CurrentTime);
86
87   /* and all the mouse moves */
88   XGrabPointer(dis, DefaultRootWindow(dis), True,
89		PointerMotionMask | ButtonPressMask | ButtonReleaseMask,
90		GrabModeAsync, GrabModeAsync, None,  None, CurrentTime);
91   /* we want _our_ cmap */
92   vis = DefaultVisual(dis, DefaultScreen(dis));
93
94   bpp = DisplayPlanes (dis, DefaultScreen(dis));
95
96
97   if (bpp <= 8)
98   {
99   cmap = XCreateColormap(dis, DefaultRootWindow(dis), vis, AllocAll);
100
101   for (i = 0; i < 256; i++) {
102       XColor xcol;
103
104       xcol.pixel = i;
105       xcol.red = (256 - i) * 255;
106       xcol.green = i * 255;
107       xcol.blue = ((128 - i)%256) * 255;
108       xcol.flags = DoBlue | DoGreen | DoRed;
109       XStoreColor(dis, cmap, &xcol);
110   }
111   }
112
113   /*
114    * Lets go live
115    */
116
117   XF86DGAGetVideo(dis, DefaultScreen(dis), &addr, &width, &bank, &ram);
118   fprintf(stderr, "%x addr:%p, width %d, bank size %d, depth %d planes\n", True,
119	   addr, width, bank, bpp);
120
121   XF86DGADirectVideo(dis, DefaultScreen(dis),
122			   XF86DGADirectGraphics|
123			   XF86DGADirectMouse|
124			   XF86DGADirectKeyb);
125
126   if (bpp <= 8)
127   {
128   /* must be called _after_ entering DGA DirectGraphics mode */
129   XF86DGAInstallColormap(dis, DefaultScreen(dis), cmap);
130   }
131
132
133#ifndef __UNIXOS2__
134   /* Give up root privs */
135   if (setuid(getuid()) == -1) {
136      fprintf(stderr, "Unable to change uid: %s\n", strerror(errno));
137      exit(2);
138   }
139#endif
140
141   XF86DGASetViewPort(dis, DefaultScreen(dis), 0, 0);
142
143   banks = (ram * 1024)/bank;
144#ifdef DEBUG
145   fprintf(stderr, "%x ram:%x, addr %x, banks %d\n", True,
146	   ram, addr, banks);
147#endif
148   while (1) {
149      XMotionEvent *mevent = (XMotionEvent *) &event;
150      XButtonEvent *bevent = (XButtonEvent *) &event;
151      int n_chars = 0;
152      char buf[21];
153      KeySym ks = 0;
154
155      i = 0;
156      XNextEvent(dis, &event);
157      switch (event.type) {
158       case KeyPress:
159	 n_chars = XLookupString(&event.xkey, buf, 20, &ks, NULL);
160         buf[n_chars] = '\0';
161	 fprintf(stderr,"KeyPress [%d]: %s\n", event.xkey.keycode, buf);
162
163	 if (buf[0] == 'b') {
164	   /*
165	    * Benchmark mode: run write/read speed test for 1 second each
166	    */
167	    int start_clock,finish_clock,diff_clock;
168	    int cycles;
169	    int size = 64;
170	    void *membuf;
171
172	    if (bank < 65536)
173		size = bank / 1024;
174
175	    /* get write timings */
176	    XF86DGASetVidPage(dis, DefaultScreen(dis), i);
177
178	    start_clock = GetTimeInMillis(); finish_clock = start_clock;
179
180	    cycles=0;
181	    while ((finish_clock - start_clock) < 1000)
182	    {
183	      cycles++;
184	      memset(addr, (char) (cycles % 255), size * 1024);
185	      finish_clock = GetTimeInMillis();
186	    }
187
188	    diff_clock = finish_clock - start_clock;
189
190	    fprintf(stderr, "Framebuffer write speed: %6dK/s\n",
191		    (size * 1000 * cycles) / diff_clock);
192
193	    /* get read timings */
194	    if ((membuf=malloc(size*1024)))
195	    {
196		XF86DGASetVidPage(dis, DefaultScreen(dis), i);
197
198		start_clock = GetTimeInMillis(); finish_clock = start_clock;
199
200	        cycles=0;
201	        while ((finish_clock - start_clock) < 1000)
202	        {
203	            cycles++;
204		    memcpy(membuf, addr, size * 1024);
205	            finish_clock = GetTimeInMillis();
206	        }
207
208		diff_clock = finish_clock - start_clock;
209
210		fprintf(stderr, "Framebuffer read speed: %6dK/s\n",
211		    (size * 1000 * cycles) / diff_clock);
212	    }
213	    else
214	      fprintf(stderr, "could not allocate scratch buffer -- read timing measurement skipped\n");
215	 }
216
217         for (i = 0; i < banks; i++) {
218		XF86DGASetVidPage(dis, DefaultScreen(dis), i);
219		memset(addr, buf[0], bank);
220#ifdef DEBUG
221   fprintf(stderr, "XF86DGASetVidPage(dis, DefaultScreen(dis), %d);\n",i);
222   fprintf(stderr, "memset(addr:%x, buf[0]:%d, bank:%d);\n",addr,buf[0],bank);
223#endif
224	 }
225	 break;
226       case KeyRelease:
227	 n_chars = XLookupString(&event.xkey, buf, 20, &ks, NULL);
228         buf[n_chars] = '\0';
229	 fprintf(stderr,"KeyRelease[%d]: %s\n", event.xkey.keycode, buf);
230	 break;
231       case MotionNotify:
232 	 fprintf(stderr,"Relative Motion: %d %d\n", mevent->x_root, mevent->y_root);
233         break;
234       case ButtonPress:
235	 fprintf(stderr,"Button %d pressed\n", bevent->button);
236	 break;
237       case ButtonRelease:
238	 fprintf(stderr,"Button %d released\n", bevent->button);
239	 break;
240       case Expose:
241	 /* maybe we should RaiseWindow? */
242	 break;
243       default:
244	 fprintf(stderr,"%X\n", event.type);
245	 break;
246      }
247      if (n_chars && (buf[0] == 'q' || buf[0] == 'Q')) {
248	 fprintf(stderr,"EXITTING\n");
249         break;
250      }
251   }
252   /*
253    * back to the X server
254    */
255   XF86DGADirectVideo(dis, DefaultScreen(dis), 0);
256   fprintf(stderr, "back now in X\n");
257
258   /* and give back control */
259   XUngrabPointer(dis, CurrentTime);
260   XUngrabKeyboard(dis, CurrentTime);
261   fprintf(stderr, "Thats all folks\n");
262   exit(0);
263}
264
265
266