From http://www.jwz.org/xscreensaver/xscreensaver-5.37.tar.gz
[xscreensaver] / android / project / xscreensaver / src / org / jwz / xscreensaver / XScreenSaverRenderer.java
1 /* -*- Mode: java; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2  * xscreensaver, Copyright (c) 2016 Jamie Zawinski <jwz@jwz.org>
3  * and Dennis Sheil <dennis@panaceasupplies.com>
4  *
5  * Permission to use, copy, modify, distribute, and sell this software and its
6  * documentation for any purpose is hereby granted without fee, provided that
7  * the above copyright notice appear in all copies and that both that
8  * copyright notice and this permission notice appear in supporting
9  * documentation.  No representations are made about the suitability of this
10  * software for any purpose.  It is provided "as is" without express or 
11  * implied warranty.
12  */
13
14 package org.jwz.xscreensaver;
15
16 import java.util.Map;
17 import java.lang.RuntimeException;
18 import android.view.Display;
19 import android.view.WindowManager;
20 import android.view.Surface;
21 import android.view.KeyEvent;
22 import android.content.Context;
23 import android.graphics.Bitmap;
24 import android.opengl.GLSurfaceView;
25 import java.util.Timer;
26 import java.util.TimerTask;
27 import javax.microedition.khronos.egl.EGLConfig;
28 import javax.microedition.khronos.opengles.GL10;
29 import org.jwz.xscreensaver.jwxyz;
30 import android.os.Message;
31 import android.os.Handler;
32 import android.util.Log;
33
34
35 public class XScreenSaverRenderer implements GLSurfaceView.Renderer {
36
37   boolean initTried = false;
38   jwxyz jwxyz_obj = null;
39
40   String hack;
41   Handler.Callback abort_callback;
42
43   Context app;
44   Bitmap screenshot;
45
46   GLSurfaceView glview;
47
48   class RenderTask extends TimerTask {
49     public void run() {
50       glview.requestRender();
51     }
52   };
53
54   Timer timer = new Timer();
55
56   private void LOG (String fmt, Object... args) {
57     Log.d ("xscreensaver",
58            this.getClass().getSimpleName() + ": " +
59            String.format (fmt, args));
60   }
61
62   private void except(Exception e) {
63     jwxyz_obj = null;
64     Message m = Message.obtain (null, 0, (Object) e);
65     abort_callback.handleMessage (m);
66   }
67
68   public XScreenSaverRenderer (String hack,
69                                Context app,
70                                Bitmap screenshot,
71                                Handler.Callback abort_callback,
72                                GLSurfaceView glview) {
73     super();
74     this.hack   = hack;
75     this.app    = app;
76     this.screenshot = screenshot;
77     this.abort_callback = abort_callback;
78     this.glview = glview;
79     LOG ("init %s", hack);
80
81     this.glview.setEGLConfigChooser (8, 8, 8, 8, 16, 0);
82     this.glview.setRenderer (this);
83     this.glview.setRenderMode (GLSurfaceView.RENDERMODE_WHEN_DIRTY);
84   }
85
86   static public String saverNameOf (Object obj) {
87     // Extract the saver name from e.g. "gen.Daydream$BouncingCow"
88     String name = obj.getClass().getSimpleName();
89     int index = name.lastIndexOf('$');
90     if (index != -1) {
91       index++;
92       name = name.substring (index, name.length() - index);
93     }
94     return name.toLowerCase();
95   }
96
97   public void onDrawFrame (GL10 gl) {
98     try {
99       if (jwxyz_obj != null) {
100         long delay = jwxyz_obj.nativeRender();
101         // java.util.Timer doesn't seem to like to re-use TimerTasks, so
102         // there's a slow object churn here: one TimerTask per frame.
103         timer.schedule(new RenderTask(), delay / 1000);
104       }
105     } catch (RuntimeException e) {
106       except (e);
107     }
108   }
109
110   public void onSurfaceChanged(GL10 gl, int w, int h) {
111     try {
112       if (jwxyz_obj == null)
113         jwxyz_obj = new jwxyz (hack, app, screenshot, w, h);
114
115       double r = 0;
116
117       Display d = glview.getDisplay();
118
119       if (d != null) {
120         switch (d.getRotation()) {
121         case Surface.ROTATION_90:  r = 90;  break;
122         case Surface.ROTATION_180: r = 180; break;
123         case Surface.ROTATION_270: r = 270; break;
124         }
125       }
126
127       jwxyz_obj.nativeResize (w, h, r);
128
129       glview.requestRender();
130
131     } catch (RuntimeException e) {
132       except (e);
133     }
134   }
135
136   public void onSurfaceCreated (GL10 gl, EGLConfig config) {
137     try {
138       LOG ("onSurfaceCreated %s / %s / %s", 
139            gl.glGetString (GL10.GL_VENDOR),
140            gl.glGetString (GL10.GL_RENDERER),
141            gl.glGetString (GL10.GL_VERSION));
142
143       if (!initTried) {
144         initTried = true;
145       } else {
146         if (jwxyz_obj != null) {
147           jwxyz_obj.nativeDone();
148           jwxyz_obj = null;
149         }
150       }
151     } catch (RuntimeException e) {
152       except (e);
153     }
154   }
155
156   public void release() {
157     try {
158       if (jwxyz_obj != null) {
159         jwxyz_obj.nativeDone();
160         jwxyz_obj = null;
161       }
162     } catch (RuntimeException e) {
163       except (e);
164     }
165   }
166
167   public void sendButtonEvent (int x, int y, boolean down) {
168     try {
169       jwxyz_obj.sendButtonEvent (x, y, down);
170     } catch (RuntimeException e) {
171       except (e);
172     }
173   }
174
175   public void sendMotionEvent (int x, int y) {
176     try {
177       jwxyz_obj.sendMotionEvent (x, y);
178     } catch (RuntimeException e) {
179       except (e);
180     }
181   }
182
183   public void sendKeyEvent (KeyEvent event) {
184     try {
185       jwxyz_obj.sendKeyEvent (event);
186     } catch (RuntimeException e) {
187       except (e);
188     }
189   }
190
191
192   static
193   {
194     System.loadLibrary ("xscreensaver");
195   }
196 }