59032aab8d1e66537c96f1ba1597961c49c70685
[xscreensaver] / hacks / glx / fps-gl.c
1 /* fps, Copyright (c) 2001-2008 Jamie Zawinski <jwz@jwz.org>
2  * Draw a frames-per-second display (Xlib and OpenGL).
3  *
4  * Permission to use, copy, modify, distribute, and sell this software and its
5  * documentation for any purpose is hereby granted without fee, provided that
6  * the above copyright notice appear in all copies and that both that
7  * copyright notice and this permission notice appear in supporting
8  * documentation.  No representations are made about the suitability of this
9  * software for any purpose.  It is provided "as is" without express or 
10  * implied warranty.
11  */
12
13 #ifdef HAVE_CONFIG_H
14 # include "config.h"
15 #endif /* HAVE_CONFIG_H */
16
17 #ifdef HAVE_COCOA
18 # include "jwxyz.h"
19 # include <OpenGL/gl.h>
20 # include <OpenGL/glu.h>
21 # include <AGL/agl.h>
22 #else /* !HAVE_COCOA -- real Xlib */
23 # include <GL/glx.h>
24 # include <GL/glu.h>
25 #endif /* !HAVE_COCOA */
26
27 #include "xlockmoreI.h"
28 #include "fpsI.h"
29 #include "glxfonts.h"
30
31 /* These are in xlock-gl.c */
32 extern void clear_gl_error (void);
33 extern void check_gl_error (const char *type);
34
35
36 static void
37 xlockmore_gl_fps_init (fps_state *st)
38 {
39   XFontStruct *f = st->font;
40   int first = f->min_char_or_byte2;
41   int last  = f->max_char_or_byte2;
42
43   clear_gl_error ();
44   st->font_dlist = glGenLists ((GLuint) last+1);
45   check_gl_error ("glGenLists");
46
47 # ifndef HAVE_COCOA
48
49   glXUseXFont (f->fid, first, last-first+1, st->font_dlist + first);
50   check_gl_error ("glXUseXFont");
51
52 # else  /* HAVE_COCOA */
53   {
54     AGLContext ctx = aglGetCurrentContext();
55     int afid, face, size;
56     afid = jwxyz_font_info (f->fid, &size, &face);
57
58     if (! aglUseFont (ctx, afid, face, size, 
59                       first, last-first+1, st->font_dlist + first)) {
60       check_gl_error ("aglUseFont");
61       abort();
62     }
63   }
64 # endif  /* HAVE_COCOA */
65 }
66
67
68
69 /* Callback in xscreensaver_function_table, via xlockmore.c.
70  */
71 void
72 xlockmore_gl_compute_fps (Display *dpy, Window w, fps_state *fpst, 
73                           void *closure)
74 {
75   ModeInfo *mi = (ModeInfo *) closure;
76   if (! mi->fpst)
77     {
78       mi->fpst = fpst;
79       xlockmore_gl_fps_init (fpst);
80     }
81
82   fps_compute (fpst, mi->polygon_count);
83 }
84
85
86 /* Called directly from GL programs (as `do_fps') before swapping buffers.
87  */
88 void
89 xlockmore_gl_draw_fps (ModeInfo *mi)
90 {
91   fps_state *st = mi->fpst;
92   if (st)   /* might be too early */
93     {
94       XWindowAttributes xgwa;
95       int lines = 1;
96       const char *s;
97       int lh = st->font->ascent + st->font->descent;
98       int y = st->y;
99
100       XGetWindowAttributes (st->dpy, st->window, &xgwa);
101       for (s = st->string; *s; s++) 
102         if (*s == '\n') lines++;
103
104       if (y < 0)
105         y = xgwa.height + y - lines*lh;
106       y += lines*lh + st->font->descent;
107
108       glColor3f (1, 1, 1);
109       print_gl_string (st->dpy, st->font, st->font_dlist, 
110                        xgwa.width, xgwa.height,
111                        st->x, y, st->string, st->clear_p);
112     }
113 }