source: libcaca/trunk/caca/driver_gl.c @ 1048

Last change on this file since 1048 was 1045, checked in by Jean-Yves Lamoureux, 14 years ago
  • Updated documentation, removed warning in cucul_render_glyph(), minor optimisation in driver_gl
  • Property svn:keywords set to Id
File size: 18.1 KB
Line 
1/*
2 *  libcaca       Colour ASCII-Art library
3 *  Copyright (c) 2002-2006 Sam Hocevar <sam@zoy.org>
4 *                All Rights Reserved
5 *
6 *  $Id: driver_gl.c 1045 2006-09-17 10:54:23Z jylam $
7 *
8 *  This library is free software; you can redistribute it and/or
9 *  modify it under the terms of the Do What The Fuck You Want To
10 *  Public License, Version 2, as published by Sam Hocevar. See
11 *  http://sam.zoy.org/wtfpl/COPYING for more details.
12 */
13
14/*
15 *  This file contains the libcaca OpenGL input and output driver
16 */
17
18#include "config.h"
19#include "common.h"
20
21#if defined(USE_GL)
22
23#ifdef HAVE_OPENGL_GL_H
24#   include <OpenGL/gl.h>
25#   include <GLUT/glut.h>
26#else
27#   include <GL/gl.h>
28#   include <GL/glut.h>
29#   include <GL/freeglut_ext.h>
30#endif
31
32#include <string.h>
33#include <stdlib.h>
34#include <stdio.h>
35
36#include "caca.h"
37#include "caca_internals.h"
38#include "cucul.h"
39#include "cucul_internals.h"
40
41
42/*
43 * Global variables
44 */
45
46static caca_display_t *gl_d; /* FIXME: we ought to get rid of this */
47
48/*
49 * Local functions
50 */
51static void gl_handle_keyboard(unsigned char, int, int);
52static void gl_handle_special_key(int, int, int);
53static void gl_handle_reshape(int, int);
54static void gl_handle_mouse(int, int, int, int);
55static void gl_handle_mouse_motion(int, int);
56#ifdef HAVE_GLUTCLOSEFUNC
57static void gl_handle_close(void);
58#endif
59static void _display(void);
60static void gl_generate_glyph(uint32_t, uint32_t, caca_display_t *);
61static void gl_generate_unicode_glyph(uint32_t, uint32_t, caca_display_t *);
62
63struct driver_private
64{
65    int window;
66    unsigned int width, height;
67    unsigned int new_width, new_height;
68    cucul_font_t *f;
69    float font_width, font_height;
70    float incx, incy;
71    int id[(128 - 32)];
72    int id_uni[8]; /* Hack, FIXME */
73    unsigned char close;
74    unsigned char bit;
75    unsigned char mouse_changed, mouse_clicked;
76    unsigned int mouse_x, mouse_y;
77    unsigned int mouse_button, mouse_state;
78
79    unsigned char key;
80    int special_key;
81
82    float sw, sh;
83
84};
85
86static int gl_init_graphics(caca_display_t *dp)
87{
88    char *empty_texture;
89    char const *geometry;
90    char *argv[2] = { "", NULL };
91    char const * const * fonts;
92    unsigned int width = 0, height = 0;
93    int argc = 1;
94    int i;
95
96    dp->drv.p = malloc(sizeof(struct driver_private));
97
98    gl_d = dp;
99
100#if defined(HAVE_GETENV)
101    geometry = getenv("CACA_GEOMETRY");
102    if(geometry && *geometry)
103        sscanf(geometry, "%ux%u", &width, &height);
104#endif
105
106    if(width && height)
107        _cucul_set_canvas_size(dp->cv, width, height);
108
109
110    /* Load a libcucul internal font */
111    fonts = cucul_get_font_list();
112    if(fonts[0] == NULL)
113    {
114        fprintf(stderr, "error: libcucul was compiled without any fonts\n");
115        return -1;
116    }
117    dp->drv.p->f = cucul_load_font(fonts[0], 0);
118    if(dp->drv.p->f == NULL)
119    {
120        fprintf(stderr, "error: could not load font \"%s\"\n", fonts[0]);
121        return -1;
122    }
123
124    dp->drv.p->font_width = cucul_get_font_width(dp->drv.p->f);
125    dp->drv.p->font_height = cucul_get_font_height(dp->drv.p->f);
126
127    dp->drv.p->width = dp->cv->width * dp->drv.p->font_width;
128    dp->drv.p->height = dp->cv->height * dp->drv.p->font_height;
129
130#ifdef HAVE_GLUTCLOSEFUNC
131    dp->drv.p->close = 0;
132#endif
133    dp->drv.p->bit = 0;
134
135    dp->drv.p->mouse_changed = dp->drv.p->mouse_clicked = 0;
136    dp->drv.p->mouse_button = dp->drv.p->mouse_state = 0;
137
138    dp->drv.p->key = 0;
139    dp->drv.p->special_key = 0;
140
141    dp->drv.p->sw = ((float)dp->drv.p->font_width) / 16.0f;
142    dp->drv.p->sh = ((float)dp->drv.p->font_height) / 16.0f;
143
144    glutInit(&argc, argv);
145
146    glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE);
147    glutInitWindowSize(dp->drv.p->width, dp->drv.p->height);
148    dp->drv.p->window = glutCreateWindow("caca for GL");
149
150    gluOrtho2D(0, dp->drv.p->width, dp->drv.p->height, 0);
151
152    glDisable(GL_CULL_FACE);
153    glDisable(GL_DEPTH_TEST);
154
155    glutKeyboardFunc(gl_handle_keyboard);
156    glutSpecialFunc(gl_handle_special_key);
157    glutReshapeFunc(gl_handle_reshape);
158    glutDisplayFunc(_display);
159
160#ifdef HAVE_GLUTCLOSEFUNC
161    glutCloseFunc(gl_handle_close);
162#endif
163
164    glutMouseFunc(gl_handle_mouse);
165    glutMotionFunc(gl_handle_mouse_motion);
166    glutPassiveMotionFunc(gl_handle_mouse_motion);
167
168    glLoadIdentity();
169
170    glMatrixMode(GL_PROJECTION);
171    glPushMatrix();
172    glLoadIdentity();
173    gluOrtho2D(0, dp->drv.p->width, dp->drv.p->height, 0);
174
175    glMatrixMode(GL_MODELVIEW);
176
177    glClear(GL_COLOR_BUFFER_BIT);
178    glEnable(GL_TEXTURE_2D);
179    glEnable(GL_BLEND);
180    glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
181
182
183    empty_texture = malloc(16 * 16 * 4);
184    if(empty_texture == NULL)
185        return -1;
186
187    memset(empty_texture, 0xff, 16 * 16 * 4);
188    glEnable(GL_TEXTURE_2D);
189
190    /* ASCII glyphes textures initialisation */
191    for(i = 32; i < 128; i++)
192    {
193        glGenTextures(1, (GLuint*)&dp->drv.p->id[i - 32]);
194        glBindTexture(GL_TEXTURE_2D, dp->drv.p->id[i - 32]);
195        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
196        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
197        glTexImage2D(GL_TEXTURE_2D, 0, 4,
198                     16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE, empty_texture);
199    }
200
201    /* Unicode (CP437) glyphes textures initialisation */
202    for(i = 0; i < 8; i++)
203    {
204        glGenTextures(1, (GLuint*)&dp->drv.p->id_uni[i]);
205        glBindTexture(GL_TEXTURE_2D, dp->drv.p->id_uni[i]);
206        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
207        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
208        glTexImage2D(GL_TEXTURE_2D, 0, 4,
209                     16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE, empty_texture);
210    }
211
212    /* Get textures for ASCII glyphs */
213    for(i = 32; i < 128; i++)
214        gl_generate_glyph(i, i-32, dp);
215
216
217    gl_generate_unicode_glyph(0x00002580, 0, dp);
218    gl_generate_unicode_glyph(0x00002584, 1, dp);
219    gl_generate_unicode_glyph(0x00002588, 2, dp);
220    gl_generate_unicode_glyph(0x0000258c, 3, dp);
221    gl_generate_unicode_glyph(0x00002590, 4, dp);
222    gl_generate_unicode_glyph(0x00002591, 5, dp);
223    gl_generate_unicode_glyph(0x00002592, 6, dp);
224    gl_generate_unicode_glyph(0x00002593, 7, dp);
225
226    return 0;
227}
228
229static int gl_end_graphics(caca_display_t *dp)
230{
231    glutDestroyWindow(dp->drv.p->window);
232    free(dp->drv.p);
233    return 0;
234}
235
236static int gl_set_display_title(caca_display_t *dp, char const *title)
237{
238    glutSetWindowTitle(title);
239    return 0;
240}
241
242static unsigned int gl_get_display_width(caca_display_t *dp)
243{
244    return dp->drv.p->width;
245}
246
247static unsigned int gl_get_display_height(caca_display_t *dp)
248{
249    return dp->drv.p->height;
250}
251
252static void gl_display(caca_display_t *dp)
253{
254    unsigned int x, y, line;
255    static int old_texture = 0;
256
257    glClear(GL_COLOR_BUFFER_BIT);
258    glDisable(GL_TEXTURE_2D);
259    glDisable(GL_BLEND);
260    line = 0;
261    for(y = 0; y < dp->drv.p->height; y += dp->drv.p->font_height)
262    {
263        uint32_t *attr = dp->cv->attr + line * dp->cv->width;
264
265        for(x = 0; x < dp->drv.p->width; x += dp->drv.p->font_width)
266        {
267            uint16_t bg = _cucul_argb32_to_rgb12bg(*attr++);
268
269            glColor4b(((bg & 0xf00) >> 8) * 8,
270                      ((bg & 0x0f0) >> 4) * 8,
271                      (bg & 0x00f) * 8,
272                      0xff);
273            glBegin(GL_QUADS);
274            glVertex2f(x, y);
275            glVertex2f(x + dp->drv.p->font_width, y);
276            glVertex2f(x + dp->drv.p->font_width,
277                       y + dp->drv.p->font_height);
278            glVertex2f(x, y + dp->drv.p->font_height);
279            glEnd();
280        }
281
282        line++;
283    }
284
285    /* 2nd pass, avoids changing render state too much */
286    glEnable(GL_TEXTURE_2D);
287    glEnable(GL_BLEND);
288
289    line = 0;
290    for(y = 0; y < dp->drv.p->height; y += dp->drv.p->font_height, line++)
291    {
292        uint32_t *attr = dp->cv->attr + line * dp->cv->width;
293        uint32_t *chars = dp->cv->chars + line * dp->cv->width;
294
295        for(x = 0; x < dp->drv.p->width; x += dp->drv.p->font_width, attr++)
296        {
297            uint32_t cv = *chars++;
298            uint16_t fg;
299
300            if(cv == ' ')
301                continue;
302
303            if(cv > 0x00000020 && cv < 0x00000080)
304            {
305                if(old_texture != dp->drv.p->id[cv - 32])
306                {
307                    glBindTexture(GL_TEXTURE_2D, dp->drv.p->id[cv - 32]);
308                    old_texture = dp->drv.p->id[cv - 32];
309                }
310            }
311            else switch(cv)
312            {
313                case 0x00002580: glBindTexture(GL_TEXTURE_2D, dp->drv.p->id_uni[0]); break;
314                case 0x00002584: glBindTexture(GL_TEXTURE_2D, dp->drv.p->id_uni[1]); break;
315                case 0x00002588: glBindTexture(GL_TEXTURE_2D, dp->drv.p->id_uni[2]); break;
316                case 0x0000258c: glBindTexture(GL_TEXTURE_2D, dp->drv.p->id_uni[3]); break;
317                case 0x00002590: glBindTexture(GL_TEXTURE_2D, dp->drv.p->id_uni[4]); break;
318                case 0x00002591: glBindTexture(GL_TEXTURE_2D, dp->drv.p->id_uni[5]); break;
319                case 0x00002592: glBindTexture(GL_TEXTURE_2D, dp->drv.p->id_uni[6]); break;
320                case 0x00002593: glBindTexture(GL_TEXTURE_2D, dp->drv.p->id_uni[7]); break;
321                default:         glBindTexture(GL_TEXTURE_2D, dp->drv.p->id['?' - 32]); break;
322            }
323
324            fg = _cucul_argb32_to_rgb12fg(*attr);
325            glColor3b(((fg & 0xf00) >> 8) * 8,
326                      ((fg & 0x0f0) >> 4) * 8,
327                      (fg & 0x00f) * 8);
328            glBegin(GL_QUADS);
329            glTexCoord2f(0, dp->drv.p->sh);
330            glVertex2f(x, y);
331            glTexCoord2f(dp->drv.p->sw, dp->drv.p->sh);
332            glVertex2f(x + dp->drv.p->font_width, y);
333            glTexCoord2f(dp->drv.p->sw, 0);
334            glVertex2f(x + dp->drv.p->font_width,
335                       y + dp->drv.p->font_height);
336            glTexCoord2f(0, 0);
337            glVertex2f(x, y + dp->drv.p->font_height);
338            glEnd();
339        }
340    }
341
342#ifdef HAVE_GLUTCHECKLOOP
343    glutCheckLoop();
344#else
345    glutMainLoopEvent();
346#endif
347    glutSwapBuffers();
348    glutPostRedisplay();
349}
350
351static void gl_handle_resize(caca_display_t *dp)
352{
353    dp->drv.p->width = dp->drv.p->new_width;
354    dp->drv.p->height = dp->drv.p->new_height;
355
356    glMatrixMode(GL_PROJECTION);
357    glPushMatrix();
358    glLoadIdentity();
359
360    glViewport(0, 0, dp->drv.p->width, dp->drv.p->height);
361    gluOrtho2D(0, dp->drv.p->width, dp->drv.p->height, 0);
362    glMatrixMode(GL_MODELVIEW);
363}
364
365static int gl_get_event(caca_display_t *dp, caca_event_t *ev)
366{
367#ifdef HAVE_GLUTCHECKLOOP
368    glutCheckLoop();
369#else
370    glutMainLoopEvent();
371#endif
372
373#ifdef HAVE_GLUTCLOSEFUNC
374    if(dp->drv.p->close)
375    {
376        dp->drv.p->close = 0;
377        ev->type = CACA_EVENT_QUIT;
378        return 1;
379    }
380#endif
381
382    if(dp->resize.resized)
383    {
384        ev->type = CACA_EVENT_RESIZE;
385        ev->data.resize.w = dp->cv->width;
386        ev->data.resize.h = dp->cv->height;
387        return 1;
388    }
389
390    if(dp->drv.p->mouse_changed)
391    {
392        ev->type = CACA_EVENT_MOUSE_MOTION;
393        ev->data.mouse.x = dp->mouse.x;
394        ev->data.mouse.y = dp->mouse.y;
395        dp->drv.p->mouse_changed = 0;
396
397        if(dp->drv.p->mouse_clicked)
398        {
399            _push_event(dp, ev);
400            ev->type = CACA_EVENT_MOUSE_PRESS;
401            ev->data.mouse.button = dp->drv.p->mouse_button;
402            dp->drv.p->mouse_clicked = 0;
403        }
404
405        return 1;
406    }
407
408    if(dp->drv.p->key != 0)
409    {
410        ev->type = CACA_EVENT_KEY_PRESS;
411        ev->data.key.ch = dp->drv.p->key;
412        ev->data.key.utf32 = (uint32_t)dp->drv.p->key;
413        ev->data.key.utf8[0] = dp->drv.p->key;
414        ev->data.key.utf8[1] = '\0';
415        dp->drv.p->key = 0;
416        return 1;
417    }
418
419    if(dp->drv.p->special_key != 0)
420    {
421        switch(dp->drv.p->special_key)
422        {
423            case GLUT_KEY_F1 : ev->data.key.ch = CACA_KEY_F1; break;
424            case GLUT_KEY_F2 : ev->data.key.ch = CACA_KEY_F2; break;
425            case GLUT_KEY_F3 : ev->data.key.ch = CACA_KEY_F3; break;
426            case GLUT_KEY_F4 : ev->data.key.ch = CACA_KEY_F4; break;
427            case GLUT_KEY_F5 : ev->data.key.ch = CACA_KEY_F5; break;
428            case GLUT_KEY_F6 : ev->data.key.ch = CACA_KEY_F6; break;
429            case GLUT_KEY_F7 : ev->data.key.ch = CACA_KEY_F7; break;
430            case GLUT_KEY_F8 : ev->data.key.ch = CACA_KEY_F8; break;
431            case GLUT_KEY_F9 : ev->data.key.ch = CACA_KEY_F9; break;
432            case GLUT_KEY_F10: ev->data.key.ch = CACA_KEY_F10; break;
433            case GLUT_KEY_F11: ev->data.key.ch = CACA_KEY_F11; break;
434            case GLUT_KEY_F12: ev->data.key.ch = CACA_KEY_F12; break;
435            case GLUT_KEY_LEFT : ev->data.key.ch = CACA_KEY_LEFT; break;
436            case GLUT_KEY_RIGHT: ev->data.key.ch = CACA_KEY_RIGHT; break;
437            case GLUT_KEY_UP   : ev->data.key.ch = CACA_KEY_UP; break;
438            case GLUT_KEY_DOWN : ev->data.key.ch = CACA_KEY_DOWN; break;
439            case GLUT_KEY_PAGE_UP : ev->data.key.ch = CACA_KEY_PAGEUP; break;
440            case GLUT_KEY_PAGE_DOWN  : ev->data.key.ch = CACA_KEY_PAGEDOWN;
441                break;
442            case GLUT_KEY_HOME : ev->data.key.ch = CACA_KEY_HOME; break;
443            case GLUT_KEY_END : ev->data.key.ch = CACA_KEY_END; break;
444            case GLUT_KEY_INSERT : ev->data.key.ch = CACA_KEY_INSERT; break;
445
446            default: ev->type = CACA_EVENT_NONE; return 0;
447        }
448
449        ev->type = CACA_EVENT_KEY_PRESS;
450        ev->data.key.utf32 = 0;
451        ev->data.key.utf8[0] = '\0';
452
453        dp->drv.p->special_key = 0;
454        return 1;
455    }
456
457    ev->type = CACA_EVENT_NONE;
458    return 0;
459}
460
461
462static void gl_set_mouse(caca_display_t *dp, int flag)
463{
464    if(flag)
465        glutSetCursor(GLUT_CURSOR_RIGHT_ARROW);
466    else
467        glutSetCursor(GLUT_CURSOR_NONE);
468}
469
470/*
471 * XXX: following functions are local
472 */
473
474static void gl_handle_keyboard(unsigned char key, int x, int y)
475{
476    caca_display_t *dp = gl_d;
477
478    dp->drv.p->key = key;
479}
480
481static void gl_handle_special_key(int key, int x, int y)
482{
483    caca_display_t *dp = gl_d;
484
485    dp->drv.p->special_key = key;
486}
487
488static void gl_handle_reshape(int w, int h)
489{
490    caca_display_t *dp = gl_d;
491
492    if(dp->drv.p->bit) /* Do not handle reshaping at the first time */
493    {
494        dp->drv.p->new_width = w;
495        dp->drv.p->new_height = h;
496
497        dp->resize.w = w / dp->drv.p->font_width;
498        dp->resize.h = (h / dp->drv.p->font_height) + 1;
499
500        dp->resize.resized = 1;
501    }
502    else
503        dp->drv.p->bit = 1;
504}
505
506static void gl_handle_mouse(int button, int state, int x, int y)
507{
508    caca_display_t *dp = gl_d;
509
510    dp->drv.p->mouse_clicked = 1;
511    dp->drv.p->mouse_button = button;
512    dp->drv.p->mouse_state = state;
513    dp->drv.p->mouse_x = x / dp->drv.p->font_width;
514    dp->drv.p->mouse_y = y / dp->drv.p->font_height;
515    dp->mouse.x = dp->drv.p->mouse_x;
516    dp->mouse.y = dp->drv.p->mouse_y;
517    dp->drv.p->mouse_changed = 1;
518}
519
520static void gl_handle_mouse_motion(int x, int y)
521{
522    caca_display_t *dp = gl_d;
523    dp->drv.p->mouse_x = x / dp->drv.p->font_width;
524    dp->drv.p->mouse_y = y / dp->drv.p->font_height;
525    dp->mouse.x = dp->drv.p->mouse_x;
526    dp->mouse.y = dp->drv.p->mouse_y;
527    dp->drv.p->mouse_changed = 1;
528}
529
530#ifdef HAVE_GLUTCLOSEFUNC
531static void gl_handle_close(void)
532{
533    caca_display_t *dp = gl_d;
534    dp->drv.p->close = 1;
535}
536#endif
537
538static void _display(void)
539{
540    caca_display_t *dp = gl_d;
541    gl_display(dp);
542}
543
544static void gl_generate_glyph(uint32_t c, uint32_t tid, caca_display_t *dp)
545{
546    int s,d;
547    uint8_t *glyph8 =  calloc(dp->drv.p->font_width*dp->drv.p->font_height, 1);
548    uint8_t *glyph32 = calloc(16*16*4, 1);
549
550    cucul_render_glyph(dp->drv.p->f, c, glyph8, dp->drv.p->font_width);
551
552    /* Convert resulting 8bbp glyph to 32bits, 16x16*/
553    for(s=0;s<(dp->drv.p->font_height<=16?dp->drv.p->font_height:16);s++)
554    {
555        for(d=0;d<dp->drv.p->font_width;d++)
556        {
557            uint32_t offset = d*4+(15-s)*16*4;
558            uint8_t c = glyph8[d+s*(int)dp->drv.p->font_width];
559            glyph32[offset] = c;
560            glyph32[1+offset] = c;
561            glyph32[2+offset] = c;
562            glyph32[3+offset] = c;
563        }
564    }
565
566    glBindTexture(GL_TEXTURE_2D, dp->drv.p->id[tid]);
567    glTexImage2D(GL_TEXTURE_2D,
568                 0, 4,
569                 16,16,
570                 0, GL_RGBA, GL_UNSIGNED_BYTE,
571                 glyph32);
572    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
573    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
574    free(glyph8);
575    free(glyph32);
576}
577
578static void gl_generate_unicode_glyph(uint32_t c, uint32_t tid,
579                                      caca_display_t *dp)
580{
581    int s,d;
582    uint8_t *glyph8 =  calloc(dp->drv.p->font_width*dp->drv.p->font_height, 1);
583    uint8_t *glyph32 = calloc(16*16*4, 1);
584
585    cucul_render_glyph(dp->drv.p->f, c, glyph8, dp->drv.p->font_width);
586
587    /* Convert resulting 8bbp glyph to 32bits, 16x16*/
588    for(s=0;s<(dp->drv.p->font_height<=16?dp->drv.p->font_height:16);s++)
589    {
590        for(d=0;d<(dp->drv.p->font_width<=16?dp->drv.p->font_width:16);d++)
591        {
592            uint32_t offset = d*4+(15-s)*16*4;
593            uint8_t c = glyph8[d+s*(int)dp->drv.p->font_width];
594            glyph32[offset] = c;
595            glyph32[1+offset] = c;
596            glyph32[2+offset] = c;
597            glyph32[3+offset] = c;
598        }
599    }
600
601    glBindTexture(GL_TEXTURE_2D, dp->drv.p->id_uni[tid]);
602    glTexImage2D(GL_TEXTURE_2D,
603                 0, 4,
604                 16,16,
605                 0, GL_RGBA, GL_UNSIGNED_BYTE,
606                 glyph32);
607    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
608    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
609    free(glyph8);
610    free(glyph32);
611}
612
613/*
614 * Driver initialisation
615 */
616
617int gl_install(caca_display_t *dp)
618{
619#if defined(HAVE_GETENV) && defined(GLUT_XLIB_IMPLEMENTATION)
620    if(!getenv("DISPLAY") || !*(getenv("DISPLAY")))
621        return -1;
622#endif
623
624    dp->drv.driver = CACA_DRIVER_GL;
625
626    dp->drv.init_graphics = gl_init_graphics;
627    dp->drv.end_graphics = gl_end_graphics;
628    dp->drv.set_display_title = gl_set_display_title;
629    dp->drv.get_display_width = gl_get_display_width;
630    dp->drv.get_display_height = gl_get_display_height;
631    dp->drv.display = gl_display;
632    dp->drv.handle_resize = gl_handle_resize;
633    dp->drv.get_event = gl_get_event;
634    dp->drv.set_mouse = gl_set_mouse;
635
636    return 0;
637}
638
639#endif /* USE_GL */
640
Note: See TracBrowser for help on using the repository browser.