-/* carousel, Copyright (c) 2005-2008 Jamie Zawinski <jwz@jwz.org>
+/* carousel, Copyright (c) 2005-2018 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 "-*-times-bold-r-normal-*-240-*"
+#if defined(HAVE_COCOA) || defined(HAVE_ANDROID)
+# define DEF_FONT "OCR A Std 48, Lucida Console 48, Monaco 48"
+#elif 0 /* real X11, XQueryFont() */
+# define DEF_FONT "-*-helvetica-bold-r-normal-*-*-480-*-*-*-*-*-*"
+#else /* real X11, load_font_retry() */
+# define DEF_FONT "-*-ocr a std-medium-r-*-*-*-480-*-*-m-*-*-*"
+#endif
+
+#define DEF_TITLE_FONT "-*-helvetica-bold-r-normal-*-*-480-*-*-*-*-*-*"
+
#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 free_carousel 0
# define release_carousel 0
# include "xlockmore.h"
#include "grab-ximage.h"
#include "texfont.h"
-# ifndef HAVE_COCOA
+# ifndef HAVE_JWXYZ
# include <X11/Intrinsic.h> /* for XrmDatabase in -debug mode */
# endif
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);
free (frame->loading.title);
frame->loading.title = (filename ? strdup (filename) : 0);
- if (frame->loading.title) /* strip filename to part after last /. */
- {
+ /* xscreensaver-getimage returns paths relative to the image directory
+ now, so leave the sub-directory part in. Unless it's an absolute path.
+ */
+ if (frame->loading.title && frame->loading.title[0] == '/')
+ { /* strip filename to part after last /. */
char *s = strrchr (frame->loading.title, '/');
if (s) strcpy (frame->loading.title, s+1);
}
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();
{
if (! ss->button_down_p)
ss->button_down_time = time((time_t *) 0);
- ss->button_down_p = True;
- gltrackball_start (ss->trackball,
- event->xbutton.x, event->xbutton.y,
- MI_WIDTH (mi), MI_HEIGHT (mi));
- return True;
}
else if (event->xany.type == ButtonRelease &&
event->xbutton.button == Button1)
for (i = 0; i < ss->nframes; i++)
ss->frames[i]->expires += secs;
}
- ss->button_down_p = False;
- return True;
- }
- else if (event->xany.type == ButtonPress &&
- (event->xbutton.button == Button4 ||
- event->xbutton.button == Button5 ||
- event->xbutton.button == Button6 ||
- event->xbutton.button == Button7))
- {
- gltrackball_mousewheel (ss->trackball, event->xbutton.button, 5,
- !event->xbutton.state);
- return True;
}
- else if (event->xany.type == MotionNotify &&
- ss->button_down_p)
+
+ if (gltrackball_event_handler (event, ss->trackball,
+ MI_WIDTH (mi), MI_HEIGHT (mi),
+ &ss->button_down_p))
+ return True;
+ else if (screenhack_event_helper (MI_DISPLAY(mi), MI_WINDOW(mi), event))
{
- gltrackball_track (ss->trackball,
- event->xmotion.x, event->xmotion.y,
- MI_WIDTH (mi), MI_HEIGHT (mi));
+ int i = random() % ss->nframes;
+ ss->frames[i]->expires = 0;
return True;
}
static void
hack_resources (Display *dpy)
{
-# ifndef HAVE_COCOA
+# ifndef HAVE_JWXYZ
char *res = "desktopGrabber";
char *val = get_string_resource (dpy, res, "DesktopGrabber");
char buf1[255];
value.addr = buf2;
value.size = strlen(buf2);
XrmPutResource (&db, buf1, "String", &value);
-# endif /* !HAVE_COCOA */
+# endif /* !HAVE_JWXYZ */
}
carousel_state *ss = &sss[MI_SCREEN(mi)];
int wire = MI_IS_WIREFRAME(mi);
char text[100];
- GLfloat scale;
if (wire) return;
sprintf (text, "Loading images... (%d%%)",
(int) (n * 100 / MI_COUNT(mi)));
- if (ss->loading_sw == 0) /* only do this once, so that the string doesn't move. */
- ss->loading_sw = texture_string_width (ss->texfont, text, &ss->loading_sh);
-
- scale = ss->loading_sh / (GLfloat) MI_HEIGHT(mi);
+ if (ss->loading_sw == 0)
+ {
+ /* only do this once, so that the string doesn't move. */
+ XCharStruct e;
+ texture_string_metrics (ss->titlefont, text, &e, 0, 0);
+ ss->loading_sw = e.width;
+ ss->loading_sh = e.ascent + e.descent;
+ }
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glLoadIdentity();
- gluOrtho2D(0, MI_WIDTH(mi), 0, MI_HEIGHT(mi));
+/*
+ {
+ double rot = current_device_rotation();
+ glRotatef(rot, 0, 0, 1);
+ if ((rot > 45 && rot < 135) ||
+ (rot < -45 && rot > -135))
+ {
+ GLfloat s = MI_WIDTH(mi) / (GLfloat) MI_HEIGHT(mi);
+ glScalef (s, 1/s, 1);
+ }
+ }
+*/
+
+# 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
+
+ glOrtho(0, MI_WIDTH(mi), 0, MI_HEIGHT(mi), -1, 1);
glTranslatef ((MI_WIDTH(mi) - ss->loading_sw) / 2,
(MI_HEIGHT(mi) - ss->loading_sh) / 2,
0);
glColor3f (1, 1, 0);
glEnable (GL_TEXTURE_2D);
glDisable (GL_DEPTH_TEST);
- print_texture_string (ss->texfont, text);
+ print_texture_string (ss->titlefont, text);
glEnable (GL_DEPTH_TEST);
glPopMatrix();
carousel_state *ss;
int wire = MI_IS_WIREFRAME(mi);
- if (sss == NULL) {
- if ((sss = (carousel_state *)
- calloc (MI_NUM_SCREENS(mi), sizeof(carousel_state))) == NULL)
- return;
- }
+ MI_INIT (mi, sss);
ss = &sss[screen];
if ((ss->glx_context = init_GL(mi)) != NULL) {
reshape_carousel (mi, MI_WIDTH(mi), MI_HEIGHT(mi));
+ clear_gl_error(); /* WTF? sometimes "invalid op" from glViewport! */
} else {
MI_CLEARWINDOW(mi);
}
ss->rot = make_rotator (spin_speed, spin_speed, spin_speed,
spin_accel, wander_speed, True);
- ss->trackball = gltrackball_init ();
+ ss->trackball = gltrackball_init (False);
}
if (strstr ((char *) glGetString(GL_EXTENSIONS),
}
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));
}
else /* Draw a title under the image. */
{
+ XCharStruct e;
int sw, sh;
GLfloat scale = 0.05;
char *title = frame->current.title ? frame->current.title : "(untitled)";
- sw = texture_string_width (ss->texfont, title, &sh);
+ texture_string_metrics (ss->texfont, title, &e, 0, 0);
+ sw = e.width;
+ sh = e.ascent + e.descent;
glTranslatef (0, -scale, 0);
glPushMatrix();
+ glRotatef(current_device_rotation(), 0, 0, 1);
+
/* Run the startup "un-shrink" animation.
*/