From http://www.jwz.org/xscreensaver/xscreensaver-5.37.tar.gz
[xscreensaver] / hacks / glx / stonerview.c
index b926f62b2ed7e81580e350a6fc3ae035fd447c4f..6ce58bb05595c1044967fe5fcef7eb275ccc1966 100644 (file)
 
 /* Ported away from GLUT (so that it can do `-root' and work with xscreensaver)
    by Jamie Zawinski <jwz@jwz.org>, 22-Jan-2001.
+
+   Revamped to work in the xlockmore framework so that it will also work
+   with the MacOS X port of xscreensaver by jwz, 21-Feb-2006.
  */
 
-#include "config.h"
+#define DEFAULTS       "*delay:        20000       \n" \
+                       "*showFPS:      False       \n" \
+                       "*wireframe:    False       \n"
+
+# define refresh_stonerview 0
+# define release_stonerview 0
+#undef countof
+#define countof(x) (sizeof((x))/sizeof((*x)))
+
+#include "xlockmore.h"
+
+#ifdef USE_GL /* whole file */
+
+#include "stonerview.h"
+#include "gltrackball.h"
+
+#define DEF_TRANSPARENT "True"
+
+typedef struct {
+  GLXContext *glx_context;
+  stonerview_state *st;
+  trackball_state *trackball;
+  Bool button_down_p;
+} stonerview_configuration;
+
+static stonerview_configuration *bps = NULL;
+
+static Bool transparent_p;
 
-#include <stdio.h>
-#include <stdlib.h>
-#include <sys/time.h>
 
-#include <GL/gl.h>
+static XrmOptionDescRec opts[] = {
+  { "-transparent",   ".transparent",   XrmoptionNoArg, "True" },
+  { "+transparent",   ".transparent",   XrmoptionNoArg, "False" },
+};
 
-#include "yarandom.h"
-#include "stonerview-move.h"
+static argtype vars[] = {
+  {&transparent_p, "transparent", "Transparent", DEF_TRANSPARENT, t_Bool},
+};
 
-extern int init_view(int *argc, char *argv[]);
-extern void win_draw(void);
+ENTRYPOINT ModeSpecOpt stonerview_opts = {countof(opts), opts, countof(vars), vars, NULL};
 
 
-static void 
-stonerview_usleep (unsigned long usecs)
+ENTRYPOINT void
+reshape_stonerview (ModeInfo *mi, int width, int height)
 {
-  struct timeval tv;
-  tv.tv_sec  = usecs / 1000000L;
-  tv.tv_usec = usecs % 1000000L;
-  (void) select (0, 0, 0, 0, &tv);
+  GLfloat h = (GLfloat) height / (GLfloat) width;
+
+  glViewport(0, 0, (GLint) width, (GLint) height);
+  glMatrixMode(GL_PROJECTION);
+  glLoadIdentity();
+  glFrustum(-1.0, 1.0, -h, h, 5.0, 60.0);
+  glMatrixMode(GL_MODELVIEW);
+  glLoadIdentity();
+  glTranslatef(0.0, 0.0, -40.0);
+}
+
+
+static void
+free_stonerview (ModeInfo *mi);
+
+
+ENTRYPOINT void 
+init_stonerview (ModeInfo *mi)
+{
+  stonerview_configuration *bp;
+
+  MI_INIT (mi, bps, free_stonerview);
+
+  bp = &bps[MI_SCREEN(mi)];
+
+  bp->glx_context = init_GL(mi);
+
+  bp->trackball = gltrackball_init (False);
+  bp->st = stonerview_init_view(MI_IS_WIREFRAME(mi), transparent_p);
+  stonerview_init_move(bp->st);
+
+  reshape_stonerview (mi, MI_WIDTH(mi), MI_HEIGHT(mi));
+  clear_gl_error(); /* WTF? sometimes "invalid op" from glViewport! */
 }
 
-int main(int argc, char *argv[])
+
+ENTRYPOINT void
+draw_stonerview (ModeInfo *mi)
 {
+  stonerview_configuration *bp = &bps[MI_SCREEN(mi)];
 
-  /* Randomize -- only need to do this here because this program
-     doesn't use the `screenhack.h' or `lockmore.h' APIs. */
-# undef ya_rand_init
-  ya_rand_init (0);
+  glXMakeCurrent(MI_DISPLAY(mi), MI_WINDOW(mi), *(bp->glx_context));
 
-  if (!init_view(&argc, argv))
-    return -1;
-  if (!init_move())
-    return -1;
+  glPushMatrix ();
+  glRotatef( current_device_rotation(), 0, 0, 1);
+  gltrackball_rotate (bp->trackball);
 
-  while (1)
-    {
-      win_draw();
-      move_increment();
-      stonerview_usleep (20000);
-    }
+# ifdef HAVE_MOBILE    /* Keep it the same relative size when rotated. */
+  {
+    GLfloat h = MI_HEIGHT(mi) / (GLfloat) MI_WIDTH(mi);
+    int o = (int) current_device_rotation();
+    if (o != 0 && o != 180 && o != -180)
+      glScalef (h, h, h);
+  }
+# endif
 
-  return 0;
+  stonerview_win_draw(bp->st);
+  if (! bp->button_down_p)
+    stonerview_move_increment(bp->st);
+  glPopMatrix ();
+
+  mi->polygon_count = NUM_ELS;
+  if (mi->fps_p) do_fps (mi);
+  glFinish();
+
+  glXSwapBuffers(MI_DISPLAY (mi), MI_WINDOW(mi));
 }
+
+static void
+free_stonerview (ModeInfo *mi)
+{
+  stonerview_configuration *bp = &bps[MI_SCREEN(mi)];
+  if (bp->st)
+    stonerview_win_release (bp->st);
+}
+
+ENTRYPOINT Bool
+stonerview_handle_event (ModeInfo *mi, XEvent *event)
+{
+  stonerview_configuration *bp = &bps[MI_SCREEN(mi)];
+
+  if (gltrackball_event_handler (event, bp->trackball,
+                                 MI_WIDTH (mi), MI_HEIGHT (mi),
+                                 &bp->button_down_p))
+    return True;
+
+  return False;
+}
+
+XSCREENSAVER_MODULE ("StonerView", stonerview)
+
+#endif /* USE_GL */