X-Git-Url: http://git.hungrycats.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=hacks%2Fglx%2Fstonerview-view.c;h=baf40e4179364497e1ba8260d0c15ec650e685aa;hb=d5186197bc394e10a4402f7f6d23fbb14103bc50;hp=96de8385a058cbc3a08b867baa375aa6976bbac1;hpb=3f9592851ce4ed76a9979bfdd6ec7dc5c457e183;p=xscreensaver diff --git a/hacks/glx/stonerview-view.c b/hacks/glx/stonerview-view.c index 96de8385..baf40e41 100644 --- a/hacks/glx/stonerview-view.c +++ b/hacks/glx/stonerview-view.c @@ -15,364 +15,69 @@ by Jamie Zawinski , 22-Jan-2001. */ -#include "config.h" +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#ifdef HAVE_COCOA +# include "jwxyz.h" +#elif defined(HAVE_ANDROID) +# include +#else /* real Xlib */ +# include +# include +#endif /* !HAVE_COCOA */ + +#ifdef HAVE_JWZGLES +# include "jwzgles.h" +#endif /* HAVE_JWZGLES */ -#include #include -#include -#include +#include "stonerview.h" -#include -#include -#include -#include -#include -#include - -#include "vroot.h" /* handle virtual root windows --- very important */ - -#include "version.h" /* get the xscreensaver package's version number */ -#include "yarandom.h" /* use xscreensaver's RNG */ - -#include "stonerview-osc.h" -#include "stonerview-move.h" - -static char *progclass = "StonerView"; -static char *progname = 0; - -#define FRAMERATE (50) /* milliseconds per frame */ - -static GLfloat view_rotx = -45.0, view_roty = 0.0, view_rotz = 0.0; +static GLfloat view_rotx = -45.0, view_roty = 0.0, view_rotz = 15.0; static GLfloat view_scale = 4.0; -/* static GLint prevtime = 0; / * for timing */ - -static void setup_window(void); - -void win_draw(void); -static void win_reshape(int width, int height); -/* static void win_visible(int vis); */ -/* static void win_idle(void); */ -static void handle_events(void); - -static Display *dpy; -static Window window; -static int wireframe = 0; - -static Atom XA_WM_PROTOCOLS, XA_WM_DELETE_WINDOW; - - -static void -usage (void) -{ - fprintf (stderr, "usage: %s [--wire] [--geom G | --root | --window-id ID]\n", - progname); - exit (1); -} - - -/* mostly lifted from xscreensaver/utils/visual.c... */ -static int -visual_depth (Display *dpy, int screen, Visual *visual) -{ - XVisualInfo vi_in, *vi_out; - int out_count, d; - vi_in.screen = screen; - vi_in.visualid = XVisualIDFromVisual (visual); - vi_out = XGetVisualInfo (dpy, VisualScreenMask|VisualIDMask, - &vi_in, &out_count); - if (! vi_out) abort (); - d = vi_out [0].depth; - XFree ((char *) vi_out); - return d; -} -/* mostly lifted from xscreensaver/hacks/screenhack.c... */ -static char *make_title_string (void) +stonerview_state * +stonerview_init_view(int wireframe_p, int transparent_p) { - char version[255]; - char *v = (char *) strdup(strchr(screensaver_id, ' ')); - char *s1, *s2, *s3, *s4; - s1 = (char *) strchr(v, ' '); s1++; - s2 = (char *) strchr(s1, ' '); - s3 = (char *) strchr(v, '('); s3++; - s4 = (char *) strchr(s3, ')'); - *s2 = 0; - *s4 = 0; - sprintf (version, "%s: from the XScreenSaver %s distribution (%s.)", - progclass, s1, s3); - return (strdup(version)); -} - - -int init_view(int *argc, char *argv[]) -{ - int ix; - int fullscreen = 0; - int on_root = 0; - Window on_window = 0; - - int undef = -65536; - int x = undef, y = undef; - int w = 500, h = 500; - char *dpystr = (char *) getenv ("DISPLAY"); - char *geom = 0; - int screen; - Visual *visual = 0; - XWindowAttributes xgwa; - XSetWindowAttributes xswa; - unsigned long xswa_mask = 0; - XSizeHints hints; - GLXContext glx_context = 0; - - progname = argv[0]; - - memset (&hints, 0, sizeof(hints)); - - for (ix=1; ix<*argc; ix++) - { - if (argv[ix][0] == '-' && argv[ix][1] == '-') - argv[ix]++; - if (!strcmp(argv[ix], "-geometry") || - !strcmp(argv[ix], "-geom")) - { - if (on_root || fullscreen) usage(); - geom = argv[++ix]; - } - else if (!strcmp(argv[ix], "-display") || - !strcmp(argv[ix], "-disp") || - !strcmp(argv[ix], "-dpy") || - !strcmp(argv[ix], "-d")) - dpystr = argv[++ix]; - else if (!strcmp(argv[ix], "-root")) - { - if (geom || fullscreen) usage(); - on_root = 1; - } - else if (!strcmp(argv[ix], "-window-id") && - *argc > ix+1) - { - unsigned long id; - char c; - if (1 != sscanf (argv[ix+1], "%lu %c", &id, &c) && - 1 != sscanf (argv[ix+1], "0x%lx %c", &id, &c)) - usage(); - ix++; - on_window = (Window) id; - } - else if (!strcmp(argv[ix], "-fullscreen") || - !strcmp(argv[ix], "-full")) - { - if (on_root || geom) usage(); - fullscreen = 1; - } - else if (!strcmp(argv[ix], "-wireframe") || - !strcmp(argv[ix], "-wire")) - { - wireframe = 1; - } - else - { - usage(); - } - } - - dpy = XOpenDisplay (dpystr); - if (!dpy) exit (1); - - screen = DefaultScreen (dpy); - - XA_WM_PROTOCOLS = XInternAtom (dpy, "WM_PROTOCOLS", False); - XA_WM_DELETE_WINDOW = XInternAtom (dpy, "WM_DELETE_WINDOW", False); - - if (on_root || on_window) - { - window = (on_window ? on_window : RootWindow (dpy, screen)); - XGetWindowAttributes (dpy, window, &xgwa); - visual = xgwa.visual; - w = xgwa.width; - h = xgwa.height; - } - else - { - int ww = WidthOfScreen (DefaultScreenOfDisplay (dpy)); - int hh = HeightOfScreen (DefaultScreenOfDisplay (dpy)); + stonerview_state *st = (stonerview_state *) calloc (1, sizeof(*st)); - if (fullscreen) - { - w = ww; - h = hh; - } - else if (geom) - { - /* Since we're not linking against Xt or GLUT, we get to parse - the `-geometry' argument ourselves. YAY. - */ - char c; - if (4 == sscanf (geom, "=%dx%d+%d+%d%c", &w, &h, &x, &y, &c)) - ; - else if (4 == sscanf (geom, "=%dx%d-%d+%d%c", &w, &h, &x, &y, &c)) - x = ww-w-x; - else if (4 == sscanf (geom, "=%dx%d+%d-%d%c", &w, &h, &x, &y, &c)) - y = hh-h-y; - else if (4 == sscanf (geom, "=%dx%d-%d-%d%c", &w, &h, &x, &y, &c)) - x = ww-w-x, y = hh-h-y; - else if (2 == sscanf (geom, "=%dx%d%c", &w, &h, &c)) - ; - else if (2 == sscanf (geom, "+%d+%d%c", &x, &y, &c)) - ; - else if (2 == sscanf (geom, "-%d+%d%c", &x, &y, &c)) - x = ww-w-x; - else if (2 == sscanf (geom, "+%d-%d%c", &x, &y, &c)) - y = hh-h-y; - else if (2 == sscanf (geom, "-%d-%d%c", &x, &y, &c)) - x = ww-w-x, y = hh-h-y; - else - { - fprintf (stderr, "%s: unparsable geometry: %s\n", - progname, geom); - exit (1); - } + st->wireframe = wireframe_p; + st->transparent = transparent_p; + st->num_els = NUM_ELS; + st->elist = (stonerview_elem_t *) calloc (st->num_els, sizeof(*st->elist)); - hints.flags = USSize; - hints.width = w; - hints.height = h; - if (x != undef && y != undef) - { - hints.flags |= USPosition; - hints.x = x; - hints.y = y; - } - } + st->osctail = &st->oscroot; - /* Pick a good GL visual */ - { -# define R GLX_RED_SIZE -# define G GLX_GREEN_SIZE -# define B GLX_BLUE_SIZE -# define D GLX_DEPTH_SIZE -# define I GLX_BUFFER_SIZE -# define DB GLX_DOUBLEBUFFER + /* for trackball, two-sided lighting and no face culling */ + glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE); - int attrs[][20] = { - { GLX_RGBA, R, 8, G, 8, B, 8, D, 8, DB, 0 }, /* rgb double */ - { GLX_RGBA, R, 4, G, 4, B, 4, D, 4, DB, 0 }, - { GLX_RGBA, R, 2, G, 2, B, 2, D, 2, DB, 0 }, - { GLX_RGBA, R, 8, G, 8, B, 8, D, 8, 0 }, /* rgb single */ - { GLX_RGBA, R, 4, G, 4, B, 4, D, 4, 0 }, - { GLX_RGBA, R, 2, G, 2, B, 2, D, 2, 0 }, - { I, 8, D, 8, DB, 0 }, /* cmap double */ - { I, 4, D, 4, DB, 0 }, - { I, 8, D, 8, 0 }, /* cmap single */ - { I, 4, D, 4, 0 }, - { GLX_RGBA, R, 1, G, 1, B, 1, D, 1, 0 } /* monochrome */ - }; - - int i; - for (i = 0; i < sizeof(attrs)/sizeof(*attrs); i++) - { - XVisualInfo *vi = glXChooseVisual (dpy, screen, attrs[i]); - if (vi) - { - visual = vi->visual; - XFree (vi); - break; - } - } - if (!visual) - { - fprintf (stderr, "%s: unable to find a GL visual\n", progname); - exit (1); - } - } - - - if (x == undef) x = 0; - if (y == undef) y = 0; - - xswa_mask = (CWEventMask | CWColormap | - CWBackPixel | CWBackingPixel | CWBorderPixel ); - xswa.colormap = XCreateColormap (dpy, RootWindow (dpy, screen), - visual, AllocNone); - xswa.background_pixel = BlackPixel (dpy, screen); - xswa.backing_pixel = xswa.background_pixel; - xswa.border_pixel = xswa.background_pixel; - xswa.event_mask = (KeyPressMask | ButtonPressMask | StructureNotifyMask); - - window = XCreateWindow (dpy, RootWindow (dpy, screen), - x, y, w, h, 0, - visual_depth (dpy, screen, visual), - InputOutput, visual, - xswa_mask, &xswa); - - { - XWMHints wmhints; - - XTextProperty tp1, tp2; - char *v = make_title_string (); - XStringListToTextProperty (&v, 1, &tp1); - XStringListToTextProperty (&progclass, 1, &tp2); - wmhints.flags = InputHint; - wmhints.input = True; - XSetWMProperties (dpy, window, &tp1, &tp2, argv, *argc, &hints, - &wmhints, 0); - free (v); - } - - XChangeProperty (dpy, window, XA_WM_PROTOCOLS, XA_ATOM, 32, - PropModeReplace, - (unsigned char *) &XA_WM_DELETE_WINDOW, 1); - - XMapRaised (dpy, window); - XSync (dpy, False); - } - - - /* Now hook up to GLX */ - { - XVisualInfo vi_in, *vi_out; - int out_count; - vi_in.screen = screen; - vi_in.visualid = XVisualIDFromVisual (visual); - vi_out = XGetVisualInfo (dpy, VisualScreenMask|VisualIDMask, - &vi_in, &out_count); - if (! vi_out) abort (); - - glx_context = glXCreateContext (dpy, vi_out, 0, GL_TRUE); - XFree((char *) vi_out); - - if (!glx_context) - { - fprintf(stderr, "%s: couldn't create GL context for root window.\n", - progname); - exit(1); - } - - glXMakeCurrent (dpy, window, glx_context); - } - - setup_window(); - win_reshape(w, h); - - return 1; -} - -static void setup_window(void) -{ glEnable(GL_CULL_FACE); glEnable(GL_LIGHTING); glEnable(GL_LIGHT0); glEnable(GL_DEPTH_TEST); glEnable(GL_NORMALIZE); + + glHint(GL_LINE_SMOOTH_HINT, GL_NICEST); + glEnable(GL_LINE_SMOOTH); + glEnable(GL_BLEND); + + if (st->transparent) + glBlendFunc(GL_SRC_ALPHA,GL_ONE); + + return st; } /* callback: draw everything */ -void win_draw(void) +void +stonerview_win_draw(stonerview_state *st) { int ix; - static GLfloat white[] = { 1.0, 1.0, 1.0, 1.0 }; - static GLfloat gray[] = { 0.6, 0.6, 0.6, 1.0 }; + static const GLfloat white[] = { 1.0, 1.0, 1.0, 1.0 }; + static const GLfloat gray[] = { 0.6, 0.6, 0.6, 1.0 }; glDrawBuffer(GL_BACK); @@ -386,13 +91,13 @@ void win_draw(void) glShadeModel(GL_FLAT); - for (ix=0; ixnum_els; ix++) { + stonerview_elem_t *el = &st->elist[ix]; glNormal3f(0.0, 0.0, 1.0); /* outline the square */ - glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, (wireframe ? white : gray)); + glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, (st->wireframe ? white : gray)); glBegin(GL_LINE_LOOP); glVertex3f(el->pos[0]-el->vervec[0], el->pos[1]-el->vervec[1], el->pos[2]); glVertex3f(el->pos[0]+el->vervec[1], el->pos[1]-el->vervec[0], el->pos[2]); @@ -400,10 +105,15 @@ void win_draw(void) glVertex3f(el->pos[0]-el->vervec[1], el->pos[1]+el->vervec[0], el->pos[2]); glEnd(); - if (wireframe) continue; + if (st->wireframe) continue; /* fill the square */ - glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, el->col); + { + GLfloat col[4]; + col[0] = el->col[0]; col[1] = el->col[1]; + col[2] = el->col[2]; col[3] = el->col[3]; + glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, col); + } glBegin(GL_QUADS); glVertex3f(el->pos[0]-el->vervec[0], el->pos[1]-el->vervec[1], el->pos[2]); glVertex3f(el->pos[0]+el->vervec[1], el->pos[1]-el->vervec[0], el->pos[2]); @@ -413,87 +123,12 @@ void win_draw(void) } glPopMatrix(); - - glFinish(); - glXSwapBuffers(dpy, window); - - handle_events(); } - -/* callback: new window size or exposure */ -static void win_reshape(int width, int height) +void +stonerview_win_release(stonerview_state *st) { - 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 -handle_events (void) -{ - while (XPending (dpy)) - { - XEvent E; - XEvent *event = &E; - XNextEvent (dpy, event); - switch (event->xany.type) - { - case ConfigureNotify: - { - XWindowAttributes xgwa; - XGetWindowAttributes (dpy, window, &xgwa); - win_reshape (xgwa.width, xgwa.height); - break; - } - case KeyPress: - { - KeySym keysym; - char c = 0; - XLookupString (&event->xkey, &c, 1, &keysym, 0); - if (c == 'q' || - c == 'Q' || - c == 3 || /* ^C */ - c == 27) /* ESC */ - exit (0); - else if (! (keysym >= XK_Shift_L && keysym <= XK_Hyper_R)) - XBell (dpy, 0); /* beep for non-chord keys */ - } - break; - case ButtonPress: - XBell (dpy, 0); - break; - case ClientMessage: - { - if (event->xclient.message_type != XA_WM_PROTOCOLS) - { - char *s = XGetAtomName(dpy, event->xclient.message_type); - if (!s) s = "(null)"; - fprintf (stderr, "%s: unknown ClientMessage %s received!\n", - progname, s); - } - else if (event->xclient.data.l[0] != XA_WM_DELETE_WINDOW) - { - char *s1 = XGetAtomName(dpy, event->xclient.message_type); - char *s2 = XGetAtomName(dpy, event->xclient.data.l[0]); - if (!s1) s1 = "(null)"; - if (!s2) s2 = "(null)"; - fprintf (stderr,"%s: unknown ClientMessage %s[%s] received!\n", - progname, s1, s2); - } - else - { - exit (0); - } - } - break; - } - } + free (st->elist); + /*free (st->oscroot); -- #### how do we free this? */ + free (st); }