Clone of mesa.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

glfbdevtest.c 17KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599
  1. /*
  2. * Test the GLFBDev interface. Only tested with radeonfb driver!!!!
  3. *
  4. * Written by Brian Paul
  5. */
  6. #include <assert.h>
  7. #include <errno.h>
  8. #include <signal.h>
  9. #include <stdio.h>
  10. #include <stdlib.h>
  11. #include <string.h>
  12. #include <fcntl.h>
  13. #include <unistd.h>
  14. #include <sys/ioctl.h>
  15. #include <sys/mman.h>
  16. #include <sys/types.h>
  17. #include <linux/fb.h>
  18. #include <linux/kd.h>
  19. #include <linux/vt.h>
  20. #include <GL/gl.h>
  21. #include <GL/glfbdev.h>
  22. #include <math.h>
  23. /**
  24. * Choose one of these modes
  25. */
  26. /*static const int XRes = 1280, YRes = 1024, Hz = 75;*/
  27. /*static const int XRes = 1280, YRes = 1024, Hz = 70;*/
  28. /*static const int XRes = 1280, YRes = 1024, Hz = 60;*/
  29. static const int XRes = 1024, YRes = 768, Hz = 70;
  30. static int DesiredDepth = 32;
  31. static int NumFrames = 100;
  32. static struct fb_fix_screeninfo FixedInfo;
  33. static struct fb_var_screeninfo VarInfo, OrigVarInfo;
  34. static int OriginalVT = -1;
  35. static int ConsoleFD = -1;
  36. static int FrameBufferFD = -1;
  37. static caddr_t FrameBuffer = (caddr_t) -1;
  38. static caddr_t MMIOAddress = (caddr_t) -1;
  39. static void
  40. print_fixed_info(const struct fb_fix_screeninfo *fixed, const char *s)
  41. {
  42. static const char *visuals[] = {
  43. "MONO01", "MONO10", "TRUECOLOR", "PSEUDOCOLOR",
  44. "DIRECTCOLOR", "STATIC_PSEUDOCOLOR"
  45. };
  46. printf("%s info -----------------------\n", s);
  47. printf("id = %16s\n", fixed->id);
  48. printf("smem_start = 0x%lx\n", fixed->smem_start);
  49. printf("smem_len = %d (0x%x)\n", fixed->smem_len, fixed->smem_len);
  50. printf("type = 0x%x\n", fixed->type);
  51. printf("type_aux = 0x%x\n", fixed->type_aux);
  52. printf("visual = 0x%x (%s)\n", fixed->visual, visuals[fixed->visual]);
  53. printf("xpanstep = %d\n", fixed->xpanstep);
  54. printf("ypanstep = %d\n", fixed->ypanstep);
  55. printf("ywrapstep = %d\n", fixed->ywrapstep);
  56. printf("line_length = %d\n", fixed->line_length);
  57. printf("mmio_start = 0x%lx\n", fixed->mmio_start);
  58. printf("mmio_len = %d (0x%x)\n", fixed->mmio_len, fixed->mmio_len);
  59. printf("accel = 0x%x\n", fixed->accel);
  60. }
  61. static void
  62. print_var_info(const struct fb_var_screeninfo *var, const char *s)
  63. {
  64. printf("%s info -----------------------\n", s);
  65. printf("xres = %d\n", var->xres);
  66. printf("yres = %d\n", var->yres);
  67. printf("xres_virtual = %d\n", var->xres_virtual);
  68. printf("yres_virtual = %d\n", var->yres_virtual);
  69. printf("xoffset = %d\n", var->xoffset);
  70. printf("yoffset = %d\n", var->yoffset);
  71. printf("bits_per_pixel = %d\n", var->bits_per_pixel);
  72. printf("grayscale = %d\n", var->grayscale);
  73. printf("red.offset = %d length = %d msb_right = %d\n",
  74. var->red.offset, var->red.length, var->red.msb_right);
  75. printf("green.offset = %d length = %d msb_right = %d\n",
  76. var->green.offset, var->green.length, var->green.msb_right);
  77. printf("blue.offset = %d length = %d msb_right = %d\n",
  78. var->blue.offset, var->blue.length, var->blue.msb_right);
  79. printf("transp.offset = %d length = %d msb_right = %d\n",
  80. var->transp.offset, var->transp.length, var->transp.msb_right);
  81. printf("nonstd = %d\n", var->nonstd);
  82. printf("activate = %d\n", var->activate);
  83. printf("height = %d mm\n", var->height);
  84. printf("width = %d mm\n", var->width);
  85. printf("accel_flags = 0x%x\n", var->accel_flags);
  86. printf("pixclock = %d\n", var->pixclock);
  87. printf("left_margin = %d\n", var->left_margin);
  88. printf("right_margin = %d\n", var->right_margin);
  89. printf("upper_margin = %d\n", var->upper_margin);
  90. printf("lower_margin = %d\n", var->lower_margin);
  91. printf("hsync_len = %d\n", var->hsync_len);
  92. printf("vsync_len = %d\n", var->vsync_len);
  93. printf("sync = %d\n", var->sync);
  94. printf("vmode = %d\n", var->vmode);
  95. }
  96. static void
  97. signal_handler(int signumber)
  98. {
  99. signal(signumber, SIG_IGN); /* prevent recursion! */
  100. fprintf(stderr, "error: got signal %d (exiting)\n", signumber);
  101. exit(1);
  102. }
  103. static void
  104. initialize_fbdev( void )
  105. {
  106. char ttystr[1000];
  107. int fd, vtnumber, ttyfd;
  108. int sz;
  109. (void) sz;
  110. if (geteuid()) {
  111. fprintf(stderr, "error: you need to be root\n");
  112. exit(1);
  113. }
  114. #if 1
  115. /* open the framebuffer device */
  116. FrameBufferFD = open("/dev/fb0", O_RDWR);
  117. if (FrameBufferFD < 0) {
  118. fprintf(stderr, "Error opening /dev/fb0: %s\n", strerror(errno));
  119. exit(1);
  120. }
  121. #endif
  122. /* open /dev/tty0 and get the vt number */
  123. if ((fd = open("/dev/tty0", O_WRONLY, 0)) < 0) {
  124. fprintf(stderr, "error opening /dev/tty0\n");
  125. exit(1);
  126. }
  127. if (ioctl(fd, VT_OPENQRY, &vtnumber) < 0 || vtnumber < 0) {
  128. fprintf(stderr, "error: couldn't get a free vt\n");
  129. exit(1);
  130. }
  131. close(fd);
  132. /* open the console tty */
  133. sprintf(ttystr, "/dev/tty%d", vtnumber); /* /dev/tty1-64 */
  134. ConsoleFD = open(ttystr, O_RDWR | O_NDELAY, 0);
  135. if (ConsoleFD < 0) {
  136. fprintf(stderr, "error couldn't open console fd\n");
  137. exit(1);
  138. }
  139. /* save current vt number */
  140. {
  141. struct vt_stat vts;
  142. if (ioctl(ConsoleFD, VT_GETSTATE, &vts) == 0)
  143. OriginalVT = vts.v_active;
  144. }
  145. /* disconnect from controlling tty */
  146. ttyfd = open("/dev/tty", O_RDWR);
  147. if (ttyfd >= 0) {
  148. ioctl(ttyfd, TIOCNOTTY, 0);
  149. close(ttyfd);
  150. }
  151. /* some magic to restore the vt when we exit */
  152. {
  153. struct vt_mode vt;
  154. if (ioctl(ConsoleFD, VT_ACTIVATE, vtnumber) != 0)
  155. printf("ioctl VT_ACTIVATE: %s\n", strerror(errno));
  156. if (ioctl(ConsoleFD, VT_WAITACTIVE, vtnumber) != 0)
  157. printf("ioctl VT_WAITACTIVE: %s\n", strerror(errno));
  158. if (ioctl(ConsoleFD, VT_GETMODE, &vt) < 0) {
  159. fprintf(stderr, "error: ioctl VT_GETMODE: %s\n", strerror(errno));
  160. exit(1);
  161. }
  162. vt.mode = VT_PROCESS;
  163. vt.relsig = SIGUSR1;
  164. vt.acqsig = SIGUSR1;
  165. if (ioctl(ConsoleFD, VT_SETMODE, &vt) < 0) {
  166. fprintf(stderr, "error: ioctl(VT_SETMODE) failed: %s\n",
  167. strerror(errno));
  168. exit(1);
  169. }
  170. }
  171. /* go into graphics mode */
  172. if (ioctl(ConsoleFD, KDSETMODE, KD_GRAPHICS) < 0) {
  173. fprintf(stderr, "error: ioctl(KDSETMODE, KD_GRAPHICS) failed: %s\n",
  174. strerror(errno));
  175. exit(1);
  176. }
  177. #if 0
  178. /* open the framebuffer device */
  179. FrameBufferFD = open("/dev/fb0", O_RDWR);
  180. if (FrameBufferFD < 0) {
  181. fprintf(stderr, "Error opening /dev/fb0: %s\n", strerror(errno));
  182. exit(1);
  183. }
  184. #endif
  185. /* Get the fixed screen info */
  186. if (ioctl(FrameBufferFD, FBIOGET_FSCREENINFO, &FixedInfo)) {
  187. fprintf(stderr, "error: ioctl(FBIOGET_FSCREENINFO) failed: %s\n",
  188. strerror(errno));
  189. exit(1);
  190. }
  191. print_fixed_info(&FixedInfo, "Fixed");
  192. /* get the variable screen info */
  193. if (ioctl(FrameBufferFD, FBIOGET_VSCREENINFO, &OrigVarInfo)) {
  194. fprintf(stderr, "error: ioctl(FBIOGET_VSCREENINFO) failed: %s\n",
  195. strerror(errno));
  196. exit(1);
  197. }
  198. print_var_info(&OrigVarInfo, "Orig Var");
  199. /* operate on a copy */
  200. VarInfo = OrigVarInfo;
  201. /* set the depth, resolution, etc */
  202. if (DesiredDepth)
  203. VarInfo.bits_per_pixel = DesiredDepth;
  204. if (VarInfo.bits_per_pixel == 16) {
  205. VarInfo.red.offset = 11;
  206. VarInfo.green.offset = 5;
  207. VarInfo.blue.offset = 0;
  208. VarInfo.red.length = 5;
  209. VarInfo.green.length = 6;
  210. VarInfo.blue.length = 5;
  211. VarInfo.transp.offset = 0;
  212. VarInfo.transp.length = 0;
  213. }
  214. else if (VarInfo.bits_per_pixel == 32) {
  215. VarInfo.red.offset = 16;
  216. VarInfo.green.offset = 8;
  217. VarInfo.blue.offset = 0;
  218. VarInfo.transp.offset = 24;
  219. VarInfo.red.length = 8;
  220. VarInfo.green.length = 8;
  221. VarInfo.blue.length = 8;
  222. VarInfo.transp.length = 8;
  223. }
  224. /* timing values taken from /etc/fb.modes */
  225. if (XRes == 1280 && YRes == 1024) {
  226. VarInfo.xres_virtual = VarInfo.xres = XRes;
  227. VarInfo.yres_virtual = VarInfo.yres = YRes;
  228. if (Hz == 75) {
  229. VarInfo.pixclock = 7408;
  230. VarInfo.left_margin = 248;
  231. VarInfo.right_margin = 16;
  232. VarInfo.upper_margin = 38;
  233. VarInfo.lower_margin = 1;
  234. VarInfo.hsync_len = 144;
  235. VarInfo.vsync_len = 3;
  236. }
  237. else if (Hz == 70) {
  238. VarInfo.pixclock = 7937;
  239. VarInfo.left_margin = 216;
  240. VarInfo.right_margin = 80;
  241. VarInfo.upper_margin = 36;
  242. VarInfo.lower_margin = 1;
  243. VarInfo.hsync_len = 112;
  244. VarInfo.vsync_len = 5;
  245. }
  246. else if (Hz == 60) {
  247. VarInfo.pixclock = 9260;
  248. VarInfo.left_margin = 248;
  249. VarInfo.right_margin = 48;
  250. VarInfo.upper_margin = 38;
  251. VarInfo.lower_margin = 1;
  252. VarInfo.hsync_len = 112;
  253. VarInfo.vsync_len = 3;
  254. }
  255. else {
  256. fprintf(stderr, "invalid rate for 1280x1024\n");
  257. exit(1);
  258. }
  259. }
  260. else if (XRes == 1024 && YRes == 768 && Hz == 70) {
  261. VarInfo.xres_virtual = VarInfo.xres = XRes;
  262. VarInfo.yres_virtual = VarInfo.yres = YRes;
  263. if (Hz == 70) {
  264. VarInfo.pixclock = 13334;
  265. VarInfo.left_margin = 144;
  266. VarInfo.right_margin = 24;
  267. VarInfo.upper_margin = 29;
  268. VarInfo.lower_margin = 3;
  269. VarInfo.hsync_len = 136;
  270. VarInfo.vsync_len = 6;
  271. }
  272. else {
  273. fprintf(stderr, "invalid rate for 1024x768\n");
  274. exit(1);
  275. }
  276. }
  277. VarInfo.xoffset = 0;
  278. VarInfo.yoffset = 0;
  279. VarInfo.nonstd = 0;
  280. VarInfo.vmode &= ~FB_VMODE_YWRAP; /* turn off scrolling */
  281. /* set new variable screen info */
  282. if (ioctl(FrameBufferFD, FBIOPUT_VSCREENINFO, &VarInfo)) {
  283. fprintf(stderr, "ioctl(FBIOPUT_VSCREENINFO failed): %s\n",
  284. strerror(errno));
  285. exit(1);
  286. }
  287. print_var_info(&VarInfo, "New Var");
  288. if (FixedInfo.visual != FB_VISUAL_TRUECOLOR &&
  289. FixedInfo.visual != FB_VISUAL_DIRECTCOLOR) {
  290. fprintf(stderr, "non-TRUE/DIRECT-COLOR visuals (0x%x) not supported by this demo.\n", FixedInfo.visual);
  291. exit(1);
  292. }
  293. /* initialize colormap */
  294. if (FixedInfo.visual == FB_VISUAL_DIRECTCOLOR) {
  295. struct fb_cmap cmap;
  296. unsigned short red[256], green[256], blue[256];
  297. int i;
  298. /* we're assuming 256 entries here */
  299. printf("initializing directcolor colormap\n");
  300. cmap.start = 0;
  301. cmap.len = 256;
  302. cmap.red = red;
  303. cmap.green = green;
  304. cmap.blue = blue;
  305. cmap.transp = NULL;
  306. for (i = 0; i < cmap.len; i++) {
  307. red[i] = green[i] = blue[i] = (i << 8) | i;
  308. }
  309. if (ioctl(FrameBufferFD, FBIOPUTCMAP, (void *) &cmap) < 0) {
  310. fprintf(stderr, "ioctl(FBIOPUTCMAP) failed [%d]\n", i);
  311. }
  312. }
  313. /*
  314. * fbdev says the frame buffer is at offset zero, and the mmio region
  315. * is immediately after.
  316. */
  317. /* mmap the framebuffer into our address space */
  318. FrameBuffer = (caddr_t) mmap(0, /* start */
  319. FixedInfo.smem_len, /* bytes */
  320. PROT_READ | PROT_WRITE, /* prot */
  321. MAP_SHARED, /* flags */
  322. FrameBufferFD, /* fd */
  323. 0 /* offset */);
  324. if (FrameBuffer == (caddr_t) - 1) {
  325. fprintf(stderr, "error: unable to mmap framebuffer: %s\n",
  326. strerror(errno));
  327. exit(1);
  328. }
  329. printf("FrameBuffer = %p\n", FrameBuffer);
  330. #if 1
  331. /* mmap the MMIO region into our address space */
  332. MMIOAddress = (caddr_t) mmap(0, /* start */
  333. FixedInfo.mmio_len, /* bytes */
  334. PROT_READ | PROT_WRITE, /* prot */
  335. MAP_SHARED, /* flags */
  336. FrameBufferFD, /* fd */
  337. FixedInfo.smem_len /* offset */);
  338. if (MMIOAddress == (caddr_t) - 1) {
  339. fprintf(stderr, "error: unable to mmap mmio region: %s\n",
  340. strerror(errno));
  341. }
  342. printf("MMIOAddress = %p\n", MMIOAddress);
  343. /* try out some simple MMIO register reads */
  344. if (0)
  345. {
  346. typedef unsigned int CARD32;
  347. typedef unsigned char CARD8;
  348. #define RADEON_CONFIG_MEMSIZE 0x00f8
  349. #define RADEON_MEM_SDRAM_MODE_REG 0x0158
  350. #define MMIO_IN32(base, offset) \
  351. *(volatile CARD32 *)(void *)(((CARD8*)(base)) + (offset))
  352. #define INREG(addr) MMIO_IN32(MMIOAddress, addr)
  353. int sz, type;
  354. const char *typeStr[] = {"SDR", "DDR", "64-bit SDR"};
  355. sz = INREG(RADEON_CONFIG_MEMSIZE);
  356. type = INREG(RADEON_MEM_SDRAM_MODE_REG);
  357. printf("RADEON_CONFIG_MEMSIZE = %d (%d MB)\n", sz, sz / 1024 / 1024);
  358. printf("RADEON_MEM_SDRAM_MODE_REG >> 30 = %d (%s)\n",
  359. type >> 30, typeStr[type>>30]);
  360. }
  361. #endif
  362. }
  363. static void
  364. shutdown_fbdev( void )
  365. {
  366. struct vt_mode VT;
  367. printf("cleaning up...\n");
  368. /* restore original variable screen info */
  369. if (ioctl(FrameBufferFD, FBIOPUT_VSCREENINFO, &OrigVarInfo)) {
  370. fprintf(stderr, "ioctl(FBIOPUT_VSCREENINFO failed): %s\n",
  371. strerror(errno));
  372. exit(1);
  373. }
  374. munmap(MMIOAddress, FixedInfo.mmio_len);
  375. munmap(FrameBuffer, FixedInfo.smem_len);
  376. close(FrameBufferFD);
  377. /* restore text mode */
  378. ioctl(ConsoleFD, KDSETMODE, KD_TEXT);
  379. /* set vt */
  380. if (ioctl(ConsoleFD, VT_GETMODE, &VT) != -1) {
  381. VT.mode = VT_AUTO;
  382. ioctl(ConsoleFD, VT_SETMODE, &VT);
  383. }
  384. /* restore original vt */
  385. if (OriginalVT >= 0) {
  386. ioctl(ConsoleFD, VT_ACTIVATE, OriginalVT);
  387. OriginalVT = -1;
  388. }
  389. close(ConsoleFD);
  390. }
  391. /* Borrowed from GLUT */
  392. static void
  393. doughnut(GLfloat r, GLfloat R, GLint nsides, GLint rings)
  394. {
  395. int i, j;
  396. GLfloat theta, phi, theta1;
  397. GLfloat cosTheta, sinTheta;
  398. GLfloat cosTheta1, sinTheta1;
  399. GLfloat ringDelta, sideDelta;
  400. ringDelta = 2.0 * M_PI / rings;
  401. sideDelta = 2.0 * M_PI / nsides;
  402. theta = 0.0;
  403. cosTheta = 1.0;
  404. sinTheta = 0.0;
  405. for (i = rings - 1; i >= 0; i--) {
  406. theta1 = theta + ringDelta;
  407. cosTheta1 = cos(theta1);
  408. sinTheta1 = sin(theta1);
  409. glBegin(GL_QUAD_STRIP);
  410. phi = 0.0;
  411. for (j = nsides; j >= 0; j--) {
  412. GLfloat cosPhi, sinPhi, dist;
  413. phi += sideDelta;
  414. cosPhi = cos(phi);
  415. sinPhi = sin(phi);
  416. dist = R + r * cosPhi;
  417. glNormal3f(cosTheta1 * cosPhi, -sinTheta1 * cosPhi, sinPhi);
  418. glVertex3f(cosTheta1 * dist, -sinTheta1 * dist, r * sinPhi);
  419. glNormal3f(cosTheta * cosPhi, -sinTheta * cosPhi, sinPhi);
  420. glVertex3f(cosTheta * dist, -sinTheta * dist, r * sinPhi);
  421. }
  422. glEnd();
  423. theta = theta1;
  424. cosTheta = cosTheta1;
  425. sinTheta = sinTheta1;
  426. }
  427. }
  428. static void
  429. gltest( void )
  430. {
  431. static const int attribs[] = {
  432. GLFBDEV_DOUBLE_BUFFER,
  433. GLFBDEV_DEPTH_SIZE, 16,
  434. GLFBDEV_NONE
  435. };
  436. GLFBDevContextPtr ctx;
  437. GLFBDevBufferPtr buf;
  438. GLFBDevVisualPtr vis;
  439. int bytes, r, g, b, a;
  440. float ang;
  441. int i;
  442. printf("GLFBDEV_VENDOR = %s\n", glFBDevGetString(GLFBDEV_VENDOR));
  443. printf("GLFBDEV_VERSION = %s\n", glFBDevGetString(GLFBDEV_VERSION));
  444. /* framebuffer size */
  445. bytes = VarInfo.xres_virtual * VarInfo.yres_virtual * VarInfo.bits_per_pixel / 8;
  446. vis = glFBDevCreateVisual( &FixedInfo, &VarInfo, attribs );
  447. assert(vis);
  448. buf = glFBDevCreateBuffer( &FixedInfo, &VarInfo, vis, FrameBuffer, NULL, bytes );
  449. assert(buf);
  450. ctx = glFBDevCreateContext( vis, NULL );
  451. assert(buf);
  452. b = glFBDevMakeCurrent( ctx, buf, buf );
  453. assert(b);
  454. /*printf("GL_EXTENSIONS: %s\n", glGetString(GL_EXTENSIONS));*/
  455. glGetIntegerv(GL_RED_BITS, &r);
  456. glGetIntegerv(GL_GREEN_BITS, &g);
  457. glGetIntegerv(GL_BLUE_BITS, &b);
  458. glGetIntegerv(GL_ALPHA_BITS, &a);
  459. printf("RED_BITS=%d GREEN_BITS=%d BLUE_BITS=%d ALPHA_BITS=%d\n",
  460. r, g, b, a);
  461. glClearColor(0.5, 0.5, 1.0, 0);
  462. glMatrixMode(GL_PROJECTION);
  463. glLoadIdentity();
  464. glFrustum(-1, 1, -1, 1, 2, 30);
  465. glMatrixMode(GL_MODELVIEW);
  466. glLoadIdentity();
  467. glTranslatef(0, 0, -15);
  468. glViewport(0, 0, VarInfo.xres_virtual, VarInfo.yres_virtual);
  469. glEnable(GL_LIGHTING);
  470. glEnable(GL_LIGHT0);
  471. glEnable(GL_DEPTH_TEST);
  472. printf("Drawing %d frames...\n", NumFrames);
  473. ang = 0.0;
  474. for (i = 0; i < NumFrames; i++) {
  475. glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  476. glPushMatrix();
  477. glRotatef(ang, 1, 0, 0);
  478. doughnut(1, 3, 40, 20);
  479. glPopMatrix();
  480. glFBDevSwapBuffers(buf);
  481. ang += 15.0;
  482. }
  483. /* clean up */
  484. b = glFBDevMakeCurrent( NULL, NULL, NULL);
  485. assert(b);
  486. glFBDevDestroyContext(ctx);
  487. glFBDevDestroyBuffer(buf);
  488. glFBDevDestroyVisual(vis);
  489. }
  490. static void
  491. parse_args(int argc, char *argv[])
  492. {
  493. int i;
  494. for (i = 1; i < argc; i++) {
  495. if (strcmp(argv[i], "-f") == 0) {
  496. NumFrames = atoi(argv[i+1]);
  497. i++;
  498. }
  499. }
  500. }
  501. int
  502. main( int argc, char *argv[] )
  503. {
  504. signal(SIGUSR1, signal_handler); /* exit if someone tries a vt switch */
  505. signal(SIGSEGV, signal_handler); /* catch segfaults */
  506. parse_args(argc, argv);
  507. printf("Setting mode to %d x %d @ %d Hz, %d bpp\n", XRes, YRes, Hz, DesiredDepth);
  508. initialize_fbdev();
  509. gltest();
  510. shutdown_fbdev();
  511. return 0;
  512. }