172 lines
4.2 KiB
C++
172 lines
4.2 KiB
C++
|
|
#include "GnomeScreensaver.h"
|
|
|
|
#define MAX_ASPECT (16.0/9.0*1.02)
|
|
|
|
static gboolean
|
|
expose (GtkWidget *da, GdkEventExpose *event, GnomeScreensaver *gs)
|
|
{
|
|
return gs->exposeCB(da, event);
|
|
}
|
|
|
|
static gboolean
|
|
configure (GtkWidget *da, GdkEventConfigure *event, GnomeScreensaver *gs)
|
|
{
|
|
return gs->configureCB(da, event);
|
|
}
|
|
|
|
static gboolean
|
|
update (void *gs)
|
|
{
|
|
return ((GnomeScreensaver *)gs)->updateCB();
|
|
}
|
|
|
|
GnomeScreensaver::GnomeScreensaver(int *argc, char ***argv,
|
|
bool (*configure_callback)(GnomeScreensaver &),
|
|
bool (*expose_callback)(GnomeScreensaver &),
|
|
bool (*update_callback)(GnomeScreensaver &),
|
|
int32_t interval_msec)
|
|
: m_configure_callback(configure_callback),
|
|
m_expose_callback(expose_callback),
|
|
m_update_callback(update_callback)
|
|
{
|
|
gchar *geometry = NULL;
|
|
GOptionEntry options[] = {
|
|
{"geometry", 0, 0, G_OPTION_ARG_STRING, &geometry,
|
|
N_("The initial size and position of window"),
|
|
N_("WIDTHxHEIGHT+X+Y")},
|
|
{NULL}
|
|
};
|
|
|
|
GtkWidget *window;
|
|
GdkGLConfig *glconfig;
|
|
GtkStateType state;
|
|
GError *error = NULL;
|
|
|
|
struct timeval tv;
|
|
gettimeofday(&tv, NULL);
|
|
m_start_msec = tv.tv_sec * 1000 + tv.tv_usec / 1000;
|
|
|
|
m_n_monitors = 1;
|
|
|
|
gtk_init_with_args (argc, argv,
|
|
_(""),
|
|
options, NULL, &error);
|
|
gtk_gl_init(argc, argv);
|
|
|
|
if (error != NULL)
|
|
{
|
|
g_printerr (_("%s. See --help for usage information.\n"),
|
|
_(error->message));
|
|
g_error_free (error);
|
|
}
|
|
|
|
window = gs_theme_window_new ();
|
|
|
|
g_signal_connect (G_OBJECT (window), "delete-event",
|
|
G_CALLBACK (gtk_main_quit), NULL);
|
|
|
|
m_drawing_area = gtk_drawing_area_new ();
|
|
|
|
glconfig = gdk_gl_config_new_by_mode( (GdkGLConfigMode)
|
|
( GDK_GL_MODE_RGB |
|
|
GDK_GL_MODE_DEPTH |
|
|
GDK_GL_MODE_DOUBLE ) );
|
|
|
|
if (!glconfig)
|
|
{
|
|
g_assert_not_reached();
|
|
}
|
|
if (!gtk_widget_set_gl_capability(m_drawing_area, glconfig, NULL, TRUE,
|
|
GDK_GL_RGBA_TYPE))
|
|
{
|
|
g_assert_not_reached();
|
|
}
|
|
|
|
g_signal_connect(m_drawing_area, "configure-event",
|
|
G_CALLBACK(configure), this);
|
|
g_signal_connect(m_drawing_area, "expose-event",
|
|
G_CALLBACK(expose), this);
|
|
|
|
gtk_widget_show (m_drawing_area);
|
|
gtk_container_add (GTK_CONTAINER (window), m_drawing_area);
|
|
|
|
if ((geometry == NULL)
|
|
|| !gtk_window_parse_geometry (GTK_WINDOW (window), geometry))
|
|
{
|
|
gtk_window_set_default_size (GTK_WINDOW (window), 800, 600);
|
|
}
|
|
|
|
gtk_widget_show (window);
|
|
|
|
gtk_timeout_add(interval_msec, update, this);
|
|
}
|
|
|
|
uint64_t GnomeScreensaver::getTicks()
|
|
{
|
|
struct timeval tv;
|
|
gettimeofday(&tv, NULL);
|
|
uint64_t msec = tv.tv_sec * 1000 + tv.tv_usec / 1000;
|
|
return msec - m_start_msec;
|
|
}
|
|
|
|
gboolean GnomeScreensaver::exposeCB(GtkWidget *da, GdkEventExpose *event)
|
|
{
|
|
GdkGLContext *glcontext = gtk_widget_get_gl_context(da);
|
|
GdkGLDrawable *gldrawable = gtk_widget_get_gl_drawable(da);
|
|
|
|
if (!gdk_gl_drawable_gl_begin(gldrawable, glcontext))
|
|
{
|
|
g_assert_not_reached();
|
|
}
|
|
|
|
gboolean rc = m_expose_callback(*this);
|
|
|
|
if (gdk_gl_drawable_is_double_buffered(gldrawable))
|
|
gdk_gl_drawable_swap_buffers(gldrawable);
|
|
else
|
|
glFlush();
|
|
|
|
gdk_gl_drawable_gl_end(gldrawable);
|
|
|
|
return rc;
|
|
}
|
|
|
|
gboolean GnomeScreensaver::configureCB(GtkWidget *da, GdkEventConfigure *event)
|
|
{
|
|
GdkGLContext *glcontext = gtk_widget_get_gl_context(da);
|
|
GdkGLDrawable *gldrawable = gtk_widget_get_gl_drawable(da);
|
|
|
|
if (!gdk_gl_drawable_gl_begin(gldrawable, glcontext))
|
|
{
|
|
g_assert_not_reached();
|
|
}
|
|
|
|
m_width = da->allocation.width;
|
|
m_height = da->allocation.height;
|
|
|
|
for (m_n_monitors = 1;
|
|
(double)m_width/(double)m_n_monitors/(double)m_height > MAX_ASPECT;
|
|
m_n_monitors++)
|
|
;
|
|
|
|
m_aspect_ratio = (float)m_width / (float)m_height;
|
|
|
|
gboolean rc = m_configure_callback(*this);
|
|
|
|
gdk_gl_drawable_gl_end(gldrawable);
|
|
|
|
return rc;
|
|
}
|
|
|
|
gboolean GnomeScreensaver::updateCB()
|
|
{
|
|
gboolean rc = m_update_callback(*this);
|
|
if (rc)
|
|
{
|
|
gtk_widget_queue_draw(m_drawing_area);
|
|
}
|
|
return rc;
|
|
}
|
|
|