1 /* xlockmore.h --- xscreensaver compatibility layer for xlockmore modules.
2 * xscreensaver, Copyright (c) 1997-2017 Jamie Zawinski <jwz@jwz.org>
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
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...)
21 #endif /* HAVE_CONFIG_H */
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.) */
29 #include "screenhackI.h"
30 #include "xlockmoreI.h"
32 # define ENTRYPOINT static
34 /* Accessor macros for the ModeInfo structure
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)
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)
91 /* Under xlockmore, MI_CLEARWINDOW runs immediately, and for animated clears
92 it delays execution while the animation runs. This doesn't work on
93 XScreenSaver, which has mandatory double-buffering on macOS/iOS/Android.
95 Tricky: As a result, MI_CLEARWINDOW doesn't clear the window until after
96 init_##() or draw_##() finishes.
99 # define MI_CLEARWINDOW(mi) XClearWindow(MI_DISPLAY(mi), MI_WINDOW(mi))
101 # define MI_CLEARWINDOW(mi) ((mi)->needs_clear = True)
104 /* MI_INIT and MI_ABORT are XScreenSaver extensions. These exist primarily for
105 the sake of ports to macOS, iOS, and Android, all of which need to restart
106 individual screenhacks repeatedly in the same process. This requires
107 reusing MI_SCREEN() numbers; previously many xlockmore API hacks did not
108 support this the way they were supposed to.
111 /* MI_INIT implements the following pattern, as seen in various forms at the
112 beginning of init_##():
115 state_array = (state_t *)calloc(MI_NUM_SCREENS(mi), sizeof(state_t));
117 fprintf(stderr, "%s: out of memory\n", progname);
122 memset(&state_array[MI_SCREEN(mi)], 0, sizeof(*state_array));
124 MI_INIT also assumes ownership of the state_array over to xlockmore.c,
125 which frees it after all screens (or "screens") are closed.
128 #define MI_INIT(mi, state_array) \
129 xlockmore_mi_init ((mi), sizeof(*(state_array)), (void **)&(state_array))
131 /* Use MI_ABORT if an init_## or draw_## hook needs to shut everything down.
132 This replaces explicit calls to release_## hooks when things go wrong from
133 inside an xlockmore API screenhack.
135 At some point this may do something other than just abort().
137 #define MI_ABORT(mi) abort();
139 #define FreeAllGL(dpy) /* */
141 /* Some other utility macros.
143 #define SINF(n) ((float)sin((double)(n)))
144 #define COSF(n) ((float)cos((double)(n)))
145 #define FABSF(n) ((float)fabs((double)(n)))
150 #define MAX(a,b)((a)>(b)?(a):(b))
151 #define MIN(a,b)((a)<(b)?(a):(b))
152 #define ABS(a)((a)<0 ? -(a) : (a))
154 /* Maximum possible number of colors (*not* default number of colors.) */
155 #define NUMCOLORS 256
158 /* In an Xlib world, we define two global symbols here:
159 a struct in `MODULENAME_xscreensaver_function_table',
160 and a pointer to that in `xscreensaver_function_table'.
162 In a Cocoa or Android world, we only define the prefixed symbol;
163 the un-prefixed symbol does not exist.
166 # define XSCREENSAVER_LINK(NAME)
168 # define XSCREENSAVER_LINK(NAME) \
169 struct xscreensaver_function_table *xscreensaver_function_table = &NAME;
173 # if !defined(USE_GL) || defined(HAVE_COCOA) || defined(HAVE_ANDROID)
174 # define xlockmore_pick_gl_visual 0
175 # define xlockmore_validate_gl_visual 0
176 # endif /* !USE_GL || HAVE_COCOA || HAVE_ANDROID */
179 # define XLOCKMORE_FPS xlockmore_gl_compute_fps
181 # define XLOCKMORE_FPS xlockmore_do_fps
184 #ifdef WRITABLE_COLORS
185 # undef WRITABLE_COLORS
186 # define WRITABLE_COLORS 1
188 # define WRITABLE_COLORS 0
191 #if defined(UNIFORM_COLORS)
192 # define XLOCKMORE_COLOR_SCHEME color_scheme_uniform
193 #elif defined(SMOOTH_COLORS)
194 # define XLOCKMORE_COLOR_SCHEME color_scheme_smooth
195 #elif defined(BRIGHT_COLORS)
196 # define XLOCKMORE_COLOR_SCHEME color_scheme_bright
198 # define XLOCKMORE_COLOR_SCHEME color_scheme_default
201 /* This is the macro that links this program in with the rest of
202 xscreensaver. For example:
204 XSCREENSAVER_MODULE ("Atlantis", atlantis)
205 XSCREENSAVER_MODULE_2 ("GLMatrix", glmatrix, matrix)
207 CLASS: a string, the class name for resources.
208 NAME: a token, the name of the executable. Should be the same
209 as CLASS, but downcased.
210 PREFIX: the symbol used in the function names, e.g., `draw_atlantis'.
212 NAME and PREFIX are usually the same. If they are not, use
213 XSCREENSAVER_MODULE_2() instead of XSCREENSAVER_MODULE().
215 #define XSCREENSAVER_MODULE_2(CLASS,NAME,PREFIX) \
217 static struct xlockmore_function_table \
218 NAME ## _xlockmore_function_table = { \
222 XLOCKMORE_COLOR_SCHEME, \
225 reshape_ ## PREFIX, \
226 release_ ## PREFIX, \
228 PREFIX ## _handle_event, \
232 struct xscreensaver_function_table \
233 NAME ## _xscreensaver_function_table = { \
236 & NAME ## _xlockmore_function_table, \
239 xlockmore_pick_gl_visual, \
240 xlockmore_validate_gl_visual }; \
242 XSCREENSAVER_LINK (NAME ## _xscreensaver_function_table)
244 #define XSCREENSAVER_MODULE(CLASS,PREFIX) \
245 XSCREENSAVER_MODULE_2(CLASS,PREFIX,PREFIX)