-/* carousel, Copyright (c) 2005-2015 Jamie Zawinski <jwz@jwz.org>
+/* carousel, Copyright © 2005-2023 Jamie Zawinski <jwz@jwz.org>
* Loads a sequence of images and rotates them around.
*
* Permission to use, copy, modify, distribute, and sell this software and its
* Created: 21-Feb-2005
*/
-#define DEF_FONT "-*-helvetica-bold-r-normal-*-*-240-*-*-*-*-*-*"
+#define DEF_FONT \
+ "OCR A 48, OCR A Std 48, Lucida Console 48, Monaco 48, Courier 48, monospace 48"
+#define DEF_TITLE_FONT "sans-serif bold 48"
+
#define DEFAULTS "*count: 7 \n" \
"*delay: 10000 \n" \
"*wireframe: False \n" \
"*fpsSolid: True \n" \
"*useSHM: True \n" \
"*font: " DEF_FONT "\n" \
+ "*titleFont: " DEF_TITLE_FONT "\n" \
"*desktopGrabber: xscreensaver-getimage -no-desktop %s\n" \
"*grabDesktopImages: False \n" \
"*chooseRandomImages: True \n"
-# define refresh_carousel 0
# define release_carousel 0
# include "xlockmore.h"
-#undef countof
-#define countof(x) (sizeof((x))/sizeof((*x)))
-
#ifdef USE_GL
# define DEF_SPEED "1.0"
Bool awaiting_first_images_p;
int loads_in_progress;
- texture_font_data *texfont;
+ texture_font_data *texfont, *titlefont;
fade_mode mode;
int mode_tick;
int h = (MI_HEIGHT(mi) / 2) - 1;
if (w <= 10) w = 10;
if (h <= 10) h = 10;
+
+ if (w > h * 5) { /* tiny window: use 16:9 boxes */
+ h = w * 9/16;
+ }
+
load_texture_async (mi->xgwa.screen, mi->window, *ss->glx_context, w, h,
mipmap_p, frame->loading.texid,
image_loaded_cb, frame);
reshape_carousel (ModeInfo *mi, int width, int height)
{
GLfloat h = (GLfloat) height / (GLfloat) width;
+ int y = 0;
+
+ if (width > height * 5) { /* tiny window: show middle */
+ height = width * 9/16;
+ y = -height/2;
+ h = height / (GLfloat) width;
+ }
- glViewport (0, 0, (GLint) width, (GLint) height);
+ glViewport (0, y, (GLint) width, (GLint) height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
value.addr = buf2;
value.size = strlen(buf2);
XrmPutResource (&db, buf1, "String", &value);
+ free (val);
# endif /* !HAVE_JWXYZ */
}
{
/* only do this once, so that the string doesn't move. */
XCharStruct e;
- texture_string_metrics (ss->texfont, text, &e, 0, 0);
+ texture_string_metrics (ss->titlefont, text, &e, 0, 0);
ss->loading_sw = e.width;
ss->loading_sh = e.ascent + e.descent;
}
}
*/
-# ifdef HAVE_MOBILE
- if (MI_WIDTH(mi) < MI_HEIGHT(mi)) /* portrait orientation */
- {
- GLfloat s = (MI_WIDTH(mi) / (GLfloat) MI_HEIGHT(mi));
- glScalef (s, s, s);
- glTranslatef(-s/2, 0, 0);
- }
-# endif
+ {
+ GLfloat s = (MI_WIDTH(mi) < MI_HEIGHT(mi)
+ ? (MI_WIDTH(mi) / (GLfloat) MI_HEIGHT(mi))
+ : 1);
+ glRotatef (current_device_rotation(), 0, 0, 1);
+ glScalef (s, s, s);
+ }
glOrtho(0, MI_WIDTH(mi), 0, MI_HEIGHT(mi), -1, 1);
glTranslatef ((MI_WIDTH(mi) - ss->loading_sw) / 2,
glColor3f (1, 1, 0);
glEnable (GL_TEXTURE_2D);
glDisable (GL_DEPTH_TEST);
- print_texture_string (ss->texfont, text);
+# ifndef HAVE_ANDROID /* Doesn't work -- photo displays as static */
+ print_texture_string (ss->titlefont, text);
+# endif
glEnable (GL_DEPTH_TEST);
glPopMatrix();
carousel_state *ss;
int wire = MI_IS_WIREFRAME(mi);
- MI_INIT (mi, sss, NULL);
+ MI_INIT (mi, sss);
ss = &sss[screen];
if ((ss->glx_context = init_GL(mi)) != NULL) {
}
ss->texfont = load_texture_font (MI_DISPLAY(mi), "font");
+ ss->titlefont = load_texture_font (MI_DISPLAY(mi), "titleFont");
if (debug_p)
hack_resources (MI_DISPLAY (mi));
glEnd();
}
- else /* Draw a title under the image. */
- {
+ else if (frame->current.title && *frame->current.title)
+ { /* Draw a title under the image. */
XCharStruct e;
int sw, sh;
GLfloat scale = 0.05;
if (!wire)
{
glEnable (GL_TEXTURE_2D);
+# ifndef HAVE_ANDROID /* Doesn't work -- photo displays as static */
print_texture_string (ss->texfont, title);
+# endif
}
else
{
if (!ss->glx_context)
return;
- glXMakeCurrent(MI_DISPLAY(mi), MI_WINDOW(mi), *(ss->glx_context));
+ glXMakeCurrent(MI_DISPLAY(mi), MI_WINDOW(mi), *ss->glx_context);
if (ss->awaiting_first_images_p)
if (!load_initial_images (mi))
glXSwapBuffers (MI_DISPLAY (mi), MI_WINDOW(mi));
}
+
+ENTRYPOINT void
+free_carousel (ModeInfo *mi)
+{
+ carousel_state *ss = &sss[MI_SCREEN(mi)];
+ int i;
+ if (!ss->glx_context) return;
+ glXMakeCurrent(MI_DISPLAY(mi), MI_WINDOW(mi), *ss->glx_context);
+ if (ss->rot) free_rotator (ss->rot);
+ if (ss->trackball) gltrackball_free (ss->trackball);
+ if (ss->texfont) free_texture_font (ss->texfont);
+ if (ss->titlefont) free_texture_font (ss->titlefont);
+ for (i = 0; i < ss->nframes; i++) {
+ if (ss->frames[i]->current.title) free (ss->frames[i]->current.title);
+ if (ss->frames[i]->loading.title) free (ss->frames[i]->loading.title);
+ if (ss->frames[i]->rot) free_rotator (ss->frames[i]->rot);
+ if (ss->frames[i]->current.texid)
+ glDeleteTextures (1, &ss->frames[i]->current.texid);
+ if (ss->frames[i]->loading.texid)
+ glDeleteTextures (1, &ss->frames[i]->loading.texid);
+ }
+}
+
XSCREENSAVER_MODULE ("Carousel", carousel)
#endif /* USE_GL */