1 /* StonerView: An eccentric visual toy.
2 Copyright 1998-2001 by Andrew Plotkin (erkyrath@eblong.com)
4 For the latest version, source code, and links to more of my stuff, see:
5 http://www.eblong.com/zarf/stonerview.html
7 Permission to use, copy, modify, distribute, and sell this software and its
8 documentation for any purpose is hereby granted without fee, provided that
9 the above copyright notice appear in all copies and that both that
10 copyright notice and this permission notice appear in supporting
11 documentation. No representations are made about the suitability of this
12 software for any purpose. It is provided "as is" without express or
16 /* Ported away from GLUT (so that it can do `-root' and work with xscreensaver)
17 by Jamie Zawinski <jwz@jwz.org>, 22-Jan-2001.
19 Revamped to work in the xlockmore framework so that it will also work
20 with the MacOS X port of xscreensaver by jwz, 21-Feb-2006.
23 #define DEFAULTS "*delay: 20000 \n" \
24 "*showFPS: False \n" \
25 "*wireframe: False \n"
27 # define release_stonerview 0
29 #define countof(x) (sizeof((x))/sizeof((*x)))
31 #include "xlockmore.h"
33 #ifdef USE_GL /* whole file */
35 #include "stonerview.h"
36 #include "gltrackball.h"
38 #define DEF_TRANSPARENT "True"
41 GLXContext *glx_context;
43 trackball_state *trackball;
45 } stonerview_configuration;
47 static stonerview_configuration *bps = NULL;
49 static Bool transparent_p;
52 static XrmOptionDescRec opts[] = {
53 { "-transparent", ".transparent", XrmoptionNoArg, "True" },
54 { "+transparent", ".transparent", XrmoptionNoArg, "False" },
57 static argtype vars[] = {
58 {&transparent_p, "transparent", "Transparent", DEF_TRANSPARENT, t_Bool},
61 ENTRYPOINT ModeSpecOpt stonerview_opts = {countof(opts), opts, countof(vars), vars, NULL};
65 reshape_stonerview (ModeInfo *mi, int width, int height)
67 GLfloat h = (GLfloat) height / (GLfloat) width;
69 glViewport(0, 0, (GLint) width, (GLint) height);
70 glMatrixMode(GL_PROJECTION);
72 glFrustum(-1.0, 1.0, -h, h, 5.0, 60.0);
73 glMatrixMode(GL_MODELVIEW);
75 glTranslatef(0.0, 0.0, -40.0);
80 init_stonerview (ModeInfo *mi)
82 stonerview_configuration *bp;
86 bp = &bps[MI_SCREEN(mi)];
88 bp->glx_context = init_GL(mi);
90 bp->trackball = gltrackball_init (False);
91 bp->st = stonerview_init_view(MI_IS_WIREFRAME(mi), transparent_p);
92 stonerview_init_move(bp->st);
94 reshape_stonerview (mi, MI_WIDTH(mi), MI_HEIGHT(mi));
95 clear_gl_error(); /* WTF? sometimes "invalid op" from glViewport! */
100 draw_stonerview (ModeInfo *mi)
102 stonerview_configuration *bp = &bps[MI_SCREEN(mi)];
104 glXMakeCurrent(MI_DISPLAY(mi), MI_WINDOW(mi), *(bp->glx_context));
107 glRotatef( current_device_rotation(), 0, 0, 1);
108 gltrackball_rotate (bp->trackball);
110 # ifdef HAVE_MOBILE /* Keep it the same relative size when rotated. */
112 GLfloat h = MI_HEIGHT(mi) / (GLfloat) MI_WIDTH(mi);
113 int o = (int) current_device_rotation();
114 if (o != 0 && o != 180 && o != -180)
119 stonerview_win_draw(bp->st);
120 if (! bp->button_down_p)
121 stonerview_move_increment(bp->st);
124 mi->polygon_count = NUM_ELS;
125 if (mi->fps_p) do_fps (mi);
128 glXSwapBuffers(MI_DISPLAY (mi), MI_WINDOW(mi));
132 free_stonerview (ModeInfo *mi)
134 stonerview_configuration *bp = &bps[MI_SCREEN(mi)];
136 stonerview_win_release (bp->st);
140 stonerview_handle_event (ModeInfo *mi, XEvent *event)
142 stonerview_configuration *bp = &bps[MI_SCREEN(mi)];
144 if (gltrackball_event_handler (event, bp->trackball,
145 MI_WIDTH (mi), MI_HEIGHT (mi),
152 XSCREENSAVER_MODULE ("StonerView", stonerview)