# define PROGCLASS "Screensaver"
# define HACK_INIT init_screensaver
# define HACK_DRAW draw_screensaver
+# define HACK_RESHAPE reshape_screensaver
# define screensaver_opts xlockmore_opts
-#define DEFAULTS "*light: False \n" \
+#define DEFAULTS "*delay: 10000 \n" \
+ "*showFPS: False \n" \
+ "*light: False \n" \
"*wire: False \n" \
"*quads: 5 \n" \
"*blend: True \n" \
"*texture: False \n" \
"*texture_quality: False \n" \
"*mipmap: False \n" \
- "*fps: False \n" \
"*doDepth: False \n" \
"*image: BUILTIN \n"
#ifdef USE_GL /* whole file */
-#ifdef HAVE_XPM
-# include <X11/xpm.h>
-# ifndef PIXEL_ALREADY_TYPEDEFED
-# define PIXEL_ALREADY_TYPEDEFED /* Sigh, Xmu/Drawing.h needs this... */
-# endif
-#endif
-
#ifdef HAVE_XMU
# ifndef VMS
# include <X11/Xmu/Drawing.h>
#include <GL/gl.h>
#include <GL/glu.h>
-#include <string.h>
-#include <malloc.h>
+#include <stdlib.h>
#include <stdio.h>
+#include <string.h>
+
+#include "xpm-ximage.h"
/* Functions for loading and storing textures */
/* Functions for handling the frames per second timer */
#include "GL/glx.h"
-#ifndef SAMPLE_FRAMES
-#define SAMPLE_FRAMES 10
-#endif
-
#undef countof
#define countof(x) (sizeof((x))/sizeof((*x)))
#define DEF_TEXTURE "False"
#define DEF_TEXTURE_QUALITY "False"
#define DEF_MIPMAP "False"
-#define DEF_FPS "False"
#define DEF_DO_DEPTH "False"
#define DEF_IMAGE "BUILTIN"
static int do_texture;
static int do_texture_quality;
static int do_mipmap;
-static int do_fps;
static int do_depth;
static char *which_image;
{"+texture_quality", ".pulsar.texture_quality", XrmoptionNoArg, (caddr_t) "false" },
{"-mipmap", ".pulsar.mipmap", XrmoptionNoArg, (caddr_t) "true" },
{"+mipmap", ".pulsar.mipmap", XrmoptionNoArg, (caddr_t) "false" },
- {"-fps", ".pulsar.fps", XrmoptionNoArg, (caddr_t) "true" },
- {"+fps", ".pulsar.fps", XrmoptionNoArg, (caddr_t) "false" },
{"-do_depth", ".pulsar.doDepth", XrmoptionNoArg, (caddr_t) "true" },
{"+do_depth", ".pulsar.doDepth", XrmoptionNoArg, (caddr_t) "false" },
{"-image", ".pulsar.image", XrmoptionSepArg, (caddr_t) NULL },
{(caddr_t *) &do_texture, "texture", "Texture", DEF_TEXTURE, t_Bool},
{(caddr_t *) &do_texture_quality, "texture_quality", "Texture_quality", DEF_TEXTURE_QUALITY, t_Bool},
{(caddr_t *) &do_mipmap, "mipmap", "Mipmap", DEF_MIPMAP, t_Bool},
- {(caddr_t *) &do_fps, "fps", "fps", DEF_FPS, t_Bool},
{(caddr_t *) &do_depth, "doDepth", "DoDepth", DEF_DO_DEPTH, t_Bool},
{(caddr_t *) &which_image, "image", "Image", DEF_IMAGE, t_String},
};
{"-/+ texture", "whether to do enable texturing (much slower)"},
{"-/+ texture_quality", "whether to do enable linear/mipmap filtering (much much slower)"},
{"-/+ mipmap", "whether to do enable mipmaps (much slower)"},
- {"-/+ fps", "whether to do enable frames per second meter (?)"},
{"-/+ depth", "whether to do enable depth buffer checking (slower)"},
- {"-image <filename>", "texture image to load (PPM, PPM4, TIFF(?), XPM(?))"},
+ {"-image <filename>", "texture image to load"},
};
ModeSpecOpt screensaver_opts = {countof(opts), opts, countof(vars), vars, desc};
};
-int global_width=WIDTH, global_height=HEIGHT;
-
-static GLint base;
-static int FrameCounter = 0;
-static double oldtime=-1., newtime=-1.;
-static char FPSstring[1024]="FPS: NONE";
-
-static float x_pos=0, y_pos=0;
-
-#define FONT "-*-courier-medium-r-normal-*-240-*"
GLint quad_list;
static float scale_x=1, scale_y=1, scale_z=1;
static int frame = 0;
-static GLenum errCode;
-static const GLubyte *errString;
-
struct quad *quads;
-int checkError(int line, char *file)
-{
- if((errCode = glGetError()) != GL_NO_ERROR) {
- errString = (GLubyte *)gluErrorString(errCode);
- fprintf(stderr, "OpenGL error: %s detected at line %d in file %s\n", errString, line, file);
- exit(1);
- }
- return 0;
-}
-
-
-void FPS_Setup(void)
-{
- Display *Dpy;
- XFontStruct *fontInfo;
- Font id;
- int first=0, last=255;
-
- Dpy = XOpenDisplay(NULL);
- fontInfo = XLoadQueryFont(Dpy, FONT);
- if (fontInfo == NULL)
- {
- fprintf(stderr, "Failed to load font %s\n", FONT);
- exit(1);
- }
-
- id = fontInfo->fid;
- first = fontInfo->min_char_or_byte2;
- last = fontInfo->max_char_or_byte2;
-
- base = glGenLists((GLuint) last+1);
- if (base == 0) {
- fprintf (stderr, "out of display lists\n");
- exit(1);
- }
- glXUseXFont(id, first, last-first+1, base+first);
-
-}
-
-void PrintString(float x, float y, char *string)
-{
- int len, i;
-
- /* save the current state */
- /* note: could be expensive! */
- glPushAttrib(GL_ALL_ATTRIB_BITS);
- glMatrixMode(GL_PROJECTION);
- glLoadIdentity();
- gluOrtho2D(0, global_width, 0, global_height);
- glMatrixMode(GL_MODELVIEW);
- glLoadIdentity();
-
- /* disable lighting and texturing when drawing bitmaps! */
- glDisable(GL_TEXTURE_2D);
- glDisable(GL_LIGHTING);
- glDisable(GL_BLEND);
-
- /* draw a black background */
-
- /* draw the text */
- glColor3f(1,1,1);
- glRasterPos2f( x, y);
- len = (int) strlen(string);
- for (i = 0; i < len; i++) {
- if (glIsList(base+string[i]))
- glCallList(base+string[i]);
- else
- fprintf(stderr, "%d+string[%d] is not a display list!\n", base, i);
- }
-
- /* clean up after our state changes */
- glPopAttrib();
-}
-
-double gettime(void)
-{
- struct timeval now;
-#ifdef GETTIMEOFDAY_TWO_ARGS
- struct timezone tzp;
- gettimeofday(&now, &tzp);
-#else
- gettimeofday(&now);
-#endif
- return (double) (now.tv_sec + (((double) now.tv_usec) * 0.000001));
-}
-
-void DoFPS(void)
-{
- /* every SAMPLE_FRAMES frames, get the time and use it to get the
- frames per second */
- if (!(FrameCounter % SAMPLE_FRAMES)) {
- oldtime = newtime;
- newtime = gettime();
- sprintf(FPSstring, "FPS: %.02f", SAMPLE_FRAMES/(newtime-oldtime));
- }
-
- PrintString(x_pos,y_pos,FPSstring);
-
- FrameCounter++;
-}
-
-GLubyte *Generate_Image(int *width, int *height, int *format)
+GLubyte *
+Generate_Image(int *width, int *height, int *format)
{
GLubyte *result;
int i, j, c;
*width = checkImageWidth;
*height = checkImageHeight;
- result = (GLubyte *)malloc(4 * *width * *height);
+ result = (GLubyte *)malloc(4 * (*width) * (*height));
counter = 0;
for (i = 0; i < checkImageWidth; i++) {
}
-
-#ifdef TIFF
-#include <tiffio>
-/* Load a TIFF texture: requires libtiff */
-uint32 *LoadTIFF(char *filename, int *width, int *height, int *format)
-{
- TIFF *tif;
- char emsg[1024];
- uint32 *raster;
- TIFFRGBAImage img;
- tsize_t npixels;
-
- tif = TIFFOpen(filename, "r");
- if (tif == NULL) {
- fprintf(stderr, "Problem showing %s\n", filename);
- return Generate_Image(&width, &height, &format);
- }
- if (TIFFRGBAImageBegin(&img, tif, 0, emsg)) {
- npixels = (tsize_t) (img.width * img.height);
- raster = (uint32 *) _TIFFmalloc(npixels * (tsize_t) sizeof(uint32));
- if (raster != NULL) {
- if (TIFFRGBAImageGet(&img, raster, img.width, img.height) == 0) {
- TIFFError(filename, emsg);
- return Generate_Image(&width, &height, &format);
- }
- }
- TIFFRGBAImageEnd(&img);
- } else {
- TIFFError(filename, emsg);
- return Generate_Image(&width, &height, &format);
- }
-
- *width = img.width;
- *height = img.height;
- *format = GL_RGBA;
-
- TIFFClose(tif);
- return raster;
-}
-#endif
-
-/* Load a modified version of PPM format with an extra byte for alpha */
-GLubyte *LoadPPM4(const char *filename, int *width, int *height, int *format)
-{
- char buff[1024];
- GLubyte *data;
- int sizeX, sizeY;
- FILE *fp;
- int maxval;
-
- fp = fopen(filename, "rb");
- if (!fp)
- {
- fprintf(stderr, "Unable to open file '%s'\n", filename);
- return Generate_Image(width, height, format);
- }
-
- if (!fgets(buff, sizeof(buff), fp))
- {
- perror("Unable to read header filename\n");
- return Generate_Image(width, height, format);
- }
-
- if (buff[0] != '6' || buff[1] != 'P')
- {
- fprintf(stderr, "Invalid image format (must be `6P')\n");
- return Generate_Image(width, height, format);
- }
-
- do
- {
- fgets(buff, sizeof(buff), fp);
- }
- while (buff[0] == '#');
-
- if (sscanf(buff, "%d %d", &sizeX, &sizeY) != 2)
- {
- fprintf(stderr, "Error loading image `%s'\n", filename);
- return Generate_Image(width, height, format);
- }
-
- if (fscanf(fp, "%d", &maxval) != 1)
- {
- fprintf(stderr, "Error loading image `%s'\n", filename);
- return Generate_Image(width, height, format);
- }
-
- while (fgetc(fp) != '\n')
- ;
-
- data = (GLubyte *)malloc(4 * sizeX * sizeY);
- if (data == NULL)
- {
- fprintf(stderr, "Unable to allocate memory\n");
- exit(1);
- }
-
- if (fread(data, 4 * sizeX, sizeY, fp) != sizeY)
- {
- fprintf(stderr, "Error loading image `%s'\n", filename);
- return Generate_Image(width, height, format);
- }
-
- fclose(fp);
-
- *width = sizeX;
- *height = sizeY;
- *format = GL_RGBA;
- return data;
-}
-
-/* Load a plain PPM image */
-GLubyte *LoadPPM(const char *filename, int *width, int *height, int *format)
-{
- char buff[1024];
- GLubyte *data;
- GLint sizeX, sizeY;
- FILE *fp;
- int maxval;
-
- fp = fopen(filename, "rb");
- if (!fp)
- {
- fprintf(stderr, "Unable to open file '%s'\n", filename);
- return Generate_Image(width, height, format);
- exit(1);
- }
- if (!fgets(buff, sizeof(buff), fp))
- {
- perror(filename);
- return Generate_Image(width, height, format);
- }
-
- if (buff[0] != 'P' || buff[1] != '6')
- {
- fprintf(stderr, "Invalid image format (must be `P6')\n");
- return Generate_Image(width, height, format);
- }
-
- do
- {
- fgets(buff, sizeof(buff), fp);
- }
- while (buff[0] == '#');
-
- if (sscanf(buff, "%d %d", &sizeX, &sizeY) != 2)
- {
- fprintf(stderr, "Error loading image `%s'\n", filename);
- return Generate_Image(width, height, format);
- }
-
- if (fscanf(fp, "%d", &maxval) != 1)
- {
- fprintf(stderr, "Error loading image `%s'\n", filename);
- return Generate_Image(width, height, format);
- }
-
- while (fgetc(fp) != '\n')
- ;
-
- data = (GLubyte *)malloc(3 * sizeX * sizeY);
- if (data == NULL)
- {
- fprintf(stderr, "Unable to allocate memory\n");
- exit(1);
- }
-
- if (fread(data, 3 * sizeX, sizeY, fp) != sizeY)
- {
- fprintf(stderr, "Error loading image `%s'\n", filename);
- return Generate_Image(width, height, format);
- }
-
- fclose(fp);
-
- *width = sizeX;
- *height = sizeY;
- *format = GL_RGB;
- return data;
-}
-
/* Create a texture in OpenGL. First an image is loaded
and stored in a raster buffer, then it's */
-void Create_Texture(char *filename)
+void Create_Texture(ModeInfo *mi, const char *filename)
{
int height, width;
GLubyte *image;
- GLint a;
int format;
if ( !strncmp(filename, "BUILTIN", 7))
image = Generate_Image(&width, &height, &format);
- else if ( !strncmp((filename+strlen(filename)-3), "ppm", 3))
- image = LoadPPM(filename, &width, &height, &format);
- else if ( !strncmp((filename+strlen(filename)-4), "ppm4", 4))
- image = LoadPPM4(filename, &width, &height, &format);
-#ifdef TIFF
- else if ( !strncmp((filename+strlen(filename)-4), "tiff", 4))
- image = (GLubyte *)LoadTIFF(filename, &width, &height, &format);
-#endif
- else {
- fprintf(stderr, "Unknown file format extension: '%s'\n", filename);
- image = Generate_Image(&width, &height, &format);
- }
+ else
+ {
+ XImage *ximage = xpm_file_to_ximage (MI_DISPLAY (mi), MI_VISUAL (mi),
+ MI_COLORMAP (mi), filename);
+ image = ximage->data;
+ width = ximage->width;
+ height = ximage->height;
+ format = GL_RGBA;
+ }
/* GL_MODULATE or GL_DECAL depending on what you want */
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
/* mipmaps make the image look much nicer */
if (do_mipmap)
- a=gluBuild2DMipmaps(GL_TEXTURE_2D, format, width, height, format, GL_UNSIGNED_BYTE, image);
+ {
+ int status;
+ clear_gl_error();
+ status = gluBuild2DMipmaps(GL_TEXTURE_2D, 3, width, height, format,
+ GL_UNSIGNED_BYTE, image);
+ if (status)
+ {
+ const char *s = gluErrorString (status);
+ fprintf (stderr, "%s: error mipmapping %dx%d texture: %s\n",
+ progname, width, height,
+ (s ? s : "(unknown)"));
+ exit (1);
+ }
+ check_gl_error("mipmapping");
+ }
else
{
clear_gl_error();
format, GL_UNSIGNED_BYTE, image);
check_gl_error("texture");
}
-
- free(image);
}
void resetProjection(void) {
}
}
-void initializeGL(GLsizei width, GLsizei height)
+void initializeGL(ModeInfo *mi, GLsizei width, GLsizei height)
{
GLfloat fogColor[4] = { 0.1, 0.1, 0.1, 0.1 };
- global_width=width;
- global_height=height;
-
glViewport( 0, 0, width, height );
resetProjection();
if (do_depth)
glEnable(GL_DEPTH_TEST);
- if (do_fps)
- FPS_Setup();
-
if (do_antialias) {
do_blend = 1;
glEnable(GL_LINE_SMOOTH);
if (do_texture)
- Create_Texture(which_image);
+ Create_Texture(mi, which_image);
GenerateQuad();
}
}
}
-GLvoid drawScene(void)
+GLvoid drawScene(ModeInfo * mi)
{
-
- checkError(__LINE__, __FILE__);
+/* check_gl_error ("drawScene"); */
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
/* we have to do this here because the FPS meter turns these 3 features off!! */
/* increment frame-counter */
frame++;
- if (do_fps)
- DoFPS();
- checkError(__LINE__, __FILE__);
+/* check_gl_error ("drawScene"); */
}
return;
glXMakeCurrent(display, window, *(gp->glx_context));
- drawScene();
+ drawScene(mi);
+ if (mi->fps_p) do_fps (mi);
glXSwapBuffers(display, window);
}
/* Standard reshape function */
-static void
-reshape(int width, int height)
+void
+reshape_screensaver(ModeInfo *mi, int width, int height)
{
- glViewport( 0, 0, global_width, global_height );
+ glViewport( 0, 0, MI_WIDTH(mi), MI_HEIGHT(mi) );
resetProjection();
}
gp->window = MI_WINDOW(mi);
if ((gp->glx_context = init_GL(mi)) != NULL) {
- reshape(MI_WIDTH(mi), MI_HEIGHT(mi));
- initializeGL(MI_WIDTH(mi), MI_HEIGHT(mi));
+ reshape_screensaver(mi, MI_WIDTH(mi), MI_HEIGHT(mi));
+ initializeGL(mi, MI_WIDTH(mi), MI_HEIGHT(mi));
} else {
MI_CLEARWINDOW(mi);
}
FreeAllGL(mi);
}
#endif
-