From http://www.jwz.org/xscreensaver/xscreensaver-5.16.tar.gz
[xscreensaver] / hacks / glx / fps-gl.c
1 /* fps, Copyright (c) 2001-2012 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 #else /* !HAVE_COCOA -- real Xlib */
20 # include <GL/glx.h>
21 # include <GL/glu.h>
22 #endif /* !HAVE_COCOA */
23
24 #ifdef HAVE_JWZGLES
25 # include "jwzgles.h"
26 #endif /* HAVE_JWZGLES */
27
28 #include "xlockmoreI.h"
29 #include "fpsI.h"
30 #include "glxfonts.h"
31
32 /* These are in xlock-gl.c */
33 extern void clear_gl_error (void);
34 extern void check_gl_error (const char *type);
35
36
37 static void
38 xlockmore_gl_fps_init (fps_state *st)
39 {
40 #ifdef HAVE_GLBITMAP
41
42   XFontStruct *f = st->font;
43   int first = f->min_char_or_byte2;
44   int last  = f->max_char_or_byte2;
45
46   clear_gl_error ();
47   st->font_dlist = glGenLists ((GLuint) last+1);
48   check_gl_error ("glGenLists");
49
50   xscreensaver_glXUseXFont (st->dpy, f->fid,
51                             first, last-first+1, st->font_dlist + first);
52   check_gl_error ("xscreensaver_glXUseXFont");
53
54 #else  /* !HAVE_GLBITMAP */
55
56   clear_gl_error();  /* screw it */
57   st->gl_fps_data = load_texture_font (st->dpy, "fpsFont");
58
59 #endif /* !HAVE_GLBITMAP */
60 }
61
62
63
64 /* Callback in xscreensaver_function_table, via xlockmore.c.
65  */
66 void
67 xlockmore_gl_compute_fps (Display *dpy, Window w, fps_state *fpst, 
68                           void *closure)
69 {
70   ModeInfo *mi = (ModeInfo *) closure;
71   if (! mi->fpst)
72     {
73       mi->fpst = fpst;
74       xlockmore_gl_fps_init (fpst);
75     }
76
77   fps_compute (fpst, mi->polygon_count, mi->recursion_depth);
78 }
79
80
81 /* Called directly from GL programs (as `do_fps') before swapping buffers.
82  */
83 void
84 xlockmore_gl_draw_fps (ModeInfo *mi)
85 {
86   fps_state *st = mi->fpst;
87   if (st)   /* might be too early */
88     {
89       XWindowAttributes xgwa;
90       int lines = 1;
91       const char *s;
92       int lh = st->font->ascent + st->font->descent;
93       int y = st->y;
94
95       XGetWindowAttributes (st->dpy, st->window, &xgwa);
96       for (s = st->string; *s; s++) 
97         if (*s == '\n') lines++;
98
99       if (y < 0)
100         y = xgwa.height + y - lines*lh;
101       y += lines*lh + st->font->descent;
102
103       glColor3f (1, 1, 1);
104       print_gl_string (st->dpy, 
105 # ifdef HAVE_GLBITMAP
106                        st->font, st->font_dlist, 
107 # else  /* !HAVE_GLBITMAP */
108                        st->gl_fps_data,
109 # endif /* !HAVE_GLBITMAP */
110                        xgwa.width, xgwa.height,
111                        st->x, y, st->string, st->clear_p);
112     }
113 }