~ubuntu-branches/ubuntu/quantal/mesa-glw/quantal

« back to all changes in this revision

Viewing changes to progs/fbdev/glfbdevtest.c

  • Committer: Bazaar Package Importer
  • Author(s): Morten Kjeldgaard
  • Date: 2008-05-06 16:19:15 UTC
  • Revision ID: james.westby@ubuntu.com-20080506161915-uynz7nftmfixu6bq
Tags: upstream-7.0.3
ImportĀ upstreamĀ versionĀ 7.0.3

Show diffs side-by-side

added added

removed removed

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