gtk/tests/animated-resizing.c
Matthias Clasen a46f9af1c0 Remove primary monitor api
We only have implementations of this on X11 and Win32,
so make it available as backend api there.

Update all callers to use either the backend api, or
just monitor 0.
2020-01-30 21:33:37 +01:00

213 lines
5.3 KiB
C

/* -*- mode: C; c-basic-offset: 2; indent-tabs-mode: nil; -*- */
#include <gtk/gtk.h>
#include <math.h>
#include <string.h>
#include "frame-stats.h"
#define RADIUS 64
#define DIAMETER (2*RADIUS)
#define WIDTH 600
#define HEIGHT 600
#define WINDOW_SIZE_JITTER 200
#define CYCLE_TIME 5.
static GtkWidget *window;
static int window_width = WIDTH, window_height = HEIGHT;
gint64 start_frame_time;
static double angle;
static double load_factor = 1.0;
static double cb_no_resize = FALSE;
static cairo_surface_t *source_surface;
static void
ensure_resources(cairo_surface_t *target)
{
cairo_t *cr;
int i, j;
if (source_surface != NULL)
return;
source_surface = cairo_surface_create_similar (target, CAIRO_CONTENT_COLOR_ALPHA,
16 * DIAMETER, 16 * DIAMETER);
cr = cairo_create(source_surface);
cairo_save(cr);
cairo_set_source_rgba(cr, 0, 0, 0, 0);
cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE);
cairo_paint(cr);
cairo_restore(cr);
cairo_set_line_width(cr, 1.0);
for (j = 0; j < 16; j++)
for (i = 0; i < 16; i++)
{
cairo_set_source_rgba(cr,
((i * 41) % 16) / 15.,
((i * 31) % 16) / 15.,
((i * 23) % 16) / 15.,
0.25);
cairo_arc(cr,
i * DIAMETER + RADIUS, j * DIAMETER + RADIUS,
RADIUS - 0.5, 0, 2 * M_PI);
cairo_fill_preserve(cr);
cairo_set_source_rgba(cr,
((i * 41) % 16) / 15.,
((i * 31) % 16) / 15.,
((i * 23) % 16) / 15.,
1.0);
cairo_stroke(cr);
}
}
static void
on_draw (GtkDrawingArea *da,
cairo_t *cr,
int width,
int height,
gpointer data)
{
GRand *rand = g_rand_new_with_seed(0);
int i;
ensure_resources (cairo_get_target (cr));
cairo_set_source_rgb(cr, 1, 1, 1);
cairo_paint(cr);
cairo_set_source_rgb(cr, 0, 0, 0);
cairo_set_line_width(cr, 1.0);
cairo_rectangle (cr, 0.5, 0.5, width - 1, height - 1);
cairo_stroke (cr);
for(i = 0; i < load_factor * 150; i++)
{
int source = g_rand_int_range(rand, 0, 255);
double phi = g_rand_double_range(rand, 0, 2 * M_PI) + angle;
double r = g_rand_double_range(rand, 0, width / 2 - RADIUS);
int x, y;
int source_x = (source % 16) * DIAMETER;
int source_y = (source / 16) * DIAMETER;
x = round(width / 2 + r * cos(phi) - RADIUS);
y = round(height / 2 - r * sin(phi) - RADIUS);
cairo_set_source_surface(cr, source_surface,
x - source_x, y - source_y);
cairo_rectangle(cr, x, y, DIAMETER, DIAMETER);
cairo_fill(cr);
}
g_rand_free(rand);
}
static void
on_frame (double progress)
{
int jitter;
angle = 2 * M_PI * progress;
jitter = WINDOW_SIZE_JITTER * sin(angle);
if (!cb_no_resize)
{
window_width = WIDTH + jitter;
window_height = HEIGHT + jitter;
}
gtk_window_resize (GTK_WINDOW (window),
window_width, window_height);
gtk_widget_queue_draw (window);
}
static gboolean
tick_callback (GtkWidget *widget,
GdkFrameClock *frame_clock,
gpointer user_data)
{
gint64 frame_time = gdk_frame_clock_get_frame_time (frame_clock);
double scaled_time;
if (start_frame_time == 0)
start_frame_time = frame_time;
scaled_time = (frame_time - start_frame_time) / (CYCLE_TIME * 1000000);
on_frame (scaled_time - floor (scaled_time));
return G_SOURCE_CONTINUE;
}
static gboolean
on_map (GtkWidget *widget)
{
gtk_widget_add_tick_callback (window, tick_callback, NULL, NULL);
return FALSE;
}
static GOptionEntry options[] = {
{ "factor", 'f', 0, G_OPTION_ARG_DOUBLE, &load_factor, "Load factor", "FACTOR" },
{ "no-resize", 'n', 0, G_OPTION_ARG_NONE, &cb_no_resize, "No Resize", NULL },
{ NULL }
};
int
main(int argc, char **argv)
{
GError *error = NULL;
GtkWidget *da;
GdkDisplay *display;
GdkMonitor *monitor;
GdkRectangle monitor_bounds;
GOptionContext *context = g_option_context_new (NULL);
g_option_context_add_main_entries (context, options, NULL);
frame_stats_add_options (g_option_context_get_main_group (context));
if (!g_option_context_parse (context, &argc, &argv, &error))
{
g_printerr ("Option parsing failed: %s\n", error->message);
return 1;
}
gtk_init ();
g_print ("# Load factor: %g\n",
load_factor);
g_print ("# Resizing?: %s\n",
cb_no_resize ? "no" : "yes");
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
frame_stats_ensure (GTK_WINDOW (window));
da = gtk_drawing_area_new ();
gtk_drawing_area_set_draw_func (GTK_DRAWING_AREA (da), on_draw, NULL, NULL);
gtk_container_add (GTK_CONTAINER (window), da);
g_signal_connect (window, "destroy",
G_CALLBACK (gtk_main_quit), NULL);
g_signal_connect (window, "map",
G_CALLBACK (on_map), NULL);
on_frame (0.);
display = gtk_widget_get_display (window);
monitor = gdk_display_get_monitor (display, 0);
gdk_monitor_get_geometry (monitor, &monitor_bounds);
gtk_widget_show (window);
gtk_main ();
return 0;
}