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 refresh_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;
85 bps = (stonerview_configuration *)
86 calloc (MI_NUM_SCREENS(mi), sizeof (stonerview_configuration));
88 fprintf(stderr, "%s: out of memory\n", progname);
92 bp = &bps[MI_SCREEN(mi)];
95 bp = &bps[MI_SCREEN(mi)];
97 bp->glx_context = init_GL(mi);
99 bp->trackball = gltrackball_init ();
100 bp->st = init_view(MI_IS_WIREFRAME(mi), transparent_p);
103 reshape_stonerview (mi, MI_WIDTH(mi), MI_HEIGHT(mi));
108 draw_stonerview (ModeInfo *mi)
110 stonerview_configuration *bp = &bps[MI_SCREEN(mi)];
112 glXMakeCurrent(MI_DISPLAY(mi), MI_WINDOW(mi), *(bp->glx_context));
115 gltrackball_rotate (bp->trackball);
117 if (! bp->button_down_p)
118 move_increment(bp->st);
121 mi->polygon_count = NUM_ELS;
122 if (mi->fps_p) do_fps (mi);
125 glXSwapBuffers(MI_DISPLAY (mi), MI_WINDOW(mi));
129 release_stonerview (ModeInfo *mi)
133 for (screen = 0; screen < MI_NUM_SCREENS(mi); screen++) {
134 stonerview_configuration *bp = &bps[screen];
136 win_release (bp->st);
145 stonerview_handle_event (ModeInfo *mi, XEvent *event)
147 stonerview_configuration *bp = &bps[MI_SCREEN(mi)];
149 if (event->xany.type == ButtonPress &&
150 event->xbutton.button == Button1)
152 bp->button_down_p = True;
153 gltrackball_start (bp->trackball,
154 event->xbutton.x, event->xbutton.y,
155 MI_WIDTH (mi), MI_HEIGHT (mi));
158 else if (event->xany.type == ButtonRelease &&
159 event->xbutton.button == Button1)
161 bp->button_down_p = False;
164 else if (event->xany.type == ButtonPress &&
165 (event->xbutton.button == Button4 ||
166 event->xbutton.button == Button5 ||
167 event->xbutton.button == Button6 ||
168 event->xbutton.button == Button7))
170 gltrackball_mousewheel (bp->trackball, event->xbutton.button, 10,
171 !!event->xbutton.state);
174 else if (event->xany.type == MotionNotify &&
177 gltrackball_track (bp->trackball,
178 event->xmotion.x, event->xmotion.y,
179 MI_WIDTH (mi), MI_HEIGHT (mi));
186 XSCREENSAVER_MODULE ("StonerView", stonerview)