[gtk+] inspector: Add more infrastructure



commit e6f711a94ac48dcc747b0a9c38d152b4a7963b0d
Author: Benjamin Otte <otte redhat com>
Date:   Sun Oct 30 06:11:38 2016 +0100

    inspector: Add more infrastructure
    
    This one introduces the Recording object which is essentially a single
    instance of something that happened.
    The RenderRecording is an instance of an actual rendering operation.

 gtk/gtkwidget.c                 |    4 ++
 gtk/inspector/Makefile.inc      |    4 ++
 gtk/inspector/recorder.c        |   67 ++++++++++++++++++++++++-
 gtk/inspector/recorder.h        |   10 +++-
 gtk/inspector/recorder.ui       |    2 +-
 gtk/inspector/recording.c       |  104 +++++++++++++++++++++++++++++++++++++++
 gtk/inspector/recording.h       |   55 ++++++++++++++++++++
 gtk/inspector/renderrecording.c |   68 +++++++++++++++++++++++++
 gtk/inspector/renderrecording.h |   64 ++++++++++++++++++++++++
 gtk/inspector/window.c          |   32 ++++++++++++
 gtk/inspector/window.h          |    5 ++
 11 files changed, 411 insertions(+), 4 deletions(-)
---
diff --git a/gtk/gtkwidget.c b/gtk/gtkwidget.c
index cdb69f4..f7879b6 100644
--- a/gtk/gtkwidget.c
+++ b/gtk/gtkwidget.c
@@ -68,6 +68,8 @@
 #include "gtkgestureprivate.h"
 #include "gtkwidgetpathprivate.h"
 
+#include "inspector/window.h"
+
 /* for the use of round() */
 #include "fallback-c89.c"
 
@@ -15748,6 +15750,8 @@ gtk_widget_render (GtkWidget            *widget,
   if (root == NULL)
     return;
 
+  gtk_inspector_record_render (widget, window, region, root);
+
   context = gdk_window_begin_draw_frame (window, region);
 
   gsk_renderer_render (renderer, root, context);
diff --git a/gtk/inspector/Makefile.inc b/gtk/inspector/Makefile.inc
index 61adc38..7d3ed8e 100644
--- a/gtk/inspector/Makefile.inc
+++ b/gtk/inspector/Makefile.inc
@@ -20,6 +20,8 @@ inspector_c_sources =                         \
        inspector/prop-editor.c         \
        inspector/prop-list.c           \
        inspector/recorder.c            \
+       inspector/recording.c           \
+       inspector/renderrecording.c     \
        inspector/resource-list.c       \
        inspector/selector.c            \
        inspector/signals-list.c        \
@@ -51,6 +53,8 @@ inspector_h_sources =                         \
        inspector/prop-editor.h         \
        inspector/prop-list.h           \
        inspector/recorder.h            \
+       inspector/recording.h           \
+       inspector/renderrecording.h     \
        inspector/resource-list.h       \
        inspector/selector.h            \
        inspector/signals-list.h        \
diff --git a/gtk/inspector/recorder.c b/gtk/inspector/recorder.c
index c545552..691954f 100644
--- a/gtk/inspector/recorder.c
+++ b/gtk/inspector/recorder.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014 Red Hat, Inc.
+ * Copyright (c) 2016 Red Hat, Inc.
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -20,21 +20,63 @@
 
 #include "recorder.h"
 
+#include <gtk/gtklabel.h>
+#include <gtk/gtklistbox.h>
+
+#include "recording.h"
+#include "renderrecording.h"
+
 struct _GtkInspectorRecorderPrivate
 {
   GListStore *recordings;
+  GtkWidget *recordings_list;
 };
 
 G_DEFINE_TYPE_WITH_PRIVATE (GtkInspectorRecorder, gtk_inspector_recorder, GTK_TYPE_BIN)
 
+static GtkWidget *
+gtk_inspector_recorder_recordings_list_create_widget (gpointer item,
+                                                      gpointer user_data)
+{
+  GtkInspectorRecording *recording = GTK_INSPECTOR_RECORDING (item);
+  GtkWidget *widget;
+  char *str;
+
+  str = g_strdup_printf ("Cute drawing at time %lld", (long long) gtk_inspector_recording_get_timestamp 
(recording));
+  widget = gtk_label_new (str);
+  g_free (str);
+  gtk_widget_show_all (widget);
+
+  return widget;
+}
+
+static void
+gtk_inspector_recorder_constructed (GObject *object)
+{
+  GtkInspectorRecorder *recorder = GTK_INSPECTOR_RECORDER (object);
+  GtkInspectorRecorderPrivate *priv = gtk_inspector_recorder_get_instance_private (recorder);
+
+  G_OBJECT_CLASS (gtk_inspector_recorder_parent_class)->constructed (object);
+
+  gtk_list_box_bind_model (GTK_LIST_BOX (priv->recordings_list),
+                           G_LIST_MODEL (priv->recordings),
+                           gtk_inspector_recorder_recordings_list_create_widget,
+                           NULL,
+                           NULL);
+}
+
 static void
 gtk_inspector_recorder_class_init (GtkInspectorRecorderClass *klass)
 {
   GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
+  GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+  object_class->constructed = gtk_inspector_recorder_constructed;
 
   gtk_widget_class_set_template_from_resource (widget_class, "/org/gtk/libgtk/inspector/recorder.ui");
 
   gtk_widget_class_bind_template_child_private (widget_class, GtkInspectorRecorder, recordings);
+  gtk_widget_class_bind_template_child_private (widget_class, GtkInspectorRecorder, recordings_list);
 }
 
 static void
@@ -43,4 +85,27 @@ gtk_inspector_recorder_init (GtkInspectorRecorder *vis)
   gtk_widget_init_template (GTK_WIDGET (vis));
 }
 
