[gtk/subsurface-test] Flesh this out a bit




commit 5d49128bdc4690a57c9ceb62a9908cf9e3cedade
Author: Matthias Clasen <mclasen redhat com>
Date:   Thu May 26 09:40:30 2022 -0400

    Flesh this out a bit

 tests/subsurface.c | 232 +++++++++++++++++++++++++++++++++++++++++++++++++----
 1 file changed, 215 insertions(+), 17 deletions(-)
---
diff --git a/tests/subsurface.c b/tests/subsurface.c
index 8daf0ee433..707c1a6935 100644
--- a/tests/subsurface.c
+++ b/tests/subsurface.c
@@ -84,12 +84,14 @@ create_subsurface (struct wl_surface     *parent,
 static void
 surface_fill (struct wl_surface *surface,
               int                width,
-              int                height)
+              int                height,
+              const GdkRGBA     *c)
 {
   size_t size;
   const char *xdg_runtime_dir;
   int fd;
   guint32 *data;
+  guint32 pixel;
   struct wl_shm_pool *pool;
   struct wl_buffer *buffer;
 
@@ -99,9 +101,11 @@ surface_fill (struct wl_surface *surface,
   ftruncate (fd, size);
   data = mmap (NULL, size, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
 
+  pixel = 0xff000000 | ((int)(c->red * 255) << 16) | ((int)(c->green * 255) << 8) | ((int)c->blue * 255);
+
   for (int i = 0; i < height; i++)
     for (int j = 0; j < width; j++)
-      data[i * width + j] = 0xff00ff00;
+      data[i * width + j] = pixel;
 
   pool = wl_shm_create_pool (wl_shm, fd, size);
   buffer = wl_shm_pool_create_buffer (pool, 0, width, height, width * 4, WL_SHM_FORMAT_XRGB8888);
@@ -113,32 +117,226 @@ surface_fill (struct wl_surface *surface,
   wl_surface_commit (surface);
 }
 
-int
-main (int argc, char *argv[])
+#define DEMO_TYPE_WIDGET (demo_widget_get_type ())
+G_DECLARE_FINAL_TYPE (DemoWidget, demo_widget, DEMO, WIDGET, GtkWidget)
+
+GtkWidget * demo_widget_new       (void);
+
+void        demo_widget_add_child (DemoWidget *self,
+                                   GtkWidget  *child);
+
+struct _DemoWidget
 {
-  GtkWidget *window;
-  GdkSurface *surface;
+  GtkWidget parent_instance;
+
   struct wl_display *wl_display;
   struct wl_surface *parent;
   struct wl_surface *child;
   struct wl_subsurface *subsurface;
 
-  gtk_init ();
+  GdkRGBA color1;
+  GdkRGBA color2;
+  guint64 time2;
+  float t;
 
-  window = gtk_window_new ();
-  gtk_window_set_title (GTK_WINDOW (window), "hello world");
+  guint tick_cb;
 
-  gtk_widget_show (window);
+  GtkPopover *popover;
+};
+
+struct _DemoWidgetClass
+{
+  GtkWidgetClass parent_class;
+};
+
+G_DEFINE_TYPE (DemoWidget, demo_widget, GTK_TYPE_WIDGET)
+
+#define TIME_SPAN (3.0 * G_TIME_SPAN_SECOND)
+
+static gboolean
+change_color (GtkWidget     *widget,
+              GdkFrameClock *frame_clock,
+              gpointer       data)
+{
+  DemoWidget *demo = DEMO_WIDGET (widget);
+  gint64 time;
+
+  time = gdk_frame_clock_get_frame_time (frame_clock);
+
+  if (time >= demo->time2)
+    {
+      demo->time2 = time + TIME_SPAN;
+
+      demo->color1 = demo->color2;
+      demo->color2.red = g_random_double_range (0, 1);
+      demo->color2.green = g_random_double_range (0, 1);
+      demo->color2.blue = g_random_double_range (0, 1);
+      demo->color2.alpha = 1;
+    }
+
+  demo->t = 1 - (demo->time2 - time) / TIME_SPAN;
+
+  gtk_widget_queue_draw (widget);
+
+  return G_SOURCE_CONTINUE;
+}
+
+static void
+pressed_cb (GtkGesture *gesture,
+            int         n_press,
+            double      x,
+            double      y,
+            gpointer    data)
+{
+  DemoWidget *demo = data;
+
+  gtk_popover_set_pointing_to (demo->popover, &(GdkRectangle){ x, y, 1, 1 });
+  gtk_popover_popup (demo->popover);
+}
+
+static void
+clicked_cb (GtkButton *button,
+            gpointer   data)
+{
+  DemoWidget *demo = data;
+
+  gtk_popover_popdown (demo->popover);
+}
+
+static void
+demo_widget_init (DemoWidget *demo)
+{
+  GtkWidget *button;
+  GtkGesture *controller;
+
+  gtk_widget_add_tick_callback (GTK_WIDGET (demo), change_color, NULL, NULL);
+
+  demo->popover = GTK_POPOVER (gtk_popover_new ());
+  gtk_widget_set_parent (GTK_WIDGET (demo->popover), GTK_WIDGET (demo));
+  button = gtk_button_new_with_label ("OK");
+  g_signal_connect (button, "clicked", G_CALLBACK (clicked_cb), demo);
+  gtk_popover_set_child (demo->popover, button);
+
+  controller = gtk_gesture_click_new ();
+  g_signal_connect (controller, "pressed", G_CALLBACK (pressed_cb), demo);
+  gtk_widget_add_controller (GTK_WIDGET (demo), GTK_EVENT_CONTROLLER (controller));
+}
+
+static void
+demo_widget_dispose (GObject *object)
+{
+  //DemoWidget *demo = DEMO_WIDGET (object);
 
-  surface = gtk_native_get_surface (GTK_NATIVE (window));
+  G_OBJECT_CLASS (demo_widget_parent_class)->dispose (object);
+}
+
+static void
+demo_widget_realize (GtkWidget *widget)
+{
+  DemoWidget *demo = DEMO_WIDGET (widget);
+  GdkSurface *surface;
+
+  GTK_WIDGET_CLASS (demo_widget_parent_class)->realize (widget);
+
+  demo->wl_display = gdk_wayland_display_get_wl_display (gtk_widget_get_display (widget));
+  surface = gtk_native_get_surface (gtk_widget_get_native (widget));
+  demo->parent = gdk_wayland_surface_get_wl_surface (surface);
+
+  set_up_registry (demo->wl_display);
+  create_subsurface (demo->parent, &demo->child, &demo->subsurface);
+}
+
+static void
+demo_widget_unrealize (GtkWidget *widget)
+{
+  GTK_WIDGET_CLASS (demo_widget_parent_class)->unrealize (widget);
 
-  wl_display = gdk_wayland_display_get_wl_display (gdk_display_get_default ());
-  parent = gdk_wayland_surface_get_wl_surface (surface);
+  /* FIXME */
+}
+
+static void
+demo_widget_measure (GtkWidget      *widget,
+                     GtkOrientation  orientation,
+                     int             for_size,
+                     int            *minimum_size,
+                     int            *natural_size,
+                     int            *minimum_baseline,
+                     int            *natural_baseline)
+{
+  *minimum_size = 100;
+  *natural_size = 200;
+}
+
+static void
+demo_widget_size_allocate (GtkWidget *widget,
+                           int        width,
+                           int        height,
+                           int        baseline)
+{
+  DemoWidget *demo = DEMO_WIDGET (widget);
+  GtkNative *native;
+  double x0, y0, x, y;
+
+  native = gtk_widget_get_native (widget);
+  gtk_native_get_surface_transform (native, &x0, &y0);
+  gtk_widget_translate_coordinates (widget,
+                                    GTK_WIDGET (native),
+                                    0, 0,
+                                    &x, &y);
+  wl_subsurface_set_position (demo->subsurface, x0 + x + 40, y0 + y + 40);
 
-  set_up_registry (wl_display);
-  create_subsurface (parent, &child, &subsurface);
-  wl_subsurface_set_position (subsurface, 100, 100);
-  surface_fill (child, 100, 100);
+  gtk_popover_present (demo->popover);
+}
+
+static void
+demo_widget_snapshot (GtkWidget   *widget,
+                      GtkSnapshot *snapshot)
+{
+  DemoWidget *demo = DEMO_WIDGET (widget);
+  int width, height;
+  GdkRGBA c;
+
+  width = gtk_widget_get_width (widget);
+  height = gtk_widget_get_height (widget);
+
+  c.red = (1 - demo->t) * demo->color1.red + demo->t * demo->color2.red;
+  c.green = (1 - demo->t) * demo->color1.green + demo->t * demo->color2.green;
+  c.blue = (1 - demo->t) * demo->color1.blue + demo->t * demo->color2.blue;
+  c.alpha = 1;
+
+  surface_fill (demo->child, width - 80, height - 80, &c);
+}
+
+static void
+demo_widget_class_init (DemoWidgetClass *class)
+{
+  GObjectClass *object_class = G_OBJECT_CLASS (class);
+  GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (class);
+
+  object_class->dispose = demo_widget_dispose;
+
+  widget_class->realize = demo_widget_realize;
+  widget_class->unrealize = demo_widget_unrealize;
+  widget_class->measure = demo_widget_measure;
+  widget_class->size_allocate = demo_widget_size_allocate;
+  widget_class->snapshot = demo_widget_snapshot;
+}
+
+int
+main (int argc, char *argv[])
+{
+  GtkWidget *window;
+  GtkWidget *child;
+
+  gtk_init ();
+
+  window = gtk_window_new ();
+  gtk_window_set_title (GTK_WINDOW (window), "hello subsurface");
+
+  child = g_object_new (demo_widget_get_type (), NULL);
+  gtk_window_set_child (GTK_WINDOW (window), child);
+
+  gtk_widget_show (window);
 
   while (TRUE)
     g_main_context_iteration (NULL, TRUE);


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]