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