+void
+gtk_inspector_recorder_record_render (GtkInspectorRecorder *recorder,
+                                      GtkWidget            *widget,
+                                      GdkWindow            *window,
+                                      const cairo_region_t *region,
+                                      GskRenderNode        *node)
+{
+  GtkInspectorRecorderPrivate *priv = gtk_inspector_recorder_get_instance_private (recorder);
+  GtkInspectorRecording *recording;
+  GdkFrameClock *frame_clock;
+
+  frame_clock = gtk_widget_get_frame_clock (widget);
+
+  recording = gtk_inspector_render_recording_new (gdk_frame_clock_get_frame_time (frame_clock),
+                                                  &(GdkRectangle) { 0, 0,
+                                                    gdk_window_get_width (window),
+                                                    gdk_window_get_height (window) },
+                                                  region,
+                                                  node);
+  g_list_store_append (priv->recordings, recording);
+  g_object_unref (recording);
+}
+
 // vim: set et sw=2 ts=2:
diff --git a/gtk/inspector/recorder.h b/gtk/inspector/recorder.h
index 7684a7c..7f0980b 100644
--- a/gtk/inspector/recorder.h
+++ b/gtk/inspector/recorder.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014 Red Hat, Inc.
+ * Copyright (c) 2016 Red Hat, Inc.
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -42,7 +42,13 @@ typedef struct _GtkInspectorRecorderClass
 
 G_BEGIN_DECLS
 
-GType      gtk_inspector_recorder_get_type   (void);
+GType      gtk_inspector_recorder_get_type              (void);
+
+void       gtk_inspector_recorder_record_render         (GtkInspectorRecorder   *recorder,
+                                                         GtkWidget              *widget,
+                                                         GdkWindow              *window,
+                                                         const cairo_region_t   *region,
+                                                         GskRenderNode          *node);
 
 G_END_DECLS
 
diff --git a/gtk/inspector/recorder.ui b/gtk/inspector/recorder.ui
index ca23b23..32952b7 100644
--- a/gtk/inspector/recorder.ui
+++ b/gtk/inspector/recorder.ui
@@ -12,7 +12,7 @@
             <property name="visible">True</property>
             <property name="orientation">horizontal</property>
             <child>
-              <object class="GtkListBox" id="visual_box">
+              <object class="GtkListBox" id="recordings_list">
                 <property name="visible">True</property>
                 <property name="selection-mode">single</property>
               </object>
