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