From http://www.jwz.org/xscreensaver/xscreensaver-5.37.tar.gz
[xscreensaver] / hacks / xlockmore.h
1 /* xlockmore.h --- xscreensaver compatibility layer for xlockmore modules.
2  * xscreensaver, Copyright (c) 1997-2012 Jamie Zawinski <jwz@jwz.org>
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  * The definitions in this file make it possible to compile an xlockmore
13  * module into a standalone program, and thus use it with xscreensaver.
14  * By Jamie Zawinski <jwz@jwz.org> on 10-May-97; based on the ideas
15  * in the older xlock.h by Charles Hannum <mycroft@ai.mit.edu>.  (I had
16  * to redo it, since xlockmore has diverged so far from xlock...)
17  */
18
19 #ifdef HAVE_CONFIG_H
20 # include "config.h"
21 #endif /* HAVE_CONFIG_H */
22
23 #ifndef __STDC__
24 ERROR!  Sorry, xlockmore.h requires ANSI C (gcc, for example.)
25   /* (The ansi dependency is that we use string concatenation,
26      and cpp-based stringification of tokens.) */
27 #endif
28
29 #include "screenhackI.h"
30 #include "xlockmoreI.h"
31
32 # define ENTRYPOINT static
33
34 /* Accessor macros for the ModeInfo structure
35  */
36 #define MI_DISPLAY(MI)          ((MI)->dpy)
37 #define MI_WINDOW(MI)           ((MI)->window)
38 #define MI_NUM_SCREENS(MI)      XLOCKMORE_NUM_SCREENS
39 #define MI_SCREEN(MI)           ((MI)->screen_number)
40 #define MI_SCREENPTR(MI)        ((MI)->xgwa.screen)
41 #define MI_WIN_WHITE_PIXEL(MI)  ((MI)->white)
42 #define MI_WIN_BLACK_PIXEL(MI)  ((MI)->black)
43 #define MI_NPIXELS(MI)          ((MI)->npixels)
44 #define MI_PIXEL(MI,N)          ((MI)->pixels[(N)])
45 #define MI_WIN_WIDTH(MI)        ((MI)->xgwa.width)
46 #define MI_WIN_HEIGHT(MI)       ((MI)->xgwa.height)
47 #define MI_WIN_DEPTH(MI)        ((MI)->xgwa.depth)
48 #define MI_DEPTH(MI)            ((MI)->xgwa.depth)
49 #define MI_WIN_COLORMAP(MI)     ((MI)->xgwa.colormap)
50 #define MI_VISUAL(MI)           ((MI)->xgwa.visual)
51 #define MI_GC(MI)               ((MI)->gc)
52 #define MI_PAUSE(MI)            ((MI)->pause)
53 #define MI_DELAY(MI)            ((MI)->pause)
54 #define MI_WIN_IS_FULLRANDOM(MI)((MI)->fullrandom)
55 #define MI_WIN_IS_VERBOSE(MI)   (False)
56 #define MI_WIN_IS_INSTALL(MI)   (True)
57 #define MI_WIN_IS_MONO(MI)      (mono_p)
58 #define MI_WIN_IS_INROOT(MI)    ((MI)->root_p)
59 #define MI_WIN_IS_INWINDOW(MI)  (!(MI)->root_p)
60 #define MI_WIN_IS_ICONIC(MI)    (False)
61 #define MI_WIN_IS_WIREFRAME(MI) ((MI)->wireframe_p)
62 #define MI_WIN_IS_USE3D(MI)     ((MI)->threed)
63 #define MI_LEFT_COLOR(MI)       ((MI)->threed_left_color)
64 #define MI_RIGHT_COLOR(MI)      ((MI)->threed_right_color)
65 #define MI_BOTH_COLOR(MI)       ((MI)->threed_both_color)
66 #define MI_NONE_COLOR(MI)       ((MI)->threed_none_color)
67 #define MI_DELTA3D(MI)          ((MI)->threed_delta)
68 #define MI_CYCLES(MI)           ((MI)->cycles)
69 #define MI_BATCHCOUNT(MI)       ((MI)->batchcount)
70 #define MI_SIZE(MI)             ((MI)->size)
71 #define MI_IS_DRAWN(MI)         ((MI)->is_drawn)
72 #define MI_IS_FPS(MI)           ((MI)->fps_p)
73 #define MI_NCOLORS(MI)          ((MI)->npixels)
74 #define MI_NAME(MI)             (progname)
75
76 #define MI_COLORMAP(MI)         (MI_WIN_COLORMAP((MI)))
77 #define MI_WIDTH(MI)            (MI_WIN_WIDTH((MI)))
78 #define MI_HEIGHT(MI)           (MI_WIN_HEIGHT((MI)))
79 #define MI_IS_ICONIC(MI)        (MI_WIN_IS_ICONIC((MI)))
80 #define MI_IS_WIREFRAME(MI)     (MI_WIN_IS_WIREFRAME((MI)))
81 #define MI_IS_MONO(MI)          (MI_WIN_IS_MONO((MI)))
82 #define MI_COUNT(MI)            (MI_BATCHCOUNT((MI)))
83 #define MI_BLACK_PIXEL(MI)      (MI_WIN_BLACK_PIXEL(MI))
84 #define MI_WHITE_PIXEL(MI)      (MI_WIN_WHITE_PIXEL(MI))
85 #define MI_IS_FULLRANDOM(MI)    (MI_WIN_IS_FULLRANDOM(MI))
86 #define MI_IS_VERBOSE(MI)       (MI_WIN_IS_VERBOSE(MI))
87 #define MI_IS_INSTALL(MI)       (MI_WIN_IS_INSTALL(MI))
88 #define MI_IS_DEBUG(MI)         (False)
89 #define MI_IS_MOUSE(MI)         (False)
90
91 #define MI_CLEARWINDOW(mi) XClearWindow(MI_DISPLAY(mi), MI_WINDOW(mi))
92
93 /* MI_INIT and MI_ABORT are XScreenSaver extensions. These exist primarily for
94    the sake of ports to macOS, iOS, and Android, all of which need to restart
95    individual screenhacks repeatedly in the same process. This requires
96    reusing MI_SCREEN() numbers; previously many xlockmore API hacks did not
97    support this the way they were supposed to.
98  */
99
100 /* MI_INIT implements the following pattern, as seen in various forms at the
101    beginning of init_##():
102
103    if(!state_array) {
104      state_array = (state_t *)calloc(MI_NUM_SCREENS(mi), sizeof(state_t));
105      if(!state_array) {
106        fprintf(stderr, "%s: out of memory\n", progname);
107        return;
108      }
109    }
110    hack_free_state(mi);
111    memset(&state_array[MI_SCREEN(mi)], 0, sizeof(*state_array));
112
113    It also enables hack_free_state to run when a screen is no longer in use.
114    This is called at some point after the last call to draw_##, but before
115    release_##.
116  */
117
118 #define MI_INIT(mi, state_array, hack_free_state) \
119   xlockmore_mi_init ((mi), sizeof(*(state_array)), (void **)&(state_array), \
120                      hack_free_state)
121
122 /* Use MI_ABORT if an init_## or draw_## hook needs to shut everything down.
123    This replaces explicit calls to release_## hooks when things go wrong from
124    inside an xlockmore API screenhack.
125
126    At some point this may do something other than just abort().
127  */
128 #define MI_ABORT(mi)            abort();
129
130 #define FreeAllGL(dpy)          /* */
131
132 /* Some other utility macros.
133  */
134 #define SINF(n)                 ((float)sin((double)(n)))
135 #define COSF(n)                 ((float)cos((double)(n)))
136 #define FABSF(n)                ((float)fabs((double)(n)))
137
138 #undef MAX
139 #undef MIN
140 #undef ABS
141 #define MAX(a,b)((a)>(b)?(a):(b))
142 #define MIN(a,b)((a)<(b)?(a):(b))
143 #define ABS(a)((a)<0 ? -(a) : (a))
144
145 /* Maximum possible number of colors (*not* default number of colors.) */
146 #define NUMCOLORS 256
147
148
149 /* In an Xlib world, we define two global symbols here:
150    a struct in `MODULENAME_xscreensaver_function_table',
151    and a pointer to that in `xscreensaver_function_table'.
152
153    In a Cocoa or Android world, we only define the prefixed symbol;
154    the un-prefixed symbol does not exist.
155  */
156 #ifdef HAVE_MOBILE
157 # define XSCREENSAVER_LINK(NAME)
158 #else
159 # define XSCREENSAVER_LINK(NAME) \
160    struct xscreensaver_function_table *xscreensaver_function_table = &NAME;
161 #endif
162
163
164 # if !defined(USE_GL) || defined(HAVE_COCOA) || defined(HAVE_ANDROID)
165 #  define xlockmore_pick_gl_visual 0
166 #  define xlockmore_validate_gl_visual 0
167 # endif  /* !USE_GL || HAVE_COCOA || HAVE_ANDROID */
168
169 # ifdef USE_GL
170 #  define XLOCKMORE_FPS xlockmore_gl_compute_fps
171 # else
172 #  define XLOCKMORE_FPS xlockmore_do_fps
173 # endif
174
175 #ifdef WRITABLE_COLORS
176 # undef WRITABLE_COLORS
177 # define WRITABLE_COLORS 1
178 #else
179 # define WRITABLE_COLORS 0
180 #endif
181
182 #if defined(UNIFORM_COLORS)
183 # define XLOCKMORE_COLOR_SCHEME color_scheme_uniform
184 #elif defined(SMOOTH_COLORS)
185 # define XLOCKMORE_COLOR_SCHEME color_scheme_smooth
186 #elif defined(BRIGHT_COLORS)
187 # define XLOCKMORE_COLOR_SCHEME color_scheme_bright
188 #else
189 # define XLOCKMORE_COLOR_SCHEME color_scheme_default
190 #endif
191
192 /* This is the macro that links this program in with the rest of
193    xscreensaver.  For example:
194
195      XSCREENSAVER_MODULE   ("Atlantis", atlantis)
196      XSCREENSAVER_MODULE_2 ("GLMatrix", glmatrix, matrix)
197
198    CLASS:   a string, the class name for resources.
199    NAME:    a token, the name of the executable.  Should be the same
200             as CLASS, but downcased.
201    PREFIX:  the symbol used in the function names, e.g., `draw_atlantis'.
202
203    NAME and PREFIX are usually the same.  If they are not, use
204    XSCREENSAVER_MODULE_2() instead of XSCREENSAVER_MODULE().
205  */
206 #define XSCREENSAVER_MODULE_2(CLASS,NAME,PREFIX)                        \
207                                                                         \
208   static struct xlockmore_function_table                                \
209          NAME ## _xlockmore_function_table = {                  \
210            CLASS,                                                       \
211            DEFAULTS,                                                    \
212            WRITABLE_COLORS,                                             \
213            XLOCKMORE_COLOR_SCHEME,                                      \
214            init_    ## PREFIX,                                          \
215            draw_    ## PREFIX,                                          \
216            reshape_ ## PREFIX,                                          \
217            refresh_ ## PREFIX,                                          \
218            release_ ## PREFIX,                                          \
219            PREFIX   ## _handle_event,                                   \
220            & PREFIX ## _opts                                            \
221   };                                                                    \
222                                                                         \
223   struct xscreensaver_function_table                                    \
224          NAME ## _xscreensaver_function_table = {                       \
225            0, 0, 0,                                                     \
226            xlockmore_setup,                                             \
227            & NAME ## _xlockmore_function_table,                         \
228            0, 0, 0, 0, 0,                                               \
229            XLOCKMORE_FPS,                                               \
230            xlockmore_pick_gl_visual,                                    \
231            xlockmore_validate_gl_visual };                              \
232                                                                         \
233   XSCREENSAVER_LINK (NAME ## _xscreensaver_function_table)
234
235 #define XSCREENSAVER_MODULE(CLASS,PREFIX)                               \
236       XSCREENSAVER_MODULE_2(CLASS,PREFIX,PREFIX)