mirror of
https://github.com/varun-r-mallya/sysprof.git
synced 2025-12-31 20:36:25 +00:00
sysprof: drop libsysprof-gtk and absorb it in sysprof
We are dropping the whole "embed this gtk stuff in your app" model since that never really worked that well.
This commit is contained in:
@ -1,14 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<gresources>
|
||||
<gresource prefix="/libsysprof-gtk">
|
||||
<file preprocess="xml-stripblanks">sysprof-callgraph-view.ui</file>
|
||||
<file preprocess="xml-stripblanks">sysprof-mark-chart.ui</file>
|
||||
<file preprocess="xml-stripblanks">sysprof-mark-chart-row.ui</file>
|
||||
<file preprocess="xml-stripblanks">sysprof-mark-table.ui</file>
|
||||
<file preprocess="xml-stripblanks">sysprof-memory-callgraph-view.ui</file>
|
||||
<file preprocess="xml-stripblanks">sysprof-track-view.ui</file>
|
||||
<file preprocess="xml-stripblanks">sysprof-tracks-view.ui</file>
|
||||
<file preprocess="xml-stripblanks">sysprof-weighted-callgraph-view.ui</file>
|
||||
<file>style.css</file>
|
||||
</gresource>
|
||||
</gresources>
|
||||
@ -1,142 +0,0 @@
|
||||
libsysprof_gtk_public_sources = [
|
||||
'sysprof-axis.c',
|
||||
'sysprof-callgraph-view.c',
|
||||
'sysprof-chart.c',
|
||||
'sysprof-chart-layer.c',
|
||||
'sysprof-column-layer.c',
|
||||
'sysprof-duplex-layer.c',
|
||||
'sysprof-line-layer.c',
|
||||
'sysprof-mark-chart.c',
|
||||
'sysprof-mark-table.c',
|
||||
'sysprof-memory-callgraph-view.c',
|
||||
'sysprof-normalized-series.c',
|
||||
'sysprof-normalized-series-item.c',
|
||||
'sysprof-series.c',
|
||||
'sysprof-session.c',
|
||||
'sysprof-session-model.c',
|
||||
'sysprof-session-model-item.c',
|
||||
'sysprof-split-layer.c',
|
||||
'sysprof-time-filter-model.c',
|
||||
'sysprof-time-label.c',
|
||||
'sysprof-time-ruler.c',
|
||||
'sysprof-time-span-layer.c',
|
||||
'sysprof-time-series.c',
|
||||
'sysprof-time-series-item.c',
|
||||
'sysprof-track.c',
|
||||
'sysprof-track-view.c',
|
||||
'sysprof-tracks-view.c',
|
||||
'sysprof-value-axis.c',
|
||||
'sysprof-weighted-callgraph-view.c',
|
||||
'sysprof-xy-layer.c',
|
||||
'sysprof-xy-series.c',
|
||||
'sysprof-xy-series-item.c',
|
||||
]
|
||||
|
||||
libsysprof_gtk_public_headers = [
|
||||
'sysprof-gtk.h',
|
||||
|
||||
'sysprof-axis.h',
|
||||
'sysprof-callgraph-view.h',
|
||||
'sysprof-chart.h',
|
||||
'sysprof-chart-layer.h',
|
||||
'sysprof-column-layer.h',
|
||||
'sysprof-duplex-layer.h',
|
||||
'sysprof-line-layer.h',
|
||||
'sysprof-mark-chart.h',
|
||||
'sysprof-mark-table.h',
|
||||
'sysprof-memory-callgraph-view.h',
|
||||
'sysprof-normalized-series.h',
|
||||
'sysprof-normalized-series-item.h',
|
||||
'sysprof-series.h',
|
||||
'sysprof-session.h',
|
||||
'sysprof-session-model.h',
|
||||
'sysprof-session-model-item.h',
|
||||
'sysprof-split-layer.h',
|
||||
'sysprof-time-filter-model.h',
|
||||
'sysprof-time-label.h',
|
||||
'sysprof-time-ruler.h',
|
||||
'sysprof-time-series.h',
|
||||
'sysprof-time-series-item.h',
|
||||
'sysprof-time-span-layer.h',
|
||||
'sysprof-track.h',
|
||||
'sysprof-track-view.h',
|
||||
'sysprof-tracks-view.h',
|
||||
'sysprof-weighted-callgraph-view.h',
|
||||
'sysprof-value-axis.h',
|
||||
'sysprof-xy-layer.h',
|
||||
'sysprof-xy-series.h',
|
||||
'sysprof-xy-series-item.h',
|
||||
]
|
||||
|
||||
libsysprof_gtk_private_sources = [
|
||||
'sysprof-color-iter.c',
|
||||
'sysprof-css.c',
|
||||
'sysprof-mark-chart-item.c',
|
||||
'sysprof-mark-chart-row.c',
|
||||
'sysprof-progress-cell.c',
|
||||
'sysprof-scheduler.c',
|
||||
'sysprof-session-discover.c',
|
||||
'sysprof-symbol-label.c',
|
||||
]
|
||||
|
||||
libsysprof_gtk_deps = [
|
||||
dependency('libadwaita-1'),
|
||||
dependency('libpanel-1'),
|
||||
dependency('gtk4', version: gtk_req_version),
|
||||
|
||||
libsysprof_analyze_dep,
|
||||
]
|
||||
|
||||
libsysprof_gtk_resources = gnome.compile_resources(
|
||||
'libsysprof-gtk-resources',
|
||||
'libsysprof-gtk.gresource.xml',
|
||||
c_name: 'libsysprof_gtk',
|
||||
)
|
||||
|
||||
libsysprof_gtk_static = static_library(
|
||||
'sysprof-gtk-@0@'.format(soname_major_version),
|
||||
(libsysprof_gtk_public_sources +
|
||||
libsysprof_gtk_private_sources +
|
||||
libsysprof_gtk_resources +
|
||||
mapped_ring_buffer_sources),
|
||||
|
||||
include_directories: [include_directories('.'),
|
||||
ipc_include_dirs,
|
||||
libsysprof_capture_include_dirs],
|
||||
dependencies: libsysprof_gtk_deps,
|
||||
gnu_symbol_visibility: 'hidden',
|
||||
)
|
||||
|
||||
libsysprof_gtk_static_dep = declare_dependency(
|
||||
link_with: libsysprof_gtk_static,
|
||||
dependencies: libsysprof_gtk_deps,
|
||||
include_directories: [include_directories('.'),
|
||||
libsysprof_capture_include_dirs],
|
||||
)
|
||||
|
||||
libsysprof_gtk = library('sysprof-gtk-@0@'.format(soname_major_version),
|
||||
dependencies: [libsysprof_gtk_static_dep],
|
||||
gnu_symbol_visibility: 'hidden',
|
||||
version: '@0@.0.0'.format(soname_major_version),
|
||||
darwin_versions: '@0@.0'.format(soname_major_version),
|
||||
install: true,
|
||||
)
|
||||
|
||||
libsysprof_gtk_dep = declare_dependency(
|
||||
link_with: libsysprof_gtk,
|
||||
dependencies: libsysprof_gtk_deps,
|
||||
include_directories: [include_directories('.'), libsysprof_capture_include_dirs],
|
||||
)
|
||||
meson.override_dependency('sysprof-gtk-@0@'.format(soname_major_version), libsysprof_gtk_dep)
|
||||
|
||||
pkgconfig.generate(libsysprof_gtk,
|
||||
subdirs: [sysprof_header_subdir],
|
||||
description: 'Provides GTK widgets for sysprof visualizion',
|
||||
install_dir: join_paths(get_option('libdir'), 'pkgconfig'),
|
||||
requires: ['gtk4'],
|
||||
variables: ['datadir=' + datadir_for_pc_file],
|
||||
)
|
||||
|
||||
install_headers(libsysprof_gtk_public_headers, subdir: sysprof_header_subdir)
|
||||
|
||||
subdir('tests')
|
||||
@ -1,58 +0,0 @@
|
||||
/* sysprof-gtk.h
|
||||
*
|
||||
* Copyright 2023 Christian Hergert <chergert@redhat.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <sysprof-analyze.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define SYSPROF_GTK_INSIDE
|
||||
# include "sysprof-axis.h"
|
||||
# include "sysprof-callgraph-view.h"
|
||||
# include "sysprof-chart.h"
|
||||
# include "sysprof-chart-layer.h"
|
||||
# include "sysprof-column-layer.h"
|
||||
# include "sysprof-duplex-layer.h"
|
||||
# include "sysprof-line-layer.h"
|
||||
# include "sysprof-mark-chart.h"
|
||||
# include "sysprof-mark-table.h"
|
||||
# include "sysprof-memory-callgraph-view.h"
|
||||
# include "sysprof-normalized-series.h"
|
||||
# include "sysprof-normalized-series-item.h"
|
||||
# include "sysprof-series.h"
|
||||
# include "sysprof-session.h"
|
||||
# include "sysprof-session-model.h"
|
||||
# include "sysprof-session-model-item.h"
|
||||
# include "sysprof-split-layer.h"
|
||||
# include "sysprof-time-label.h"
|
||||
# include "sysprof-time-ruler.h"
|
||||
# include "sysprof-time-series.h"
|
||||
# include "sysprof-time-series-item.h"
|
||||
# include "sysprof-time-span-layer.h"
|
||||
# include "sysprof-tracks-view.h"
|
||||
# include "sysprof-value-axis.h"
|
||||
# include "sysprof-weighted-callgraph-view.h"
|
||||
# include "sysprof-xy-layer.h"
|
||||
# include "sysprof-xy-series.h"
|
||||
# include "sysprof-xy-series-item.h"
|
||||
#undef SYSPROF_GTK_INSIDE
|
||||
|
||||
G_END_DECLS
|
||||
@ -1,672 +0,0 @@
|
||||
/* sysprof-session-discover.c
|
||||
*
|
||||
* Copyright 2023 Christian Hergert <chergert@redhat.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <glib/gi18n.h>
|
||||
|
||||
#include "sysprof-chart.h"
|
||||
#include "sysprof-chart-layer.h"
|
||||
#include "sysprof-color-iter-private.h"
|
||||
#include "sysprof-column-layer.h"
|
||||
#include "sysprof-line-layer.h"
|
||||
#include "sysprof-session-private.h"
|
||||
#include "sysprof-time-span-layer.h"
|
||||
#include "sysprof-track-private.h"
|
||||
#include "sysprof-value-axis.h"
|
||||
|
||||
typedef enum _LineFlags
|
||||
{
|
||||
LINE_FLAGS_DASHED = 1 << 0,
|
||||
LINE_FLAGS_NO_SPLINE = 1 << 1,
|
||||
LINE_FLAGS_FILL = 1 << 2,
|
||||
LINE_FLAGS_IGNORE_RANGE_ON_SUBCHART = 1 << 3,
|
||||
LINE_FLAGS_FORMAT_MEMORY = 1 << 4,
|
||||
} LineFlags;
|
||||
|
||||
typedef struct _SysprofTrackSamples
|
||||
{
|
||||
SysprofSession *session;
|
||||
GListModel *samples;
|
||||
} SysprofTrackSamples;
|
||||
|
||||
typedef struct _SysprofTrackCounter
|
||||
{
|
||||
const char *track_name;
|
||||
|
||||
/* Used to layer values into main view */
|
||||
const char *category;
|
||||
const char *name;
|
||||
|
||||
/* Used to split out sub views */
|
||||
const char *subtracks_category;
|
||||
const char *subtracks_name;
|
||||
|
||||
double min_value;
|
||||
double max_value;
|
||||
|
||||
LineFlags flags;
|
||||
} SysprofTrackCounter;
|
||||
|
||||
typedef struct _SysprofTrackCounterChart
|
||||
{
|
||||
GListModel *counters;
|
||||
GListModel *subcounters;
|
||||
SysprofDocument *document;
|
||||
SysprofSession *session;
|
||||
const SysprofTrackCounter *info;
|
||||
GdkRGBA color;
|
||||
guint apply_range : 1;
|
||||
} SysprofTrackCounterChart;
|
||||
|
||||
typedef struct _SysprofTrackMarksChart
|
||||
{
|
||||
GListModel *model;
|
||||
SysprofDocument *document;
|
||||
SysprofSession *session;
|
||||
} SysprofTrackMarksChart;
|
||||
|
||||
static const SysprofTrackCounter discovery_counters[] = {
|
||||
{
|
||||
N_("CPU Usage"),
|
||||
"CPU Percent", "Combined",
|
||||
"CPU Percent", "Total *",
|
||||
.0, 100.,
|
||||
LINE_FLAGS_FILL,
|
||||
},
|
||||
|
||||
{
|
||||
N_("CPU Frequency"),
|
||||
"CPU Frequency", "*",
|
||||
"CPU Frequency", "*",
|
||||
.0, 100.,
|
||||
LINE_FLAGS_DASHED,
|
||||
},
|
||||
|
||||
{ N_("Memory"),
|
||||
"Memory", "Used",
|
||||
NULL, NULL,
|
||||
.0, .0,
|
||||
LINE_FLAGS_FILL | LINE_FLAGS_FORMAT_MEMORY,
|
||||
},
|
||||
|
||||
{ N_("FPS"), "gtk", "fps", "gtk", "*",
|
||||
0, 144, LINE_FLAGS_IGNORE_RANGE_ON_SUBCHART },
|
||||
|
||||
{
|
||||
N_("Energy"),
|
||||
"RAPL", "*",
|
||||
"RAPL*", "*",
|
||||
},
|
||||
|
||||
};
|
||||
|
||||
static void
|
||||
sysprof_track_samples_free (SysprofTrackSamples *samples)
|
||||
{
|
||||
g_clear_object (&samples->samples);
|
||||
g_clear_weak_pointer (&samples->session);
|
||||
g_free (samples);
|
||||
}
|
||||
|
||||
static SysprofTrackSamples *
|
||||
sysprof_track_samples_new (SysprofSession *session,
|
||||
GListModel *samples)
|
||||
{
|
||||
SysprofTrackSamples *state;
|
||||
|
||||
state = g_new0 (SysprofTrackSamples, 1);
|
||||
state->samples = g_object_ref (samples);
|
||||
g_set_weak_pointer (&state->session, session);
|
||||
return state;
|
||||
}
|
||||
|
||||
static void
|
||||
sysprof_track_counter_chart_free (SysprofTrackCounterChart *info)
|
||||
{
|
||||
g_clear_object (&info->counters);
|
||||
g_clear_object (&info->document);
|
||||
g_clear_weak_pointer (&info->session);
|
||||
info->info = NULL;
|
||||
g_free (info);
|
||||
}
|
||||
|
||||
static void
|
||||
sysprof_track_marks_chart_free (SysprofTrackMarksChart *info)
|
||||
{
|
||||
g_clear_object (&info->model);
|
||||
g_clear_object (&info->document);
|
||||
g_clear_weak_pointer (&info->session);
|
||||
g_free (info);
|
||||
}
|
||||
|
||||
static GListModel *
|
||||
filter_counters (GListModel *model,
|
||||
const char *category_glob,
|
||||
const char *name_glob)
|
||||
{
|
||||
g_autoptr(GListStore) store = NULL;
|
||||
g_autoptr(GPatternSpec) cat_spec = NULL;
|
||||
g_autoptr(GPatternSpec) name_spec = NULL;
|
||||
guint n_items;
|
||||
|
||||
g_assert (G_IS_LIST_MODEL (model));
|
||||
|
||||
if (category_glob == NULL || name_glob == NULL)
|
||||
return NULL;
|
||||
|
||||
store = g_list_store_new (SYSPROF_TYPE_DOCUMENT_COUNTER);
|
||||
|
||||
cat_spec = g_pattern_spec_new (category_glob);
|
||||
name_spec = g_pattern_spec_new (name_glob);
|
||||
|
||||
n_items = g_list_model_get_n_items (model);
|
||||
|
||||
for (guint i = 0; i < n_items; i++)
|
||||
{
|
||||
g_autoptr(SysprofDocumentCounter) counter = g_list_model_get_item (model, i);
|
||||
const char *ctrcat = sysprof_document_counter_get_category (counter);
|
||||
const char *ctrname = sysprof_document_counter_get_name (counter);
|
||||
|
||||
if (g_pattern_spec_match (cat_spec, strlen (ctrcat), ctrcat, NULL) &&
|
||||
g_pattern_spec_match (name_spec, strlen (ctrname), ctrname, NULL))
|
||||
g_list_store_append (store, counter);
|
||||
}
|
||||
|
||||
if (g_list_model_get_n_items (G_LIST_MODEL (store)) == 0)
|
||||
return NULL;
|
||||
|
||||
return G_LIST_MODEL (g_steal_pointer (&store));
|
||||
}
|
||||
|
||||
static GtkWidget *
|
||||
create_chart_for_samples (SysprofTrack *track,
|
||||
SysprofTrackSamples *state)
|
||||
{
|
||||
g_autoptr(SysprofSeries) xy_series = NULL;
|
||||
g_autoptr(SysprofAxis) y_axis = NULL;
|
||||
SysprofChartLayer *layer;
|
||||
SysprofChart *chart;
|
||||
SysprofAxis *x_axis = NULL;
|
||||
|
||||
g_assert (state != NULL);
|
||||
g_assert (SYSPROF_IS_SESSION (state->session));
|
||||
g_assert (SYSPROF_IS_TRACK (track));
|
||||
|
||||
x_axis = sysprof_session_get_visible_time_axis (state->session);
|
||||
y_axis = sysprof_value_axis_new (0, 128);
|
||||
xy_series = sysprof_xy_series_new (sysprof_track_get_title (track),
|
||||
g_object_ref (state->samples),
|
||||
gtk_property_expression_new (SYSPROF_TYPE_DOCUMENT_SAMPLE, NULL, "time"),
|
||||
gtk_property_expression_new (SYSPROF_TYPE_DOCUMENT_SAMPLE, NULL, "stack-depth"));
|
||||
|
||||
chart = g_object_new (SYSPROF_TYPE_CHART, NULL);
|
||||
layer = g_object_new (SYSPROF_TYPE_COLUMN_LAYER,
|
||||
"series", xy_series,
|
||||
"x-axis", x_axis,
|
||||
"y-axis", y_axis,
|
||||
NULL);
|
||||
sysprof_chart_add_layer (chart, layer);
|
||||
|
||||
return GTK_WIDGET (chart);
|
||||
}
|
||||
|
||||
static void
|
||||
sysprof_session_discover_sampler (SysprofSession *self,
|
||||
SysprofDocument *document,
|
||||
GListStore *tracks)
|
||||
{
|
||||
g_autoptr(GListModel) samples = NULL;
|
||||
g_autoptr(GListModel) samples_with_context_switch = NULL;
|
||||
g_autoptr(GListModel) samples_without_context_switch = NULL;
|
||||
|
||||
g_assert (SYSPROF_IS_SESSION (self));
|
||||
g_assert (SYSPROF_IS_DOCUMENT (document));
|
||||
g_assert (G_IS_LIST_STORE (tracks));
|
||||
|
||||
samples = sysprof_document_list_samples (document);
|
||||
samples_with_context_switch = sysprof_document_list_samples_with_context_switch (document);
|
||||
samples_without_context_switch = sysprof_document_list_samples_without_context_switch (document);
|
||||
|
||||
if (g_list_model_get_n_items (samples) > 0)
|
||||
{
|
||||
g_autoptr(SysprofTrack) track = NULL;
|
||||
|
||||
track = g_object_new (SYSPROF_TYPE_TRACK,
|
||||
"title", _("Profiler"),
|
||||
NULL);
|
||||
g_signal_connect_data (track,
|
||||
"create-chart",
|
||||
G_CALLBACK (create_chart_for_samples),
|
||||
sysprof_track_samples_new (self, samples),
|
||||
(GClosureNotify)sysprof_track_samples_free,
|
||||
0);
|
||||
g_list_store_append (tracks, track);
|
||||
|
||||
if (g_list_model_get_n_items (samples_with_context_switch))
|
||||
{
|
||||
g_autoptr(SysprofTrack) subtrack = NULL;
|
||||
|
||||
subtrack = g_object_new (SYSPROF_TYPE_TRACK,
|
||||
"title", _("Stack Traces (In Kernel)"),
|
||||
NULL);
|
||||
g_signal_connect_data (subtrack,
|
||||
"create-chart",
|
||||
G_CALLBACK (create_chart_for_samples),
|
||||
sysprof_track_samples_new (self, samples_with_context_switch),
|
||||
(GClosureNotify)sysprof_track_samples_free,
|
||||
0);
|
||||
_sysprof_track_add_subtrack (track, subtrack);
|
||||
}
|
||||
|
||||
if (g_list_model_get_n_items (samples_without_context_switch))
|
||||
{
|
||||
g_autoptr(SysprofTrack) subtrack = NULL;
|
||||
|
||||
subtrack = g_object_new (SYSPROF_TYPE_TRACK,
|
||||
"title", _("Stack Traces (In User)"),
|
||||
NULL);
|
||||
g_signal_connect_data (subtrack,
|
||||
"create-chart",
|
||||
G_CALLBACK (create_chart_for_samples),
|
||||
sysprof_track_samples_new (self, samples_without_context_switch),
|
||||
(GClosureNotify)sysprof_track_samples_free,
|
||||
0);
|
||||
_sysprof_track_add_subtrack (track, subtrack);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static GtkWidget *
|
||||
create_chart_for_counters (SysprofTrack *track,
|
||||
SysprofTrackCounterChart *info)
|
||||
{
|
||||
g_autoptr(SysprofDocumentCounter) first = NULL;
|
||||
g_autoptr(SysprofSeries) xy_series = NULL;
|
||||
g_autoptr(SysprofAxis) y_axis = NULL;
|
||||
SysprofChartLayer *layer;
|
||||
SysprofColorIter colors;
|
||||
SysprofChart *chart;
|
||||
SysprofAxis *x_axis = NULL;
|
||||
double min_value = 0;
|
||||
double max_value = 0;
|
||||
gboolean ignore_range = FALSE;
|
||||
guint n_items;
|
||||
|
||||
g_assert (SYSPROF_IS_TRACK (track));
|
||||
g_assert (info != NULL);
|
||||
g_assert (SYSPROF_IS_DOCUMENT (info->document));
|
||||
g_assert (SYSPROF_IS_SESSION (info->session));
|
||||
g_assert (G_IS_LIST_MODEL (info->counters));
|
||||
|
||||
if (!(n_items = g_list_model_get_n_items (info->counters)))
|
||||
return NULL;
|
||||
|
||||
sysprof_color_iter_init (&colors);
|
||||
|
||||
x_axis = sysprof_session_get_visible_time_axis (info->session);
|
||||
|
||||
chart = g_object_new (SYSPROF_TYPE_CHART, NULL);
|
||||
|
||||
/* Setup Y axis usin first item. We'll expand the range
|
||||
* after we've processed all the counters.
|
||||
*/
|
||||
first = g_list_model_get_item (info->counters, 0);
|
||||
min_value = sysprof_document_counter_get_min_value (first);
|
||||
max_value = sysprof_document_counter_get_max_value (first);
|
||||
y_axis = sysprof_value_axis_new (min_value, max_value);
|
||||
|
||||
if (info->apply_range &&
|
||||
(info->info->min_value != .0 || info->info->max_value != .0))
|
||||
{
|
||||
min_value = info->info->min_value;
|
||||
max_value = info->info->max_value;
|
||||
ignore_range = TRUE;
|
||||
}
|
||||
|
||||
for (guint i = 0; i < n_items; i++)
|
||||
{
|
||||
g_autoptr(SysprofDocumentCounter) counter = g_list_model_get_item (info->counters, i);
|
||||
double item_min_value = sysprof_document_counter_get_min_value (counter);
|
||||
double item_max_value = sysprof_document_counter_get_max_value (counter);
|
||||
const GdkRGBA *color;
|
||||
|
||||
if (!ignore_range)
|
||||
{
|
||||
if (item_min_value < min_value)
|
||||
min_value = item_min_value;
|
||||
|
||||
if (item_max_value > max_value)
|
||||
max_value = item_max_value;
|
||||
}
|
||||
|
||||
if (info->color.alpha > 0)
|
||||
color = &info->color;
|
||||
else
|
||||
color = sysprof_color_iter_next (&colors);
|
||||
|
||||
xy_series = sysprof_xy_series_new (sysprof_track_get_title (track),
|
||||
g_object_ref (G_LIST_MODEL (counter)),
|
||||
gtk_property_expression_new (SYSPROF_TYPE_DOCUMENT_COUNTER_VALUE, NULL, "time"),
|
||||
gtk_property_expression_new (SYSPROF_TYPE_DOCUMENT_COUNTER_VALUE, NULL, "value-double"));
|
||||
|
||||
layer = g_object_new (SYSPROF_TYPE_LINE_LAYER,
|
||||
"spline", !(info->info->flags & LINE_FLAGS_NO_SPLINE),
|
||||
"dashed", !!(info->info->flags & LINE_FLAGS_DASHED),
|
||||
"fill", !!(info->info->flags & LINE_FLAGS_FILL),
|
||||
"color", color,
|
||||
"series", xy_series,
|
||||
"x-axis", x_axis,
|
||||
"y-axis", y_axis,
|
||||
NULL);
|
||||
sysprof_chart_add_layer (chart, layer);
|
||||
}
|
||||
|
||||
sysprof_value_axis_set_min_value (SYSPROF_VALUE_AXIS (y_axis), min_value);
|
||||
sysprof_value_axis_set_max_value (SYSPROF_VALUE_AXIS (y_axis), max_value);
|
||||
|
||||
return GTK_WIDGET (chart);
|
||||
}
|
||||
|
||||
static char *
|
||||
format_value_as_memory (SysprofTrack *track,
|
||||
SysprofDocumentCounterValue *value,
|
||||
SysprofDocument *document)
|
||||
{
|
||||
const SysprofTimeSpan *span = sysprof_document_get_time_span (document);
|
||||
gint64 v = sysprof_document_counter_value_get_value_int64 (value);
|
||||
gint64 t = sysprof_document_counter_value_get_time (value) - span->begin_nsec;
|
||||
g_autofree char *vstr = g_format_size (v);
|
||||
g_autofree char *tstr = sysprof_time_offset_to_string (t);
|
||||
|
||||
return g_strdup_printf ("%s: %s", tstr, vstr);
|
||||
}
|
||||
|
||||
static void
|
||||
sysprof_session_discover_counters (SysprofSession *self,
|
||||
SysprofDocument *document,
|
||||
GListStore *tracks)
|
||||
{
|
||||
g_autoptr(GListModel) counters = NULL;
|
||||
|
||||
g_assert (SYSPROF_IS_SESSION (self));
|
||||
g_assert (SYSPROF_IS_DOCUMENT (document));
|
||||
g_assert (G_IS_LIST_STORE (tracks));
|
||||
|
||||
counters = sysprof_document_list_counters (document);
|
||||
|
||||
for (guint i = 0; i < G_N_ELEMENTS (discovery_counters); i++)
|
||||
{
|
||||
const SysprofTrackCounter *info = &discovery_counters[i];
|
||||
g_autoptr(GListModel) track_counters = filter_counters (counters, info->category, info->name);
|
||||
|
||||
if (track_counters != NULL)
|
||||
{
|
||||
g_autoptr(SysprofTrack) track = NULL;
|
||||
g_autoptr(GListModel) subtrack_counters = NULL;
|
||||
SysprofTrackCounterChart *chart;
|
||||
SysprofColorIter iter;
|
||||
|
||||
sysprof_color_iter_init (&iter);
|
||||
|
||||
chart = g_new0 (SysprofTrackCounterChart, 1);
|
||||
g_set_weak_pointer (&chart->session, self);
|
||||
chart->document = g_object_ref (document);
|
||||
chart->counters = g_object_ref (track_counters);
|
||||
chart->info = info;
|
||||
chart->apply_range = TRUE;
|
||||
|
||||
track = g_object_new (SYSPROF_TYPE_TRACK,
|
||||
"title", info->track_name,
|
||||
NULL);
|
||||
|
||||
if ((info->flags & LINE_FLAGS_FORMAT_MEMORY) != 0)
|
||||
g_signal_connect_object (track,
|
||||
"format-item-for-display",
|
||||
G_CALLBACK (format_value_as_memory),
|
||||
document,
|
||||
0);
|
||||
|
||||
g_signal_connect_data (track,
|
||||
"create-chart",
|
||||
G_CALLBACK (create_chart_for_counters),
|
||||
chart,
|
||||
(GClosureNotify)sysprof_track_counter_chart_free,
|
||||
0);
|
||||
|
||||
if ((subtrack_counters = filter_counters (counters, info->subtracks_category, info->subtracks_name)))
|
||||
{
|
||||
guint n_items = g_list_model_get_n_items (subtrack_counters);
|
||||
|
||||
for (guint j = 0; j < n_items; j++)
|
||||
{
|
||||
g_autoptr(SysprofDocumentCounter) subtrack_counter = g_list_model_get_item (subtrack_counters, j);
|
||||
g_autoptr(SysprofTrack) subtrack = NULL;
|
||||
g_autoptr(GListStore) store = g_list_store_new (SYSPROF_TYPE_DOCUMENT_COUNTER);
|
||||
SysprofTrackCounterChart *subchart;
|
||||
|
||||
g_list_store_append (store, subtrack_counter);
|
||||
|
||||
subchart = g_new0 (SysprofTrackCounterChart, 1);
|
||||
g_set_weak_pointer (&subchart->session, self);
|
||||
subchart->document = g_object_ref (document);
|
||||
subchart->counters = g_object_ref (G_LIST_MODEL (store));
|
||||
subchart->info = info;
|
||||
subchart->apply_range = !(info->flags & LINE_FLAGS_IGNORE_RANGE_ON_SUBCHART);
|
||||
subchart->color = *sysprof_color_iter_next (&iter);
|
||||
|
||||
subtrack = g_object_new (SYSPROF_TYPE_TRACK,
|
||||
"title", sysprof_document_counter_get_name (subtrack_counter),
|
||||
NULL);
|
||||
|
||||
if ((info->flags & LINE_FLAGS_FORMAT_MEMORY) != 0)
|
||||
g_signal_connect_object (subtrack,
|
||||
"format-item-for-display",
|
||||
G_CALLBACK (format_value_as_memory),
|
||||
document,
|
||||
0);
|
||||
|
||||
g_signal_connect_data (subtrack,
|
||||
"create-chart",
|
||||
G_CALLBACK (create_chart_for_counters),
|
||||
subchart,
|
||||
(GClosureNotify)sysprof_track_counter_chart_free,
|
||||
0);
|
||||
|
||||
_sysprof_track_add_subtrack (track, subtrack);
|
||||
}
|
||||
}
|
||||
|
||||
g_list_store_append (tracks, track);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
activate_mark_cb (SysprofSession *session,
|
||||
SysprofTimeSpanLayer *layer,
|
||||
SysprofDocumentMark *mark,
|
||||
SysprofChart *chart)
|
||||
{
|
||||
gint64 duration;
|
||||
|
||||
g_assert (SYSPROF_IS_SESSION (session));
|
||||
g_assert (SYSPROF_IS_TIME_SPAN_LAYER (layer));
|
||||
g_assert (SYSPROF_IS_DOCUMENT_MARK (mark));
|
||||
g_assert (SYSPROF_IS_CHART (chart));
|
||||
|
||||
if ((duration = sysprof_document_mark_get_duration (mark)))
|
||||
{
|
||||
gint64 t = sysprof_document_frame_get_time (SYSPROF_DOCUMENT_FRAME (mark));
|
||||
SysprofTimeSpan span = { t, t + duration };
|
||||
|
||||
sysprof_session_select_time (session, &span);
|
||||
sysprof_session_zoom_to_selection (session);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static GtkWidget *
|
||||
create_chart_for_marks (SysprofTrack *track,
|
||||
SysprofTrackMarksChart *info)
|
||||
{
|
||||
g_autoptr(SysprofSeries) time_series = NULL;
|
||||
SysprofChartLayer *layer;
|
||||
SysprofChart *chart;
|
||||
SysprofAxis *x_axis = NULL;
|
||||
|
||||
g_assert (SYSPROF_IS_TRACK (track));
|
||||
g_assert (info != NULL);
|
||||
g_assert (SYSPROF_IS_SESSION (info->session));
|
||||
g_assert (SYSPROF_IS_DOCUMENT (info->document));
|
||||
g_assert (G_IS_LIST_MODEL (info->model));
|
||||
|
||||
x_axis = sysprof_session_get_visible_time_axis (info->session);
|
||||
time_series = sysprof_time_series_new (sysprof_track_get_title (track),
|
||||
g_object_ref (G_LIST_MODEL (info->model)),
|
||||
gtk_property_expression_new (SYSPROF_TYPE_DOCUMENT_MARK, NULL, "time"),
|
||||
gtk_property_expression_new (SYSPROF_TYPE_DOCUMENT_MARK, NULL, "duration"),
|
||||
gtk_property_expression_new (SYSPROF_TYPE_DOCUMENT_MARK, NULL, "message"));
|
||||
|
||||
chart = g_object_new (SYSPROF_TYPE_CHART, NULL);
|
||||
g_signal_connect_object (chart,
|
||||
"activate-layer-item",
|
||||
G_CALLBACK (activate_mark_cb),
|
||||
info->session,
|
||||
G_CONNECT_SWAPPED);
|
||||
layer = g_object_new (SYSPROF_TYPE_TIME_SPAN_LAYER,
|
||||
"series", time_series,
|
||||
"axis", x_axis,
|
||||
NULL);
|
||||
sysprof_chart_add_layer (chart, layer);
|
||||
|
||||
return GTK_WIDGET (chart);
|
||||
}
|
||||
|
||||
static void
|
||||
sysprof_session_discover_marks (SysprofSession *self,
|
||||
SysprofDocument *document,
|
||||
GListStore *tracks)
|
||||
{
|
||||
g_autoptr(GListModel) catalogs = NULL;
|
||||
g_autoptr(SysprofTrack) toplevel = NULL;
|
||||
SysprofTrackMarksChart *topchart;
|
||||
guint n_catalogs;
|
||||
|
||||
g_assert (SYSPROF_IS_SESSION (self));
|
||||
g_assert (SYSPROF_IS_DOCUMENT (document));
|
||||
g_assert (G_IS_LIST_STORE (tracks));
|
||||
|
||||
catalogs = sysprof_document_catalog_marks (document);
|
||||
n_catalogs = g_list_model_get_n_items (catalogs);
|
||||
|
||||
if (n_catalogs == 0)
|
||||
return;
|
||||
|
||||
toplevel = g_object_new (SYSPROF_TYPE_TRACK,
|
||||
"title", _("Points of Interest"),
|
||||
NULL);
|
||||
topchart = g_new0 (SysprofTrackMarksChart, 1);
|
||||
g_set_weak_pointer (&topchart->session, self);
|
||||
topchart->document = g_object_ref (document);
|
||||
topchart->model = sysprof_document_list_marks (document);
|
||||
g_signal_connect_data (toplevel,
|
||||
"create-chart",
|
||||
G_CALLBACK (create_chart_for_marks),
|
||||
topchart,
|
||||
(GClosureNotify)sysprof_track_marks_chart_free,
|
||||
0);
|
||||
|
||||
for (guint i = 0; i < n_catalogs; i++)
|
||||
{
|
||||
g_autoptr(GListModel) by_group = g_list_model_get_item (catalogs, i);
|
||||
g_autoptr(SysprofMarkCatalog) first = g_list_model_get_item (by_group, 0);
|
||||
g_autoptr(SysprofTrack) track = NULL;
|
||||
SysprofTrackMarksChart *chart;
|
||||
const char *group;
|
||||
guint n_names;
|
||||
|
||||
if (first == NULL)
|
||||
continue;
|
||||
|
||||
n_names = g_list_model_get_n_items (G_LIST_MODEL (by_group));
|
||||
group = sysprof_mark_catalog_get_group (first);
|
||||
|
||||
chart = g_new0 (SysprofTrackMarksChart, 1);
|
||||
g_set_weak_pointer (&chart->session, self);
|
||||
chart->document = g_object_ref (document);
|
||||
chart->model = sysprof_document_list_marks_by_group (document, group);
|
||||
|
||||
track = g_object_new (SYSPROF_TYPE_TRACK,
|
||||
"title", sysprof_mark_catalog_get_group (first),
|
||||
NULL);
|
||||
g_signal_connect_data (track,
|
||||
"create-chart",
|
||||
G_CALLBACK (create_chart_for_marks),
|
||||
chart,
|
||||
(GClosureNotify)sysprof_track_marks_chart_free,
|
||||
0);
|
||||
_sysprof_track_add_subtrack (toplevel, track);
|
||||
|
||||
for (guint j = 0; j < n_names; j++)
|
||||
{
|
||||
g_autoptr(SysprofMarkCatalog) catalog = g_list_model_get_item (by_group, j);
|
||||
g_autoptr(SysprofTrack) subtrack = NULL;
|
||||
SysprofTrackMarksChart *subchart;
|
||||
|
||||
subchart = g_new0 (SysprofTrackMarksChart, 1);
|
||||
g_set_weak_pointer (&subchart->session, self);
|
||||
subchart->document = g_object_ref (document);
|
||||
subchart->model = g_object_ref (G_LIST_MODEL (catalog));
|
||||
|
||||
subtrack = g_object_new (SYSPROF_TYPE_TRACK,
|
||||
"title", sysprof_mark_catalog_get_name (catalog),
|
||||
NULL);
|
||||
|
||||
g_signal_connect_data (subtrack,
|
||||
"create-chart",
|
||||
G_CALLBACK (create_chart_for_marks),
|
||||
subchart,
|
||||
(GClosureNotify)sysprof_track_marks_chart_free,
|
||||
0);
|
||||
|
||||
_sysprof_track_add_subtrack (track, subtrack);
|
||||
}
|
||||
}
|
||||
|
||||
g_list_store_append (tracks, toplevel);
|
||||
}
|
||||
|
||||
void
|
||||
_sysprof_session_discover_tracks (SysprofSession *self,
|
||||
SysprofDocument *document,
|
||||
GListStore *tracks)
|
||||
{
|
||||
g_assert (SYSPROF_IS_SESSION (self));
|
||||
g_assert (SYSPROF_IS_DOCUMENT (document));
|
||||
g_assert (G_IS_LIST_STORE (tracks));
|
||||
|
||||
sysprof_session_discover_sampler (self, document, tracks);
|
||||
sysprof_session_discover_counters (self, document, tracks);
|
||||
sysprof_session_discover_marks (self, document, tracks);
|
||||
}
|
||||
@ -1,33 +0,0 @@
|
||||
/* sysprof-track-private.h
|
||||
*
|
||||
* Copyright 2023 Christian Hergert <chergert@redhat.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "sysprof-track.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
GtkWidget *_sysprof_track_create_chart (SysprofTrack *self);
|
||||
void _sysprof_track_add_subtrack (SysprofTrack *self,
|
||||
SysprofTrack *subtrack);
|
||||
char *_sysprof_track_format_item_for_display (SysprofTrack *self,
|
||||
gpointer item);
|
||||
|
||||
G_END_DECLS
|
||||
@ -1,164 +0,0 @@
|
||||
/* sysprof-track-view.c
|
||||
*
|
||||
* Copyright 2023 Christian Hergert <chergert@redhat.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "sysprof-track-private.h"
|
||||
#include "sysprof-track-view.h"
|
||||
|
||||
struct _SysprofTrackView
|
||||
{
|
||||
GtkWidget parent_instance;
|
||||
SysprofTrack *track;
|
||||
};
|
||||
|
||||
enum {
|
||||
PROP_0,
|
||||
PROP_TRACK,
|
||||
N_PROPS
|
||||
};
|
||||
|
||||
G_DEFINE_FINAL_TYPE (SysprofTrackView, sysprof_track_view, GTK_TYPE_WIDGET)
|
||||
|
||||
static GParamSpec *properties [N_PROPS];
|
||||
|
||||
static void
|
||||
sysprof_track_view_dispose (GObject *object)
|
||||
{
|
||||
SysprofTrackView *self = (SysprofTrackView *)object;
|
||||
GtkWidget *child;
|
||||
|
||||
gtk_widget_dispose_template (GTK_WIDGET (self), SYSPROF_TYPE_TRACK_VIEW);
|
||||
|
||||
g_clear_object (&self->track);
|
||||
|
||||
while ((child = gtk_widget_get_first_child (GTK_WIDGET (self))))
|
||||
gtk_widget_unparent (child);
|
||||
|
||||
G_OBJECT_CLASS (sysprof_track_view_parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
static void
|
||||
sysprof_track_view_get_property (GObject *object,
|
||||
guint prop_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
SysprofTrackView *self = SYSPROF_TRACK_VIEW (object);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_TRACK:
|
||||
g_value_set_object (value, sysprof_track_view_get_track (self));
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
sysprof_track_view_set_property (GObject *object,
|
||||
guint prop_id,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
SysprofTrackView *self = SYSPROF_TRACK_VIEW (object);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_TRACK:
|
||||
sysprof_track_view_set_track (self, g_value_get_object (value));
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
sysprof_track_view_class_init (SysprofTrackViewClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
|
||||
|
||||
object_class->dispose = sysprof_track_view_dispose;
|
||||
object_class->get_property = sysprof_track_view_get_property;
|
||||
object_class->set_property = sysprof_track_view_set_property;
|
||||
|
||||
properties[PROP_TRACK] =
|
||||
g_param_spec_object ("track", NULL, NULL,
|
||||
SYSPROF_TYPE_TRACK,
|
||||
(G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS));
|
||||
|
||||
g_object_class_install_properties (object_class, N_PROPS, properties);
|
||||
|
||||
gtk_widget_class_set_template_from_resource (widget_class, "/libsysprof-gtk/sysprof-track-view.ui");
|
||||
gtk_widget_class_set_layout_manager_type (widget_class, GTK_TYPE_BIN_LAYOUT);
|
||||
|
||||
g_type_ensure (SYSPROF_TYPE_TRACK);
|
||||
}
|
||||
|
||||
static void
|
||||
sysprof_track_view_init (SysprofTrackView *self)
|
||||
{
|
||||
gtk_widget_init_template (GTK_WIDGET (self));
|
||||
}
|
||||
|
||||
GtkWidget *
|
||||
sysprof_track_view_new (void)
|
||||
{
|
||||
return g_object_new (SYSPROF_TYPE_TRACK_VIEW, NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* sysprof_track_view_get_track:
|
||||
* @self: a #SysprofTrackView
|
||||
*
|
||||
* Returns: (transfer none) (nullable): A #SysprofTrack or %NULL
|
||||
*/
|
||||
SysprofTrack *
|
||||
sysprof_track_view_get_track (SysprofTrackView *self)
|
||||
{
|
||||
g_return_val_if_fail (SYSPROF_IS_TRACK_VIEW (self), NULL);
|
||||
|
||||
return self->track;
|
||||
}
|
||||
|
||||
void
|
||||
sysprof_track_view_set_track (SysprofTrackView *self,
|
||||
SysprofTrack *track)
|
||||
{
|
||||
g_return_if_fail (SYSPROF_IS_TRACK_VIEW (self));
|
||||
g_return_if_fail (!track || SYSPROF_IS_TRACK (track));
|
||||
|
||||
if (g_set_object (&self->track, track))
|
||||
{
|
||||
GtkWidget *child;
|
||||
|
||||
while ((child = gtk_widget_get_first_child (GTK_WIDGET (self))))
|
||||
gtk_widget_unparent (child);
|
||||
|
||||
if ((child = _sysprof_track_create_chart (track)))
|
||||
gtk_widget_set_parent (child, GTK_WIDGET (self));
|
||||
|
||||
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_TRACK]);
|
||||
}
|
||||
}
|
||||
@ -1,42 +0,0 @@
|
||||
/* sysprof-track-view.h
|
||||
*
|
||||
* Copyright 2023 Christian Hergert <chergert@redhat.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
#include "sysprof-track.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define SYSPROF_TYPE_TRACK_VIEW (sysprof_track_view_get_type())
|
||||
|
||||
SYSPROF_AVAILABLE_IN_ALL
|
||||
G_DECLARE_FINAL_TYPE (SysprofTrackView, sysprof_track_view, SYSPROF, TRACK_VIEW, GtkWidget)
|
||||
|
||||
SYSPROF_AVAILABLE_IN_ALL
|
||||
GtkWidget *sysprof_track_view_new (void);
|
||||
SYSPROF_AVAILABLE_IN_ALL
|
||||
SysprofTrack *sysprof_track_view_get_track (SysprofTrackView *self);
|
||||
SYSPROF_AVAILABLE_IN_ALL
|
||||
void sysprof_track_view_set_track (SysprofTrackView *self,
|
||||
SysprofTrack *track);
|
||||
|
||||
G_END_DECLS
|
||||
@ -1,5 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<interface>
|
||||
<template class="SysprofTrackView" parent="GtkWidget">
|
||||
</template>
|
||||
</interface>
|
||||
@ -1,271 +0,0 @@
|
||||
/* sysprof-track.c
|
||||
*
|
||||
* Copyright 2023 Christian Hergert <chergert@redhat.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "sysprof-track-private.h"
|
||||
|
||||
struct _SysprofTrack
|
||||
{
|
||||
GObject parent_instance;
|
||||
SysprofSession *session;
|
||||
char *title;
|
||||
GListStore *subtracks;
|
||||
GMenuModel *menu_model;
|
||||
};
|
||||
|
||||
enum {
|
||||
PROP_0,
|
||||
PROP_MENU_MODEL,
|
||||
PROP_SESSION,
|
||||
PROP_SUBTRACKS,
|
||||
PROP_TITLE,
|
||||
N_PROPS
|
||||
};
|
||||
|
||||
enum {
|
||||
CREATE_CHART,
|
||||
FORMAT_ITEM_FOR_DISPLAY,
|
||||
N_SIGNALS
|
||||
};
|
||||
|
||||
G_DEFINE_FINAL_TYPE (SysprofTrack, sysprof_track, G_TYPE_OBJECT)
|
||||
|
||||
static GParamSpec *properties [N_PROPS];
|
||||
static guint signals[N_SIGNALS];
|
||||
|
||||
static void
|
||||
sysprof_track_dispose (GObject *object)
|
||||
{
|
||||
SysprofTrack *self = (SysprofTrack *)object;
|
||||
|
||||
g_clear_object (&self->menu_model);
|
||||
g_clear_object (&self->subtracks);
|
||||
g_clear_pointer (&self->title, g_free);
|
||||
g_clear_weak_pointer (&self->session);
|
||||
|
||||
G_OBJECT_CLASS (sysprof_track_parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
static void
|
||||
sysprof_track_get_property (GObject *object,
|
||||
guint prop_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
SysprofTrack *self = SYSPROF_TRACK (object);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_MENU_MODEL:
|
||||
g_value_set_object (value, sysprof_track_get_menu_model (self));
|
||||
break;
|
||||
|
||||
case PROP_SESSION:
|
||||
g_value_set_object (value, sysprof_track_get_session (self));
|
||||
break;
|
||||
|
||||
case PROP_SUBTRACKS:
|
||||
g_value_take_object (value, sysprof_track_list_subtracks (self));
|
||||
break;
|
||||
|
||||
case PROP_TITLE:
|
||||
g_value_set_string (value, sysprof_track_get_title (self));
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
sysprof_track_set_property (GObject *object,
|
||||
guint prop_id,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
SysprofTrack *self = SYSPROF_TRACK (object);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_MENU_MODEL:
|
||||
self->menu_model = g_value_dup_object (value);
|
||||
break;
|
||||
|
||||
case PROP_SESSION:
|
||||
g_set_weak_pointer (&self->session, g_value_get_object (value));
|
||||
break;
|
||||
|
||||
case PROP_TITLE:
|
||||
self->title = g_value_dup_string (value);
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
sysprof_track_class_init (SysprofTrackClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
|
||||
object_class->dispose = sysprof_track_dispose;
|
||||
object_class->get_property = sysprof_track_get_property;
|
||||
object_class->set_property = sysprof_track_set_property;
|
||||
|
||||
properties [PROP_MENU_MODEL] =
|
||||
g_param_spec_object ("menu-model", NULL, NULL,
|
||||
G_TYPE_MENU_MODEL,
|
||||
(G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS));
|
||||
|
||||
properties [PROP_SESSION] =
|
||||
g_param_spec_object ("session", NULL, NULL,
|
||||
SYSPROF_TYPE_SESSION,
|
||||
(G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS));
|
||||
|
||||
properties[PROP_SUBTRACKS] =
|
||||
g_param_spec_object ("subtracks", NULL, NULL,
|
||||
G_TYPE_LIST_MODEL,
|
||||
(G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
|
||||
|
||||
properties[PROP_TITLE] =
|
||||
g_param_spec_string ("title", NULL, NULL,
|
||||
NULL,
|
||||
(G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS));
|
||||
|
||||
g_object_class_install_properties (object_class, N_PROPS, properties);
|
||||
|
||||
signals[CREATE_CHART] =
|
||||
g_signal_new ("create-chart",
|
||||
G_TYPE_FROM_CLASS (klass),
|
||||
G_SIGNAL_RUN_LAST,
|
||||
0,
|
||||
g_signal_accumulator_first_wins, NULL,
|
||||
NULL,
|
||||
GTK_TYPE_WIDGET, 0);
|
||||
|
||||
signals[FORMAT_ITEM_FOR_DISPLAY] =
|
||||
g_signal_new ("format-item-for-display",
|
||||
G_TYPE_FROM_CLASS (klass),
|
||||
G_SIGNAL_RUN_LAST,
|
||||
0,
|
||||
g_signal_accumulator_first_wins, NULL,
|
||||
NULL,
|
||||
G_TYPE_STRING, 1, G_TYPE_OBJECT);
|
||||
}
|
||||
|
||||
static void
|
||||
sysprof_track_init (SysprofTrack *self)
|
||||
{
|
||||
self->subtracks = g_list_store_new (SYSPROF_TYPE_TRACK);
|
||||
}
|
||||
|
||||
const char *
|
||||
sysprof_track_get_title (SysprofTrack *self)
|
||||
{
|
||||
g_return_val_if_fail (SYSPROF_IS_TRACK (self), NULL);
|
||||
|
||||
return self->title;
|
||||
}
|
||||
|
||||
void
|
||||
_sysprof_track_add_subtrack (SysprofTrack *self,
|
||||
SysprofTrack *subtrack)
|
||||
{
|
||||
g_return_if_fail (SYSPROF_IS_TRACK (self));
|
||||
g_return_if_fail (SYSPROF_IS_TRACK (subtrack));
|
||||
g_return_if_fail (subtrack != self);
|
||||
|
||||
g_list_store_append (self->subtracks, subtrack);
|
||||
}
|
||||
|
||||
/**
|
||||
* sysprof_track_list_subtracks:
|
||||
* @self: a #SysprofTrack
|
||||
*
|
||||
* Returns: (transfer full) (nullable): a #GListModel of #SysprofTrack
|
||||
*/
|
||||
GListModel *
|
||||
sysprof_track_list_subtracks (SysprofTrack *self)
|
||||
{
|
||||
g_return_val_if_fail (SYSPROF_IS_TRACK (self), NULL);
|
||||
|
||||
if (g_list_model_get_n_items (G_LIST_MODEL (self->subtracks)) == 0)
|
||||
return NULL;
|
||||
|
||||
return g_object_ref (G_LIST_MODEL (self->subtracks));
|
||||
}
|
||||
|
||||
/**
|
||||
* sysprof_track_get_session:
|
||||
* @self: a #SysprofTrack
|
||||
*
|
||||
* Returns: (transfer none) (nullable): a #SysprofSession or %NULL
|
||||
*/
|
||||
SysprofSession *
|
||||
sysprof_track_get_session (SysprofTrack *self)
|
||||
{
|
||||
g_return_val_if_fail (SYSPROF_IS_TRACK (self), NULL);
|
||||
|
||||
return self->session;
|
||||
}
|
||||
|
||||
/**
|
||||
* sysprof_track_get_menu_model:
|
||||
* @self: a #SysprofTrack
|
||||
*
|
||||
* Gets the optional menu model for a track.
|
||||
*
|
||||
* Returns: (transfer none) (nullable): a #GMenuModel or %NULL
|
||||
*/
|
||||
GMenuModel *
|
||||
sysprof_track_get_menu_model (SysprofTrack *self)
|
||||
{
|
||||
g_return_val_if_fail (SYSPROF_IS_TRACK (self), NULL);
|
||||
|
||||
return self->menu_model;
|
||||
}
|
||||
|
||||
GtkWidget *
|
||||
_sysprof_track_create_chart (SysprofTrack *self)
|
||||
{
|
||||
GtkWidget *ret = NULL;
|
||||
|
||||
g_return_val_if_fail (SYSPROF_IS_TRACK (self), NULL);
|
||||
|
||||
g_signal_emit (self, signals[CREATE_CHART], 0, &ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
char *
|
||||
_sysprof_track_format_item_for_display (SysprofTrack *self,
|
||||
gpointer item)
|
||||
{
|
||||
char *ret = NULL;
|
||||
|
||||
g_return_val_if_fail (SYSPROF_IS_TRACK (self), NULL);
|
||||
g_return_val_if_fail (G_IS_OBJECT (item), NULL);
|
||||
|
||||
g_signal_emit (self, signals[FORMAT_ITEM_FOR_DISPLAY], 0, item, &ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@ -1,45 +0,0 @@
|
||||
/* sysprof-track.h
|
||||
*
|
||||
* Copyright 2023 Christian Hergert <chergert@redhat.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
#include <sysprof-analyze.h>
|
||||
|
||||
#include "sysprof-session.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define SYSPROF_TYPE_TRACK (sysprof_track_get_type())
|
||||
|
||||
SYSPROF_AVAILABLE_IN_ALL
|
||||
G_DECLARE_FINAL_TYPE (SysprofTrack, sysprof_track, SYSPROF, TRACK, GObject)
|
||||
|
||||
SYSPROF_AVAILABLE_IN_ALL
|
||||
SysprofSession *sysprof_track_get_session (SysprofTrack *self);
|
||||
SYSPROF_AVAILABLE_IN_ALL
|
||||
const char *sysprof_track_get_title (SysprofTrack *self);
|
||||
SYSPROF_AVAILABLE_IN_ALL
|
||||
GListModel *sysprof_track_list_subtracks (SysprofTrack *self);
|
||||
SYSPROF_AVAILABLE_IN_ALL
|
||||
GMenuModel *sysprof_track_get_menu_model (SysprofTrack *self);
|
||||
|
||||
G_END_DECLS
|
||||
@ -1,720 +0,0 @@
|
||||
/* sysprof-tracks-view.c
|
||||
*
|
||||
* Copyright 2023 Christian Hergert <chergert@redhat.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "sysprof-chart-layer.h"
|
||||
#include "sysprof-css-private.h"
|
||||
#include "sysprof-session-private.h"
|
||||
#include "sysprof-track-view.h"
|
||||
#include "sysprof-tracks-view.h"
|
||||
#include "sysprof-time-ruler.h"
|
||||
|
||||
struct _SysprofTracksView
|
||||
{
|
||||
GtkWidget parent_instance;
|
||||
|
||||
SysprofSession *session;
|
||||
|
||||
GtkBox *box;
|
||||
GtkLabel *informative;
|
||||
GtkWidget *top_left;
|
||||
GtkListView *list_view;
|
||||
SysprofTimeRuler *ruler;
|
||||
GtkLabel *timecode;
|
||||
GtkButton *zoom;
|
||||
|
||||
double motion_x;
|
||||
double motion_y;
|
||||
|
||||
double drag_start_x;
|
||||
double drag_start_y;
|
||||
double drag_offset_x;
|
||||
double drag_offset_y;
|
||||
|
||||
guint in_drag_selection : 1;
|
||||
};
|
||||
|
||||
enum {
|
||||
PROP_0,
|
||||
PROP_SESSION,
|
||||
N_PROPS
|
||||
};
|
||||
|
||||
G_DEFINE_FINAL_TYPE (SysprofTracksView, sysprof_tracks_view, GTK_TYPE_WIDGET)
|
||||
|
||||
static GParamSpec *properties [N_PROPS];
|
||||
|
||||
static void
|
||||
set_motion (SysprofTracksView *self,
|
||||
double x,
|
||||
double y)
|
||||
{
|
||||
gboolean timecode_visible = FALSE;
|
||||
gboolean informative_visible = FALSE;
|
||||
GtkWidget *pick;
|
||||
int ruler_start;
|
||||
|
||||
g_assert (SYSPROF_IS_TRACKS_VIEW (self));
|
||||
|
||||
if (self->motion_x == x && self->motion_y == y)
|
||||
return;
|
||||
|
||||
self->motion_x = x;
|
||||
self->motion_y = y;
|
||||
|
||||
ruler_start = gtk_widget_get_width (self->top_left);
|
||||
timecode_visible = x >= ruler_start;
|
||||
|
||||
if (timecode_visible)
|
||||
{
|
||||
g_autofree char *str = sysprof_time_ruler_get_label_at_point (self->ruler, x - ruler_start);
|
||||
gtk_label_set_label (self->timecode, str);
|
||||
}
|
||||
|
||||
pick = gtk_widget_pick (GTK_WIDGET (self), x, y, 0);
|
||||
|
||||
if (pick != NULL)
|
||||
{
|
||||
SysprofChartLayer *layer = SYSPROF_CHART_LAYER (gtk_widget_get_ancestor (pick, SYSPROF_TYPE_CHART_LAYER));
|
||||
SysprofTrackView *track_view = SYSPROF_TRACK_VIEW (gtk_widget_get_ancestor (pick, SYSPROF_TYPE_TRACK_VIEW));
|
||||
|
||||
if (layer != NULL && track_view != NULL)
|
||||
{
|
||||
SysprofTrack *track = sysprof_track_view_get_track (track_view);
|
||||
g_autoptr(GObject) item = NULL;
|
||||
g_autofree char *text = NULL;
|
||||
double layer_x;
|
||||
double layer_y;
|
||||
|
||||
gtk_widget_translate_coordinates (GTK_WIDGET (self),
|
||||
GTK_WIDGET (layer),
|
||||
x, y, &layer_x, &layer_y);
|
||||
|
||||
if ((item = sysprof_chart_layer_lookup_item (layer, layer_x, layer_y)))
|
||||
text = _sysprof_session_describe (self->session, track, item);
|
||||
|
||||
gtk_label_set_label (self->informative, text);
|
||||
|
||||
informative_visible = text != NULL;
|
||||
}
|
||||
}
|
||||
|
||||
gtk_widget_set_visible (GTK_WIDGET (self->timecode), timecode_visible);
|
||||
gtk_widget_set_visible (GTK_WIDGET (self->informative), informative_visible);
|
||||
|
||||
gtk_widget_queue_draw (GTK_WIDGET (self));
|
||||
}
|
||||
|
||||
static void
|
||||
sysprof_tracks_view_motion_enter_cb (SysprofTracksView *self,
|
||||
double x,
|
||||
double y,
|
||||
GtkEventControllerMotion *motion)
|
||||
{
|
||||
g_assert (SYSPROF_IS_TRACKS_VIEW (self));
|
||||
g_assert (GTK_IS_EVENT_CONTROLLER_MOTION (motion));
|
||||
|
||||
set_motion (self, x, y);
|
||||
}
|
||||
|
||||
static void
|
||||
sysprof_tracks_view_motion_leave_cb (SysprofTracksView *self,
|
||||
GtkEventControllerMotion *motion)
|
||||
{
|
||||
g_assert (SYSPROF_IS_TRACKS_VIEW (self));
|
||||
g_assert (GTK_IS_EVENT_CONTROLLER_MOTION (motion));
|
||||
|
||||
set_motion (self, -1, -1);
|
||||
}
|
||||
|
||||
static void
|
||||
sysprof_tracks_view_motion_cb (SysprofTracksView *self,
|
||||
double x,
|
||||
double y,
|
||||
GtkEventControllerMotion *motion)
|
||||
{
|
||||
g_assert (SYSPROF_IS_TRACKS_VIEW (self));
|
||||
g_assert (GTK_IS_EVENT_CONTROLLER_MOTION (motion));
|
||||
|
||||
set_motion (self, x, y);
|
||||
}
|
||||
|
||||
static void
|
||||
sysprof_tracks_view_drag_begin_cb (SysprofTracksView *self,
|
||||
double start_x,
|
||||
double start_y,
|
||||
GtkGestureDrag *drag)
|
||||
{
|
||||
graphene_rect_t zoom_area;
|
||||
double x, y;
|
||||
|
||||
g_assert (SYSPROF_IS_TRACKS_VIEW (self));
|
||||
g_assert (GTK_IS_GESTURE_DRAG (drag));
|
||||
|
||||
gtk_widget_translate_coordinates (GTK_WIDGET (self->zoom),
|
||||
GTK_WIDGET (self),
|
||||
0, 0, &x, &y);
|
||||
zoom_area = GRAPHENE_RECT_INIT (x, y,
|
||||
gtk_widget_get_width (GTK_WIDGET (self->zoom)),
|
||||
gtk_widget_get_height (GTK_WIDGET (self->zoom)));
|
||||
|
||||
if (start_x < gtk_widget_get_width (self->top_left) ||
|
||||
(gtk_widget_get_visible (GTK_WIDGET (self->zoom)) &&
|
||||
graphene_rect_contains_point (&zoom_area, &GRAPHENE_POINT_INIT (start_x, start_y))))
|
||||
{
|
||||
gtk_gesture_set_state (GTK_GESTURE (drag), GTK_EVENT_SEQUENCE_DENIED);
|
||||
return;
|
||||
}
|
||||
|
||||
self->drag_start_x = start_x;
|
||||
self->drag_start_y = start_y;
|
||||
self->drag_offset_x = 0;
|
||||
self->drag_offset_y = 0;
|
||||
|
||||
gtk_widget_set_visible (GTK_WIDGET (self->zoom), FALSE);
|
||||
|
||||
self->in_drag_selection = TRUE;
|
||||
|
||||
gtk_widget_queue_draw (GTK_WIDGET (self));
|
||||
}
|
||||
|
||||
static void
|
||||
sysprof_tracks_view_drag_end_cb (SysprofTracksView *self,
|
||||
double offset_x,
|
||||
double offset_y,
|
||||
GtkGestureDrag *drag)
|
||||
{
|
||||
int base_x;
|
||||
|
||||
g_assert (SYSPROF_IS_TRACKS_VIEW (self));
|
||||
g_assert (GTK_IS_GESTURE_DRAG (drag));
|
||||
|
||||
if (self->session == NULL)
|
||||
goto cleanup;
|
||||
|
||||
base_x = gtk_widget_get_width (self->top_left);
|
||||
|
||||
if (self->drag_offset_x != .0)
|
||||
{
|
||||
graphene_rect_t selection;
|
||||
graphene_rect_t area;
|
||||
int width;
|
||||
int height;
|
||||
|
||||
width = gtk_widget_get_width (GTK_WIDGET (self)) - base_x;
|
||||
height = gtk_widget_get_height (GTK_WIDGET (self));
|
||||
|
||||
area = GRAPHENE_RECT_INIT (base_x, 0, width, height);
|
||||
selection = GRAPHENE_RECT_INIT (self->drag_start_x,
|
||||
0,
|
||||
self->drag_offset_x,
|
||||
height);
|
||||
graphene_rect_normalize (&selection);
|
||||
|
||||
if (graphene_rect_intersection (&area, &selection, &selection))
|
||||
{
|
||||
double begin = (selection.origin.x - area.origin.x) / area.size.width;
|
||||
double end = (selection.origin.x + selection.size.width - area.origin.x) / area.size.width;
|
||||
const SysprofTimeSpan *visible = sysprof_session_get_visible_time (self->session);
|
||||
gint64 visible_duration = visible->end_nsec - visible->begin_nsec;
|
||||
SysprofTimeSpan to_select;
|
||||
|
||||
to_select.begin_nsec = visible->begin_nsec + (begin * visible_duration);
|
||||
to_select.end_nsec = visible->begin_nsec + (end * visible_duration);
|
||||
|
||||
sysprof_session_select_time (self->session, &to_select);
|
||||
}
|
||||
}
|
||||
else if (self->drag_start_x >= base_x)
|
||||
{
|
||||
sysprof_session_select_time (self->session, sysprof_session_get_visible_time (self->session));
|
||||
}
|
||||
|
||||
cleanup:
|
||||
self->drag_start_x = -1;
|
||||
self->drag_start_y = -1;
|
||||
self->drag_offset_x = 0;
|
||||
self->drag_offset_y = 0;
|
||||
|
||||
self->in_drag_selection = FALSE;
|
||||
|
||||
gtk_widget_queue_draw (GTK_WIDGET (self));
|
||||
}
|
||||
|
||||
static void
|
||||
sysprof_tracks_view_drag_update_cb (SysprofTracksView *self,
|
||||
double offset_x,
|
||||
double offset_y,
|
||||
GtkGestureDrag *drag)
|
||||
{
|
||||
g_assert (SYSPROF_IS_TRACKS_VIEW (self));
|
||||
g_assert (GTK_IS_GESTURE_DRAG (drag));
|
||||
|
||||
self->drag_offset_x = offset_x,
|
||||
self->drag_offset_y = offset_y;
|
||||
|
||||
gtk_widget_queue_draw (GTK_WIDGET (self));
|
||||
}
|
||||
|
||||
static gboolean
|
||||
get_selected_area (SysprofTracksView *self,
|
||||
graphene_rect_t *area,
|
||||
graphene_rect_t *selection)
|
||||
{
|
||||
const SysprofTimeSpan *selected;
|
||||
const SysprofTimeSpan *visible;
|
||||
SysprofTimeSpan relative;
|
||||
gint64 time_duration;
|
||||
double begin;
|
||||
double end;
|
||||
int base_x;
|
||||
int width;
|
||||
int height;
|
||||
|
||||
g_assert (SYSPROF_IS_TRACKS_VIEW (self));
|
||||
g_assert (area != NULL);
|
||||
g_assert (selection != NULL);
|
||||
|
||||
if (self->session == NULL)
|
||||
return FALSE;
|
||||
|
||||
base_x = gtk_widget_get_width (self->top_left);
|
||||
width = gtk_widget_get_width (GTK_WIDGET (self)) - base_x;
|
||||
height = gtk_widget_get_height (GTK_WIDGET (self));
|
||||
|
||||
*area = GRAPHENE_RECT_INIT (base_x, 0, width, height);
|
||||
|
||||
if (self->in_drag_selection && self->drag_offset_x != .0)
|
||||
{
|
||||
*selection = GRAPHENE_RECT_INIT (self->drag_start_x,
|
||||
0,
|
||||
self->drag_offset_x,
|
||||
height);
|
||||
graphene_rect_normalize (selection);
|
||||
return graphene_rect_intersection (area, selection, selection);
|
||||
}
|
||||
|
||||
/* If selected range == visible range, then there is no selection */
|
||||
selected = sysprof_session_get_selected_time (self->session);
|
||||
visible = sysprof_session_get_visible_time (self->session);
|
||||
if (memcmp (selected, visible, sizeof *selected) == 0)
|
||||
return FALSE;
|
||||
|
||||
time_duration = sysprof_time_span_duration (*visible);
|
||||
relative = sysprof_time_span_relative_to (*selected, visible->begin_nsec);
|
||||
|
||||
begin = relative.begin_nsec / (double)time_duration;
|
||||
end = relative.end_nsec / (double)time_duration;
|
||||
|
||||
*selection = GRAPHENE_RECT_INIT (area->origin.x + (begin * width),
|
||||
0,
|
||||
(end * width) - (begin * width),
|
||||
area->size.height);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
sysprof_tracks_view_snapshot (GtkWidget *widget,
|
||||
GtkSnapshot *snapshot)
|
||||
{
|
||||
SysprofTracksView *self = (SysprofTracksView *)widget;
|
||||
graphene_rect_t area;
|
||||
graphene_rect_t selection;
|
||||
GdkRGBA shadow_color;
|
||||
GdkRGBA line_color;
|
||||
GdkRGBA color;
|
||||
|
||||
g_assert (SYSPROF_IS_TRACKS_VIEW (self));
|
||||
g_assert (GTK_IS_SNAPSHOT (snapshot));
|
||||
|
||||
gtk_widget_snapshot_child (GTK_WIDGET (self), GTK_WIDGET (self->box), snapshot);
|
||||
|
||||
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
|
||||
{
|
||||
GtkStyleContext *style_context = gtk_widget_get_style_context (GTK_WIDGET (self));
|
||||
gtk_style_context_get_color (style_context, &color);
|
||||
|
||||
shadow_color = color;
|
||||
shadow_color.alpha *= .1;
|
||||
|
||||
line_color = color;
|
||||
line_color.alpha *= .5;
|
||||
}
|
||||
G_GNUC_END_IGNORE_DEPRECATIONS
|
||||
|
||||
if (get_selected_area (self, &area, &selection))
|
||||
{
|
||||
gtk_snapshot_append_color (snapshot,
|
||||
&shadow_color,
|
||||
&GRAPHENE_RECT_INIT (area.origin.x,
|
||||
area.origin.y,
|
||||
selection.origin.x - area.origin.x,
|
||||
area.size.height));
|
||||
|
||||
gtk_snapshot_append_color (snapshot,
|
||||
&shadow_color,
|
||||
&GRAPHENE_RECT_INIT (selection.origin.x + selection.size.width,
|
||||
area.origin.y,
|
||||
(area.origin.x + area.size.width) - (selection.origin.x + selection.size.width),
|
||||
area.size.height));
|
||||
}
|
||||
|
||||
if (self->motion_x != -1 &&
|
||||
self->motion_y != -1 &&
|
||||
self->motion_x > gtk_widget_get_width (self->top_left))
|
||||
gtk_snapshot_append_color (snapshot,
|
||||
&line_color,
|
||||
&GRAPHENE_RECT_INIT (self->motion_x, 0, 1,
|
||||
gtk_widget_get_height (GTK_WIDGET (self))));
|
||||
|
||||
if (gtk_widget_get_visible (GTK_WIDGET (self->zoom)))
|
||||
gtk_widget_snapshot_child (GTK_WIDGET (self), GTK_WIDGET (self->zoom), snapshot);
|
||||
|
||||
if (gtk_widget_get_visible (GTK_WIDGET (self->timecode)))
|
||||
gtk_widget_snapshot_child (GTK_WIDGET (self), GTK_WIDGET (self->timecode), snapshot);
|
||||
|
||||
if (gtk_widget_get_visible (GTK_WIDGET (self->informative)))
|
||||
gtk_widget_snapshot_child (GTK_WIDGET (self), GTK_WIDGET (self->informative), snapshot);
|
||||
}
|
||||
|
||||
static void
|
||||
sysprof_tracks_view_zoom_to_selection (GtkWidget *widget,
|
||||
const char *action_name,
|
||||
GVariant *params)
|
||||
{
|
||||
SysprofTracksView *self = (SysprofTracksView *)widget;
|
||||
|
||||
g_assert (SYSPROF_IS_TRACKS_VIEW (self));
|
||||
|
||||
if (self->session != NULL)
|
||||
sysprof_session_zoom_to_selection (self->session);
|
||||
}
|
||||
|
||||
static void
|
||||
sysprof_tracks_view_measure (GtkWidget *widget,
|
||||
GtkOrientation orientation,
|
||||
int for_size,
|
||||
int *minimum,
|
||||
int *natural,
|
||||
int *minimum_baseline,
|
||||
int *natural_baseline)
|
||||
{
|
||||
SysprofTracksView *self = (SysprofTracksView *)widget;
|
||||
|
||||
g_assert (SYSPROF_IS_TRACKS_VIEW (self));
|
||||
|
||||
gtk_widget_measure (GTK_WIDGET (self->box),
|
||||
orientation,
|
||||
for_size,
|
||||
minimum,
|
||||
natural,
|
||||
minimum_baseline,
|
||||
natural_baseline);
|
||||
}
|
||||
|
||||
static void
|
||||
sysprof_tracks_view_size_allocate (GtkWidget *widget,
|
||||
int width,
|
||||
int height,
|
||||
int baseline)
|
||||
{
|
||||
SysprofTracksView *self = (SysprofTracksView *)widget;
|
||||
graphene_rect_t area;
|
||||
graphene_rect_t selection;
|
||||
|
||||
g_assert (SYSPROF_IS_TRACKS_VIEW (self));
|
||||
|
||||
gtk_widget_size_allocate (GTK_WIDGET (self->box),
|
||||
&(GtkAllocation) {0, 0, width, height},
|
||||
baseline);
|
||||
|
||||
if (get_selected_area (self, &area, &selection))
|
||||
{
|
||||
graphene_point_t middle;
|
||||
GtkRequisition min_req;
|
||||
GtkRequisition nat_req;
|
||||
|
||||
/* Position the zoom button in the center of the selected area */
|
||||
gtk_widget_get_preferred_size (GTK_WIDGET (self->zoom), &min_req, &nat_req);
|
||||
graphene_rect_get_center (&selection, &middle);
|
||||
gtk_widget_size_allocate (GTK_WIDGET (self->zoom),
|
||||
&(GtkAllocation) {
|
||||
middle.x - (min_req.width/2),
|
||||
middle.y - (min_req.height/2),
|
||||
min_req.width,
|
||||
min_req.height
|
||||
}, -1);
|
||||
}
|
||||
|
||||
if (gtk_widget_get_visible (GTK_WIDGET (self->timecode)))
|
||||
{
|
||||
GtkRequisition min_req;
|
||||
GtkRequisition nat_req;
|
||||
|
||||
gtk_widget_get_preferred_size (GTK_WIDGET (self->timecode), &min_req, &nat_req);
|
||||
|
||||
if (self->motion_x + min_req.width < gtk_widget_get_width (GTK_WIDGET (self)))
|
||||
gtk_widget_size_allocate (GTK_WIDGET (self->timecode),
|
||||
&(GtkAllocation) {
|
||||
self->motion_x, 0,
|
||||
min_req.width, min_req.height
|
||||
}, -1);
|
||||
else
|
||||
gtk_widget_size_allocate (GTK_WIDGET (self->timecode),
|
||||
&(GtkAllocation) {
|
||||
self->motion_x - min_req.width, 0,
|
||||
min_req.width, min_req.height
|
||||
}, -1);
|
||||
}
|
||||
|
||||
if (gtk_widget_get_visible (GTK_WIDGET (self->informative)))
|
||||
{
|
||||
GtkRequisition min_req;
|
||||
GtkRequisition nat_req;
|
||||
|
||||
gtk_widget_get_preferred_size (GTK_WIDGET (self->informative), &min_req, &nat_req);
|
||||
|
||||
if (self->motion_x + min_req.width < gtk_widget_get_width (GTK_WIDGET (self)))
|
||||
gtk_widget_size_allocate (GTK_WIDGET (self->informative),
|
||||
&(GtkAllocation) {
|
||||
self->motion_x, self->motion_y,
|
||||
min_req.width, min_req.height
|
||||
}, -1);
|
||||
else
|
||||
gtk_widget_size_allocate (GTK_WIDGET (self->informative),
|
||||
&(GtkAllocation) {
|
||||
self->motion_x - min_req.width, self->motion_y,
|
||||
min_req.width, min_req.height
|
||||
}, -1);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
sysprof_tracks_view_dispose (GObject *object)
|
||||
{
|
||||
SysprofTracksView *self = (SysprofTracksView *)object;
|
||||
GtkWidget *child;
|
||||
|
||||
sysprof_tracks_view_set_session (self, NULL);
|
||||
|
||||
gtk_widget_dispose_template (GTK_WIDGET (self), SYSPROF_TYPE_TRACKS_VIEW);
|
||||
|
||||
while ((child = gtk_widget_get_first_child (GTK_WIDGET (self))))
|
||||
gtk_widget_unparent (child);
|
||||
|
||||
G_OBJECT_CLASS (sysprof_tracks_view_parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
static void
|
||||
sysprof_tracks_view_get_property (GObject *object,
|
||||
guint prop_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
SysprofTracksView *self = SYSPROF_TRACKS_VIEW (object);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_SESSION:
|
||||
g_value_set_object (value, sysprof_tracks_view_get_session (self));
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
sysprof_tracks_view_set_property (GObject *object,
|
||||
guint prop_id,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
SysprofTracksView *self = SYSPROF_TRACKS_VIEW (object);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_SESSION:
|
||||
sysprof_tracks_view_set_session (self, g_value_get_object (value));
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
sysprof_tracks_view_class_init (SysprofTracksViewClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
|
||||
|
||||
object_class->dispose = sysprof_tracks_view_dispose;
|
||||
object_class->get_property = sysprof_tracks_view_get_property;
|
||||
object_class->set_property = sysprof_tracks_view_set_property;
|
||||
|
||||
widget_class->snapshot = sysprof_tracks_view_snapshot;
|
||||
widget_class->measure = sysprof_tracks_view_measure;
|
||||
widget_class->size_allocate = sysprof_tracks_view_size_allocate;
|
||||
|
||||
properties[PROP_SESSION] =
|
||||
g_param_spec_object ("session", NULL, NULL,
|
||||
SYSPROF_TYPE_SESSION,
|
||||
(G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS));
|
||||
|
||||
g_object_class_install_properties (object_class, N_PROPS, properties);
|
||||
|
||||
gtk_widget_class_set_template_from_resource (widget_class, "/libsysprof-gtk/sysprof-tracks-view.ui");
|
||||
gtk_widget_class_set_css_name (widget_class, "tracks");
|
||||
|
||||
gtk_widget_class_bind_template_child (widget_class, SysprofTracksView, box);
|
||||
gtk_widget_class_bind_template_child (widget_class, SysprofTracksView, informative);
|
||||
gtk_widget_class_bind_template_child (widget_class, SysprofTracksView, list_view);
|
||||
gtk_widget_class_bind_template_child (widget_class, SysprofTracksView, ruler);
|
||||
gtk_widget_class_bind_template_child (widget_class, SysprofTracksView, timecode);
|
||||
gtk_widget_class_bind_template_child (widget_class, SysprofTracksView, top_left);
|
||||
gtk_widget_class_bind_template_child (widget_class, SysprofTracksView, zoom);
|
||||
|
||||
gtk_widget_class_bind_template_callback (widget_class, sysprof_tracks_view_motion_enter_cb);
|
||||
gtk_widget_class_bind_template_callback (widget_class, sysprof_tracks_view_motion_leave_cb);
|
||||
gtk_widget_class_bind_template_callback (widget_class, sysprof_tracks_view_motion_cb);
|
||||
|
||||
gtk_widget_class_bind_template_callback (widget_class, sysprof_tracks_view_drag_begin_cb);
|
||||
gtk_widget_class_bind_template_callback (widget_class, sysprof_tracks_view_drag_end_cb);
|
||||
gtk_widget_class_bind_template_callback (widget_class, sysprof_tracks_view_drag_update_cb);
|
||||
|
||||
gtk_widget_class_install_action (widget_class, "zoom-to-selection", NULL, sysprof_tracks_view_zoom_to_selection);
|
||||
|
||||
g_type_ensure (SYSPROF_TYPE_TIME_RULER);
|
||||
g_type_ensure (SYSPROF_TYPE_TRACK_VIEW);
|
||||
}
|
||||
|
||||
static void
|
||||
sysprof_tracks_view_init (SysprofTracksView *self)
|
||||
{
|
||||
_sysprof_css_init ();
|
||||
|
||||
gtk_widget_init_template (GTK_WIDGET (self));
|
||||
}
|
||||
|
||||
GtkWidget *
|
||||
sysprof_tracks_view_new (void)
|
||||
{
|
||||
return g_object_new (SYSPROF_TYPE_TRACKS_VIEW, NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* sysprof_tracks_view_get_session:
|
||||
* @self: a #SysprofTracksView
|
||||
*
|
||||
* Gets the session for the tracks.
|
||||
*
|
||||
* Returns: (transfer none) (nullable): a #SysprofSession or %NULL
|
||||
*/
|
||||
SysprofSession *
|
||||
sysprof_tracks_view_get_session (SysprofTracksView *self)
|
||||
{
|
||||
g_return_val_if_fail (SYSPROF_IS_TRACKS_VIEW (self), NULL);
|
||||
|
||||
return self->session;
|
||||
}
|
||||
|
||||
static GListModel *
|
||||
sysprof_tracks_view_create_model_func (gpointer item,
|
||||
gpointer user_data)
|
||||
{
|
||||
g_assert (SYSPROF_IS_TRACK (item));
|
||||
|
||||
return sysprof_track_list_subtracks (item);
|
||||
}
|
||||
|
||||
static void
|
||||
sysprof_tracks_view_notify_time_cb (SysprofTracksView *self,
|
||||
GParamSpec *pspec,
|
||||
SysprofSession *session)
|
||||
{
|
||||
const SysprofTimeSpan *visible;
|
||||
const SysprofTimeSpan *selected;
|
||||
gboolean button_visible;
|
||||
|
||||
g_assert (SYSPROF_IS_TRACKS_VIEW (self));
|
||||
g_assert (SYSPROF_IS_SESSION (session));
|
||||
|
||||
visible = sysprof_session_get_visible_time (session);
|
||||
selected = sysprof_session_get_selected_time (session);
|
||||
|
||||
button_visible = memcmp (visible, selected, sizeof *visible) != 0;
|
||||
|
||||
gtk_widget_set_visible (GTK_WIDGET (self->zoom), button_visible);
|
||||
}
|
||||
|
||||
void
|
||||
sysprof_tracks_view_set_session (SysprofTracksView *self,
|
||||
SysprofSession *session)
|
||||
{
|
||||
g_return_if_fail (SYSPROF_IS_TRACKS_VIEW (self));
|
||||
g_return_if_fail (!session || SYSPROF_IS_SESSION (session));
|
||||
|
||||
if (self->session == session)
|
||||
return;
|
||||
|
||||
if (self->session)
|
||||
{
|
||||
g_signal_handlers_disconnect_by_func (self->session,
|
||||
G_CALLBACK (sysprof_tracks_view_notify_time_cb),
|
||||
self);
|
||||
gtk_list_view_set_model (self->list_view, NULL);
|
||||
g_clear_object (&self->session);
|
||||
}
|
||||
|
||||
if (session)
|
||||
{
|
||||
g_autoptr(GtkTreeListModel) tree_list_model = NULL;
|
||||
g_autoptr(GtkNoSelection) no = NULL;
|
||||
g_autoptr(GListModel) tracks = NULL;
|
||||
|
||||
self->session = g_object_ref (session);
|
||||
|
||||
tracks = sysprof_session_list_tracks (session);
|
||||
tree_list_model = gtk_tree_list_model_new (g_object_ref (tracks),
|
||||
FALSE,
|
||||
FALSE,
|
||||
sysprof_tracks_view_create_model_func,
|
||||
self, NULL);
|
||||
no = gtk_no_selection_new (g_object_ref (G_LIST_MODEL (tree_list_model)));
|
||||
|
||||
gtk_list_view_set_model (self->list_view, GTK_SELECTION_MODEL (no));
|
||||
|
||||
g_signal_connect_object (session,
|
||||
"notify::selected-time",
|
||||
G_CALLBACK (sysprof_tracks_view_notify_time_cb),
|
||||
self,
|
||||
G_CONNECT_SWAPPED);
|
||||
g_signal_connect_object (session,
|
||||
"notify::visible-time",
|
||||
G_CALLBACK (sysprof_tracks_view_notify_time_cb),
|
||||
self,
|
||||
G_CONNECT_SWAPPED);
|
||||
}
|
||||
|
||||
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_SESSION]);
|
||||
}
|
||||
@ -1,44 +0,0 @@
|
||||
/* sysprof-tracks-view.h
|
||||
*
|
||||
* Copyright 2023 Christian Hergert <chergert@redhat.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
#include <sysprof-analyze.h>
|
||||
|
||||
#include "sysprof-session.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define SYSPROF_TYPE_TRACKS_VIEW (sysprof_tracks_view_get_type())
|
||||
|
||||
SYSPROF_AVAILABLE_IN_ALL
|
||||
G_DECLARE_FINAL_TYPE (SysprofTracksView, sysprof_tracks_view, SYSPROF, TRACKS_VIEW, GtkWidget)
|
||||
|
||||
SYSPROF_AVAILABLE_IN_ALL
|
||||
GtkWidget *sysprof_tracks_view_new (void);
|
||||
SYSPROF_AVAILABLE_IN_ALL
|
||||
SysprofSession *sysprof_tracks_view_get_session (SysprofTracksView *self);
|
||||
SYSPROF_AVAILABLE_IN_ALL
|
||||
void sysprof_tracks_view_set_session (SysprofTracksView *self,
|
||||
SysprofSession *session);
|
||||
|
||||
G_END_DECLS
|
||||
@ -1,181 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<interface>
|
||||
<template class="SysprofTracksView" parent="GtkWidget">
|
||||
<child>
|
||||
<object class="GtkBox" id="box">
|
||||
<child>
|
||||
<object class="GtkEventControllerMotion" id="motion">
|
||||
<property name="propagation-phase">capture</property>
|
||||
<signal name="enter" handler="sysprof_tracks_view_motion_enter_cb" swapped="true"/>
|
||||
<signal name="leave" handler="sysprof_tracks_view_motion_leave_cb" swapped="true"/>
|
||||
<signal name="motion" handler="sysprof_tracks_view_motion_cb" swapped="true"/>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkGestureDrag" id="drag">
|
||||
<property name="propagation-phase">bubble</property>
|
||||
<signal name="drag-begin" handler="sysprof_tracks_view_drag_begin_cb" swapped="true"/>
|
||||
<signal name="drag-end" handler="sysprof_tracks_view_drag_end_cb" swapped="true"/>
|
||||
<signal name="drag-update" handler="sysprof_tracks_view_drag_update_cb" swapped="true"/>
|
||||
</object>
|
||||
</child>
|
||||
<property name="orientation">vertical</property>
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<child>
|
||||
<object class="GtkInscription" id="top_left">
|
||||
<property name="min-chars">30</property>
|
||||
<property name="nat-chars">30</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="SysprofTimeRuler" id="ruler">
|
||||
<property name="hexpand">true</property>
|
||||
<binding name="session">
|
||||
<lookup name="session">SysprofTracksView</lookup>
|
||||
</binding>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkScrolledWindow">
|
||||
<property name="hscrollbar-policy">never</property>
|
||||
<property name="propagate-natural-height">true</property>
|
||||
<property name="vexpand">true</property>
|
||||
<child>
|
||||
<object class="GtkListView" id="list_view">
|
||||
<property name="factory">
|
||||
<object class="GtkBuilderListItemFactory">
|
||||
<property name="bytes"><![CDATA[
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<interface>
|
||||
<template class="GtkListItem">
|
||||
<property name="child">
|
||||
<object class="GtkBox">
|
||||
<property name="css-name">track</property>
|
||||
<child>
|
||||
<object class="GtkStack">
|
||||
<property name="css-name">info</property>
|
||||
<property name="hhomogeneous">true</property>
|
||||
<property name="vhomogeneous">true</property>
|
||||
<property name="hexpand">false</property>
|
||||
<child>
|
||||
<object class="GtkStackPage">
|
||||
<property name="child">
|
||||
<object class="GtkTreeExpander">
|
||||
<binding name="list-row">
|
||||
<lookup name="item">GtkListItem</lookup>
|
||||
</binding>
|
||||
<property name="child">
|
||||
<object class="GtkBox">
|
||||
<property name="spacing">6</property>
|
||||
<child>
|
||||
<object class="GtkInscription" id="title">
|
||||
<property name="hexpand">true</property>
|
||||
<property name="text-overflow">ellipsize-end</property>
|
||||
<style>
|
||||
<class name="heading"/>
|
||||
</style>
|
||||
<binding name="text">
|
||||
<lookup name="title" type="SysprofTrack">
|
||||
<lookup name="item" type="GtkTreeListRow">
|
||||
<lookup name="item">GtkListItem</lookup>
|
||||
</lookup>
|
||||
</lookup>
|
||||
</binding>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkMenuButton">
|
||||
<style>
|
||||
<class name="flat"/>
|
||||
</style>
|
||||
<property name="icon-name">view-more-symbolic</property>
|
||||
<binding name="menu-model">
|
||||
<lookup name="menu-model" type="SysprofTrack">
|
||||
<lookup name="item" type="GtkTreeListRow">
|
||||
<lookup name="item">GtkListItem</lookup>
|
||||
</lookup>
|
||||
</lookup>
|
||||
</binding>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</property>
|
||||
</object>
|
||||
</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkStackPage">
|
||||
<property name="child">
|
||||
<object class="GtkInscription">
|
||||
<property name="min-chars">30</property>
|
||||
<property name="nat-chars">30</property>
|
||||
</object>
|
||||
</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="SysprofTrackView">
|
||||
<property name="hexpand">true</property>
|
||||
<binding name="track">
|
||||
<lookup name="item" type="GtkTreeListRow">
|
||||
<lookup name="item">GtkListItem</lookup>
|
||||
</lookup>
|
||||
</binding>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</property>
|
||||
</template>
|
||||
</interface>
|
||||
]]>
|
||||
</property>
|
||||
</object>
|
||||
</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton" id="zoom">
|
||||
<property name="action-name">zoom-to-selection</property>
|
||||
<property name="icon-name">zoom-in-symbolic</property>
|
||||
<property name="valign">center</property>
|
||||
<property name="halign">center</property>
|
||||
<property name="visible">false</property>
|
||||
<style>
|
||||
<class name="circular"/>
|
||||
</style>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="timecode">
|
||||
<property name="css-name">timecode</property>
|
||||
<property name="can-focus">false</property>
|
||||
<property name="can-target">false</property>
|
||||
<property name="visible">false</property>
|
||||
<property name="xalign">.5</property>
|
||||
<property name="single-line-mode">true</property>
|
||||
<property name="width-chars">10</property>
|
||||
<property name="max-width-chars">10</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkLabel" id="informative">
|
||||
<property name="css-name">informative</property>
|
||||
<property name="can-focus">false</property>
|
||||
<property name="can-target">false</property>
|
||||
<property name="visible">false</property>
|
||||
<property name="xalign">0</property>
|
||||
<property name="single-line-mode">true</property>
|
||||
</object>
|
||||
</child>
|
||||
</template>
|
||||
</interface>
|
||||
@ -1,44 +0,0 @@
|
||||
libsysprof_gtk_test_env = [
|
||||
'G_DEBUG=gc-friendly',
|
||||
'GSETTINGS_BACKEND=memory',
|
||||
'MALLOC_CHECK_=2',
|
||||
]
|
||||
|
||||
libsysprof_gtk_testsuite_c_args = [
|
||||
'-DG_LOG_DOMAIN="libsysprof-gtk"',
|
||||
'-DG_ENABLE_DEBUG',
|
||||
'-UG_DISABLE_ASSERT',
|
||||
'-UG_DISABLE_CAST_CHECKS',
|
||||
]
|
||||
|
||||
libsysprof_gtk_testsuite = {
|
||||
'test-callgraph' : {'skip': true},
|
||||
'test-charts' : {'skip': true},
|
||||
'test-files' : {'skip': true},
|
||||
'test-processes' : {'skip': true},
|
||||
'test-tracks' : {'skip': true},
|
||||
'test-mark-chart' : {'skip': true},
|
||||
'test-mark-table' : {'skip': true},
|
||||
}
|
||||
|
||||
libsysprof_gtk_testsuite_deps = [
|
||||
libsysprof_analyze_static_dep,
|
||||
libsysprof_gtk_static_dep,
|
||||
]
|
||||
|
||||
tests_resources = gnome.compile_resources(
|
||||
'tests-resources',
|
||||
'tests.gresource.xml',
|
||||
c_name: 'tests',
|
||||
)
|
||||
|
||||
foreach test, params: libsysprof_gtk_testsuite
|
||||
test_exe = executable(test,
|
||||
['@0@.c'.format(test), tests_resources[0]],
|
||||
c_args: libsysprof_gtk_testsuite_c_args,
|
||||
dependencies: libsysprof_gtk_testsuite_deps,
|
||||
)
|
||||
if not params.get('skip', false)
|
||||
test(test, test_exe, env: libsysprof_gtk_test_env)
|
||||
endif
|
||||
endforeach
|
||||
@ -1,180 +0,0 @@
|
||||
/* test-callgraph.c
|
||||
*
|
||||
* Copyright 2023 Christian Hergert <chergert@redhat.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <adwaita.h>
|
||||
#include <gtk/gtk.h>
|
||||
#include <sysprof-analyze.h>
|
||||
#include <sysprof-gtk.h>
|
||||
|
||||
static GMainLoop *main_loop;
|
||||
static char *kallsyms_path;
|
||||
static char *filename;
|
||||
static gboolean include_threads;
|
||||
static gboolean hide_system_libraries;
|
||||
static const GOptionEntry entries[] = {
|
||||
{ "kallsyms", 'k', 0, G_OPTION_ARG_FILENAME, &kallsyms_path, "The path to kallsyms to use for decoding", "PATH" },
|
||||
{ "threads", 't', 0, G_OPTION_ARG_NONE, &include_threads, "Include threads in the callgraph" },
|
||||
{ "hide-system-libraries", 's', 0, G_OPTION_ARG_NONE, &hide_system_libraries, "Hide system libraries in the callgraph" },
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
static void
|
||||
load_cb (GObject *object,
|
||||
GAsyncResult *result,
|
||||
gpointer user_data)
|
||||
{
|
||||
g_autoptr(GtkWidget) view = user_data;
|
||||
g_autoptr(SysprofDocument) document = NULL;
|
||||
g_autoptr(GListModel) model = NULL;
|
||||
g_autoptr(GError) error = NULL;
|
||||
|
||||
document = sysprof_document_loader_load_finish (SYSPROF_DOCUMENT_LOADER (object), result, &error);
|
||||
g_assert_no_error (error);
|
||||
g_assert_nonnull (document);
|
||||
|
||||
model = sysprof_document_list_samples (document);
|
||||
|
||||
g_object_set (view,
|
||||
"document", document,
|
||||
"traceables", model,
|
||||
NULL);
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc,
|
||||
char *argv[])
|
||||
{
|
||||
g_autoptr(GOptionContext) context = g_option_context_new ("- show a callgraph");
|
||||
g_autoptr(SysprofDocumentLoader) loader = NULL;
|
||||
g_autoptr(SysprofDocument) document = NULL;
|
||||
g_autoptr(SysprofMultiSymbolizer) multi = NULL;
|
||||
g_autoptr(GError) error = NULL;
|
||||
SysprofCallgraphView *view;
|
||||
GtkWidget *box;
|
||||
GtkWidget *hbox;
|
||||
GtkWidget *status;
|
||||
GtkWidget *progress;
|
||||
GtkWidget *message;
|
||||
GtkWidget *threads;
|
||||
GtkWidget *system_libs;
|
||||
GtkWindow *window;
|
||||
|
||||
sysprof_clock_init ();
|
||||
|
||||
gtk_init ();
|
||||
adw_init ();
|
||||
|
||||
g_option_context_add_main_entries (context, entries, NULL);
|
||||
if (!g_option_context_parse (context, &argc, &argv, &error))
|
||||
{
|
||||
g_printerr ("%s\n", error->message);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (argc != 2)
|
||||
{
|
||||
g_print ("usage: %s [OPTIONS] CAPTURE_FILE\n", argv[0]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
filename = argv[1];
|
||||
|
||||
main_loop = g_main_loop_new (NULL, FALSE);
|
||||
|
||||
multi = sysprof_multi_symbolizer_new ();
|
||||
|
||||
if (kallsyms_path)
|
||||
{
|
||||
g_autoptr(GFile) kallsyms_file = g_file_new_for_path (kallsyms_path);
|
||||
GFileInputStream *kallsyms_stream = g_file_read (kallsyms_file, NULL, NULL);
|
||||
|
||||
sysprof_multi_symbolizer_take (multi, sysprof_kallsyms_symbolizer_new_for_symbols (G_INPUT_STREAM (kallsyms_stream)));
|
||||
}
|
||||
else
|
||||
{
|
||||
sysprof_multi_symbolizer_take (multi, sysprof_kallsyms_symbolizer_new ());
|
||||
}
|
||||
|
||||
sysprof_multi_symbolizer_take (multi, sysprof_elf_symbolizer_new ());
|
||||
sysprof_multi_symbolizer_take (multi, sysprof_jitmap_symbolizer_new ());
|
||||
|
||||
loader = sysprof_document_loader_new (filename);
|
||||
sysprof_document_loader_set_symbolizer (loader, SYSPROF_SYMBOLIZER (multi));
|
||||
|
||||
window = g_object_new (GTK_TYPE_WINDOW,
|
||||
"default-width", 800,
|
||||
"default-height", 600,
|
||||
NULL);
|
||||
box = g_object_new (GTK_TYPE_BOX,
|
||||
"orientation", GTK_ORIENTATION_VERTICAL,
|
||||
"spacing", 12,
|
||||
NULL);
|
||||
hbox = g_object_new (GTK_TYPE_BOX,
|
||||
"spacing", 6,
|
||||
NULL);
|
||||
gtk_box_append (GTK_BOX (box), hbox);
|
||||
gtk_box_append (GTK_BOX (hbox), gtk_label_new ("Show Threads"));
|
||||
threads = g_object_new (GTK_TYPE_SWITCH,
|
||||
"active", include_threads,
|
||||
NULL);
|
||||
gtk_box_append (GTK_BOX (hbox), threads);
|
||||
gtk_box_append (GTK_BOX (hbox), gtk_label_new ("Hide System Libraries"));
|
||||
system_libs = g_object_new (GTK_TYPE_SWITCH,
|
||||
"active", hide_system_libraries,
|
||||
NULL);
|
||||
gtk_box_append (GTK_BOX (hbox), system_libs);
|
||||
view = g_object_new (SYSPROF_TYPE_WEIGHTED_CALLGRAPH_VIEW,
|
||||
"include-threads", include_threads,
|
||||
"hide-system-libraries", hide_system_libraries,
|
||||
"vexpand", TRUE,
|
||||
NULL);
|
||||
gtk_box_append (GTK_BOX (box), GTK_WIDGET (view));
|
||||
g_signal_connect_swapped (window,
|
||||
"close-request",
|
||||
G_CALLBACK (g_main_loop_quit),
|
||||
main_loop);
|
||||
status = g_object_new (GTK_TYPE_BOX,
|
||||
"spacing", 6,
|
||||
NULL);
|
||||
message = g_object_new (GTK_TYPE_LABEL,
|
||||
"xalign", 1.f,
|
||||
"hexpand", TRUE,
|
||||
NULL);
|
||||
progress = g_object_new (GTK_TYPE_PROGRESS_BAR,
|
||||
NULL);
|
||||
gtk_box_append (GTK_BOX (status), message);
|
||||
gtk_box_append (GTK_BOX (status), progress);
|
||||
gtk_box_append (GTK_BOX (box), status);
|
||||
gtk_window_set_child (window, box);
|
||||
gtk_window_present (window);
|
||||
|
||||
g_object_bind_property (threads, "active", view, "include-threads", 0);
|
||||
g_object_bind_property (system_libs, "active", view, "hide-system-libraries", 0);
|
||||
g_object_bind_property (loader, "message", message, "label", 0);
|
||||
g_object_bind_property (loader, "fraction", progress, "fraction", 0);
|
||||
|
||||
sysprof_document_loader_load_async (loader, NULL, load_cb, g_object_ref (view));
|
||||
|
||||
g_main_loop_run (main_loop);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -1,269 +0,0 @@
|
||||
/* test-charts.c
|
||||
*
|
||||
* Copyright 2023 Christian Hergert <chergert@redhat.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <adwaita.h>
|
||||
#include <libpanel.h>
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
#include <sysprof-analyze.h>
|
||||
#include <sysprof-gtk.h>
|
||||
|
||||
static GMainLoop *main_loop;
|
||||
static char *filename;
|
||||
static const GOptionEntry entries[] = {
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
#define TEST_TYPE_CHARTS (test_charts_get_type())
|
||||
G_DECLARE_FINAL_TYPE (TestCharts, test_charts, TEST, CHARTS, AdwWindow)
|
||||
|
||||
struct _TestCharts
|
||||
{
|
||||
AdwWindow parent_instance;
|
||||
|
||||
SysprofDocument *document;
|
||||
SysprofSession *session;
|
||||
};
|
||||
|
||||
G_DEFINE_FINAL_TYPE (TestCharts, test_charts, ADW_TYPE_WINDOW)
|
||||
|
||||
enum {
|
||||
PROP_0,
|
||||
PROP_DOCUMENT,
|
||||
PROP_SESSION,
|
||||
N_PROPS
|
||||
};
|
||||
|
||||
static GParamSpec *properties [N_PROPS];
|
||||
|
||||
static gboolean
|
||||
activate_layer_item_cb (SysprofChart *chart,
|
||||
SysprofChartLayer *layer,
|
||||
gpointer item,
|
||||
TestCharts *test)
|
||||
{
|
||||
g_assert (SYSPROF_IS_CHART (chart));
|
||||
g_assert (SYSPROF_IS_CHART_LAYER (layer));
|
||||
g_assert (G_IS_OBJECT (item));
|
||||
g_assert (TEST_IS_CHARTS (test));
|
||||
|
||||
g_print ("Activated %s in layer '%s' [%s]\n",
|
||||
G_OBJECT_TYPE_NAME (item),
|
||||
sysprof_chart_layer_get_title (layer),
|
||||
G_OBJECT_TYPE_NAME (layer));
|
||||
|
||||
if (SYSPROF_IS_DOCUMENT_FRAME (item))
|
||||
{
|
||||
g_print ("time_offset=%"G_GINT64_FORMAT" pid=%d\n",
|
||||
sysprof_document_frame_get_time_offset (item),
|
||||
sysprof_document_frame_get_pid (item));
|
||||
}
|
||||
|
||||
if (SYSPROF_IS_DOCUMENT_TRACEABLE (item))
|
||||
{
|
||||
guint depth = sysprof_document_traceable_get_stack_depth (item);
|
||||
|
||||
g_print ("Thread-Id: %u\n",
|
||||
sysprof_document_traceable_get_thread_id (item));
|
||||
g_print ("Stack Depth: %u\n", depth);
|
||||
|
||||
if (depth <= 128)
|
||||
{
|
||||
SysprofSymbol *symbols[128];
|
||||
SysprofAddressContext final_context;
|
||||
guint n_symbols = G_N_ELEMENTS (symbols);
|
||||
|
||||
n_symbols = sysprof_document_symbolize_traceable (test->document,
|
||||
item,
|
||||
symbols,
|
||||
n_symbols,
|
||||
&final_context);
|
||||
|
||||
for (guint i = 0; i < n_symbols; i++)
|
||||
g_print (" %s\n", sysprof_symbol_get_name (symbols[i]));
|
||||
}
|
||||
}
|
||||
|
||||
return GDK_EVENT_STOP;
|
||||
}
|
||||
|
||||
static void
|
||||
test_charts_set_document (TestCharts *self,
|
||||
SysprofDocument *document)
|
||||
{
|
||||
if (g_set_object (&self->document, document))
|
||||
{
|
||||
g_clear_object (&self->session);
|
||||
|
||||
self->session = sysprof_session_new (self->document);
|
||||
|
||||
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_DOCUMENT]);
|
||||
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_SESSION]);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
test_charts_dispose (GObject *object)
|
||||
{
|
||||
TestCharts *self = (TestCharts *)object;
|
||||
|
||||
g_clear_object (&self->document);
|
||||
g_clear_object (&self->session);
|
||||
|
||||
G_OBJECT_CLASS (test_charts_parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
static void
|
||||
test_charts_get_property (GObject *object,
|
||||
guint prop_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
TestCharts *self = TEST_CHARTS (object);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_DOCUMENT:
|
||||
g_value_set_object (value, self->document);
|
||||
break;
|
||||
|
||||
case PROP_SESSION:
|
||||
g_value_set_object (value, self->session);
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
test_charts_set_property (GObject *object,
|
||||
guint prop_id,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
TestCharts *self = TEST_CHARTS (object);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_DOCUMENT:
|
||||
test_charts_set_document (self, g_value_get_object (value));
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
test_charts_class_init (TestChartsClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
|
||||
|
||||
object_class->dispose = test_charts_dispose;
|
||||
object_class->get_property = test_charts_get_property;
|
||||
object_class->set_property = test_charts_set_property;
|
||||
|
||||
properties [PROP_DOCUMENT] =
|
||||
g_param_spec_object ("document", NULL, NULL,
|
||||
SYSPROF_TYPE_DOCUMENT,
|
||||
(G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
|
||||
|
||||
properties [PROP_SESSION] =
|
||||
g_param_spec_object ("session", NULL, NULL,
|
||||
SYSPROF_TYPE_SESSION,
|
||||
(G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
|
||||
|
||||
g_object_class_install_properties (object_class, N_PROPS, properties);
|
||||
|
||||
gtk_widget_class_set_template_from_resource (widget_class, "/test-charts.ui");
|
||||
gtk_widget_class_bind_template_callback (widget_class, activate_layer_item_cb);
|
||||
|
||||
g_type_ensure (SYSPROF_TYPE_CHART);
|
||||
g_type_ensure (SYSPROF_TYPE_CHART_LAYER);
|
||||
g_type_ensure (SYSPROF_TYPE_COLUMN_LAYER);
|
||||
g_type_ensure (SYSPROF_TYPE_LINE_LAYER);
|
||||
g_type_ensure (SYSPROF_TYPE_DOCUMENT_COUNTER_VALUE);
|
||||
g_type_ensure (SYSPROF_TYPE_VALUE_AXIS);
|
||||
g_type_ensure (SYSPROF_TYPE_SESSION_MODEL);
|
||||
g_type_ensure (SYSPROF_TYPE_SESSION_MODEL_ITEM);
|
||||
g_type_ensure (SYSPROF_TYPE_DUPLEX_LAYER);
|
||||
g_type_ensure (SYSPROF_TYPE_TIME_RULER);
|
||||
}
|
||||
|
||||
static void
|
||||
test_charts_init (TestCharts *self)
|
||||
{
|
||||
gtk_widget_init_template (GTK_WIDGET (self));
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc,
|
||||
char *argv[])
|
||||
{
|
||||
g_autoptr(GOptionContext) context = g_option_context_new ("- test various charts");
|
||||
g_autoptr(SysprofDocumentLoader) loader = NULL;
|
||||
g_autoptr(SysprofDocument) document = NULL;
|
||||
g_autoptr(GError) error = NULL;
|
||||
GtkWindow *window;
|
||||
|
||||
sysprof_clock_init ();
|
||||
|
||||
gtk_init ();
|
||||
adw_init ();
|
||||
|
||||
g_option_context_add_main_entries (context, entries, NULL);
|
||||
if (!g_option_context_parse (context, &argc, &argv, &error))
|
||||
{
|
||||
g_printerr ("%s\n", error->message);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (argc != 2)
|
||||
{
|
||||
g_print ("usage: %s [OPTIONS] CAPTURE_FILE\n", argv[0]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
filename = argv[1];
|
||||
|
||||
main_loop = g_main_loop_new (NULL, FALSE);
|
||||
|
||||
loader = sysprof_document_loader_new (filename);
|
||||
if (!(document = sysprof_document_loader_load (loader, NULL, &error)))
|
||||
g_error ("Failed to load document: %s", error->message);
|
||||
|
||||
window = g_object_new (TEST_TYPE_CHARTS,
|
||||
"default-width", 800,
|
||||
"default-height", 600,
|
||||
"document", document,
|
||||
NULL);
|
||||
g_signal_connect_swapped (window,
|
||||
"close-request",
|
||||
G_CALLBACK (g_main_loop_quit),
|
||||
main_loop);
|
||||
gtk_window_present (window);
|
||||
g_main_loop_run (main_loop);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -1,303 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<interface>
|
||||
<template class="TestCharts" parent="AdwWindow">
|
||||
<child>
|
||||
<object class="AdwToolbarView">
|
||||
<property name="top-bar-style">raised</property>
|
||||
<child type="top">
|
||||
<object class="AdwHeaderBar">
|
||||
</object>
|
||||
</child>
|
||||
<property name="content">
|
||||
<object class="GtkPaned">
|
||||
<property name="position">200</property>
|
||||
<child type="start">
|
||||
<object class="GtkBox">
|
||||
<property name="orientation">vertical</property>
|
||||
<child>
|
||||
<object class="SysprofChart">
|
||||
<property name="height-request">128</property>
|
||||
<signal name="activate-layer-item" handler="activate_layer_item_cb"/>
|
||||
<child>
|
||||
<object class="SysprofColumnLayer">
|
||||
<property name="title">Stack Traces</property>
|
||||
<binding name="x-axis">
|
||||
<lookup name="selected-time-axis" type="SysprofSession">
|
||||
<lookup name="session">TestCharts</lookup>
|
||||
</lookup>
|
||||
</binding>
|
||||
<property name="y-axis">
|
||||
<object class="SysprofValueAxis">
|
||||
<property name="min-value">0</property>
|
||||
<property name="max-value">128</property>
|
||||
</object>
|
||||
</property>
|
||||
<property name="series">
|
||||
<object class="SysprofXYSeries">
|
||||
<property name="model">
|
||||
<object class="GtkFilterListModel">
|
||||
<binding name="filter">
|
||||
<lookup name="filter" type="SysprofSession">
|
||||
<lookup name="session">TestCharts</lookup>
|
||||
</lookup>
|
||||
</binding>
|
||||
<binding name="model">
|
||||
<lookup name="samples" type="SysprofDocument">
|
||||
<lookup name="document">TestCharts</lookup>
|
||||
</lookup>
|
||||
</binding>
|
||||
</object>
|
||||
</property>
|
||||
<property name="x-expression">
|
||||
<lookup name="time" type="SysprofDocumentFrame"/>
|
||||
</property>
|
||||
<property name="y-expression">
|
||||
<lookup name="stack-depth" type="SysprofDocumentTraceable"/>
|
||||
</property>
|
||||
</object>
|
||||
</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="SysprofChart">
|
||||
<property name="height-request">128</property>
|
||||
<signal name="activate-layer-item" handler="activate_layer_item_cb"/>
|
||||
<child>
|
||||
<object class="SysprofDuplexLayer">
|
||||
<property name="upper-layer">
|
||||
<object class="SysprofLineLayer">
|
||||
<property name="vexpand">true</property>
|
||||
<binding name="x-axis">
|
||||
<lookup name="selected-time-axis" type="SysprofSession">
|
||||
<lookup name="session">TestCharts</lookup>
|
||||
</lookup>
|
||||
</binding>
|
||||
<property name="y-axis">
|
||||
<object class="SysprofValueAxis">
|
||||
<property name="min-value">0</property>
|
||||
<property name="max-value">128</property>
|
||||
</object>
|
||||
</property>
|
||||
<property name="series">
|
||||
<object class="SysprofXYSeries">
|
||||
<property name="model">
|
||||
<object class="GtkFilterListModel">
|
||||
<binding name="filter">
|
||||
<lookup name="filter" type="SysprofSession">
|
||||
<lookup name="session">TestCharts</lookup>
|
||||
</lookup>
|
||||
</binding>
|
||||
<binding name="model">
|
||||
<lookup name="samples" type="SysprofDocument">
|
||||
<lookup name="document">TestCharts</lookup>
|
||||
</lookup>
|
||||
</binding>
|
||||
</object>
|
||||
</property>
|
||||
<property name="x-expression">
|
||||
<lookup name="time" type="SysprofDocumentFrame"/>
|
||||
</property>
|
||||
<property name="y-expression">
|
||||
<lookup name="stack-depth" type="SysprofDocumentTraceable"/>
|
||||
</property>
|
||||
</object>
|
||||
</property>
|
||||
</object>
|
||||
</property>
|
||||
<property name="lower-layer">
|
||||
<object class="SysprofLineLayer">
|
||||
<property name="antialias">false</property>
|
||||
<property name="vexpand">true</property>
|
||||
<property name="flip-y">true</property>
|
||||
<binding name="x-axis">
|
||||
<lookup name="selected-time-axis" type="SysprofSession">
|
||||
<lookup name="session">TestCharts</lookup>
|
||||
</lookup>
|
||||
</binding>
|
||||
<property name="y-axis">
|
||||
<object class="SysprofValueAxis">
|
||||
<property name="min-value">0</property>
|
||||
<property name="max-value">128</property>
|
||||
</object>
|
||||
</property>
|
||||
<property name="series">
|
||||
<object class="SysprofXYSeries">
|
||||
<property name="model">
|
||||
<object class="GtkFilterListModel">
|
||||
<binding name="filter">
|
||||
<lookup name="filter" type="SysprofSession">
|
||||
<lookup name="session">TestCharts</lookup>
|
||||
</lookup>
|
||||
</binding>
|
||||
<binding name="model">
|
||||
<lookup name="samples" type="SysprofDocument">
|
||||
<lookup name="document">TestCharts</lookup>
|
||||
</lookup>
|
||||
</binding>
|
||||
</object>
|
||||
</property>
|
||||
<property name="x-expression">
|
||||
<lookup name="time" type="SysprofDocumentFrame"/>
|
||||
</property>
|
||||
<property name="y-expression">
|
||||
<lookup name="stack-depth" type="SysprofDocumentTraceable"/>
|
||||
</property>
|
||||
</object>
|
||||
</property>
|
||||
</object>
|
||||
</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child type="end">
|
||||
<object class="GtkBox">
|
||||
<property name="orientation">vertical</property>
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<child>
|
||||
<object class="GtkInscription">
|
||||
<property name="nat-chars">35</property>
|
||||
<property name="min-chars">35</property>
|
||||
<property name="margin-end">8</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="SysprofTimeRuler" id="ruler">
|
||||
<property name="height-request">24</property>
|
||||
<property name="hexpand">true</property>
|
||||
<binding name="session">
|
||||
<lookup name="session">TestCharts</lookup>
|
||||
</binding>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkScrolledWindow">
|
||||
<property name="hscrollbar-policy">never</property>
|
||||
<property name="vexpand">true</property>
|
||||
<style>
|
||||
<class name="undershoot-top"/>
|
||||
</style>
|
||||
<child>
|
||||
<object class="GtkListView">
|
||||
<property name="show-separators">true</property>
|
||||
<style>
|
||||
<class name="data-table"/>
|
||||
</style>
|
||||
<property name="model">
|
||||
<object class="GtkNoSelection">
|
||||
<property name="model">
|
||||
<object class="SysprofSessionModel">
|
||||
<property name="session" bind-source="TestCharts" bind-property="session" bind-flags="sync-create"/>
|
||||
<binding name="model">
|
||||
<lookup name="counters" type="SysprofDocument">
|
||||
<lookup name="document">TestCharts</lookup>
|
||||
</lookup>
|
||||
</binding>
|
||||
</object>
|
||||
</property>
|
||||
</object>
|
||||
</property>
|
||||
<property name="factory">
|
||||
<object class="GtkBuilderListItemFactory">
|
||||
<property name="bytes"><![CDATA[
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<interface>
|
||||
<template class="GtkListItem">
|
||||
<property name="child">
|
||||
<object class="GtkBox">
|
||||
<child>
|
||||
<object class="GtkInscription">
|
||||
<property name="xalign">1</property>
|
||||
<property name="nat-chars">35</property>
|
||||
<property name="min-chars">35</property>
|
||||
<property name="margin-end">8</property>
|
||||
<property name="text-overflow">clip</property>
|
||||
<binding name="text">
|
||||
<lookup name="name" type="SysprofDocumentCounter">
|
||||
<lookup name="item" type="SysprofSessionModelItem">
|
||||
<lookup name="item">GtkListItem</lookup>
|
||||
</lookup>
|
||||
</lookup>
|
||||
</binding>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="SysprofChart">
|
||||
<property name="hexpand">true</property>
|
||||
<signal name="activate-layer-item" handler="activate_layer_item_cb"/>
|
||||
<child>
|
||||
<object class="SysprofLineLayer">
|
||||
<property name="spline">true</property>
|
||||
<property name="dashed">true</property>
|
||||
<property name="fill">true</property>
|
||||
<binding name="x-axis">
|
||||
<lookup name="selected-time-axis" type="SysprofSession">
|
||||
<lookup name="session" type="SysprofSessionModelItem">
|
||||
<lookup name="item">GtkListItem</lookup>
|
||||
</lookup>
|
||||
</lookup>
|
||||
</binding>
|
||||
<property name="y-axis">
|
||||
<object class="SysprofValueAxis">
|
||||
<binding name="min-value">
|
||||
<lookup name="min-value" type="SysprofDocumentCounter">
|
||||
<lookup name="item" type="SysprofSessionModelItem">
|
||||
<lookup name="item">GtkListItem</lookup>
|
||||
</lookup>
|
||||
</lookup>
|
||||
</binding>
|
||||
<binding name="max-value">
|
||||
<lookup name="max-value" type="SysprofDocumentCounter">
|
||||
<lookup name="item" type="SysprofSessionModelItem">
|
||||
<lookup name="item">GtkListItem</lookup>
|
||||
</lookup>
|
||||
</lookup>
|
||||
</binding>
|
||||
</object>
|
||||
</property>
|
||||
<property name="series">
|
||||
<object class="SysprofXYSeries">
|
||||
<binding name="model">
|
||||
<lookup name="item" type="SysprofSessionModelItem">
|
||||
<lookup name="item">GtkListItem</lookup>
|
||||
</lookup>
|
||||
</binding>
|
||||
<property name="x-expression">
|
||||
<lookup name="time" type="SysprofDocumentCounterValue"/>
|
||||
</property>
|
||||
<property name="y-expression">
|
||||
<lookup name="value-double" type="SysprofDocumentCounterValue"/>
|
||||
</property>
|
||||
</object>
|
||||
</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</property>
|
||||
</template>
|
||||
</interface>
|
||||
]]>
|
||||
</property>
|
||||
</object>
|
||||
</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</property>
|
||||
</object>
|
||||
</child>
|
||||
</template>
|
||||
</interface>
|
||||
@ -1,208 +0,0 @@
|
||||
/* test-files.c
|
||||
*
|
||||
* Copyright 2023 Christian Hergert <chergert@redhat.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <adwaita.h>
|
||||
#include <libpanel.h>
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
#include <sysprof-analyze.h>
|
||||
#include <sysprof-gtk.h>
|
||||
|
||||
static GMainLoop *main_loop;
|
||||
static char *filename;
|
||||
static const GOptionEntry entries[] = {
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
#define TEST_TYPE_FILES (test_files_get_type())
|
||||
G_DECLARE_FINAL_TYPE (TestFiles, test_files, TEST, FILES, AdwWindow)
|
||||
|
||||
struct _TestFiles
|
||||
{
|
||||
AdwWindow parent_instance;
|
||||
|
||||
SysprofDocument *document;
|
||||
SysprofSession *session;
|
||||
};
|
||||
|
||||
G_DEFINE_FINAL_TYPE (TestFiles, test_files, ADW_TYPE_WINDOW)
|
||||
|
||||
enum {
|
||||
PROP_0,
|
||||
PROP_DOCUMENT,
|
||||
PROP_SESSION,
|
||||
N_PROPS
|
||||
};
|
||||
|
||||
static GParamSpec *properties [N_PROPS];
|
||||
|
||||
static void
|
||||
test_files_set_document (TestFiles *self,
|
||||
SysprofDocument *document)
|
||||
{
|
||||
if (g_set_object (&self->document, document))
|
||||
{
|
||||
g_clear_object (&self->session);
|
||||
|
||||
self->session = sysprof_session_new (self->document);
|
||||
|
||||
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_DOCUMENT]);
|
||||
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_SESSION]);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
test_files_dispose (GObject *object)
|
||||
{
|
||||
TestFiles *self = (TestFiles *)object;
|
||||
|
||||
g_clear_object (&self->document);
|
||||
g_clear_object (&self->session);
|
||||
|
||||
G_OBJECT_CLASS (test_files_parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
static void
|
||||
test_files_get_property (GObject *object,
|
||||
guint prop_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
TestFiles *self = TEST_FILES (object);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_DOCUMENT:
|
||||
g_value_set_object (value, self->document);
|
||||
break;
|
||||
|
||||
case PROP_SESSION:
|
||||
g_value_set_object (value, self->session);
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
test_files_set_property (GObject *object,
|
||||
guint prop_id,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
TestFiles *self = TEST_FILES (object);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_DOCUMENT:
|
||||
test_files_set_document (self, g_value_get_object (value));
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
test_files_class_init (TestFilesClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
|
||||
|
||||
object_class->dispose = test_files_dispose;
|
||||
object_class->get_property = test_files_get_property;
|
||||
object_class->set_property = test_files_set_property;
|
||||
|
||||
properties [PROP_DOCUMENT] =
|
||||
g_param_spec_object ("document", NULL, NULL,
|
||||
SYSPROF_TYPE_DOCUMENT,
|
||||
(G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
|
||||
|
||||
properties [PROP_SESSION] =
|
||||
g_param_spec_object ("session", NULL, NULL,
|
||||
SYSPROF_TYPE_SESSION,
|
||||
(G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
|
||||
|
||||
g_object_class_install_properties (object_class, N_PROPS, properties);
|
||||
|
||||
gtk_widget_class_set_template_from_resource (widget_class, "/test-files.ui");
|
||||
|
||||
g_type_ensure (SYSPROF_TYPE_DOCUMENT_FILE);
|
||||
}
|
||||
|
||||
static void
|
||||
test_files_init (TestFiles *self)
|
||||
{
|
||||
gtk_widget_init_template (GTK_WIDGET (self));
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc,
|
||||
char *argv[])
|
||||
{
|
||||
g_autoptr(GOptionContext) context = g_option_context_new ("- test various files");
|
||||
g_autoptr(SysprofDocumentLoader) loader = NULL;
|
||||
g_autoptr(SysprofDocument) document = NULL;
|
||||
g_autoptr(GError) error = NULL;
|
||||
GtkWindow *window;
|
||||
|
||||
sysprof_clock_init ();
|
||||
|
||||
gtk_init ();
|
||||
adw_init ();
|
||||
|
||||
g_option_context_add_main_entries (context, entries, NULL);
|
||||
if (!g_option_context_parse (context, &argc, &argv, &error))
|
||||
{
|
||||
g_printerr ("%s\n", error->message);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (argc != 2)
|
||||
{
|
||||
g_print ("usage: %s [OPTIONS] CAPTURE_FILE\n", argv[0]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
filename = argv[1];
|
||||
|
||||
main_loop = g_main_loop_new (NULL, FALSE);
|
||||
|
||||
loader = sysprof_document_loader_new (filename);
|
||||
if (!(document = sysprof_document_loader_load (loader, NULL, &error)))
|
||||
g_error ("Failed to load document: %s", error->message);
|
||||
|
||||
window = g_object_new (TEST_TYPE_FILES,
|
||||
"default-width", 800,
|
||||
"default-height", 600,
|
||||
"document", document,
|
||||
NULL);
|
||||
g_signal_connect_swapped (window,
|
||||
"close-request",
|
||||
G_CALLBACK (g_main_loop_quit),
|
||||
main_loop);
|
||||
gtk_window_present (window);
|
||||
g_main_loop_run (main_loop);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -1,56 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<interface>
|
||||
<template class="TestFiles" parent="AdwWindow">
|
||||
<child>
|
||||
<object class="AdwToolbarView">
|
||||
<child type="top">
|
||||
<object class="AdwHeaderBar">
|
||||
</object>
|
||||
</child>
|
||||
<property name="content">
|
||||
<object class="GtkScrolledWindow">
|
||||
<child>
|
||||
<object class="GtkListView">
|
||||
<property name="show-separators">true</property>
|
||||
<style>
|
||||
<class name="data-table"/>
|
||||
</style>
|
||||
<property name="model">
|
||||
<object class="GtkNoSelection">
|
||||
<binding name="model">
|
||||
<lookup name="files" type="SysprofDocument">
|
||||
<lookup name="document">TestFiles</lookup>
|
||||
</lookup>
|
||||
</binding>
|
||||
</object>
|
||||
</property>
|
||||
<property name="factory">
|
||||
<object class="GtkBuilderListItemFactory">
|
||||
<property name="bytes"><![CDATA[
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<interface>
|
||||
<template class="GtkListItem">
|
||||
<property name="child">
|
||||
<object class="GtkLabel">
|
||||
<property name="xalign">0</property>
|
||||
<binding name="label">
|
||||
<lookup name="path" type="SysprofDocumentFile">
|
||||
<lookup name="item">GtkListItem</lookup>
|
||||
</lookup>
|
||||
</binding>
|
||||
</object>
|
||||
</property>
|
||||
</template>
|
||||
</interface>
|
||||
]]>
|
||||
</property>
|
||||
</object>
|
||||
</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</property>
|
||||
</object>
|
||||
</child>
|
||||
</template>
|
||||
</interface>
|
||||
@ -1,94 +0,0 @@
|
||||
/* test-mark-chart.c
|
||||
*
|
||||
* Copyright 2023 Christian Hergert <chergert@redhat.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <adwaita.h>
|
||||
#include <gtk/gtk.h>
|
||||
#include <sysprof-analyze.h>
|
||||
#include <sysprof-gtk.h>
|
||||
|
||||
static GMainLoop *main_loop;
|
||||
static char *filename;
|
||||
static const GOptionEntry entries[] = {
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
int
|
||||
main (int argc,
|
||||
char *argv[])
|
||||
{
|
||||
g_autoptr(GOptionContext) context = g_option_context_new ("- test the mark chart");
|
||||
g_autoptr(SysprofDocumentLoader) loader = NULL;
|
||||
g_autoptr(SysprofDocument) document = NULL;
|
||||
g_autoptr(SysprofSession) session = NULL;
|
||||
g_autoptr(GError) error = NULL;
|
||||
SysprofMarkChart *chart;
|
||||
GtkWindow *window;
|
||||
|
||||
sysprof_clock_init ();
|
||||
|
||||
gtk_init ();
|
||||
adw_init ();
|
||||
|
||||
g_option_context_add_main_entries (context, entries, NULL);
|
||||
if (!g_option_context_parse (context, &argc, &argv, &error))
|
||||
{
|
||||
g_printerr ("%s\n", error->message);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (argc != 2)
|
||||
{
|
||||
g_print ("usage: %s [OPTIONS] CAPTURE_FILE\n", argv[0]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
filename = argv[1];
|
||||
|
||||
main_loop = g_main_loop_new (NULL, FALSE);
|
||||
|
||||
loader = sysprof_document_loader_new (filename);
|
||||
sysprof_document_loader_set_symbolizer (loader, sysprof_no_symbolizer_get ());
|
||||
|
||||
g_print ("Loading %s, ignoring embedded symbols...\n", filename);
|
||||
if (!(document = sysprof_document_loader_load (loader, NULL, &error)))
|
||||
g_error ("Failed to load document: %s", error->message);
|
||||
|
||||
session = sysprof_session_new (document);
|
||||
|
||||
window = g_object_new (GTK_TYPE_WINDOW,
|
||||
"default-width", 800,
|
||||
"default-height", 600,
|
||||
NULL);
|
||||
chart = g_object_new (SYSPROF_TYPE_MARK_CHART,
|
||||
"session", session,
|
||||
NULL);
|
||||
g_signal_connect_swapped (window,
|
||||
"close-request",
|
||||
G_CALLBACK (g_main_loop_quit),
|
||||
main_loop);
|
||||
gtk_window_set_child (window, GTK_WIDGET (chart));
|
||||
gtk_window_present (window);
|
||||
|
||||
g_main_loop_run (main_loop);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -1,94 +0,0 @@
|
||||
/* test-callgraph.c
|
||||
*
|
||||
* Copyright 2023 Christian Hergert <chergert@redhat.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <adwaita.h>
|
||||
#include <gtk/gtk.h>
|
||||
#include <sysprof-analyze.h>
|
||||
#include <sysprof-gtk.h>
|
||||
|
||||
static GMainLoop *main_loop;
|
||||
static char *filename;
|
||||
static const GOptionEntry entries[] = {
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
int
|
||||
main (int argc,
|
||||
char *argv[])
|
||||
{
|
||||
g_autoptr(GOptionContext) context = g_option_context_new ("- show a callgraph");
|
||||
g_autoptr(SysprofDocumentLoader) loader = NULL;
|
||||
g_autoptr(SysprofDocument) document = NULL;
|
||||
g_autoptr(SysprofSession) session = NULL;
|
||||
g_autoptr(GError) error = NULL;
|
||||
SysprofMarkTable *table;
|
||||
GtkWindow *window;
|
||||
|
||||
sysprof_clock_init ();
|
||||
|
||||
gtk_init ();
|
||||
adw_init ();
|
||||
|
||||
g_option_context_add_main_entries (context, entries, NULL);
|
||||
if (!g_option_context_parse (context, &argc, &argv, &error))
|
||||
{
|
||||
g_printerr ("%s\n", error->message);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (argc != 2)
|
||||
{
|
||||
g_print ("usage: %s [OPTIONS] CAPTURE_FILE\n", argv[0]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
filename = argv[1];
|
||||
|
||||
main_loop = g_main_loop_new (NULL, FALSE);
|
||||
|
||||
loader = sysprof_document_loader_new (filename);
|
||||
sysprof_document_loader_set_symbolizer (loader, sysprof_no_symbolizer_get ());
|
||||
|
||||
g_print ("Loading %s, ignoring embedded symbols...\n", filename);
|
||||
if (!(document = sysprof_document_loader_load (loader, NULL, &error)))
|
||||
g_error ("Failed to load document: %s", error->message);
|
||||
|
||||
session = sysprof_session_new (document);
|
||||
|
||||
window = g_object_new (GTK_TYPE_WINDOW,
|
||||
"default-width", 800,
|
||||
"default-height", 600,
|
||||
NULL);
|
||||
table = g_object_new (SYSPROF_TYPE_MARK_TABLE,
|
||||
"session", session,
|
||||
NULL);
|
||||
g_signal_connect_swapped (window,
|
||||
"close-request",
|
||||
G_CALLBACK (g_main_loop_quit),
|
||||
main_loop);
|
||||
gtk_window_set_child (window, GTK_WIDGET (table));
|
||||
gtk_window_present (window);
|
||||
|
||||
g_main_loop_run (main_loop);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -1,350 +0,0 @@
|
||||
/* test-processes.c
|
||||
*
|
||||
* Copyright 2023 Christian Hergert <chergert@redhat.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "tests-resources.h"
|
||||
|
||||
#include <adwaita.h>
|
||||
#include <libpanel.h>
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
#include <sysprof-analyze.h>
|
||||
#include <sysprof-gtk.h>
|
||||
|
||||
static GMainLoop *main_loop;
|
||||
static char *filename;
|
||||
static const GOptionEntry entries[] = {
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
#define TEST_TYPE_SINGLE_MODEL (test_single_model_get_type())
|
||||
G_DECLARE_FINAL_TYPE (TestSingleModel, test_single_model, TEST, SINGLE_MODEL, GObject)
|
||||
|
||||
struct _TestSingleModel
|
||||
{
|
||||
GObject parent_instance;
|
||||
GObject *item;
|
||||
};
|
||||
|
||||
enum {
|
||||
MODEL_PROP_0,
|
||||
MODEL_PROP_ITEM,
|
||||
MODEL_N_PROPS
|
||||
};
|
||||
|
||||
static GParamSpec *model_properties[MODEL_N_PROPS];
|
||||
|
||||
static guint
|
||||
get_n_items (GListModel *model)
|
||||
{
|
||||
return TEST_SINGLE_MODEL (model)->item ? 1 : 0;
|
||||
}
|
||||
|
||||
static gpointer
|
||||
get_item (GListModel *model,
|
||||
guint position)
|
||||
{
|
||||
if (position == 0 && TEST_SINGLE_MODEL (model)->item)
|
||||
return g_object_ref (TEST_SINGLE_MODEL (model)->item);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static GType
|
||||
get_item_type (GListModel *model)
|
||||
{
|
||||
if (TEST_SINGLE_MODEL (model)->item)
|
||||
return G_OBJECT_TYPE (TEST_SINGLE_MODEL (model)->item);
|
||||
return G_TYPE_OBJECT;
|
||||
}
|
||||
|
||||
static void
|
||||
list_model_iface_init (GListModelInterface *iface)
|
||||
{
|
||||
iface->get_n_items = get_n_items;
|
||||
iface->get_item = get_item;
|
||||
iface->get_item_type = get_item_type;
|
||||
}
|
||||
|
||||
G_DEFINE_FINAL_TYPE_WITH_CODE (TestSingleModel, test_single_model, G_TYPE_OBJECT,
|
||||
G_IMPLEMENT_INTERFACE (G_TYPE_LIST_MODEL, list_model_iface_init))
|
||||
|
||||
static void
|
||||
test_single_model_finalize (GObject *object)
|
||||
{
|
||||
TestSingleModel *self = (TestSingleModel *)object;
|
||||
|
||||
g_clear_object (&self->item);
|
||||
|
||||
G_OBJECT_CLASS (test_single_model_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
test_single_model_get_property (GObject *object,
|
||||
guint prop_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
TestSingleModel *self = TEST_SINGLE_MODEL (object);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case MODEL_PROP_ITEM:
|
||||
g_value_set_object (value, self->item);
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
test_single_model_set_property (GObject *object,
|
||||
guint prop_id,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
TestSingleModel *self = TEST_SINGLE_MODEL (object);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case MODEL_PROP_ITEM:
|
||||
if (self->item != NULL)
|
||||
{
|
||||
g_clear_object (&self->item);
|
||||
g_list_model_items_changed (G_LIST_MODEL (self), 0, 1, 0);
|
||||
}
|
||||
self->item = g_value_dup_object (value);
|
||||
if (self->item != NULL)
|
||||
g_list_model_items_changed (G_LIST_MODEL (self), 0, 0, 1);
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
test_single_model_class_init (TestSingleModelClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
|
||||
object_class->finalize = test_single_model_finalize;
|
||||
object_class->get_property = test_single_model_get_property;
|
||||
object_class->set_property = test_single_model_set_property;
|
||||
|
||||
model_properties[MODEL_PROP_ITEM] =
|
||||
g_param_spec_object ("item", NULL, NULL,
|
||||
G_TYPE_OBJECT,
|
||||
(G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
|
||||
|
||||
g_object_class_install_properties (object_class, MODEL_N_PROPS, model_properties);
|
||||
}
|
||||
|
||||
static void
|
||||
test_single_model_init (TestSingleModel *self)
|
||||
{
|
||||
}
|
||||
|
||||
#define TEST_TYPE_PROCESSES (test_processes_get_type())
|
||||
G_DECLARE_FINAL_TYPE (TestProcesses, test_processes, TEST, PROCESSES, AdwWindow)
|
||||
|
||||
struct _TestProcesses
|
||||
{
|
||||
AdwWindow parent_instance;
|
||||
|
||||
SysprofDocument *document;
|
||||
SysprofSession *session;
|
||||
};
|
||||
|
||||
G_DEFINE_FINAL_TYPE (TestProcesses, test_processes, ADW_TYPE_WINDOW)
|
||||
|
||||
enum {
|
||||
PROP_0,
|
||||
PROP_DOCUMENT,
|
||||
PROP_SESSION,
|
||||
N_PROPS
|
||||
};
|
||||
|
||||
static GParamSpec *properties [N_PROPS];
|
||||
|
||||
static void
|
||||
test_processes_set_document (TestProcesses *self,
|
||||
SysprofDocument *document)
|
||||
{
|
||||
if (g_set_object (&self->document, document))
|
||||
{
|
||||
g_clear_object (&self->session);
|
||||
|
||||
self->session = sysprof_session_new (self->document);
|
||||
|
||||
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_DOCUMENT]);
|
||||
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_SESSION]);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
test_processes_dispose (GObject *object)
|
||||
{
|
||||
TestProcesses *self = (TestProcesses *)object;
|
||||
|
||||
g_clear_object (&self->document);
|
||||
g_clear_object (&self->session);
|
||||
|
||||
G_OBJECT_CLASS (test_processes_parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
static void
|
||||
test_processes_get_property (GObject *object,
|
||||
guint prop_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
TestProcesses *self = TEST_PROCESSES (object);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_DOCUMENT:
|
||||
g_value_set_object (value, self->document);
|
||||
break;
|
||||
|
||||
case PROP_SESSION:
|
||||
g_value_set_object (value, self->session);
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
test_processes_set_property (GObject *object,
|
||||
guint prop_id,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
TestProcesses *self = TEST_PROCESSES (object);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_DOCUMENT:
|
||||
test_processes_set_document (self, g_value_get_object (value));
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
test_processes_class_init (TestProcessesClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
|
||||
|
||||
object_class->dispose = test_processes_dispose;
|
||||
object_class->get_property = test_processes_get_property;
|
||||
object_class->set_property = test_processes_set_property;
|
||||
|
||||
properties [PROP_DOCUMENT] =
|
||||
g_param_spec_object ("document", NULL, NULL,
|
||||
SYSPROF_TYPE_DOCUMENT,
|
||||
(G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
|
||||
|
||||
properties [PROP_SESSION] =
|
||||
g_param_spec_object ("session", NULL, NULL,
|
||||
SYSPROF_TYPE_SESSION,
|
||||
(G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
|
||||
|
||||
g_object_class_install_properties (object_class, N_PROPS, properties);
|
||||
|
||||
gtk_widget_class_set_template_from_resource (widget_class, "/test-processes.ui");
|
||||
|
||||
g_type_ensure (TEST_TYPE_SINGLE_MODEL);
|
||||
g_type_ensure (SYSPROF_TYPE_CHART);
|
||||
g_type_ensure (SYSPROF_TYPE_CHART_LAYER);
|
||||
g_type_ensure (SYSPROF_TYPE_COLUMN_LAYER);
|
||||
g_type_ensure (SYSPROF_TYPE_LINE_LAYER);
|
||||
g_type_ensure (SYSPROF_TYPE_VALUE_AXIS);
|
||||
g_type_ensure (SYSPROF_TYPE_SESSION_MODEL);
|
||||
g_type_ensure (SYSPROF_TYPE_SESSION_MODEL_ITEM);
|
||||
g_type_ensure (SYSPROF_TYPE_TIME_RULER);
|
||||
g_type_ensure (SYSPROF_TYPE_TIME_SPAN_LAYER);
|
||||
g_type_ensure (SYSPROF_TYPE_TIME_SERIES);
|
||||
}
|
||||
|
||||
static void
|
||||
test_processes_init (TestProcesses *self)
|
||||
{
|
||||
gtk_widget_init_template (GTK_WIDGET (self));
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc,
|
||||
char *argv[])
|
||||
{
|
||||
g_autoptr(GOptionContext) context = g_option_context_new ("- test processes listing");
|
||||
g_autoptr(SysprofDocumentLoader) loader = NULL;
|
||||
g_autoptr(SysprofDocument) document = NULL;
|
||||
g_autoptr(GError) error = NULL;
|
||||
GtkWindow *window;
|
||||
|
||||
sysprof_clock_init ();
|
||||
|
||||
gtk_init ();
|
||||
adw_init ();
|
||||
|
||||
g_option_context_add_main_entries (context, entries, NULL);
|
||||
if (!g_option_context_parse (context, &argc, &argv, &error))
|
||||
{
|
||||
g_printerr ("%s\n", error->message);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (argc != 2)
|
||||
{
|
||||
g_print ("usage: %s [OPTIONS] CAPTURE_FILE\n", argv[0]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
g_resources_register (tests_get_resource ());
|
||||
|
||||
filename = argv[1];
|
||||
|
||||
main_loop = g_main_loop_new (NULL, FALSE);
|
||||
|
||||
loader = sysprof_document_loader_new (filename);
|
||||
if (!(document = sysprof_document_loader_load (loader, NULL, &error)))
|
||||
g_error ("Failed to load document: %s", error->message);
|
||||
|
||||
window = g_object_new (TEST_TYPE_PROCESSES,
|
||||
"default-width", 800,
|
||||
"default-height", 600,
|
||||
"document", document,
|
||||
NULL);
|
||||
g_signal_connect_swapped (window,
|
||||
"close-request",
|
||||
G_CALLBACK (g_main_loop_quit),
|
||||
main_loop);
|
||||
gtk_window_present (window);
|
||||
g_main_loop_run (main_loop);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -1,90 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<interface>
|
||||
<template class="TestProcesses" parent="AdwWindow">
|
||||
<child>
|
||||
<object class="AdwToolbarView">
|
||||
<child type="top">
|
||||
<object class="AdwHeaderBar">
|
||||
</object>
|
||||
</child>
|
||||
<property name="content">
|
||||
<object class="GtkScrolledWindow">
|
||||
<child>
|
||||
<object class="GtkListView">
|
||||
<property name="model">
|
||||
<object class="GtkNoSelection">
|
||||
<property name="model">
|
||||
<object class="SysprofSessionModel">
|
||||
<property name="session" bind-source="TestProcesses" bind-property="session" bind-flags="sync-create"/>
|
||||
<binding name="model">
|
||||
<lookup name="processes" type="SysprofDocument">
|
||||
<lookup name="document">TestProcesses</lookup>
|
||||
</lookup>
|
||||
</binding>
|
||||
</object>
|
||||
</property>
|
||||
</object>
|
||||
</property>
|
||||
<property name="factory">
|
||||
<object class="GtkBuilderListItemFactory">
|
||||
<property name="bytes"><![CDATA[
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<interface>
|
||||
<template class="GtkListItem">
|
||||
<property name="child">
|
||||
<object class="GtkBox">
|
||||
<property name="height-request">16</property>
|
||||
<child>
|
||||
<object class="SysprofChart">
|
||||
<property name="hexpand">true</property>
|
||||
<child>
|
||||
<object class="SysprofTimeSpanLayer">
|
||||
<binding name="axis">
|
||||
<lookup name="selected-time-axis" type="SysprofSession">
|
||||
<lookup name="session" type="SysprofSessionModelItem">
|
||||
<lookup name="item">GtkListItem</lookup>
|
||||
</lookup>
|
||||
</lookup>
|
||||
</binding>
|
||||
<property name="series">
|
||||
<object class="SysprofTimeSeries">
|
||||
<property name="model">
|
||||
<object class="TestSingleModel">
|
||||
<binding name="item">
|
||||
<lookup name="item" type="SysprofSessionModelItem">
|
||||
<lookup name="item">GtkListItem</lookup>
|
||||
</lookup>
|
||||
</binding>
|
||||
</object>
|
||||
</property>
|
||||
<property name="begin-time-expression">
|
||||
<lookup name="time" type="SysprofDocumentFrame"/>
|
||||
</property>
|
||||
<property name="end-time-expression">
|
||||
<lookup name="exit-time" type="SysprofDocumentProcess"/>
|
||||
</property>
|
||||
<property name="label-expression">
|
||||
<lookup name="command-line" type="SysprofDocumentProcess"/>
|
||||
</property>
|
||||
</object>
|
||||
</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</property>
|
||||
</template>
|
||||
</interface>
|
||||
]]>
|
||||
</property>
|
||||
</object>
|
||||
</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</property>
|
||||
</object>
|
||||
</child>
|
||||
</template>
|
||||
</interface>
|
||||
@ -1,212 +0,0 @@
|
||||
/* test-tracks.c
|
||||
*
|
||||
* Copyright 2023 Christian Hergert <chergert@redhat.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <adwaita.h>
|
||||
#include <gtk/gtk.h>
|
||||
#include <libpanel.h>
|
||||
|
||||
#include <sysprof-analyze.h>
|
||||
#include <sysprof-gtk.h>
|
||||
|
||||
static GMainLoop *main_loop;
|
||||
static char *filename;
|
||||
static const GOptionEntry entries[] = {
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
#define TEST_TYPE_TRACKS (test_tracks_get_type())
|
||||
G_DECLARE_FINAL_TYPE (TestTracks, test_tracks, TEST, TRACKS, AdwWindow)
|
||||
|
||||
struct _TestTracks
|
||||
{
|
||||
AdwWindow parent_instance;
|
||||
|
||||
SysprofDocument *document;
|
||||
SysprofSession *session;
|
||||
};
|
||||
|
||||
G_DEFINE_FINAL_TYPE (TestTracks, test_tracks, ADW_TYPE_WINDOW)
|
||||
|
||||
enum {
|
||||
PROP_0,
|
||||
PROP_DOCUMENT,
|
||||
PROP_SESSION,
|
||||
N_PROPS
|
||||
};
|
||||
|
||||
static GParamSpec *properties [N_PROPS];
|
||||
|
||||
static void
|
||||
test_tracks_set_document (TestTracks *self,
|
||||
SysprofDocument *document)
|
||||
{
|
||||
if (g_set_object (&self->document, document))
|
||||
{
|
||||
g_clear_object (&self->session);
|
||||
|
||||
self->session = sysprof_session_new (self->document);
|
||||
|
||||
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_DOCUMENT]);
|
||||
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_SESSION]);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
test_tracks_dispose (GObject *object)
|
||||
{
|
||||
TestTracks *self = (TestTracks *)object;
|
||||
|
||||
g_clear_object (&self->document);
|
||||
g_clear_object (&self->session);
|
||||
|
||||
G_OBJECT_CLASS (test_tracks_parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
static void
|
||||
test_tracks_get_property (GObject *object,
|
||||
guint prop_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
TestTracks *self = TEST_TRACKS (object);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_DOCUMENT:
|
||||
g_value_set_object (value, self->document);
|
||||
break;
|
||||
|
||||
case PROP_SESSION:
|
||||
g_value_set_object (value, self->session);
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
test_tracks_set_property (GObject *object,
|
||||
guint prop_id,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
TestTracks *self = TEST_TRACKS (object);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_DOCUMENT:
|
||||
test_tracks_set_document (self, g_value_get_object (value));
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
test_tracks_class_init (TestTracksClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
|
||||
|
||||
object_class->dispose = test_tracks_dispose;
|
||||
object_class->get_property = test_tracks_get_property;
|
||||
object_class->set_property = test_tracks_set_property;
|
||||
|
||||
properties [PROP_DOCUMENT] =
|
||||
g_param_spec_object ("document", NULL, NULL,
|
||||
SYSPROF_TYPE_DOCUMENT,
|
||||
(G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
|
||||
|
||||
properties [PROP_SESSION] =
|
||||
g_param_spec_object ("session", NULL, NULL,
|
||||
SYSPROF_TYPE_SESSION,
|
||||
(G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
|
||||
|
||||
g_object_class_install_properties (object_class, N_PROPS, properties);
|
||||
|
||||
gtk_widget_class_set_template_from_resource (widget_class, "/test-tracks.ui");
|
||||
|
||||
g_type_ensure (SYSPROF_TYPE_TRACKS_VIEW);
|
||||
g_type_ensure (SYSPROF_TYPE_MARK_CHART);
|
||||
g_type_ensure (SYSPROF_TYPE_MARK_TABLE);
|
||||
g_type_ensure (SYSPROF_TYPE_WEIGHTED_CALLGRAPH_VIEW);
|
||||
}
|
||||
|
||||
static void
|
||||
test_tracks_init (TestTracks *self)
|
||||
{
|
||||
gtk_widget_init_template (GTK_WIDGET (self));
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc,
|
||||
char *argv[])
|
||||
{
|
||||
g_autoptr(GOptionContext) context = g_option_context_new ("- test track layout");
|
||||
g_autoptr(SysprofDocumentLoader) loader = NULL;
|
||||
g_autoptr(SysprofDocument) document = NULL;
|
||||
g_autoptr(GError) error = NULL;
|
||||
GtkWindow *window;
|
||||
|
||||
sysprof_clock_init ();
|
||||
|
||||
gtk_init ();
|
||||
adw_init ();
|
||||
panel_init ();
|
||||
|
||||
g_option_context_add_main_entries (context, entries, NULL);
|
||||
if (!g_option_context_parse (context, &argc, &argv, &error))
|
||||
{
|
||||
g_printerr ("%s\n", error->message);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (argc != 2)
|
||||
{
|
||||
g_print ("usage: %s [OPTIONS] CAPTURE_FILE\n", argv[0]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
filename = argv[1];
|
||||
|
||||
main_loop = g_main_loop_new (NULL, FALSE);
|
||||
|
||||
loader = sysprof_document_loader_new (filename);
|
||||
if (!(document = sysprof_document_loader_load (loader, NULL, &error)))
|
||||
g_error ("Failed to load document: %s", error->message);
|
||||
|
||||
window = g_object_new (TEST_TYPE_TRACKS,
|
||||
"default-width", 800,
|
||||
"default-height", 600,
|
||||
"document", document,
|
||||
NULL);
|
||||
g_signal_connect_swapped (window,
|
||||
"close-request",
|
||||
G_CALLBACK (g_main_loop_quit),
|
||||
main_loop);
|
||||
gtk_window_present (window);
|
||||
g_main_loop_run (main_loop);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -1,222 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<interface>
|
||||
<template class="TestTracks" parent="AdwWindow">
|
||||
<child>
|
||||
<object class="AdwToolbarView">
|
||||
<property name="top-bar-style">raised</property>
|
||||
<property name="bottom-bar-style">raised</property>
|
||||
<child type="top">
|
||||
<object class="AdwHeaderBar">
|
||||
<child type="start">
|
||||
<object class="GtkMenuButton">
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<property name="spacing">3</property>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="label">Open</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkImage">
|
||||
<property name="icon-name">pan-down-symbolic</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child type="title">
|
||||
<object class="PanelOmniBar">
|
||||
<property name="menu-model">omni_menu</property>
|
||||
<child type="prefix">
|
||||
<object class="GtkInscription">
|
||||
<property name="min-chars">25</property>
|
||||
<property name="nat-chars">25</property>
|
||||
<property name="valign">center</property>
|
||||
<property name="text-overflow">ellipsize-end</property>
|
||||
<binding name="text">
|
||||
<lookup name="title" type="AdwTabPage">
|
||||
<lookup name="selected-page">tracks_view</lookup>
|
||||
</lookup>
|
||||
</binding>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child type="end">
|
||||
<object class="GtkMenuButton">
|
||||
<property name="icon-name">open-menu-symbolic</property>
|
||||
<property name="menu-model">primary_menu</property>
|
||||
<property name="primary">true</property>
|
||||
</object>
|
||||
</child>
|
||||
<child type="end">
|
||||
<object class="GtkMenuButton">
|
||||
<property name="icon-name">document-properties-symbolic</property>
|
||||
<property name="menu-model">view_menu</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child type="top">
|
||||
<object class="AdwTabBar">
|
||||
<property name="view">tracks_view</property>
|
||||
</object>
|
||||
</child>
|
||||
<property name="content">
|
||||
<object class="GtkPaned">
|
||||
<property name="orientation">vertical</property>
|
||||
<child>
|
||||
<object class="AdwTabView" id="tracks_view">
|
||||
<child>
|
||||
<object class="AdwTabPage">
|
||||
<binding name="title">
|
||||
<lookup name="title" type="SysprofDocument">
|
||||
<lookup name="document" type="SysprofSession">
|
||||
<lookup name="session">TestTracks</lookup>
|
||||
</lookup>
|
||||
</lookup>
|
||||
</binding>
|
||||
<property name="child">
|
||||
<object class="SysprofTracksView">
|
||||
<binding name="session">
|
||||
<lookup name="session">TestTracks</lookup>
|
||||
</binding>
|
||||
</object>
|
||||
</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<property name="orientation">vertical</property>
|
||||
<property name="vexpand">true</property>
|
||||
<child>
|
||||
<object class="GtkStackSwitcher">
|
||||
<property name="halign">center</property>
|
||||
<property name="stack">data_stack</property>
|
||||
<property name="margin-top">3</property>
|
||||
<property name="margin-bottom">3</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkStack" id="data_stack">
|
||||
<property name="vexpand">true</property>
|
||||
<child>
|
||||
<object class="GtkStackPage">
|
||||
<property name="title">Callgraph</property>
|
||||
<property name="child">
|
||||
<object class="SysprofWeightedCallgraphView">
|
||||
<binding name="document">
|
||||
<lookup name="document" type="SysprofSession">
|
||||
<lookup name="session">TestTracks</lookup>
|
||||
</lookup>
|
||||
</binding>
|
||||
<binding name="traceables">
|
||||
<lookup name="samples" type="SysprofDocument">
|
||||
<lookup name="document" type="SysprofSession">
|
||||
<lookup name="session">TestTracks</lookup>
|
||||
</lookup>
|
||||
</lookup>
|
||||
</binding>
|
||||
</object>
|
||||
</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkStackPage">
|
||||
<property name="title">Mark Chart</property>
|
||||
<property name="child">
|
||||
<object class="SysprofMarkChart">
|
||||
<binding name="session">
|
||||
<lookup name="session">TestTracks</lookup>
|
||||
</binding>
|
||||
</object>
|
||||
</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkStackPage">
|
||||
<property name="title">Mark Table</property>
|
||||
<property name="child">
|
||||
<object class="SysprofMarkTable">
|
||||
<binding name="session">
|
||||
<lookup name="session">TestTracks</lookup>
|
||||
</binding>
|
||||
</object>
|
||||
</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</property>
|
||||
<child type="bottom">
|
||||
<object class="PanelStatusbar">
|
||||
<child type="suffix">
|
||||
<object class="PanelToggleButton">
|
||||
<property name="area">bottom</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</template>
|
||||
<menu id="primary_menu">
|
||||
<section>
|
||||
<item>
|
||||
<attribute name="label">Preferences</attribute>
|
||||
</item>
|
||||
<item>
|
||||
<attribute name="label">Keyboard Shortcuts</attribute>
|
||||
<attribute name="accel"><ctrl>question</attribute>
|
||||
</item>
|
||||
<item>
|
||||
<attribute name="label">Help</attribute>
|
||||
</item>
|
||||
<item>
|
||||
<attribute name="label">About Sysprof</attribute>
|
||||
</item>
|
||||
</section>
|
||||
</menu>
|
||||
<menu id="view_menu">
|
||||
<section>
|
||||
<attribute name="label">Callgraph</attribute>
|
||||
<item><attribute name="label">Show Threads</attribute></item>
|
||||
<item><attribute name="label">Show System Libraries</attribute></item>
|
||||
</section>
|
||||
</menu>
|
||||
<menu id="omni_menu">
|
||||
<section>
|
||||
<attribute name="label">Profiling</attribute>
|
||||
<item><attribute name="label">Sample Native Stacks</attribute></item>
|
||||
<item><attribute name="label">Sample JavaScript Stacks</attribute></item>
|
||||
<item><attribute name="label">Trace Memory Allocations</attribute></item>
|
||||
</section>
|
||||
<section>
|
||||
<attribute name="label">Graphics</attribute>
|
||||
<item><attribute name="label">Display Timings</attribute></item>
|
||||
</section>
|
||||
<section>
|
||||
<attribute name="label">Counters</attribute>
|
||||
<item><attribute name="label">CPU Usage</attribute></item>
|
||||
<item><attribute name="label">Memory Usage</attribute></item>
|
||||
<item><attribute name="label">Storage I/O</attribute></item>
|
||||
<item><attribute name="label">Network I/O</attribute></item>
|
||||
</section>
|
||||
<section>
|
||||
<attribute name="label">Energy</attribute>
|
||||
<item><attribute name="label">Consumption</attribute></item>
|
||||
<item><attribute name="label">Battery Charge</attribute></item>
|
||||
</section>
|
||||
<section>
|
||||
<item><attribute name="label">Allow Application Integration</attribute></item>
|
||||
<item><attribute name="label">Allow CPU Throttling</attribute></item>
|
||||
</section>
|
||||
</menu>
|
||||
</interface>
|
||||
@ -1,9 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<gresources>
|
||||
<gresource prefix="/">
|
||||
<file preprocess="xml-stripblanks">test-charts.ui</file>
|
||||
<file preprocess="xml-stripblanks">test-files.ui</file>
|
||||
<file preprocess="xml-stripblanks">test-processes.ui</file>
|
||||
<file preprocess="xml-stripblanks">test-tracks.ui</file>
|
||||
</gresource>
|
||||
</gresources>
|
||||
@ -72,9 +72,6 @@ endif
|
||||
if get_option('libsysprof') or get_option('agent')
|
||||
subdir('libsysprof')
|
||||
endif
|
||||
if get_option('gtk') and get_option('libsysprof')
|
||||
subdir('libsysprof-gtk')
|
||||
endif
|
||||
if get_option('gtk') and get_option('libsysprof')
|
||||
subdir('sysprof')
|
||||
endif
|
||||
|
||||
@ -1,26 +1,61 @@
|
||||
sysprof_sources = [
|
||||
'main.c',
|
||||
'sysprof-application.c',
|
||||
'sysprof-axis.c',
|
||||
'sysprof-callgraph-view.c',
|
||||
'sysprof-chart-layer.c',
|
||||
'sysprof-chart.c',
|
||||
'sysprof-color-iter.c',
|
||||
'sysprof-column-layer.c',
|
||||
'sysprof-counters-section.c',
|
||||
'sysprof-cpu-info-dialog.c',
|
||||
'sysprof-cpu-section.c',
|
||||
'sysprof-css.c',
|
||||
'sysprof-duplex-layer.c',
|
||||
'sysprof-files-section.c',
|
||||
'sysprof-frame-utility.c',
|
||||
'sysprof-greeter.c',
|
||||
'sysprof-line-layer.c',
|
||||
'sysprof-logs-section.c',
|
||||
'sysprof-mark-chart-item.c',
|
||||
'sysprof-mark-chart-row.c',
|
||||
'sysprof-mark-chart.c',
|
||||
'sysprof-mark-table.c',
|
||||
'sysprof-marks-section.c',
|
||||
'sysprof-memory-callgraph-view.c',
|
||||
'sysprof-memory-section.c',
|
||||
'sysprof-metadata-section.c',
|
||||
'sysprof-normalized-series-item.c',
|
||||
'sysprof-normalized-series.c',
|
||||
'sysprof-process-dialog.c',
|
||||
'sysprof-processes-section.c',
|
||||
'sysprof-progress-cell.c',
|
||||
'sysprof-recording-pad.c',
|
||||
'sysprof-samples-section.c',
|
||||
'sysprof-scheduler.c',
|
||||
'sysprof-section.c',
|
||||
'sysprof-series.c',
|
||||
'sysprof-session-model-item.c',
|
||||
'sysprof-session-model.c',
|
||||
'sysprof-session.c',
|
||||
'sysprof-sidebar.c',
|
||||
'sysprof-single-model.c',
|
||||
'sysprof-split-layer.c',
|
||||
'sysprof-symbol-label.c',
|
||||
'sysprof-time-filter-model.c',
|
||||
'sysprof-time-label.c',
|
||||
'sysprof-time-ruler.c',
|
||||
'sysprof-time-scrubber.c',
|
||||
'sysprof-time-series-item.c',
|
||||
'sysprof-time-series.c',
|
||||
'sysprof-time-span-layer.c',
|
||||
'sysprof-traceables-utility.c',
|
||||
'sysprof-value-axis.c',
|
||||
'sysprof-weighted-callgraph-view.c',
|
||||
'sysprof-window.c',
|
||||
'sysprof-xy-layer.c',
|
||||
'sysprof-xy-series-item.c',
|
||||
'sysprof-xy-series.c',
|
||||
]
|
||||
|
||||
sysprof_resources = gnome.compile_resources('sysprof-resources', 'sysprof.gresource.xml',
|
||||
@ -30,11 +65,11 @@ sysprof_resources = gnome.compile_resources('sysprof-resources', 'sysprof.gresou
|
||||
|
||||
sysprof_deps = [
|
||||
cc.find_library('m', required: false),
|
||||
dependency('gtk4', version: gtk_req_version),
|
||||
dependency('libadwaita-1', version: '>= 1.4.alpha'),
|
||||
dependency('libpanel-1', version: '>= 1.3.0'),
|
||||
libsysprof_analyze_static_dep,
|
||||
libsysprof_profile_static_dep,
|
||||
libsysprof_gtk_static_dep,
|
||||
]
|
||||
|
||||
sysprof = executable('sysprof', sysprof_resources + sysprof_sources,
|
||||
|
||||
@ -73,9 +73,7 @@ timeruler {
|
||||
}
|
||||
|
||||
timescrubber informative,
|
||||
timescrubber timecode,
|
||||
tracks informative,
|
||||
tracks timecode {
|
||||
timescrubber timecode {
|
||||
border-radius: 7px;
|
||||
background: @accent_bg_color;
|
||||
color: @accent_fg_color;
|
||||
@ -87,24 +85,6 @@ tracks timecode {
|
||||
font-size: .9em;
|
||||
}
|
||||
|
||||
tracks track chart {
|
||||
margin-top: 1px;
|
||||
}
|
||||
tracks track info {
|
||||
background: alpha(@borders, .25);
|
||||
}
|
||||
tracks track info button {
|
||||
min-height: 0px;
|
||||
min-width: 0px;
|
||||
}
|
||||
tracks row {
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
}
|
||||
tracks row track info {
|
||||
padding: 1px 0 0 0;
|
||||
}
|
||||
|
||||
.utility .view {
|
||||
background: transparent;
|
||||
}
|
||||
@ -22,7 +22,7 @@
|
||||
|
||||
#include <libpanel.h>
|
||||
|
||||
#include "libsysprof-gtk-resources.h"
|
||||
#include "sysprof-resources.h"
|
||||
|
||||
#include "sysprof-callgraph-view-private.h"
|
||||
#include "sysprof-symbol-label-private.h"
|
||||
@ -441,7 +441,7 @@ sysprof_callgraph_view_class_init (SysprofCallgraphViewClass *klass)
|
||||
|
||||
klass->augment_size = GLIB_SIZEOF_VOID_P;
|
||||
|
||||
g_resources_register (libsysprof_gtk_get_resource ());
|
||||
g_resources_register (sysprof_get_resource ());
|
||||
|
||||
g_type_ensure (PANEL_TYPE_PANED);
|
||||
g_type_ensure (SYSPROF_TYPE_SYMBOL_LABEL);
|
||||
@ -20,9 +20,12 @@
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <sysprof-gtk.h>
|
||||
|
||||
#include "sysprof-chart.h"
|
||||
#include "sysprof-counters-section.h"
|
||||
#include "sysprof-line-layer.h"
|
||||
#include "sysprof-time-series.h"
|
||||
#include "sysprof-time-span-layer.h"
|
||||
#include "sysprof-xy-series.h"
|
||||
|
||||
struct _SysprofCountersSection
|
||||
{
|
||||
|
||||
@ -20,12 +20,15 @@
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <sysprof-gtk.h>
|
||||
|
||||
#include "sysprof-chart.h"
|
||||
#include "sysprof-cpu-section.h"
|
||||
#include "sysprof-line-layer.h"
|
||||
#include "sysprof-time-filter-model.h"
|
||||
#include "sysprof-time-scrubber.h"
|
||||
#include "sysprof-time-series.h"
|
||||
#include "sysprof-time-span-layer.h"
|
||||
#include "sysprof-value-axis.h"
|
||||
#include "sysprof-xy-series.h"
|
||||
|
||||
struct _SysprofCpuSection
|
||||
{
|
||||
|
||||
@ -20,7 +20,7 @@
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "libsysprof-gtk-resources.h"
|
||||
#include "sysprof-resources.h"
|
||||
|
||||
#include "sysprof-css-private.h"
|
||||
|
||||
@ -31,7 +31,7 @@ _sysprof_css_init (void)
|
||||
|
||||
if (css == NULL)
|
||||
{
|
||||
g_resources_register (libsysprof_gtk_get_resource ());
|
||||
g_resources_register (sysprof_get_resource ());
|
||||
|
||||
css = gtk_css_provider_new ();
|
||||
gtk_css_provider_load_from_resource (css, "/libsysprof-gtk/style.css");
|
||||
@ -23,9 +23,9 @@
|
||||
#include <glib/gi18n.h>
|
||||
|
||||
#include <adwaita.h>
|
||||
#include <sysprof-gtk.h>
|
||||
|
||||
#include "sysprof-files-section.h"
|
||||
#include "sysprof-time-label.h"
|
||||
|
||||
struct _SysprofFilesSection
|
||||
{
|
||||
|
||||
@ -20,9 +20,8 @@
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <sysprof-gtk.h>
|
||||
|
||||
#include "sysprof-frame-utility.h"
|
||||
#include "sysprof-session.h"
|
||||
|
||||
struct _SysprofFrameUtility
|
||||
{
|
||||
|
||||
@ -22,11 +22,13 @@
|
||||
|
||||
#include <glib/gi18n.h>
|
||||
|
||||
#include <sysprof-gtk.h>
|
||||
|
||||
#include "sysprof-chart.h"
|
||||
#include "sysprof-document-bitset-index-private.h"
|
||||
#include "sysprof-frame-utility.h"
|
||||
#include "sysprof-logs-section.h"
|
||||
#include "sysprof-time-label.h"
|
||||
#include "sysprof-time-series.h"
|
||||
#include "sysprof-time-span-layer.h"
|
||||
|
||||
struct _SysprofLogsSection
|
||||
{
|
||||
|
||||
@ -25,7 +25,7 @@
|
||||
#include "sysprof-mark-chart-item-private.h"
|
||||
#include "sysprof-mark-chart-row-private.h"
|
||||
|
||||
#include "libsysprof-gtk-resources.h"
|
||||
#include "sysprof-resources.h"
|
||||
|
||||
struct _SysprofMarkChart
|
||||
{
|
||||
@ -164,7 +164,7 @@ sysprof_mark_chart_class_init (SysprofMarkChartClass *klass)
|
||||
gtk_widget_class_bind_template_child (widget_class, SysprofMarkChart, box);
|
||||
gtk_widget_class_bind_template_child (widget_class, SysprofMarkChart, list_view);
|
||||
|
||||
g_resources_register (libsysprof_gtk_get_resource ());
|
||||
g_resources_register (sysprof_get_resource ());
|
||||
|
||||
g_type_ensure (SYSPROF_TYPE_MARK_CHART_ITEM);
|
||||
g_type_ensure (SYSPROF_TYPE_MARK_CHART_ROW);
|
||||
@ -25,7 +25,7 @@
|
||||
#include "sysprof-mark-table.h"
|
||||
#include "sysprof-time-label.h"
|
||||
|
||||
#include "libsysprof-gtk-resources.h"
|
||||
#include "sysprof-resources.h"
|
||||
|
||||
struct _SysprofMarkTable
|
||||
{
|
||||
@ -149,7 +149,7 @@ sysprof_mark_table_class_init (SysprofMarkTableClass *klass)
|
||||
gtk_widget_class_bind_template_child (widget_class, SysprofMarkTable, start_column);
|
||||
gtk_widget_class_bind_template_callback (widget_class, sysprof_mark_table_activate_cb);
|
||||
|
||||
g_resources_register (libsysprof_gtk_get_resource ());
|
||||
g_resources_register (sysprof_get_resource ());
|
||||
|
||||
g_type_ensure (SYSPROF_TYPE_DOCUMENT_MARK);
|
||||
g_type_ensure (SYSPROF_TYPE_TIME_FILTER_MODEL);
|
||||
@ -20,9 +20,14 @@
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <sysprof-gtk.h>
|
||||
|
||||
#include "sysprof-chart.h"
|
||||
#include "sysprof-mark-chart.h"
|
||||
#include "sysprof-mark-table.h"
|
||||
#include "sysprof-marks-section.h"
|
||||
#include "sysprof-session-model.h"
|
||||
#include "sysprof-session-model-item.h"
|
||||
#include "sysprof-time-series.h"
|
||||
#include "sysprof-time-span-layer.h"
|
||||
|
||||
struct _SysprofMarksSection
|
||||
{
|
||||
|
||||
@ -20,15 +20,22 @@
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <sysprof-gtk.h>
|
||||
|
||||
#include "sysprof-chart.h"
|
||||
#include "sysprof-column-layer.h"
|
||||
#include "sysprof-memory-callgraph-view.h"
|
||||
#include "sysprof-memory-section.h"
|
||||
#include "sysprof-session-model-item.h"
|
||||
#include "sysprof-session-model.h"
|
||||
#include "sysprof-time-series.h"
|
||||
#include "sysprof-time-span-layer.h"
|
||||
#include "sysprof-value-axis.h"
|
||||
#include "sysprof-xy-series.h"
|
||||
|
||||
struct _SysprofMemorySection
|
||||
{
|
||||
SysprofSection parent_instance;
|
||||
|
||||
SysprofWeightedCallgraphView *callgraph_view;
|
||||
SysprofMemoryCallgraphView *callgraph_view;
|
||||
};
|
||||
|
||||
G_DEFINE_FINAL_TYPE (SysprofMemorySection, sysprof_memory_section, SYSPROF_TYPE_SECTION)
|
||||
|
||||
@ -23,9 +23,9 @@
|
||||
#include <glib/gi18n.h>
|
||||
|
||||
#include <adwaita.h>
|
||||
#include <sysprof-gtk.h>
|
||||
|
||||
#include "sysprof-metadata-section.h"
|
||||
#include "sysprof-time-label.h"
|
||||
|
||||
struct _SysprofMetadataSection
|
||||
{
|
||||
|
||||
@ -23,11 +23,19 @@
|
||||
#include <glib/gi18n.h>
|
||||
|
||||
#include <adwaita.h>
|
||||
#include <sysprof-gtk.h>
|
||||
|
||||
#include "sysprof-chart-layer.h"
|
||||
#include "sysprof-chart.h"
|
||||
#include "sysprof-document-process.h"
|
||||
#include "sysprof-process-dialog.h"
|
||||
#include "sysprof-processes-section.h"
|
||||
#include "sysprof-session-model-item.h"
|
||||
#include "sysprof-session-model.h"
|
||||
#include "sysprof-single-model.h"
|
||||
#include "sysprof-time-label.h"
|
||||
#include "sysprof-time-series.h"
|
||||
#include "sysprof-time-span-layer.h"
|
||||
#include "sysprof-value-axis.h"
|
||||
|
||||
struct _SysprofProcessesSection
|
||||
{
|
||||
|
||||
@ -20,12 +20,19 @@
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <sysprof-gtk.h>
|
||||
|
||||
#include "sysprof-chart.h"
|
||||
#include "sysprof-column-layer.h"
|
||||
#include "sysprof-samples-section.h"
|
||||
#include "sysprof-traceables-utility.h"
|
||||
#include "sysprof-session-model-item.h"
|
||||
#include "sysprof-session-model.h"
|
||||
#include "sysprof-time-filter-model.h"
|
||||
#include "sysprof-time-scrubber.h"
|
||||
#include "sysprof-time-series.h"
|
||||
#include "sysprof-time-span-layer.h"
|
||||
#include "sysprof-traceables-utility.h"
|
||||
#include "sysprof-value-axis.h"
|
||||
#include "sysprof-weighted-callgraph-view.h"
|
||||
#include "sysprof-xy-series.h"
|
||||
|
||||
struct _SysprofSamplesSection
|
||||
{
|
||||
|
||||
@ -22,7 +22,7 @@
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
#include <sysprof-gtk.h>
|
||||
#include "sysprof-session.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
|
||||
@ -21,15 +21,10 @@
|
||||
#pragma once
|
||||
|
||||
#include "sysprof-session.h"
|
||||
#include "sysprof-track.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
void _sysprof_session_discover_tracks (SysprofSession *session,
|
||||
SysprofDocument *document,
|
||||
GListStore *tracks);
|
||||
char *_sysprof_session_describe (SysprofSession *self,
|
||||
SysprofTrack *track,
|
||||
gpointer item);
|
||||
char *_sysprof_session_describe (SysprofSession *self,
|
||||
gpointer item);
|
||||
|
||||
G_END_DECLS
|
||||
@ -23,7 +23,6 @@
|
||||
#include <glib/gi18n.h>
|
||||
|
||||
#include "sysprof-session-private.h"
|
||||
#include "sysprof-track-private.h"
|
||||
#include "sysprof-value-axis.h"
|
||||
|
||||
struct _SysprofSession
|
||||
@ -33,8 +32,6 @@ struct _SysprofSession
|
||||
SysprofDocument *document;
|
||||
GtkEveryFilter *filter;
|
||||
|
||||
GListStore *tracks;
|
||||
|
||||
SysprofAxis *visible_time_axis;
|
||||
SysprofAxis *selected_time_axis;
|
||||
|
||||
@ -57,7 +54,6 @@ enum {
|
||||
PROP_INCLUDE_THREADS,
|
||||
PROP_SELECTED_TIME,
|
||||
PROP_SELECTED_TIME_AXIS,
|
||||
PROP_TRACKS,
|
||||
PROP_VISIBLE_TIME,
|
||||
PROP_VISIBLE_TIME_AXIS,
|
||||
N_PROPS
|
||||
@ -99,9 +95,6 @@ sysprof_session_set_document (SysprofSession *self,
|
||||
time_span = sysprof_document_get_time_span (document);
|
||||
self->selected_time = self->visible_time = self->document_time = *time_span;
|
||||
sysprof_session_update_axis (self);
|
||||
|
||||
/* Discover tracks to show from the document */
|
||||
_sysprof_session_discover_tracks (self, self->document, self->tracks);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -109,7 +102,6 @@ sysprof_session_dispose (GObject *object)
|
||||
{
|
||||
SysprofSession *self = (SysprofSession *)object;
|
||||
|
||||
g_clear_object (&self->tracks);
|
||||
g_clear_object (&self->visible_time_axis);
|
||||
g_clear_object (&self->selected_time_axis);
|
||||
g_clear_object (&self->document);
|
||||
@ -168,10 +160,6 @@ sysprof_session_get_property (GObject *object,
|
||||
g_value_set_object (value, sysprof_session_get_visible_time_axis (self));
|
||||
break;
|
||||
|
||||
case PROP_TRACKS:
|
||||
g_value_take_object (value, sysprof_session_list_tracks (self));
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
}
|
||||
@ -267,11 +255,6 @@ sysprof_session_class_init (SysprofSessionClass *klass)
|
||||
SYSPROF_TYPE_AXIS,
|
||||
(G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
|
||||
|
||||
properties [PROP_TRACKS] =
|
||||
g_param_spec_object ("tracks", NULL, NULL,
|
||||
G_TYPE_LIST_MODEL,
|
||||
(G_PARAM_READABLE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS));
|
||||
|
||||
g_object_class_install_properties (object_class, N_PROPS, properties);
|
||||
}
|
||||
|
||||
@ -281,7 +264,6 @@ sysprof_session_init (SysprofSession *self)
|
||||
self->filter = gtk_every_filter_new ();
|
||||
self->selected_time_axis = sysprof_value_axis_new (0, 0);
|
||||
self->visible_time_axis = sysprof_value_axis_new (0, 0);
|
||||
self->tracks = g_list_store_new (SYSPROF_TYPE_TRACK);
|
||||
}
|
||||
|
||||
SysprofSession *
|
||||
@ -414,22 +396,6 @@ sysprof_session_get_visible_time_axis (SysprofSession *self)
|
||||
return self->visible_time_axis;
|
||||
}
|
||||
|
||||
/**
|
||||
* sysprof_session_list_tracks:
|
||||
* @self: a #SysprofSession
|
||||
*
|
||||
* Gets a list of #SysprofTrack to be displayed in the session.
|
||||
*
|
||||
* Returns: (transfer full): a #GListModel of #SysprofTrack
|
||||
*/
|
||||
GListModel *
|
||||
sysprof_session_list_tracks (SysprofSession *self)
|
||||
{
|
||||
g_return_val_if_fail (SYSPROF_IS_SESSION (self), NULL);
|
||||
|
||||
return g_object_ref (G_LIST_MODEL (self->tracks));
|
||||
}
|
||||
|
||||
void
|
||||
sysprof_session_zoom_to_selection (SysprofSession *self)
|
||||
{
|
||||
@ -485,20 +451,15 @@ append_time_string (GString *str,
|
||||
|
||||
char *
|
||||
_sysprof_session_describe (SysprofSession *self,
|
||||
SysprofTrack *track,
|
||||
gpointer item)
|
||||
{
|
||||
g_autofree char *text = NULL;
|
||||
|
||||
g_return_val_if_fail (SYSPROF_IS_SESSION (self), NULL);
|
||||
g_return_val_if_fail (!track || SYSPROF_IS_TRACK (track), NULL);
|
||||
|
||||
if (self->document == NULL)
|
||||
return NULL;
|
||||
|
||||
if (track && (text = _sysprof_track_format_item_for_display (track, item)))
|
||||
return g_steal_pointer (&text);
|
||||
|
||||
if (SYSPROF_IS_DOCUMENT_MARK (item))
|
||||
{
|
||||
SysprofDocumentMark *mark = item;
|
||||
@ -55,7 +55,5 @@ void sysprof_session_select_time (SysprofSession
|
||||
const SysprofTimeSpan *time_span);
|
||||
SYSPROF_AVAILABLE_IN_ALL
|
||||
void sysprof_session_zoom_to_selection (SysprofSession *self);
|
||||
SYSPROF_AVAILABLE_IN_ALL
|
||||
GListModel *sysprof_session_list_tracks (SysprofSession *self);
|
||||
|
||||
G_END_DECLS
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user