#include typedef struct _GtkTextureView GtkTextureView; typedef struct _GtkTextureViewClass GtkTextureViewClass; #define GTK_TYPE_TEXTURE_VIEW (gtk_texture_view_get_type ()) #define GTK_TEXTURE_VIEW(obj) (G_TYPE_CHECK_INSTANCE_CAST(obj, GTK_TYPE_TEXTURE_VIEW, GtkTextureView)) #define GTK_TEXTURE_VIEW_CLASS(cls) (G_TYPE_CHECK_CLASS_CAST(cls, GTK_TYPE_TEXTURE_VIEW, GtkTextureViewClass)) struct _GtkTextureView { GtkWidget parent_instance; GdkTexture *texture; }; struct _GtkTextureViewClass { GtkWidgetClass parent_class; }; GType gtk_texture_view_get_type (void) G_GNUC_CONST; G_DEFINE_TYPE(GtkTextureView, gtk_texture_view, GTK_TYPE_WIDGET) static void gtk_texture_view_measure (GtkWidget *widget, GtkOrientation orientation, int for_size, int *minimum, int *natural, int *minimum_baseline, int *natural_baseline) { GtkTextureView *self = GTK_TEXTURE_VIEW (widget); if (self->texture == NULL) return; if (orientation == GTK_ORIENTATION_HORIZONTAL) { *minimum = 0; *natural = gdk_texture_get_width (self->texture); } else /* VERTICAL */ { *minimum = 0; *natural = gdk_texture_get_height (self->texture); } } static void gtk_texture_view_snapshot (GtkWidget *widget, GtkSnapshot *snapshot) { GtkTextureView *self = GTK_TEXTURE_VIEW (widget); int width = gtk_widget_get_width (widget); int height = gtk_widget_get_height (widget); if (self->texture != NULL) { graphene_rect_t bounds; bounds.origin.x = MAX (0, width / 2 - gdk_texture_get_width (self->texture)); bounds.origin.y = MAX (0, height / 2 - gdk_texture_get_height (self->texture)); bounds.size.width = MIN (width, gdk_texture_get_width (self->texture)); bounds.size.height = MIN (height, gdk_texture_get_height (self->texture)); gtk_snapshot_append_texture (snapshot, self->texture, &bounds); } } static void gtk_texture_view_finalize (GObject *object) { GtkTextureView *self = GTK_TEXTURE_VIEW (object); g_clear_object (&self->texture); G_OBJECT_CLASS (gtk_texture_view_parent_class)->finalize (object); } static void gtk_texture_view_init (GtkTextureView *self) { } static void gtk_texture_view_class_init (GtkTextureViewClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS (klass); GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass); object_class->finalize = gtk_texture_view_finalize; widget_class->measure = gtk_texture_view_measure; widget_class->snapshot = gtk_texture_view_snapshot; } static void quit_cb (GtkWidget *widget, gpointer data) { gboolean *done = data; *done = TRUE; g_main_context_wakeup (NULL); } int main (int argc, char **argv) { GtkWidget *window; GtkWidget *view; GdkTexture *texture; GFile *file; GError *error = NULL; gboolean done = FALSE; gtk_init (); if (argc != 2) { g_error ("No texture file path given."); return -1; } file = g_file_new_for_path (argv[1]); texture = gdk_texture_new_from_file (file, &error); if (error != NULL) { g_error ("Error: %s", error->message); return -1; } window = gtk_window_new (); g_signal_connect (window, "destroy", G_CALLBACK (quit_cb), &done); view = g_object_new (GTK_TYPE_TEXTURE_VIEW, NULL); ((GtkTextureView*)view)->texture = g_steal_pointer (&texture); gtk_window_set_child (GTK_WINDOW (window), view); gtk_window_present (GTK_WINDOW (window)); while (!done) g_main_context_iteration (NULL, TRUE); g_object_unref (file); return 0; }