mirror of
https://gitlab.gnome.org/GNOME/gtk.git
synced 2024-11-05 16:20:10 +00:00
574301d34d
Clean up the code with a #define for circle size. This also allows determining we're throttled by number-of-requests or number-of-pixels. https://bugzilla.gnome.org/show_bug.cgi?id=685460
201 lines
5.4 KiB
C
201 lines
5.4 KiB
C
/* -*- mode: C; c-basic-offset: 2; indent-tabs-mode: nil; -*- */
|
|
|
|
#include <gtk/gtk.h>
|
|
#include <math.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;
|
|
|
|
static double angle;
|
|
static int frames_since_last_print = 0;
|
|
|
|
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_window_draw (GtkWidget *widget,
|
|
cairo_t *cr)
|
|
|
|
{
|
|
GRand *rand = g_rand_new_with_seed(0);
|
|
int i;
|
|
int width, height;
|
|
|
|
width = gtk_widget_get_allocated_width (widget);
|
|
height = gtk_widget_get_allocated_height (widget);
|
|
|
|
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 (GtkTimeline *timeline,
|
|
double progress)
|
|
{
|
|
int jitter;
|
|
double current_time;
|
|
static double last_print_time = 0;
|
|
|
|
current_time = g_get_monotonic_time () / 1000000.;
|
|
if (current_time >= last_print_time + 5)
|
|
{
|
|
if (frames_since_last_print != 0)
|
|
{
|
|
g_print ("%g\n", frames_since_last_print / (current_time - last_print_time));
|
|
frames_since_last_print = 0;
|
|
}
|
|
|
|
last_print_time = current_time;
|
|
}
|
|
frames_since_last_print++;
|
|
|
|
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 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;
|
|
GdkScreen *screen;
|
|
GdkRectangle monitor_bounds;
|
|
GtkTimeline *timeline;
|
|
|
|
if (!gtk_init_with_args (&argc, &argv, "",
|
|
options, NULL, NULL))
|
|
{
|
|
g_printerr ("Option parsing failed: %s", error->message);
|
|
return 1;
|
|
}
|
|
|
|
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
|
|
gtk_window_set_keep_above (GTK_WINDOW (window), TRUE);
|
|
gtk_window_set_gravity (GTK_WINDOW (window), GDK_GRAVITY_CENTER);
|
|
gtk_widget_set_app_paintable (window, TRUE);
|
|
|
|
g_signal_connect (window, "draw",
|
|
G_CALLBACK (on_window_draw), NULL);
|
|
g_signal_connect (window, "destroy",
|
|
G_CALLBACK (gtk_main_quit), NULL);
|
|
|
|
timeline = gtk_timeline_new (window, CYCLE_TIME * 1000);
|
|
gtk_timeline_set_loop (timeline, TRUE);
|
|
gtk_timeline_set_progress_type (timeline, GTK_TIMELINE_PROGRESS_LINEAR);
|
|
|
|
g_signal_connect (timeline, "frame",
|
|
G_CALLBACK (on_frame), NULL);
|
|
on_frame (timeline, 0.);
|
|
gtk_timeline_start (timeline);
|
|
|
|
screen = gtk_widget_get_screen (window);
|
|
gdk_screen_get_monitor_geometry (screen,
|
|
gdk_screen_get_primary_monitor (screen),
|
|
&monitor_bounds);
|
|
|
|
gtk_window_move (GTK_WINDOW (window),
|
|
monitor_bounds.x + (monitor_bounds.width - window_width) / 2,
|
|
monitor_bounds.y + (monitor_bounds.height - window_height) / 2);
|
|
|
|
gtk_widget_show (window);
|
|
|
|
gtk_main ();
|
|
|
|
return 0;
|
|
}
|