diff --git a/gtk/inspector/recording.c b/gtk/inspector/recording.c
new file mode 100644
index 0000000..b51e0ae
--- /dev/null
+++ b/gtk/inspector/recording.c
@@ -0,0 +1,104 @@
+/*
+ * Copyright (c) 2016 Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "config.h"
+#include <glib/gi18n-lib.h>
+
+#include "recording.h"
+
+enum
+{
+  PROP_0,
+  PROP_TIMESTAMP,
+  LAST_PROP
+};
+
+static GParamSpec *props[LAST_PROP] = { NULL, };
+
+
+G_DEFINE_TYPE (GtkInspectorRecording, gtk_inspector_recording, G_TYPE_OBJECT)
+
+static void
+gtk_inspector_recording_get_property (GObject    *object,
+                                      guint       param_id,
+                                      GValue     *value,
+                                      GParamSpec *pspec)
+{
+  GtkInspectorRecording *recording = GTK_INSPECTOR_RECORDING (object);
+
+  switch (param_id)
+    {
+    case PROP_TIMESTAMP:
+      g_value_set_int64 (value, recording->timestamp);
+      break;
+
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
+      break;
+    }
+}
+
+static void
+gtk_inspector_recording_set_property (GObject      *object,
+                                      guint         param_id,
+                                      const GValue *value,
+                                      GParamSpec   *pspec)
+{
+  GtkInspectorRecording *recording = GTK_INSPECTOR_RECORDING (object);
+
+  switch (param_id)
+    {
+    case PROP_TIMESTAMP:
+      recording->timestamp = g_value_get_int64 (value);
+      break;
+
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
+      break;
+    }
+}
+
+static void
+gtk_inspector_recording_class_init (GtkInspectorRecordingClass *klass)
+{
+  GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+  object_class->get_property = gtk_inspector_recording_get_property;
+  object_class->set_property = gtk_inspector_recording_set_property;
+
+  props[PROP_TIMESTAMP] =
+    g_param_spec_int64 ("timestamp",
+                        "Timestamp",
+                        "Timestamp when this event was recorded",
+                        G_MININT64, G_MAXINT64, 0,
+                        G_PARAM_READWRITE | G_PARAM_CONSTRUCT);
+
+  g_object_class_install_properties (object_class, LAST_PROP, props);
+}
+
+static void
+gtk_inspector_recording_init (GtkInspectorRecording *vis)
+{
+}
+
+gint64
+gtk_inspector_recording_get_timestamp (GtkInspectorRecording *recording)
+{
+  return recording->timestamp;
+}
+
+// vim: set et sw=2 ts=2:
diff --git a/gtk/inspector/recording.h b/gtk/inspector/recording.h
new file mode 100644
index 0000000..dddfdc4
--- /dev/null
+++ b/gtk/inspector/recording.h
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2016 Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _GTK_INSPECTOR_RECORDING_H_
+#define _GTK_INSPECTOR_RECORDING_H_
+
+#include <glib-object.h>
+
+#define GTK_TYPE_INSPECTOR_RECORDING            (gtk_inspector_recording_get_type())
+#define GTK_INSPECTOR_RECORDING(obj)            (G_TYPE_CHECK_INSTANCE_CAST((obj), 
GTK_TYPE_INSPECTOR_RECORDING, GtkInspectorRecording))
+#define GTK_INSPECTOR_RECORDING_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST((klass), 
GTK_TYPE_INSPECTOR_RECORDING, GtkInspectorRecordingClass))
+#define GTK_INSPECTOR_IS_RECORDING(obj)         (G_TYPE_CHECK_INSTANCE_TYPE((obj), 
GTK_TYPE_INSPECTOR_RECORDING))
+#define GTK_INSPECTOR_IS_RECORDING_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), 
GTK_TYPE_INSPECTOR_RECORDING))
+#define GTK_INSPECTOR_RECORDING_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS((obj), 
GTK_TYPE_INSPECTOR_RECORDING, GtkInspectorRecordingClass))
+
+
+typedef struct _GtkInspectorRecordingPrivate GtkInspectorRecordingPrivate;
+
+typedef struct _GtkInspectorRecording
+{
+  GObject parent;
+
+  gint64 timestamp;
+} GtkInspectorRecording;
+
+typedef struct _GtkInspectorRecordingClass
+{
+  GObjectClass parent;
+} GtkInspectorRecordingClass;
+
+G_BEGIN_DECLS
+
+GType           gtk_inspector_recording_get_type                (void);
+
+gint64          gtk_inspector_recording_get_timestamp           (GtkInspectorRecording  *recording);
+
+G_END_DECLS
+
+#endif // _GTK_INSPECTOR_RECORDING_H_
+
+// vim: set et sw=2 ts=2:
diff --git a/gtk/inspector/renderrecording.c b/gtk/inspector/renderrecording.c
new file mode 100644
index 0000000..5c52226
--- /dev/null
+++ b/gtk/inspector/renderrecording.c
@@ -0,0 +1,68 @@
+/*
+ * Copyright (c) 2016 Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "config.h"
+#include <glib/gi18n-lib.h>
+
+#include "renderrecording.h"
+
+G_DEFINE_TYPE (GtkInspectorRenderRecording, gtk_inspector_render_recording, GTK_TYPE_INSPECTOR_RECORDING)
+
+static void
+gtk_inspector_render_recording_finalize (GObject *object)
+{
+  GtkInspectorRenderRecording *recording = GTK_INSPECTOR_RENDER_RECORDING (object);
+
+  g_clear_pointer (&recording->clip, cairo_region_destroy);
+  g_clear_pointer (&recording->node, gsk_render_node_unref);
+
+  G_OBJECT_CLASS (gtk_inspector_render_recording_parent_class)->finalize (object);
+}
+
+static void
+gtk_inspector_render_recording_class_init (GtkInspectorRenderRecordingClass *klass)
+{
+  GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+  object_class->finalize = gtk_inspector_render_recording_finalize;
+}
+
+static void
+gtk_inspector_render_recording_init (GtkInspectorRenderRecording *vis)
+{
+}
+
+GtkInspectorRecording *
+gtk_inspector_render_recording_new (gint64                timestamp,
+                                    const GdkRectangle   *area,
+                                    const cairo_region_t *clip,
+                                    GskRenderNode        *node)
+{
+  GtkInspectorRenderRecording *recording;
+
+  recording = g_object_new (GTK_TYPE_INSPECTOR_RENDER_RECORDING,
+                            "timestamp", timestamp,
+                            NULL);
+
+  recording->area = *area;
+  recording->clip = cairo_region_copy (clip);
+  recording->node = gsk_render_node_ref (node);
+
+  return GTK_INSPECTOR_RECORDING (recording);
+}
+
+// vim: set et sw=2 ts=2:
diff --git a/gtk/inspector/renderrecording.h b/gtk/inspector/renderrecording.h
new file mode 100644
index 0000000..ce0a993
--- /dev/null
+++ b/gtk/inspector/renderrecording.h
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2016 Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _GTK_INSPECTOR_RENDER_RECORDING_H_
+#define _GTK_INSPECTOR_RENDER_RECORDING_H_
+
+#include <gdk/gdk.h>
+#include <gsk/gsk.h>
+
+#include "inspector/recording.h"
+
+G_BEGIN_DECLS
+
+#define GTK_TYPE_INSPECTOR_RENDER_RECORDING            (gtk_inspector_render_recording_get_type())
+#define GTK_INSPECTOR_RENDER_RECORDING(obj)            (G_TYPE_CHECK_INSTANCE_CAST((obj), 
GTK_TYPE_INSPECTOR_RENDER_RECORDING, GtkInspectorRenderRecording))
+#define GTK_INSPECTOR_RENDER_RECORDING_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST((klass), 
GTK_TYPE_INSPECTOR_RENDER_RECORDING, GtkInspectorRenderRecordingClass))
+#define GTK_INSPECTOR_IS_RENDER_RECORDING(obj)         (G_TYPE_CHECK_INSTANCE_TYPE((obj), 
GTK_TYPE_INSPECTOR_RENDER_RECORDING))
+#define GTK_INSPECTOR_IS_RENDER_RECORDING_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), 
GTK_TYPE_INSPECTOR_RENDER_RECORDING))
+#define GTK_INSPECTOR_RENDER_RECORDING_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS((obj), 
GTK_TYPE_INSPECTOR_RENDER_RECORDING, GtkInspectorRenderRecordingClass))
+
+
+typedef struct _GtkInspectorRenderRecordingPrivate GtkInspectorRenderRecordingPrivate;
+
+typedef struct _GtkInspectorRenderRecording
+{
+  GtkInspectorRecording parent;
+
+  GdkRectangle area;
+  cairo_region_t *clip;
+  GskRenderNode *node;
+} GtkInspectorRenderRecording;
+
+typedef struct _GtkInspectorRenderRecordingClass
+{
+  GtkInspectorRecordingClass parent;
+} GtkInspectorRenderRecordingClass;
+
+GType      gtk_inspector_render_recording_get_type      (void);
+
+GtkInspectorRecording *
+           gtk_inspector_render_recording_new           (gint64                  timestamp,
+                                                         const GdkRectangle     *area,
+                                                         const cairo_region_t   *clip,
+                                                         GskRenderNode          *node);
+
+G_END_DECLS
+
+#endif // _GTK_INSPECTOR_RENDER_RECORDING_H_
+
+// vim: set et sw=2 ts=2:
diff --git a/gtk/inspector/window.c b/gtk/inspector/window.c
index 9f84a5c..beb0db9 100644
--- a/gtk/inspector/window.c
+++ b/gtk/inspector/window.c
@@ -42,6 +42,7 @@
 #include "misc-info.h"
 #include "gestures.h"
 #include "magnifier.h"
+#include "recorder.h"
 
 #include "gtklabel.h"
 #include "gtkbutton.h"
@@ -228,6 +229,8 @@ gtk_inspector_window_constructed (GObject *object)
 
   G_OBJECT_CLASS (gtk_inspector_window_parent_class)->constructed (object);
 
+  g_object_set_data (G_OBJECT (gdk_display_get_default ()), "-gtk-inspector", iw);
+
   gtk_inspector_object_tree_scan (GTK_INSPECTOR_OBJECT_TREE (iw->object_tree), NULL);
 }
 
@@ -332,4 +335,33 @@ gtk_inspector_window_rescan (GtkWidget *widget)
   gtk_inspector_object_tree_scan (GTK_INSPECTOR_OBJECT_TREE (iw->object_tree), NULL);
 }
 
+static GtkInspectorWindow *
+gtk_inspector_window_get_for_display (GdkDisplay *display)
+{
+  return g_object_get_data (G_OBJECT (display), "-gtk-inspector");
+}
+
+void
+gtk_inspector_record_render (GtkWidget            *widget,
+                             GdkWindow            *window,
+                             const cairo_region_t *region,
+                             GskRenderNode        *node)
+{
+  GtkInspectorWindow *iw;
+
+  iw = gtk_inspector_window_get_for_display (gtk_widget_get_display (widget));
+  if (iw == NULL)
+    return;
+
+  /* sanity check for single-display GDK backends */
+  if (GTK_WIDGET (iw) == widget)
+    return;
+
+  gtk_inspector_recorder_record_render (GTK_INSPECTOR_RECORDER (iw->widget_recorder),
+                                        widget,
+                                        window,
+                                        region,
+                                        node);
+}
+
 // vim: set et sw=2 ts=2:
diff --git a/gtk/inspector/window.h b/gtk/inspector/window.h
index 13d066a..0ca153d 100644
--- a/gtk/inspector/window.h
+++ b/gtk/inspector/window.h
@@ -106,6 +106,11 @@ void       gtk_inspector_window_select_widget_under_pointer (GtkInspectorWindow
 
 void       gtk_inspector_window_rescan     (GtkWidget          *iw);
 
+void       gtk_inspector_record_render     (GtkWidget          *widget,
+                                            GdkWindow          *window,
+                                            const cairo_region_t *region,
+                                            GskRenderNode      *node);
+
 G_END_DECLS
 
 


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