From http://www.jwz.org/xscreensaver/xscreensaver-5.31.tar.gz
[xscreensaver] / android / glue.c
1 #include <jni.h>
2 #include <math.h>
3 #include <stdlib.h>
4 #include <stdio.h>
5 #include <time.h>
6 #include <pthread.h>
7 #include <GLES/gl.h>
8
9 #include "screenhackI.h"
10 #include "jwzglesI.h"
11 #include "version.h"
12
13 #undef PI
14 #define PI 3.1415926535897932f
15
16 void drawXscreensaver();
17
18 int sWindowWidth = 0;
19 int sWindowHeight = 0;
20 int initTried = 0;
21 int renderTried = 0;
22 int resetTried = 0;
23 int currentFlip = 0;
24
25 pthread_mutex_t mutg = PTHREAD_MUTEX_INITIALIZER;
26
27 extern struct xscreensaver_function_table *xscreensaver_function_table;
28
29 // if adding a table here, increase the magic number
30 struct xscreensaver_function_table
31 *hypertorus_xscreensaver_function_table,
32     *hilbert_xscreensaver_function_table,
33     *endgame_xscreensaver_function_table,
34     *stonerview_xscreensaver_function_table,
35     *sproingies_xscreensaver_function_table,
36     *blinkbox_xscreensaver_function_table,
37     *flipflop_xscreensaver_function_table,
38     *superquadrics_xscreensaver_function_table;
39
40
41 Bool mono_p;
42
43
44 static XrmOptionDescRec default_options[] = {
45     {"-root", ".root", XrmoptionNoArg, "True"},
46     {"-window", ".root", XrmoptionNoArg, "False"},
47     {"-mono", ".mono", XrmoptionNoArg, "True"},
48     {"-install", ".installColormap", XrmoptionNoArg, "True"},
49     {"-noinstall", ".installColormap", XrmoptionNoArg, "False"},
50     {"-visual", ".visualID", XrmoptionSepArg, 0},
51     {"-window-id", ".windowID", XrmoptionSepArg, 0},
52     {"-fps", ".doFPS", XrmoptionNoArg, "True"},
53     {"-no-fps", ".doFPS", XrmoptionNoArg, "False"},
54
55 #ifdef DEBUG_PAIR
56     {"-pair", ".pair", XrmoptionNoArg, "True"},
57 #endif                          /* DEBUG_PAIR */
58     {0, 0, 0, 0}
59 };
60
61 static char *default_defaults[] = {
62     ".root:               false",
63     "*geometry:           600x480",     /* this should be .geometry, but nooooo... */
64     "*mono:               false",
65     "*installColormap:    false",
66     "*doFPS:              false",
67     "*multiSample:        false",
68     "*visualID:           default",
69     "*windowID:           ",
70     "*desktopGrabber:     xscreensaver-getimage %s",
71     0
72 };
73
74 static XrmOptionDescRec *merged_options;
75 static int merged_options_size;
76 static char **merged_defaults;
77
78
79 struct running_hack {
80     struct xscreensaver_function_table *xsft;
81     Display *dpy;
82     Window window;
83     void *closure;
84 };
85
86 const char *progname;
87 const char *progclass;
88
89
90 struct running_hack rh[8];
91 // ^ magic number of hacks - TODO: remove magic number
92
93
94
95 int chosen;
96 // 0 superquadrics
97 // 1 stonerview
98 // 2 sproingies
99 // 3 hilbert
100
101 JNIEXPORT void JNICALL
102     Java_org_jwz_xscreensaver_CallNative_nativeInit
103     (JNIEnv * env);
104 JNIEXPORT void JNICALL
105     Java_org_jwz_xscreensaver_CallNative_nativeResize
106     (JNIEnv * env, jobject thiz, jint w, jint h);
107 JNIEXPORT void JNICALL
108     Java_org_jwz_xscreensaver_CallNative_nativeRender
109     (JNIEnv * env);
110 JNIEXPORT void JNICALL
111     Java_org_jwz_xscreensaver_CallNative_nativeDone
112     (JNIEnv * env);
113 JNIEXPORT void JNICALL
114     Java_org_jwz_xscreensaver_gen_SuperquadricsWallpaper_nativeSettings
115     (JNIEnv * env, jobject thiz, jstring jhack, jstring hackPref,
116      jint draw);
117 JNIEXPORT void JNICALL
118     Java_org_jwz_xscreensaver_gen_StonerviewWallpaper_nativeSettings
119     (JNIEnv * env, jobject thiz, jstring jhack, jstring hackPref,
120      jint draw);
121 JNIEXPORT void JNICALL
122     Java_org_jwz_xscreensaver_gen_SproingiesWallpaper_nativeSettings
123     (JNIEnv * env, jobject thiz, jstring jhack, jstring hackPref,
124      jint draw);
125 JNIEXPORT void JNICALL
126     Java_org_jwz_xscreensaver_gen_HilbertWallpaper_nativeSettings
127     (JNIEnv * env, jobject thiz, jstring jhack, jstring hackPref,
128      jint draw);
129
130 void doinit()
131 {
132
133
134     if (chosen == 0) {
135         progname = "superquadrics";
136         rh[chosen].xsft = &superquadrics_xscreensaver_function_table;
137         //progname = "blinkbox";
138         //rh[chosen].xsft = &blinkbox_xscreensaver_function_table;
139         //progname = "flipflop";
140         //rh[chosen].xsft = &flipflop_xscreensaver_function_table;
141         //progname = "hypertorus";
142         //rh[chosen].xsft = &hypertorus_xscreensaver_function_table;
143     } else if (chosen == 1) {
144         progname = "stonerview";
145         rh[chosen].xsft = &stonerview_xscreensaver_function_table;
146
147     } else if (chosen == 2) {
148         progname = "sproingies";
149         rh[chosen].xsft = &sproingies_xscreensaver_function_table;
150
151     } else if (chosen == 3) {
152         progname = "hilbert";
153         rh[chosen].xsft = &hilbert_xscreensaver_function_table;
154     } else {
155         progname = "sproingies";
156         rh[chosen].xsft = &sproingies_xscreensaver_function_table;
157     }
158
159     rh[chosen].dpy = jwxyz_make_display(0, 0);
160     rh[chosen].window = XRootWindow(rh[chosen].dpy, 0);
161 // TODO: Zero looks right, but double-check that is the right number
162
163     progclass = rh[chosen].xsft->progclass;
164
165     if (rh[chosen].xsft->setup_cb)
166         rh[chosen].xsft->setup_cb(rh[chosen].xsft,
167                                   rh[chosen].xsft->setup_arg);
168
169     if (resetTried < 1) {
170         resetTried++;
171         jwzgles_reset();
172     }
173
174     void *(*init_cb) (Display *, Window, void *) =
175         (void *(*)(Display *, Window, void *)) rh[chosen].xsft->init_cb;
176
177     rh[chosen].closure =
178         init_cb(rh[chosen].dpy, rh[chosen].window,
179                 rh[chosen].xsft->setup_arg);
180
181 }
182
183
184 JNIEXPORT void JNICALL
185     Java_org_jwz_xscreensaver_CallNative_nativeInit
186     (JNIEnv * env) {
187
188     if (initTried < 1) {
189         initTried++;
190     } else {
191         if (!rh[chosen].dpy) {
192             doinit();
193         } else {
194             rh[chosen].xsft->free_cb(rh[chosen].dpy, rh[chosen].window,
195                                      rh[chosen].closure);
196             jwxyz_free_display(rh[chosen].dpy);
197             rh[chosen].dpy = NULL;
198             rh[chosen].window = NULL;
199             if (!rh[chosen].dpy) {
200                 doinit();
201             }
202
203         }
204     }
205
206 }
207
208
209 JNIEXPORT void JNICALL
210     Java_org_jwz_xscreensaver_CallNative_nativeResize
211     (JNIEnv * env, jobject thiz, jint w, jint h) {
212
213     sWindowWidth = w;
214     sWindowHeight = h;
215
216     if (!rh[chosen].dpy) {
217         doinit();
218     }
219
220     jwxyz_window_resized(rh[chosen].dpy, rh[chosen].window, 0, 0, w, h, 0);
221
222     rh[chosen].xsft->reshape_cb(rh[chosen].dpy, rh[chosen].window,
223                                 rh[chosen].closure, w, h);
224 }
225
226 JNIEXPORT void JNICALL
227     Java_org_jwz_xscreensaver_CallNative_nativeRender
228     (JNIEnv * env) {
229     if (renderTried < 1) {
230         renderTried++;
231     } else {
232         drawXscreensaver();
233     }
234 }
235
236 // TODO: Check Java side is calling this properly
237 JNIEXPORT void JNICALL
238     Java_org_jwz_xscreensaver_CallNative_nativeDone
239     (JNIEnv * env) {
240
241     rh[chosen].xsft->free_cb(rh[chosen].dpy, rh[chosen].window,
242                              rh[chosen].closure);
243     jwxyz_free_display(rh[chosen].dpy);
244     rh[chosen].dpy = NULL;
245     rh[chosen].window = NULL;
246
247 }
248
249 JNIEXPORT void JNICALL
250     Java_org_jwz_xscreensaver_gen_SuperquadricsWallpaper_nativeSettings
251     (JNIEnv * env, jobject thiz, jstring jhack, jstring hackPref,
252      jint draw) {
253
254     double sq_speed;
255     const char *chack = (*env)->GetStringUTFChars(env, hackPref, NULL);
256     char *hck = (char *) chack;
257
258     if (draw == 0) {
259
260         double sqd;
261         sq_speed = sscanf(hck, "%lf", &sqd);
262         setSuperquadricsSpeed(sqd);
263     }
264
265     chosen = 0;
266 }
267
268 JNIEXPORT void JNICALL
269     Java_org_jwz_xscreensaver_gen_StonerviewWallpaper_nativeSettings
270     (JNIEnv * env, jobject thiz, jstring jhack, jstring hackPref,
271      jint draw) {
272
273     int count;
274     const char *chack = (*env)->GetStringUTFChars(env, hackPref, NULL);
275     char *hck = (char *) chack;
276     count = atoi(hck);
277     if (draw == 0) {
278         setStonerviewTransparency(count);
279     }
280
281     chosen = 1;
282 }
283
284
285
286 JNIEXPORT void JNICALL
287     Java_org_jwz_xscreensaver_gen_SproingiesWallpaper_nativeSettings
288     (JNIEnv * env, jobject thiz, jstring jhack, jstring hackPref,
289      jint draw) {
290
291     int count;
292     const char *chack = (*env)->GetStringUTFChars(env, hackPref, NULL);
293     char *hck = (char *) chack;
294     count = atoi(hck);
295     if (draw == 0) {
296         setSproingiesCount(count);
297     }
298
299     chosen = 2;
300 }
301
302 JNIEXPORT void JNICALL
303     Java_org_jwz_xscreensaver_gen_HilbertWallpaper_nativeSettings
304     (JNIEnv * env, jobject thiz, jstring jhack, jstring hackPref,
305      jint draw) {
306     const char *chack = (*env)->GetStringUTFChars(env, hackPref, NULL);
307     char *hck = (char *) chack;
308     if (draw == 0) {
309         setHilbertMode(hck);
310     }
311     chosen = 3;
312 }
313
314
315
316 void drawXscreensaver()
317 {
318     pthread_mutex_lock(&mutg);
319     rh[chosen].xsft->draw_cb(rh[chosen].dpy, rh[chosen].window,
320                              rh[chosen].closure);
321     pthread_mutex_unlock(&mutg);
322
323 }