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