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