summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAkira TAGOH <akira@tagoh.org>2006-05-28 15:45:01 +0000
committerAkira TAGOH <akira@tagoh.org>2006-05-28 15:45:01 +0000
commitb9493c84352ed867597ba173fe33e7dace6f5b1d (patch)
tree913396116c963fec25f8c2aa67ae210150c2963e
parenta62e012e7a1561c4978d34043049c546e06cd9d4 (diff)
""
-rw-r--r--Makefile.am2
-rw-r--r--configure.ac8
-rw-r--r--hieroglyph/version.h.in2
-rw-r--r--po/POTFILES.in2
-rw-r--r--src/Makefile.am73
-rwxr-xr-xsrc/hgspy5
-rw-r--r--src/hgspy.c312
-rw-r--r--src/hgspy_helper.c118
-rw-r--r--src/hgspy_helper.h32
-rw-r--r--src/visualizer.c334
-rw-r--r--src/visualizer.h63
11 files changed, 949 insertions, 2 deletions
diff --git a/Makefile.am b/Makefile.am
index 8ea7d4d..f81e0f6 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -1,5 +1,5 @@
NULL =
-SUBDIRS = hieroglyph libretto devices lib tests examples
+SUBDIRS = hieroglyph libretto src devices lib tests examples
pkgconfigdir = $(libdir)/pkgconfig
pkgconfig_DATA = hg-libretto.pc hieroglyph.pc
diff --git a/configure.ac b/configure.ac
index 51271f0..f86196e 100644
--- a/configure.ac
+++ b/configure.ac
@@ -57,16 +57,23 @@ AC_DEFINE_UNQUOTED(GETTEXT_PACKAGE, "$GETTEXT_PACKAGE", [Gettext package])
ALL_LINGUAS=""
AM_GLIB_GNU_GETTEXT
+AM_GLIB_DEFINE_LOCALEDIR(HGSPY_LOCALEDIR)
dnl ======================================================================
dnl check pkg-config stuff
dnl ======================================================================
PKG_CHECK_MODULES(HG, glib-2.0)
PKG_CHECK_MODULES(HG_MODULE, gmodule-2.0)
+PKG_CHECK_MODULES(GTK2, gtk+-2.0)
+PKG_CHECK_MODULES(GTHREAD, gthread-2.0)
AC_SUBST(HG_CFLAGS)
AC_SUBST(HG_LIBS)
AC_SUBST(HG_MODULE_CFLAGS)
AC_SUBST(HG_MODULE_LIBS)
+AC_SUBST(GTK2_CFLAGS)
+AC_SUBST(GTK2_LIBS)
+AC_SUBST(GTHREAD_CFLAGS)
+AC_SUBST(GTHREAD_LIBS)
dnl ======================================================================
dnl check glib-2.0 stuff
@@ -228,6 +235,7 @@ hieroglyph/version.h
lib/Makefile
libretto/Makefile
po/Makefile.in
+src/Makefile
tests/Makefile
hg-libretto.pc
hieroglyph.pc
diff --git a/hieroglyph/version.h.in b/hieroglyph/version.h.in
index 1f13c18..a3f8f01 100644
--- a/hieroglyph/version.h.in
+++ b/hieroglyph/version.h.in
@@ -27,7 +27,7 @@
#include <glib/gmacros.h>
#define HIEROGLYPH_VERSION "@VERSION@"
-#define HIEROGLYPH_UUID "2179ec3b-5459-4a09-8455-99983a759554"
+#define HIEROGLYPH_UUID "013b24c0-943f-40ea-ac36-bf75ff641d7d"
const char *__hg_rcsid G_GNUC_UNUSED = "$Rev$";
diff --git a/po/POTFILES.in b/po/POTFILES.in
index e69de29..30d8f57 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -0,0 +1,2 @@
+src/hgspy.c
+src/visualizer.c \ No newline at end of file
diff --git a/src/Makefile.am b/src/Makefile.am
new file mode 100644
index 0000000..c340ced
--- /dev/null
+++ b/src/Makefile.am
@@ -0,0 +1,73 @@
+NULL =
+
+INCLUDES = \
+ $(HG_CFLAGS) \
+ $(NULL)
+LIBS = \
+ @LDFLAGS@ \
+ $(HG_LIBS) \
+ $(NULL)
+DEPS = \
+ $(top_builddir)/hieroglyph/libhieroglyph.la \
+ $(top_builddir)/libretto/libretto.la \
+ $(NULL)
+
+noinst_PROGRAMS = \
+ hgspy-bin \
+ $(NULL)
+noinst_LTLIBRARIES = \
+ libhgspy.la \
+ libhgspy-helper.la \
+ $(NULL)
+
+hgspy_bin_SOURCES = \
+ hgspy.c \
+ $(NULL)
+hgspy_bin_CFLAGS = \
+ $(GTK2_CFLAGS) \
+ $(HG_MODULE_CFLAGS) \
+ $(GTHREAD_CFLAGS) \
+ $(NULL)
+hgspy_bin_LDADD = \
+ $(GTK2_LIBS) \
+ $(HG_MODULE_LIBS) \
+ $(GTHREAD_LIBS) \
+ libhgspy.la \
+ $(top_builddir)/libretto/libretto.la \
+ $(NULL)
+
+libhgspy_la_SOURCES = \
+ visualizer.c \
+ visualizer.h \
+ $(NULL)
+libhgspy_la_CFLAGS = \
+ $(GTK2_CFLAGS) \
+ $(NULL)
+libhgspy_la_LIBADD = \
+ $(GTK2_LIBS) \
+ $(NULL)
+libhgspy.la: $(libhgspy_la_OBJECTS) $(libhgspy_la_DEPENDENCIES)
+ $(LINK) -rpath $(libdir) $(libhgspy_la_LDFLAGS) $(libhgspy_la_OBJECTS) $(libhgspy_la_LIBADD) $(LIBS)
+
+libhgspy_helper_la_SOURCES = \
+ hgspy_helper.c \
+ hgspy_helper.h \
+ $(NULL)
+libhgspy_helper_la_CFLAGS = \
+ $(GTK2_CFLAGS) \
+ $(HG_MODULE_CFLAGS) \
+ $(NULL)
+libhgspy_helper_la_LDFLAGS = \
+ -avoid-version \
+ -module \
+ $(LDFLAGS) \
+ $(GTK2_LIBS) \
+ $(HG_MODULE_LIBS) \
+ libhgspy.la \
+ $(NULL)
+libhgspy-helper.la: $(libhgspy_helper_la_OBJECTS) $(libhgspy_helper_la_DEPENDENCIES)
+ $(LINK) -rpath $(libdir) $(libhgspy_helper_la_LDFLAGS) $(libhgspy_helper_la_OBJECTS) $(libhgspy_helper_la_LIBADD) $(LIBS)
+
+EXTRA_DIST = \
+ hgspy \
+ $(NULL)
diff --git a/src/hgspy b/src/hgspy
new file mode 100755
index 0000000..30b18ac
--- /dev/null
+++ b/src/hgspy
@@ -0,0 +1,5 @@
+#! /bin/sh
+
+topdir=`dirname $0`
+
+LD_LIBRARY_PATH=$topdir/.libs:$LD_LIBRARY_PATH LD_PRELOAD=$topdir/.libs/libhgspy-helper.so gdb $topdir/.libs/hgspy-bin $@
diff --git a/src/hgspy.c b/src/hgspy.c
new file mode 100644
index 0000000..48a200a
--- /dev/null
+++ b/src/hgspy.c
@@ -0,0 +1,312 @@
+/*
+ * hgspy.c
+ * Copyright (C) 2006 Akira TAGOH
+ *
+ * Authors:
+ * Akira TAGOH <at@gclab.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+#include <string.h>
+#include <glib/gi18n.h>
+#include <gtk/gtk.h>
+#include <libretto/vm.h>
+#include "visualizer.h"
+
+
+typedef struct _HieroGlyphSpy HgSpy;
+
+struct _HieroGlyphSpy {
+ GtkWidget *window;
+ GtkWidget *visualizer;
+ GThread *vm_thread;
+};
+
+static gpointer __hg_spy_helper_get_widget = NULL;
+
+/*
+ * Private Functions
+ */
+static gpointer
+_hgspy_vm_thread(gpointer data)
+{
+ LibrettoVM *vm;
+
+ libretto_vm_init();
+
+ vm = libretto_vm_new(LB_EMULATION_LEVEL_1);
+ libretto_vm_startjob(vm, (gchar *)data, TRUE);
+
+ return NULL;
+}
+
+static void
+_hgspy_run_vm(HgSpy *spy,
+ const gchar *file)
+{
+ if (spy->vm_thread != NULL) {
+ }
+ g_thread_create(_hgspy_vm_thread, NULL, FALSE, NULL);
+}
+
+static void
+_hgspy_about_email_cb(GtkAboutDialog *about,
+ const gchar *link,
+ gpointer data)
+{
+}
+
+static void
+_hgspy_about_url_cb(GtkAboutDialog *about,
+ const gchar *link,
+ gpointer data)
+{
+}
+
+static void
+_hgspy_action_menubar_run_cb(GtkAction *action,
+ HgSpy *spy)
+{
+ _hgspy_run_vm(spy, NULL);
+}
+
+static void
+_hgspy_action_menubar_open_cb(GtkAction *action,
+ HgSpy *spy)
+{
+ GtkWidget *dialog;
+ gint result;
+ GtkFileFilter *filter;
+
+ filter = gtk_file_filter_new();
+ gtk_file_filter_add_mime_type(filter, "application/postscript");
+
+ dialog = gtk_file_chooser_dialog_new(_("Open a PostScript file"),
+ GTK_WINDOW (spy->window),
+ GTK_FILE_CHOOSER_ACTION_OPEN,
+ GTK_STOCK_CANCEL,
+ GTK_RESPONSE_CANCEL,
+ GTK_STOCK_OPEN,
+ GTK_RESPONSE_OK,
+ NULL);
+ gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (dialog), filter);
+
+ result = gtk_dialog_run(GTK_DIALOG (dialog));
+ switch (result) {
+ case GTK_RESPONSE_OK:
+ _hgspy_run_vm(spy,
+ gtk_file_chooser_get_filename(GTK_FILE_CHOOSER (dialog)));
+ break;
+ case GTK_RESPONSE_CANCEL:
+ default:
+ break;
+ }
+ gtk_widget_destroy(dialog);
+}
+
+static void
+_hgspy_action_menubar_quit_cb(GtkAction *action,
+ HgSpy *spy)
+{
+ gtk_main_quit();
+}
+
+static void
+_hgspy_action_menubar_about_cb(GtkAction *action,
+ HgSpy *spy)
+{
+ const gchar *authors[] = {
+ "Akira TAGOH",
+ NULL
+ };
+ const gchar *license =
+ "This library is free software; you can redistribute it and/or\n"
+ "modify it under the terms of the GNU Lesser General Public\n"
+ "License as published by the Free Software Foundation; either\n"
+ "version 2 of the License, or (at your option) any later version.\n"
+ "\n"
+ "This library is distributed in the hope that it will be useful,\n"
+ "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
+ "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\n"
+ "Lesser General Public License for more details.\n"
+ "\n"
+ "You should have received a copy of the GNU Lesser General Public\n"
+ "License along with this library; if not, write to the\n"
+ "Free Software Foundation, Inc., 59 Temple Place - Suite 330,\n"
+ "Boston, MA 02111-1307, USA.\n";
+
+ gtk_about_dialog_set_email_hook(_hgspy_about_email_cb, NULL, NULL);
+ gtk_about_dialog_set_url_hook(_hgspy_about_url_cb, NULL, NULL);
+ gtk_show_about_dialog(GTK_WINDOW (spy->window),
+ "name", "Memory visualizer",
+ "version", PACKAGE_VERSION,
+ "copyright", "(C) 2006 Akira TAGOH",
+ "license", license,
+ "website", "http://hieroglyph.freedesktop.org/",
+ "comments", "for Hieroglyph memory management system",
+ "authors", authors,
+ NULL);
+}
+
+/*
+ * Public Functions
+ */
+int
+main(int argc,
+ char **argv)
+{
+ GModule *module;
+ HgSpy *spy;
+ GtkWidget *menubar, *vbox;
+ GtkUIManager *uiman;
+ GtkActionGroup *actions;
+ GtkActionEntry action_entries[] = {
+ /* toplevel menu */
+ {
+ .name = "VMMenu",
+ .stock_id = NULL,
+ .label = _("_VM"),
+ .accelerator = NULL,
+ .tooltip = NULL,
+ .callback = NULL
+ },
+ {
+ .name = "HelpMenu",
+ .stock_id = NULL,
+ .label = _("_Help"),
+ .accelerator = NULL,
+ .tooltip = NULL,
+ .callback = NULL
+ },
+ /* submenu - VM */
+ {
+ .name = "Run",
+ .stock_id = GTK_STOCK_EXECUTE,
+ .label = NULL,
+ .accelerator = NULL,
+ .tooltip = _("Run VM interactively"),
+ .callback = G_CALLBACK (_hgspy_action_menubar_run_cb)
+ },
+ {
+ .name = "Open",
+ .stock_id = GTK_STOCK_OPEN,
+ .label = NULL,
+ .accelerator = "<control>O",
+ .tooltip = _("Run a PostScript file on VM"),
+ .callback = G_CALLBACK (_hgspy_action_menubar_open_cb)
+ },
+ {
+ .name = "Quit",
+ .stock_id = GTK_STOCK_QUIT,
+ .label = NULL,
+ .accelerator = "<control>Q",
+ .tooltip = _("Quit"),
+ .callback = G_CALLBACK (_hgspy_action_menubar_quit_cb)
+ },
+ /* submenu - Help */
+ {
+ .name = "About",
+ .stock_id = GTK_STOCK_ABOUT,
+ .label = NULL,
+ .accelerator = NULL,
+ .tooltip = _("About"),
+ .callback = G_CALLBACK (_hgspy_action_menubar_about_cb)
+ }
+ };
+ gchar *uixml =
+ "<ui>"
+ " <menubar name='MenuBar'>"
+ " <menu action='VMMenu'>"
+ " <menuitem action='Run'/>"
+ " <menuitem action='Open'/>"
+ " <separator/>"
+ " <menuitem action='Quit'/>"
+ " </menu>"
+ " <menu action='HelpMenu'>"
+ " <menuitem action='About'/>"
+ " </menu>"
+ " </menubar>"
+ "</ui>";
+
+ if ((module = g_module_open("libhgspy-helper.so", 0)) == NULL) {
+ g_warning("Failed g_module_open: %s", g_module_error());
+ return 1;
+ }
+ if (!g_module_symbol(module, "hg_spy_helper_get_widget", &__hg_spy_helper_get_widget)) {
+ g_warning("Failed g_module_symbol: %s", g_module_error());
+ g_module_close(module);
+ return 1;
+ }
+
+#ifdef ENABLE_NLS
+ bindtextdomain (GETTEXT_PACKAGE, HGSPY_LOCALEDIR);
+#ifdef HAVE_BIND_TEXTDOMAIN_CODESET
+ bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
+#endif /* HAVE_BIND_TEXTDOMAIN_CODESET */
+ textdomain (GETTEXT_PACKAGE);
+#endif /* ENABLE_NLS */
+
+ g_thread_init(NULL);
+ gtk_init(&argc, &argv);
+
+ spy = g_new(HgSpy, 1);
+ spy->window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
+ spy->vm_thread = NULL;
+ actions = gtk_action_group_new("MenuBar");
+ uiman = gtk_ui_manager_new();
+ vbox = gtk_vbox_new(FALSE, 0);
+ spy->visualizer = ((GtkWidget * (*) (void))__hg_spy_helper_get_widget) ();
+
+ if (spy->visualizer == NULL) {
+ g_warning("Failed to initialize a helper module.");
+ return 1;
+ }
+
+ /* setup action groups */
+ gtk_action_group_add_actions(actions,
+ action_entries,
+ sizeof (action_entries) / sizeof (GtkActionEntry),
+ spy);
+
+ /* setup UI */
+ gtk_ui_manager_add_ui_from_string(uiman, uixml, strlen(uixml), NULL);
+ gtk_ui_manager_insert_action_group(uiman, actions, 0);
+
+ /* setup accelerators */
+ gtk_window_add_accel_group(GTK_WINDOW (spy->window), gtk_ui_manager_get_accel_group(uiman));
+
+ /* widget connections */
+ menubar = gtk_ui_manager_get_widget(uiman, "/MenuBar");
+ gtk_box_pack_start(GTK_BOX (vbox), menubar, FALSE, TRUE, 0);
+ gtk_box_pack_start(GTK_BOX (vbox), spy->visualizer, TRUE, TRUE, 0);
+ gtk_container_add(GTK_CONTAINER (spy->window), vbox);
+
+ /* setup signals */
+ g_signal_connect(spy->window, "delete-event",
+ G_CALLBACK (gtk_main_quit), NULL);
+
+ gtk_widget_show_all(spy->window);
+
+ gtk_main();
+
+ /* finalize */
+ g_module_close(module);
+
+ return 0;
+}
diff --git a/src/hgspy_helper.c b/src/hgspy_helper.c
new file mode 100644
index 0000000..46782f1
--- /dev/null
+++ b/src/hgspy_helper.c
@@ -0,0 +1,118 @@
+/*
+ * hgspy_helper.c
+ * Copyright (C) 2006 Akira TAGOH
+ *
+ * Authors:
+ * Akira TAGOH <at@gclab.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+#include <stdlib.h>
+#include <gmodule.h>
+#include <hieroglyph/hgtypes.h>
+#include <hieroglyph/hgmem.h>
+#include "hgspy_helper.h"
+#include "visualizer.h"
+
+
+static gpointer __hg_mem_alloc_with_flags = NULL;
+static gpointer __hg_mem_free = NULL;
+static GModule *__handle = NULL;
+static GtkWidget *visual = NULL;
+
+/*
+ * Private Functions
+ */
+static void __attribute__((constructor))
+helper_init(void)
+{
+ unsetenv("LD_PRELOAD");
+ __handle = g_module_open("libhieroglyph.so", 0);
+ if (__handle == NULL) {
+ g_warning("Failed g_module_open: %s", g_module_error());
+ exit(1);
+ }
+ if (!g_module_symbol(__handle, "hg_mem_alloc_with_flags", &__hg_mem_alloc_with_flags)) {
+ g_warning("Failed g_module_symbol: %s", g_module_error());
+ exit(1);
+ }
+ if (!g_module_symbol(__handle, "hg_mem_free", &__hg_mem_free)) {
+ g_warning("Failed g_module_symbol: %s", g_module_error());
+ exit(1);
+ }
+ g_type_init();
+ visual = hg_memory_visualizer_new();
+}
+
+void __attribute__((destructor))
+helper_finalize(void)
+{
+ if (__handle)
+ g_module_close(__handle);
+}
+
+/*
+ * preload functions
+ */
+gpointer
+hg_mem_alloc_with_flags(HgMemPool *pool,
+ gsize size,
+ guint flags)
+{
+ gpointer retval = ((gpointer (*) (HgMemPool *, gsize, guint))
+ __hg_mem_alloc_with_flags) (pool, size, flags);
+ HgMemObject *obj;
+
+ hg_mem_get_object__inline(retval, obj);
+ if (obj) {
+ hg_memory_visualizer_set_chunk_state(HG_MEMORY_VISUALIZER (visual),
+ obj->heap_id,
+ obj,
+ obj->block_size,
+ HG_CHUNK_USED);
+ }
+
+ return retval;
+}
+
+gboolean
+hg_mem_free(gpointer data)
+{
+ HgMemObject *obj;
+
+ hg_mem_get_object__inline(data, obj);
+ if (obj) {
+ hg_memory_visualizer_set_chunk_state(HG_MEMORY_VISUALIZER (visual),
+ obj->heap_id,
+ obj,
+ obj->block_size,
+ HG_CHUNK_FREE);
+ }
+
+ return ((gboolean (*) (gpointer))__hg_mem_free) (data);
+}
+
+/*
+ * Public Functions
+ */
+GtkWidget *
+hg_spy_helper_get_widget(void)
+{
+ return visual;
+}
diff --git a/src/hgspy_helper.h b/src/hgspy_helper.h
new file mode 100644
index 0000000..974e447
--- /dev/null
+++ b/src/hgspy_helper.h
@@ -0,0 +1,32 @@
+/*
+ * hgspy_helper.h
+ * Copyright (C) 2006 Akira TAGOH
+ *
+ * Authors:
+ * Akira TAGOH <at@gclab.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+#ifndef __HG_SPY_HELPER_H__
+#define __HG_SPY_HELPER_H__
+
+#include <glib.h>
+
+G_BEGIN_DECLS
+
+G_END_DECLS
+
+#endif /* __HG_SPY_HELPER_H__ */
diff --git a/src/visualizer.c b/src/visualizer.c
new file mode 100644
index 0000000..d1c6b86
--- /dev/null
+++ b/src/visualizer.c
@@ -0,0 +1,334 @@
+/*
+ * visualizer.c
+ * Copyright (C) 2006 Akira TAGOH
+ *
+ * Authors:
+ * Akira TAGOH <at@gclab.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+#include <math.h>
+#include <glib/gi18n.h>
+#include "visualizer.h"
+
+
+enum {
+ PROP_0,
+ PROP_MAX_SIZE,
+};
+
+enum {
+ LAST_SIGNAL
+};
+
+struct _HgMemoryVisualizerClass {
+ GtkLayoutClass parent_class;
+};
+
+struct _HgMemoryVisualizer {
+ GtkLayout parent_instance;
+
+ /*< private >*/
+ glong max_size;
+ gdouble block_size;
+};
+
+
+static GtkLayoutClass *parent_class = NULL;
+//static guint signals[LAST_SIGNAL] = { 0 };
+
+
+/*
+ * Signal handlers
+ */
+/* GObject */
+static void
+hg_memory_visualizer_real_set_property(GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ HgMemoryVisualizer *visual = HG_MEMORY_VISUALIZER (object);
+
+ switch (prop_id) {
+ case PROP_MAX_SIZE:
+ hg_memory_visualizer_set_max_size(visual, g_value_get_long(value));
+ break;
+ default:
+ break;
+ }
+}
+
+static void
+hg_memory_visualizer_real_get_property(GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ HgMemoryVisualizer *visual = HG_MEMORY_VISUALIZER (object);
+
+ switch (prop_id) {
+ case PROP_MAX_SIZE:
+ g_value_set_long(value, hg_memory_visualizer_get_max_size(visual));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+/* GtkObject */
+static void
+hg_memory_visualizer_real_destroy(GtkObject *object)
+{
+ /* FIXME: not yet implemented */
+
+ (* GTK_OBJECT_CLASS (parent_class)->destroy) (object);
+}
+
+/* GtkWidget */
+static gboolean
+hg_memory_visualizer_real_expose(GtkWidget *widget,
+ GdkEventExpose *event)
+{
+ HgMemoryVisualizer *visual;
+
+ g_return_val_if_fail (HG_IS_MEMORY_VISUALIZER (widget), FALSE);
+ g_return_val_if_fail (event != NULL, FALSE);
+
+ visual = HG_MEMORY_VISUALIZER (widget);
+
+ if (!GTK_WIDGET_DRAWABLE (widget) || (event->window != visual->parent_instance.bin_window))
+ return FALSE;
+
+ /* FIXME: not yet implemented */
+
+ return FALSE;
+}
+
+static void
+hg_memory_visualizer_real_realize(GtkWidget *widget)
+{
+ HgMemoryVisualizer *visual;
+
+ g_return_if_fail (HG_IS_MEMORY_VISUALIZER (widget));
+
+ if (GTK_WIDGET_CLASS (parent_class)->realize)
+ (* GTK_WIDGET_CLASS (parent_class)->realize) (widget);
+
+ visual = HG_MEMORY_VISUALIZER (widget);
+
+ gdk_window_set_events(visual->parent_instance.bin_window,
+ (gdk_window_get_events(visual->parent_instance.bin_window)
+ | GDK_EXPOSURE_MASK));
+
+ /* FIXME: not yet implemented */
+
+}
+
+static void
+hg_memory_visualizer_real_unrealize(GtkWidget *widget)
+{
+ HgMemoryVisualizer *visual;
+
+ g_return_if_fail (HG_IS_MEMORY_VISUALIZER (widget));
+
+ visual = HG_MEMORY_VISUALIZER (widget);
+
+ /* FIXME: not yet implemented */
+
+ if (GTK_WIDGET_CLASS (parent_class)->unrealize)
+ (* GTK_WIDGET_CLASS (parent_class)->unrealize) (widget);
+}
+
+static void
+hg_memory_visualizer_real_map(GtkWidget *widget)
+{
+ HgMemoryVisualizer *visual;
+
+ g_return_if_fail (HG_IS_MEMORY_VISUALIZER (widget));
+
+ if (GTK_WIDGET_CLASS (parent_class)->map)
+ (* GTK_WIDGET_CLASS (parent_class)->map) (widget);
+
+ visual = HG_MEMORY_VISUALIZER (widget);
+
+ /* FIXME: not yet implemented */
+
+}
+
+static void
+hg_memory_visualizer_real_unmap(GtkWidget *widget)
+{
+ HgMemoryVisualizer *visual;
+
+ g_return_if_fail (HG_IS_MEMORY_VISUALIZER (widget));
+
+ visual = HG_MEMORY_VISUALIZER (widget);
+
+ /* FIXME: not yet implemented */
+
+ if (GTK_WIDGET_CLASS (parent_class)->unmap)
+ (* GTK_WIDGET_CLASS (parent_class)->unmap) (widget);
+}
+
+static void
+hg_memory_visualizer_real_size_request(GtkWidget *widget,
+ GtkRequisition *requisition)
+{
+}
+
+static void
+hg_memory_visualizer_real_size_allocate(GtkWidget *widget,
+ GtkAllocation *allocation)
+{
+ HgMemoryVisualizer *visual;
+
+ g_return_if_fail (HG_IS_MEMORY_VISUALIZER (widget));
+ g_return_if_fail (allocation != NULL);
+
+ if (GTK_WIDGET_CLASS (parent_class)->size_allocate)
+ (* GTK_WIDGET_CLASS (parent_class)->size_allocate) (widget, allocation);
+
+ visual = HG_MEMORY_VISUALIZER (widget);
+
+ /* FIXME: not yet implemented */
+
+}
+
+/*
+ * Private Functions
+ */
+static void
+hg_memory_visualizer_class_init(HgMemoryVisualizerClass *klass)
+{
+ GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+ GtkObjectClass *object_class = GTK_OBJECT_CLASS (klass);
+ GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
+
+ parent_class = g_type_class_peek_parent(klass);
+
+ /* initialize GObject */
+ gobject_class->set_property = hg_memory_visualizer_real_set_property;
+ gobject_class->get_property = hg_memory_visualizer_real_get_property;
+
+ /* initialize GtkObject */
+ object_class->destroy = hg_memory_visualizer_real_destroy;
+
+ /* initialize GtkWidget */
+ widget_class->expose_event = hg_memory_visualizer_real_expose;
+ widget_class->realize = hg_memory_visualizer_real_realize;
+ widget_class->unrealize = hg_memory_visualizer_real_unrealize;
+ widget_class->map = hg_memory_visualizer_real_map;
+ widget_class->unmap = hg_memory_visualizer_real_unmap;
+ widget_class->size_request = hg_memory_visualizer_real_size_request;
+ widget_class->size_allocate = hg_memory_visualizer_real_size_allocate;
+
+ /* initialize HgMemoryVisualizer */
+
+ /* GObject properties */
+ g_object_class_install_property(gobject_class,
+ PROP_MAX_SIZE,
+ g_param_spec_long("max_size",
+ _("Max size of memory pool"),
+ _("Max size of memory pool that is now being visualized."),
+ 0,
+ G_MAXLONG,
+ 0,
+ G_PARAM_READWRITE));
+
+ /* signals */
+}
+
+static void
+hg_memory_visualizer_instance_init(HgMemoryVisualizer *visual)
+{
+ visual->max_size = 0;
+}
+
+/*
+ * Public Functions
+ */
+GType
+hg_memory_visualizer_get_type(void)
+{
+ static GType mv_type = 0;
+
+ if (!mv_type) {
+ static const GTypeInfo mv_info = {
+ .class_size = sizeof (HgMemoryVisualizerClass),
+ .base_init = NULL,
+ .base_finalize = NULL,
+ .class_init = (GClassInitFunc)hg_memory_visualizer_class_init,
+ .class_finalize = NULL,
+ .class_data = NULL,
+ .instance_size = sizeof (HgMemoryVisualizer),
+ .n_preallocs = 0,
+ .instance_init = (GInstanceInitFunc)hg_memory_visualizer_instance_init,
+ .value_table = NULL,
+ };
+
+ mv_type = g_type_register_static(GTK_TYPE_LAYOUT, "HgMemoryVisualizer",
+ &mv_info, 0);
+ }
+
+ return mv_type;
+}
+
+GtkWidget *
+hg_memory_visualizer_new(void)
+{
+ return GTK_WIDGET (g_object_new(HG_TYPE_MEMORY_VISUALIZER, NULL));
+}
+
+void
+hg_memory_visualizer_set_max_size(HgMemoryVisualizer *visual,
+ glong size)
+{
+ glong area;
+ gdouble scale;
+
+ g_return_if_fail (HG_IS_MEMORY_VISUALIZER (visual));
+
+ area = visual->parent_instance.width * visual->parent_instance.height;
+ visual->max_size = size;
+ if (area > size) {
+ scale = area / size;
+ visual->block_size = sqrt(scale);
+ } else {
+ /* FIXME: need to scale up to fit in */
+ }
+}
+
+glong
+hg_memory_visualizer_get_max_size(HgMemoryVisualizer *visual)
+{
+ g_return_val_if_fail (HG_IS_MEMORY_VISUALIZER (visual), 0);
+
+ return visual->max_size;
+}
+
+void
+hg_memory_visualizer_set_chunk_state(HgMemoryVisualizer *visual,
+ gint heap_id,
+ gpointer addr,
+ gsize size,
+ HgMemoryChunkState state)
+{
+}
diff --git a/src/visualizer.h b/src/visualizer.h
new file mode 100644
index 0000000..70bd5ab
--- /dev/null
+++ b/src/visualizer.h
@@ -0,0 +1,63 @@
+/*
+ * visualizer.h
+ * Copyright (C) 2006 Akira TAGOH
+ *
+ * Authors:
+ * Akira TAGOH <at@gclab.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+#ifndef __VISUALIZER_H__
+#define __VISUALIZER_H__
+
+#include <gtk/gtk.h>
+
+G_BEGIN_DECLS
+
+#define HG_TYPE_MEMORY_VISUALIZER (hg_memory_visualizer_get_type())
+#define HG_MEMORY_VISUALIZER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), HG_TYPE_MEMORY_VISUALIZER, HgMemoryVisualizer))
+#define HG_MEMORY_VISUALIZER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), HG_TYPE_MEMORY_VISUALIZER, HgMemoryVisualizerClass))
+#define HG_IS_MEMORY_VISUALIZER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), HG_TYPE_MEMORY_VISUALIZER))
+#define HG_IS_MEMORY_VISUALIZER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), HG_TYPE_MEMORY_VISUALIZER))
+#define HG_MEMORY_VISUALIZER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), HG_TYPE_MEMORY_VISUALIZER, HgMemoryVisualizerClass))
+
+
+typedef struct _HgMemoryVisualizerClass HgMemoryVisualizerClass;
+typedef struct _HgMemoryVisualizer HgMemoryVisualizer;
+typedef enum _HgMemoryChunkState HgMemoryChunkState;
+
+
+enum _HgMemoryChunkState {
+ HG_CHUNK_FREE,
+ HG_CHUNK_USED,
+};
+
+
+GType hg_memory_visualizer_get_type (void) G_GNUC_CONST;
+GtkWidget *hg_memory_visualizer_new (void);
+void hg_memory_visualizer_set_max_size (HgMemoryVisualizer *visual,
+ glong size);
+glong hg_memory_visualizer_get_max_size (HgMemoryVisualizer *visual);
+void hg_memory_visualizer_set_chunk_state(HgMemoryVisualizer *visual,
+ gint heap_id,
+ gpointer addr,
+ gsize size,
+ HgMemoryChunkState state);
+
+
+G_END_DECLS
+
+#endif /* __VISUALIZER_H__ */