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