X-Git-Url: http://git.hungrycats.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=hacks%2Fglx%2Fcrackberg.c;h=74c691570e2b46d87c2b23303cb353bf4dd25fa2;hb=39809ded547bdbb08207d3e514950425215b4410;hp=c4e925c73670fdcc389bce8954db781cad9f0004;hpb=f8cf5ac7b2f53510f80a0eaf286a25298be17bfe;p=xscreensaver diff --git a/hacks/glx/crackberg.c b/hacks/glx/crackberg.c index c4e925c7..74c69157 100644 --- a/hacks/glx/crackberg.c +++ b/hacks/glx/crackberg.c @@ -1,7 +1,7 @@ /*************************** ** crackberg; Matus Telgarsky [ catachresis@cmu.edu ] 2005 ** */ -#ifndef HAVE_COCOA +#ifndef HAVE_JWXYZ # define XK_MISCELLANY # include #endif @@ -10,7 +10,7 @@ "*showFPS: False \n" \ "*wireframe: False \n" \ -# define refresh_crackberg 0 +# define release_crackberg 0 #undef countof #define countof(x) (sizeof((x))/sizeof((*x))) @@ -131,6 +131,10 @@ struct _cberg_state { double vs0r,vs0g,vs0b, vs1r, vs1g, vs1b, vf0r,vf0g,vf0b, vf1r, vf1g, vf1b; + + Bool button_down_p; + int mouse_x, mouse_y; + struct timeval paused; }; @@ -1167,18 +1171,13 @@ ENTRYPOINT void init_crackberg (ModeInfo *mi) { cberg_state *cberg; - if (!cbergs) { - nsubdivs %= 16; /* just in case.. */ + nsubdivs %= 16; /* just in case.. */ - if ( !(cbergs = calloc(MI_NUM_SCREENS(mi), sizeof(cberg_state)))) { - perror(progname); - exit(1); - } + MI_INIT(mi, cbergs); - if (visibility > 1.0 || visibility < 0.2) { - printf("visibility must be in range [0.2 .. 1.0]\n"); - visibility = 1.0; - } + if (visibility > 1.0 || visibility < 0.2) { + printf("visibility must be in range [0.2 .. 1.0]\n"); + visibility = 1.0; } cberg = &cbergs[MI_SCREEN(mi)]; @@ -1207,7 +1206,9 @@ ENTRYPOINT void init_crackberg (ModeInfo *mi) glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glShadeModel((flat) ? GL_FLAT : GL_SMOOTH); +# ifndef HAVE_JWZGLES /* #### glPolygonMode other than GL_FILL unimplemented */ glPolygonMode(GL_FRONT_AND_BACK, (MI_IS_WIREFRAME(mi)) ? GL_LINE : GL_FILL); +# endif if (lit) { glEnable(GL_LIGHTING); @@ -1254,7 +1255,9 @@ ENTRYPOINT Bool crackberg_handle_event (ModeInfo *mi, XEvent *ev) if (ev->xany.type == KeyPress) { switch (keysym) { case XK_Left: cberg->motion_state |= MOTION_LROT; break; + case XK_Prior: cberg->motion_state |= MOTION_LROT; break; case XK_Right: cberg->motion_state |= MOTION_RROT; break; + case XK_Next: cberg->motion_state |= MOTION_RROT; break; case XK_Down: cberg->motion_state |= MOTION_BACK; break; case XK_Up: cberg->motion_state |= MOTION_FORW; break; case '1': cberg->motion_state |= MOTION_DEC; break; @@ -1282,7 +1285,9 @@ ENTRYPOINT Bool crackberg_handle_event (ModeInfo *mi, XEvent *ev) switch (keysym) { case XK_Left: cberg->motion_state &= ~MOTION_LROT; break; + case XK_Prior: cberg->motion_state &= ~MOTION_LROT; break; case XK_Right: cberg->motion_state &= ~MOTION_RROT; break; + case XK_Next: cberg->motion_state &= ~MOTION_RROT; break; case XK_Down: cberg->motion_state &= ~MOTION_BACK; break; case XK_Up: cberg->motion_state &= ~MOTION_FORW; break; case '1': cberg->motion_state &= ~MOTION_DEC; break; @@ -1297,6 +1302,51 @@ ENTRYPOINT Bool crackberg_handle_event (ModeInfo *mi, XEvent *ev) break; default: return False; } + } else if (ev->xany.type == ButtonPress && + ev->xbutton.button == Button1) { + cberg->button_down_p = True; + cberg->mouse_x = ev->xbutton.x; + cberg->mouse_y = ev->xbutton.y; + cberg->motion_state = MOTION_MANUAL; + cberg->paused.tv_sec = 0; + } else if (ev->xany.type == ButtonRelease && + ev->xbutton.button == Button1) { + cberg->button_down_p = False; + cberg->motion_state = MOTION_AUTO; + /* After mouse-up, don't go back into auto-motion mode for a second, so + that repeated click-and-drag gestures don't fight with auto-motion. */ + gettimeofday(&cberg->paused, NULL); + } else if (ev->xany.type == MotionNotify && + cberg->button_down_p) { + int dx = ev->xmotion.x - cberg->mouse_x; + int dy = ev->xmotion.y - cberg->mouse_y; + cberg->mouse_x = ev->xmotion.x; + cberg->mouse_y = ev->xmotion.y; + cberg->motion_state = MOTION_MANUAL; + + /* Take the larger dimension, since motion_state doesn't scale */ + if (dx > 0 && dx > dy) dy = 0; + if (dx < 0 && dx < dy) dy = 0; + if (dy > 0 && dy > dx) dx = 0; + if (dy < 0 && dy < dx) dx = 0; + + { + int rot = current_device_rotation(); + int swap; + while (rot <= -180) rot += 360; + while (rot > 180) rot -= 360; + if (rot > 135 || rot < -135) /* 180 */ + dx = -dx, dy = -dy; + else if (rot > 45) /* 90 */ + swap = dx, dx = -dy, dy = swap; + else if (rot < -45) /* 270 */ + swap = dx, dx = dy, dy = -swap; + } + + if (dx > 0) cberg->motion_state |= MOTION_LEFT; + else if (dx < 0) cberg->motion_state |= MOTION_RIGHT; + else if (dy > 0) cberg->motion_state |= MOTION_FORW; + else if (dy < 0) cberg->motion_state |= MOTION_BACK; } else return False; return True; @@ -1320,7 +1370,8 @@ ENTRYPOINT void draw_crackberg (ModeInfo *mi) cberg->elapsed = cur_frame - cberg->prev_frame; - if (cberg->motion_state == MOTION_AUTO) { + if (cberg->motion_state == MOTION_AUTO && + cberg->paused.tv_sec < cur_frame_t.tv_sec) { cberg->x += cberg->dx * cberg->elapsed; cberg->y += cberg->dy * cberg->elapsed; /* cberg->z */ @@ -1404,19 +1455,12 @@ ENTRYPOINT void draw_crackberg (ModeInfo *mi) } /* uh */ -ENTRYPOINT void release_crackberg (ModeInfo *mi) +ENTRYPOINT void free_crackberg (ModeInfo *mi) { - if (cbergs) { - int screen; - for (screen = 0; screen < MI_NUM_SCREENS(mi); screen++) { - cberg_state *cberg = &cbergs[screen]; - if (cberg->norms) - free(cberg->norms); - free(cberg->heights); - } - free (cbergs); - cbergs = 0; - } + cberg_state *cberg = &cbergs[MI_SCREEN(mi)]; + if (cberg->norms) + free(cberg->norms); + free(cberg->heights); } XSCREENSAVER_MODULE ("Crackberg", crackberg)