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"
39 GLXContext *glx_context;
41 trackball_state *trackball;
43 } stonerview_configuration;
45 static stonerview_configuration *bps = NULL;
47 ENTRYPOINT ModeSpecOpt stonerview_opts = {0, NULL, 0, NULL, NULL};
51 reshape_stonerview (ModeInfo *mi, int width, int height)
53 GLfloat h = (GLfloat) height / (GLfloat) width;
55 glViewport(0, 0, (GLint) width, (GLint) height);
56 glMatrixMode(GL_PROJECTION);
58 glFrustum(-1.0, 1.0, -h, h, 5.0, 60.0);
59 glMatrixMode(GL_MODELVIEW);
61 glTranslatef(0.0, 0.0, -40.0);
66 init_stonerview (ModeInfo *mi)
68 stonerview_configuration *bp;
71 bps = (stonerview_configuration *)
72 calloc (MI_NUM_SCREENS(mi), sizeof (stonerview_configuration));
74 fprintf(stderr, "%s: out of memory\n", progname);
78 bp = &bps[MI_SCREEN(mi)];
81 bp = &bps[MI_SCREEN(mi)];
83 bp->glx_context = init_GL(mi);
85 bp->trackball = gltrackball_init ();
86 bp->st = init_view(MI_IS_WIREFRAME(mi));
89 reshape_stonerview (mi, MI_WIDTH(mi), MI_HEIGHT(mi));
94 draw_stonerview (ModeInfo *mi)
96 stonerview_configuration *bp = &bps[MI_SCREEN(mi)];
98 glXMakeCurrent(MI_DISPLAY(mi), MI_WINDOW(mi), *(bp->glx_context));
101 gltrackball_rotate (bp->trackball);
103 if (! bp->button_down_p)
104 move_increment(bp->st);
107 mi->polygon_count = NUM_ELS;
108 if (mi->fps_p) do_fps (mi);
111 glXSwapBuffers(MI_DISPLAY (mi), MI_WINDOW(mi));
115 release_stonerview (ModeInfo *mi)
119 for (screen = 0; screen < MI_NUM_SCREENS(mi); screen++) {
120 stonerview_configuration *bp = &bps[screen];
122 win_release (bp->st);
131 stonerview_handle_event (ModeInfo *mi, XEvent *event)
133 stonerview_configuration *bp = &bps[MI_SCREEN(mi)];
135 if (event->xany.type == ButtonPress &&
136 event->xbutton.button == Button1)
138 bp->button_down_p = True;
139 gltrackball_start (bp->trackball,
140 event->xbutton.x, event->xbutton.y,
141 MI_WIDTH (mi), MI_HEIGHT (mi));
144 else if (event->xany.type == ButtonRelease &&
145 event->xbutton.button == Button1)
147 bp->button_down_p = False;
150 else if (event->xany.type == ButtonPress &&
151 (event->xbutton.button == Button4 ||
152 event->xbutton.button == Button5 ||
153 event->xbutton.button == Button6 ||
154 event->xbutton.button == Button7))
156 gltrackball_mousewheel (bp->trackball, event->xbutton.button, 10,
157 !!event->xbutton.state);
160 else if (event->xany.type == MotionNotify &&
163 gltrackball_track (bp->trackball,
164 event->xmotion.x, event->xmotion.y,
165 MI_WIDTH (mi), MI_HEIGHT (mi));
172 XSCREENSAVER_MODULE ("StonerView", stonerview)