diff options
author | Joakim Sindholt <opensource@zhasha.com> | 2010-04-06 01:39:25 +0200 |
---|---|---|
committer | Joakim Sindholt <opensource@zhasha.com> | 2010-04-06 01:39:25 +0200 |
commit | e9f96e863deb3cdf1bea48aba71ca7b0b89fa30b (patch) | |
tree | 5cf9cbdcf4e7c2ae688f17b19c134e6077de5a7b | |
parent | 7baec6b83ae5533f9f19baef3850265b07cf12ab (diff) |
rsim: code/interface cleanups
-rw-r--r-- | Makefile.am | 3 | ||||
-rw-r--r-- | configure.ac | 9 | ||||
-rw-r--r-- | src/cs.c | 164 | ||||
-rw-r--r-- | src/cs.vala | 40 | ||||
-rw-r--r-- | src/csimport.vala | 34 | ||||
-rw-r--r-- | src/csview.c | 21 | ||||
-rw-r--r-- | src/csview.vala | 173 | ||||
-rw-r--r-- | src/main.c | 298 | ||||
-rw-r--r-- | src/main.vala | 163 | ||||
-rw-r--r-- | src/registers.c | 131 | ||||
-rw-r--r-- | src/registers.vala | 115 |
11 files changed, 757 insertions, 394 deletions
diff --git a/Makefile.am b/Makefile.am index d1d16ff..6765924 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,4 +1,4 @@ -NULL = +NULL = AUTOMAKE_OPTIONS = subdir-objects @@ -22,6 +22,7 @@ rsim_SOURCES = \ $(NULL) rsim_VALAFLAGS = \ + --thread \ --pkg gtk+-2.0 \ --pkg libxml-2.0 diff --git a/configure.ac b/configure.ac index eb80cb6..e65d358 100644 --- a/configure.ac +++ b/configure.ac @@ -19,10 +19,11 @@ GTK_REQUIRED=2.10.0 LIBXML_REQUIRED=2.0 PKG_CHECK_MODULES(RSIM, - glib-2.0 >= $GLIB_REQUIRED - gobject-2.0 >= $GLIB_REQUIRED - gtk+-2.0 >= $GTK_REQUIRED - libxml-2.0 >= $LIBXML_REQUIRED) + glib-2.0 >= $GLIB_REQUIRED + gobject-2.0 >= $GLIB_REQUIRED + gthread-2.0 >= $GLIB_REQUIRED + gtk+-2.0 >= $GTK_REQUIRED + libxml-2.0 >= $LIBXML_REQUIRED) AC_SUBST(RSIM_CFLAGS) AC_SUBST(RSIM_LIBS) @@ -5,6 +5,7 @@ #include <glib.h> #include <glib-object.h> #include <string.h> +#include <gobject/gvaluecollector.h> #define EMULATION_TYPE_CHIP (emulation_chip_get_type ()) @@ -69,8 +70,8 @@ typedef struct _EmulationPacket3Class EmulationPacket3Class; typedef struct _EmulationPacketIterator EmulationPacketIterator; typedef struct _EmulationPacketIteratorClass EmulationPacketIteratorClass; typedef struct _EmulationPacketIteratorPrivate EmulationPacketIteratorPrivate; -#define _g_object_unref0(var) ((var == NULL) ? NULL : (var = (g_object_unref (var), NULL))) typedef struct _EmulationPacketBasePrivate EmulationPacketBasePrivate; +typedef struct _EmulationParamSpecPacketIterator EmulationParamSpecPacketIterator; typedef struct _EmulationPacket0Private EmulationPacket0Private; typedef struct _EmulationPacket1Private EmulationPacket1Private; typedef struct _EmulationPacket2Private EmulationPacket2Private; @@ -86,6 +87,7 @@ typedef struct _EmulationPacket3Private EmulationPacket3Private; typedef struct _EmulationCS EmulationCS; typedef struct _EmulationCSClass EmulationCSClass; typedef struct _EmulationCSPrivate EmulationCSPrivate; +#define _g_object_unref0(var) ((var == NULL) ? NULL : (var = (g_object_unref (var), NULL))) typedef enum { EMULATION_CHIP_R300, @@ -93,12 +95,14 @@ typedef enum { } EmulationChip; struct _EmulationPacketIterator { - GObject parent_instance; + GTypeInstance parent_instance; + volatile int ref_count; EmulationPacketIteratorPrivate * priv; }; struct _EmulationPacketIteratorClass { - GObjectClass parent_class; + GTypeClass parent_class; + void (*finalize) (EmulationPacketIterator *self); }; struct _EmulationPacketIteratorPrivate { @@ -118,6 +122,10 @@ struct _EmulationPacketBaseClass { guint (*get_length) (EmulationPacketBase* self); }; +struct _EmulationParamSpecPacketIterator { + GParamSpec parent_instance; +}; + struct _EmulationPacket0 { EmulationPacketBase parent_instance; EmulationPacket0Private * priv; @@ -194,6 +202,11 @@ GType emulation_packet3_get_type (void); EmulationPacketBase* emulation_packet_base_new (void); EmulationPacketBase* emulation_packet_base_construct (GType object_type); EmulationPacketBase* emulation_make_packet (guint32 header, guint32* dwords); +gpointer emulation_packet_iterator_ref (gpointer instance); +void emulation_packet_iterator_unref (gpointer instance); +GParamSpec* emulation_param_spec_packet_iterator (const gchar* name, const gchar* nick, const gchar* blurb, GType object_type, GParamFlags flags); +void emulation_value_set_packet_iterator (GValue* value, gpointer v_object); +gpointer emulation_value_get_packet_iterator (const GValue* value); GType emulation_packet_iterator_get_type (void); #define EMULATION_PACKET_ITERATOR_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), EMULATION_TYPE_PACKET_ITERATOR, EmulationPacketIteratorPrivate)) enum { @@ -204,7 +217,7 @@ EmulationPacketIterator* emulation_packet_iterator_construct (GType object_type, guint emulation_packet_base_get_length (EmulationPacketBase* self); gboolean emulation_packet_iterator_next (EmulationPacketIterator* self); guint32 emulation_packet_iterator_get (EmulationPacketIterator* self); -static void emulation_packet_iterator_finalize (GObject* obj); +static void emulation_packet_iterator_finalize (EmulationPacketIterator* obj); enum { EMULATION_PACKET_BASE_DUMMY_PROPERTY, EMULATION_PACKET_BASE_EXTRACT_TYPE, @@ -318,17 +331,11 @@ inline EmulationPacketBase* emulation_make_packet (guint32 header, guint32* dwor } -static gpointer _g_object_ref0 (gpointer self) { - return self ? g_object_ref (self) : NULL; -} - - EmulationPacketIterator* emulation_packet_iterator_construct (GType object_type, EmulationPacketBase* p) { - EmulationPacketIterator * self; - EmulationPacketBase* _tmp0_; + EmulationPacketIterator* self; g_return_val_if_fail (p != NULL, NULL); - self = (EmulationPacketIterator*) g_object_new (object_type, NULL); - self->priv->m_packet = (_tmp0_ = _g_object_ref0 (p), _g_object_unref0 (self->priv->m_packet), _tmp0_); + self = (EmulationPacketIterator*) g_type_create_instance (object_type); + self->priv->m_packet = p; self->priv->m_pos = (guint) 0; return self; } @@ -355,36 +362,148 @@ guint32 emulation_packet_iterator_get (EmulationPacketIterator* self) { } +static void emulation_value_packet_iterator_init (GValue* value) { + value->data[0].v_pointer = NULL; +} + + +static void emulation_value_packet_iterator_free_value (GValue* value) { + if (value->data[0].v_pointer) { + emulation_packet_iterator_unref (value->data[0].v_pointer); + } +} + + +static void emulation_value_packet_iterator_copy_value (const GValue* src_value, GValue* dest_value) { + if (src_value->data[0].v_pointer) { + dest_value->data[0].v_pointer = emulation_packet_iterator_ref (src_value->data[0].v_pointer); + } else { + dest_value->data[0].v_pointer = NULL; + } +} + + +static gpointer emulation_value_packet_iterator_peek_pointer (const GValue* value) { + return value->data[0].v_pointer; +} + + +static gchar* emulation_value_packet_iterator_collect_value (GValue* value, guint n_collect_values, GTypeCValue* collect_values, guint collect_flags) { + if (collect_values[0].v_pointer) { + EmulationPacketIterator* object; + object = collect_values[0].v_pointer; + if (object->parent_instance.g_class == NULL) { + return g_strconcat ("invalid unclassed object pointer for value type `", G_VALUE_TYPE_NAME (value), "'", NULL); + } else if (!g_value_type_compatible (G_TYPE_FROM_INSTANCE (object), G_VALUE_TYPE (value))) { + return g_strconcat ("invalid object type `", g_type_name (G_TYPE_FROM_INSTANCE (object)), "' for value type `", G_VALUE_TYPE_NAME (value), "'", NULL); + } + value->data[0].v_pointer = emulation_packet_iterator_ref (object); + } else { + value->data[0].v_pointer = NULL; + } + return NULL; +} + + +static gchar* emulation_value_packet_iterator_lcopy_value (const GValue* value, guint n_collect_values, GTypeCValue* collect_values, guint collect_flags) { + EmulationPacketIterator** object_p; + object_p = collect_values[0].v_pointer; + if (!object_p) { + return g_strdup_printf ("value location for `%s' passed as NULL", G_VALUE_TYPE_NAME (value)); + } + if (!value->data[0].v_pointer) { + *object_p = NULL; + } else if (collect_flags && G_VALUE_NOCOPY_CONTENTS) { + *object_p = value->data[0].v_pointer; + } else { + *object_p = emulation_packet_iterator_ref (value->data[0].v_pointer); + } + return NULL; +} + + +GParamSpec* emulation_param_spec_packet_iterator (const gchar* name, const gchar* nick, const gchar* blurb, GType object_type, GParamFlags flags) { + EmulationParamSpecPacketIterator* spec; + g_return_val_if_fail (g_type_is_a (object_type, EMULATION_TYPE_PACKET_ITERATOR), NULL); + spec = g_param_spec_internal (G_TYPE_PARAM_OBJECT, name, nick, blurb, flags); + G_PARAM_SPEC (spec)->value_type = object_type; + return G_PARAM_SPEC (spec); +} + + +gpointer emulation_value_get_packet_iterator (const GValue* value) { + g_return_val_if_fail (G_TYPE_CHECK_VALUE_TYPE (value, EMULATION_TYPE_PACKET_ITERATOR), NULL); + return value->data[0].v_pointer; +} + + +void emulation_value_set_packet_iterator (GValue* value, gpointer v_object) { + EmulationPacketIterator* old; + g_return_if_fail (G_TYPE_CHECK_VALUE_TYPE (value, EMULATION_TYPE_PACKET_ITERATOR)); + old = value->data[0].v_pointer; + if (v_object) { + g_return_if_fail (G_TYPE_CHECK_INSTANCE_TYPE (v_object, EMULATION_TYPE_PACKET_ITERATOR)); + g_return_if_fail (g_value_type_compatible (G_TYPE_FROM_INSTANCE (v_object), G_VALUE_TYPE (value))); + value->data[0].v_pointer = v_object; + emulation_packet_iterator_ref (value->data[0].v_pointer); + } else { + value->data[0].v_pointer = NULL; + } + if (old) { + emulation_packet_iterator_unref (old); + } +} + + static void emulation_packet_iterator_class_init (EmulationPacketIteratorClass * klass) { emulation_packet_iterator_parent_class = g_type_class_peek_parent (klass); + EMULATION_PACKET_ITERATOR_CLASS (klass)->finalize = emulation_packet_iterator_finalize; g_type_class_add_private (klass, sizeof (EmulationPacketIteratorPrivate)); - G_OBJECT_CLASS (klass)->finalize = emulation_packet_iterator_finalize; } static void emulation_packet_iterator_instance_init (EmulationPacketIterator * self) { self->priv = EMULATION_PACKET_ITERATOR_GET_PRIVATE (self); + self->ref_count = 1; } -static void emulation_packet_iterator_finalize (GObject* obj) { +static void emulation_packet_iterator_finalize (EmulationPacketIterator* obj) { EmulationPacketIterator * self; self = EMULATION_PACKET_ITERATOR (obj); - _g_object_unref0 (self->priv->m_packet); - G_OBJECT_CLASS (emulation_packet_iterator_parent_class)->finalize (obj); } GType emulation_packet_iterator_get_type (void) { static GType emulation_packet_iterator_type_id = 0; if (emulation_packet_iterator_type_id == 0) { - static const GTypeInfo g_define_type_info = { sizeof (EmulationPacketIteratorClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) emulation_packet_iterator_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (EmulationPacketIterator), 0, (GInstanceInitFunc) emulation_packet_iterator_instance_init, NULL }; - emulation_packet_iterator_type_id = g_type_register_static (G_TYPE_OBJECT, "EmulationPacketIterator", &g_define_type_info, 0); + static const GTypeValueTable g_define_type_value_table = { emulation_value_packet_iterator_init, emulation_value_packet_iterator_free_value, emulation_value_packet_iterator_copy_value, emulation_value_packet_iterator_peek_pointer, "p", emulation_value_packet_iterator_collect_value, "p", emulation_value_packet_iterator_lcopy_value }; + static const GTypeInfo g_define_type_info = { sizeof (EmulationPacketIteratorClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) emulation_packet_iterator_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (EmulationPacketIterator), 0, (GInstanceInitFunc) emulation_packet_iterator_instance_init, &g_define_type_value_table }; + static const GTypeFundamentalInfo g_define_type_fundamental_info = { (G_TYPE_FLAG_CLASSED | G_TYPE_FLAG_INSTANTIATABLE | G_TYPE_FLAG_DERIVABLE | G_TYPE_FLAG_DEEP_DERIVABLE) }; + emulation_packet_iterator_type_id = g_type_register_fundamental (g_type_fundamental_next (), "EmulationPacketIterator", &g_define_type_info, &g_define_type_fundamental_info, 0); } return emulation_packet_iterator_type_id; } +gpointer emulation_packet_iterator_ref (gpointer instance) { + EmulationPacketIterator* self; + self = instance; + g_atomic_int_inc (&self->ref_count); + return instance; +} + + +void emulation_packet_iterator_unref (gpointer instance) { + EmulationPacketIterator* self; + self = instance; + if (g_atomic_int_dec_and_test (&self->ref_count)) { + EMULATION_PACKET_ITERATOR_GET_CLASS (self)->finalize (self); + g_type_free_instance ((GTypeInstance *) self); + } +} + + EmulationPacketIterator* emulation_packet_base_iterator (EmulationPacketBase* self) { EmulationPacketIterator* result; g_return_val_if_fail (self != NULL, NULL); @@ -881,10 +1000,15 @@ static guint32* _vala_array_dup1 (guint32* self, int length) { } +static gpointer _g_object_ref0 (gpointer self) { + return self ? g_object_ref (self) : NULL; +} + + static EmulationPacketBase** _vala_array_dup2 (EmulationPacketBase** self, int length) { EmulationPacketBase** result; int i; - result = g_new0 (EmulationPacketBase*, length); + result = g_new0 (EmulationPacketBase*, length + 1); for (i = 0; i < length; i++) { result[i] = _g_object_ref0 (self[i]); } diff --git a/src/cs.vala b/src/cs.vala index b1fb500..cd73037 100644 --- a/src/cs.vala +++ b/src/cs.vala @@ -6,7 +6,7 @@ namespace Emulation } private static inline uint packet_typeid(uint32 header) { return (header >> 30) & 3; } - + public static inline PacketBase make_packet(uint32 header, uint32 *dwords = null) { switch (packet_typeid(header)) { @@ -18,18 +18,18 @@ namespace Emulation assert(false); return new PacketBase(); } - - public class PacketIterator : Object + + public class PacketIterator { - private PacketBase m_packet; + private weak PacketBase m_packet; private uint m_pos; - + public PacketIterator(PacketBase p) { m_packet = p; m_pos = 0; } - + public bool next() { return m_pos < m_packet.length; } public new uint32 get() { return m_packet.dwords[m_pos++]; } } @@ -39,13 +39,13 @@ namespace Emulation public uint32 *dwords; public Type extract_type { get { return typeof(uint32); } } public PacketIterator iterator() { return new PacketIterator(this); } - + public uint32 header; public uint type_id { get { return packet_typeid(header); } } - + public abstract uint length { get; } public new uint32 get(uint index) { return dwords[index]; } - + protected inline uint32 extract_bits(uint high, uint low) { return (header >> low) & ((1 << (high-low+1))-1); @@ -57,11 +57,11 @@ namespace Emulation public uint32 addr { get { return _ADDR << 2; } } public bool one_reg_wr { get { return (bool)_ONE_REG_WR; } } public override uint length { get { return (uint)_COUNT+1; } } - + public uint32 _ADDR { get { return extract_bits(12, 0); } } public uint32 _ONE_REG_WR { get { return extract_bits(15, 15); } } public uint32 _COUNT { get { return extract_bits(29, 16); } } - + public Packet0(uint32 header, uint32 *dwords = null) { this.header = header; @@ -74,10 +74,10 @@ namespace Emulation public uint32 addr1 { get { return _ADDR1 << 2; } } public uint32 addr2 { get { return _ADDR2 << 2; } } public override uint length { get { return 2; } } - + public uint32 _ADDR1 { get { return extract_bits(10, 0); } } public uint32 _ADDR2 { get { return extract_bits(21, 11); } } - + public Packet1(uint32 header, uint32 *dwords = null) { this.header = header; @@ -88,7 +88,7 @@ namespace Emulation public class Packet2 : PacketBase { public override uint length { get { return 0; } } - + public Packet2(uint32 header, uint32 *dwords = null) { this.header = header; @@ -100,10 +100,10 @@ namespace Emulation { public uint32 opcode { get { return _IT_OPCODE; } } public override uint length { get { return (uint)_COUNT+1; } } - + public uint32 _IT_OPCODE { get { return extract_bits(15, 8); } } public uint32 _COUNT { get { return extract_bits(29, 16); } } - + public Packet3(uint32 header, uint32 *dwords = null) { this.header = header; @@ -115,7 +115,7 @@ namespace Emulation { public PacketBase[] packets; public uint32[] dwords; - + private static uint check(uint32 *cs, uint len) { int pkt_count = 0; @@ -125,16 +125,16 @@ namespace Emulation } return pkt_count; } - + public CS(uint32 *cs, uint len) { if (len > 0) { assert(cs != null); } - + dwords = (len > 0) ? new uint32[len] : null; if (len > 0) { Memory.copy(dwords, cs, len*sizeof(uint32)); } - + var pkt_count = check(cs, len); packets = (pkt_count > 0) ? new PacketBase[pkt_count] : null; if (pkt_count > 0) { diff --git a/src/csimport.vala b/src/csimport.vala index 5743db4..f0f597d 100644 --- a/src/csimport.vala +++ b/src/csimport.vala @@ -35,7 +35,7 @@ namespace GUI namealign.left_padding = 12; namealign.bottom_padding = 4; namealign.add(m_name_entry = new Entry()); - + var nameframe = new Frame("<b>Name</b>"); (nameframe.label_widget as Label).use_markup = true; nameframe.shadow = ShadowType.NONE; @@ -43,7 +43,7 @@ namespace GUI this.vbox.pack_start(nameframe, false, true, 0); } - + private inline void create_dwords_frame() { m_dwords_store = new ListStore(2, typeof(uint32), typeof(string)); @@ -58,10 +58,10 @@ namespace GUI sw.shadow_type = ShadowType.ETCHED_IN; sw.hscrollbar_policy = PolicyType.AUTOMATIC; sw.vscrollbar_policy = PolicyType.AUTOMATIC; - + Gdk.Color col = Gdk.Color(); col.red = 0xFFFF; col.green = 0x0000; col.blue = 0x0000; - + m_status_label = new Label(null); var loadbtn = new Button.with_label("Load"); var loadalign = new Alignment(0.5f, 0.5f, 1.0f, 1.0f); @@ -72,11 +72,11 @@ namespace GUI loadbox.pack_end(loadbtn, false, true, 0); loadalign.right_padding = 3; loadalign.add(loadbox); - + var bbox = new HBox(false, 0); bbox.pack_start(m_status_label, true, true, 0); bbox.pack_start(loadalign, false, true, 0); - + var dbox = new VBox(false, 4); dbox.pack_start(sw, true, true, 0); dbox.pack_start(bbox, false, false, 0); @@ -85,28 +85,28 @@ namespace GUI dwordsalign.left_padding = 12; dwordsalign.bottom_padding = 3; dwordsalign.add(dbox); - + var dwordsframe = new Frame("<b>DWORDs</b>"); (dwordsframe.label_widget as Label).use_markup = true; dwordsframe.shadow = ShadowType.NONE; dwordsframe.add(dwordsalign); - + vbox.pack_start(dwordsframe, true, true, 0); set_transient_for(main); } - + construct { create_name_frame(); create_dwords_frame(); - + add_button(STOCK_CLOSE, ResponseType.CLOSE); m_okbtn = add_button(STOCK_OK, ResponseType.APPLY) as Button; m_okbtn.sensitive = false; - + m_validcs = false; m_dwords = new Array<uint32>(false, false, (uint)sizeof(uint32)); m_name_entry.changed += update_okbtn; - + title = "Import CS"; response.connect(on_response); set_default_size(300, 400); @@ -137,7 +137,7 @@ namespace GUI if (fc.run() == ResponseType.ACCEPT) { open_cs(fc.get_filename()); } fc.destroy(); } - + private void open_cs(string filename) { FileStream fs = FileStream.open(filename, "r"); @@ -147,11 +147,11 @@ namespace GUI dlg.destroy(); return; } - + m_dwords_store.clear(); m_dwords.set_size(0); TreeIter iter; - + uint32 dword; uint dword_count = 0; string pktname; @@ -168,11 +168,11 @@ namespace GUI m_dwords_store.set(iter, 0, id, 1, pktname, -1); m_dwords.append_val(dword); } - + m_validcs = (dword_count == 0); update_okbtn(); } - + private void update_okbtn() { if (m_validcs) { diff --git a/src/csview.c b/src/csview.c index 80ad233..512f4df 100644 --- a/src/csview.c +++ b/src/csview.c @@ -242,8 +242,6 @@ struct _GUICSViewPrivate { GtkButton* m_pkgup; GtkButton* m_pkgdown; GUICSListModel* m_pkg_store; - GtkListStore* m_reg_store; - GtkListStore* m_raw_store; guint m_pos; }; @@ -349,7 +347,6 @@ gboolean gui_cs_list_model_cs_iter_get_in_bitfields (GUICSListModelCSIter* self) gboolean gui_cs_list_model_cs_iter_get_in_variants (GUICSListModelCSIter* self); guint32 gui_cs_list_model_cs_iter_get_bitfield (GUICSListModelCSIter* self); static GtkTreePath* gui_cs_list_model_real_get_path (GtkTreeModel* base, GtkTreeIter* iter); -guint32 gui_cs_list_model_get_numeric_value (GUICSListModel* self, GtkTreeIter* iter); const char* emulation_register_info_get_name (EmulationRegisterInfo* self); static char* gui_cs_list_model_translate_addr (GUICSListModel* self, guint32 addr); static const char* gui_cs_list_model_variant_name (GUICSListModel* self, guint32 addr, guint variant); @@ -429,7 +426,7 @@ GType gui_cs_list_model_row_type_get_type (void) { static char** _vala_array_dup3 (char** self, int length) { char** result; int i; - result = g_new0 (char*, length); + result = g_new0 (char*, length + 1); for (i = 0; i < length; i++) { result[i] = g_strdup (self[i]); } @@ -441,7 +438,7 @@ static char** _vala_array_dup4 (char** self, int length) { char** result; int i; char** _tmp5_; - result = g_new0 (char*, length); + result = g_new0 (char*, length + 1); for (i = 0; i < length; i++) { result[i] = g_strdup (self[i]); } @@ -454,7 +451,7 @@ static char** _vala_array_dup5 (char** self, int length) { int i; char** _tmp6_; char** _tmp5_; - result = g_new0 (char*, length); + result = g_new0 (char*, length + 1); for (i = 0; i < length; i++) { result[i] = g_strdup (self[i]); } @@ -468,7 +465,7 @@ static char** _vala_array_dup6 (char** self, int length) { char** _tmp7_; char** _tmp6_; char** _tmp5_; - result = g_new0 (char*, length); + result = g_new0 (char*, length + 1); for (i = 0; i < length; i++) { result[i] = g_strdup (self[i]); } @@ -722,14 +719,6 @@ static GtkTreePath* gui_cs_list_model_real_get_path (GtkTreeModel* base, GtkTree } -guint32 gui_cs_list_model_get_numeric_value (GUICSListModel* self, GtkTreeIter* iter) { - guint32 result; - g_return_val_if_fail (self != NULL, 0U); - result = (guint32) 0; - return result; -} - - static char* gui_cs_list_model_translate_addr (GUICSListModel* self, guint32 addr) { char* result; EmulationRegisterList* regs; @@ -2147,8 +2136,6 @@ static void gui_cs_view_finalize (GObject* obj) { _g_object_unref0 (self->priv->m_pkgup); _g_object_unref0 (self->priv->m_pkgdown); _g_object_unref0 (self->priv->m_pkg_store); - _g_object_unref0 (self->priv->m_reg_store); - _g_object_unref0 (self->priv->m_raw_store); G_OBJECT_CLASS (gui_cs_view_parent_class)->finalize (obj); } diff --git a/src/csview.vala b/src/csview.vala index 0e07a1e..b2c0374 100644 --- a/src/csview.vala +++ b/src/csview.vala @@ -12,7 +12,7 @@ namespace GUI TARGET, COUNT } - + public enum RowType { PACKET = 0, @@ -22,63 +22,63 @@ namespace GUI BITFIELD, HEADER_BITFIELD } - + private static string[] packet_strings = { "packet0", "packet1", "packet2", "packet3" }; - + private static string[] packet0_headers = { "BASE_INDEX", "ONE_REG_WR", "COUNT", "TYPE" }; - + private static string[] packet1_headers = { "REG_INDEX1", "REG_INDEX2", "TYPE" }; - + private static string[] packet2_headers = { "TYPE" }; - + private static string[] packet3_headers = { "IT_OPCODE", "COUNT", "TYPE" }; - + private static string[][] packet_headers = { packet0_headers, packet1_headers, packet2_headers, packet3_headers }; - + private static uint[] packet_headers_length = { 4, 3, 1, 3 }; - + public class CSIter { private TreeIter *m_iter; - + public CSIter(TreeIter? iter) { assert(iter != null); m_iter = (TreeIter *)iter; } - + /* TreeIters contain 3 void* fields, which means we can partition * them into enough space to store our CS stuff. We need: * iter.user_data iter.user_data2 iter.user_data3 * |--------------------------------|--------------------------------|--------------------------------| * |------------|x|-------------|x| -------------|x|---| * packet (14) DWORD (15) Va riant (15) Bitfield (5) - * 14 + 1 + 15 + 1 + 15 + 1 + 5 = 53 + * 14 + 1 + 15 + 1 + 15 + 1 + 5 = 52 * Meaning we need 50 bits (and this will never run on something below 32bit addrs) * X denotes a boolean to indicate whether or not a level is reached * @@ -92,7 +92,7 @@ namespace GUI * Bitfields [47;51]: * Each DWORD has a max of 32 bitfields, and a minimum of 1, so we need 5 bits. */ - + /* we really never want to handle values larger than 32 bit */ private inline uint32 get_iter_bits(uint low, uint high) { @@ -104,7 +104,7 @@ namespace GUI //stdout.printf("get_iter_bits(%u, %u) = %u (%016llX)\n", low, high, (uint32)((num >> low) & (((uint64)1 << (high-low+1))-1)), num); return (uint32)((num >> low) & (((uint64)1 << (high-low+1))-1)); } - + private inline void set_iter_bits(uint low, uint high, uint32 val) { uint64 num = (uint64)(*((uint32*)(&m_iter->user_data))) | @@ -113,7 +113,7 @@ namespace GUI uint64 mask = (((uint64)1 << (high-low+1))-1) << low; num &= ~mask; num |= ((uint64)val << low) & mask; - + uint32 num32[2]; num32[0] = (uint32)num; num32[1] = (uint32)(num >> 32); @@ -121,7 +121,7 @@ namespace GUI m_iter->user_data2 = *((void**)(&num32[1])); //stdout.printf("setting [%u;%u] = %u | got %u @ %016llX\n", low, high, val, get_iter_bits(low, high), mask); } - + public uint32 packet { get { return get_iter_bits(0, 13); } set { set_iter_bits(0, 13, value); } @@ -138,7 +138,7 @@ namespace GUI get { return get_iter_bits(47, 51); } set { set_iter_bits(47, 51, value); } } - + public bool in_dwords { get { return (get_iter_bits(14, 14) == 1) ? true : false; } set { set_iter_bits(14, 14, value ? 1 : 0); } @@ -154,7 +154,7 @@ namespace GUI public bool is_header { get { return dword == 0 && in_dwords; } } - + public RowType row_type { get { if (in_bitfields) { @@ -164,28 +164,28 @@ namespace GUI } else if (in_dwords) { return is_header ? RowType.HEADER : RowType.DWORD; } - + return RowType.PACKET; } } - + public void reset() { set_iter_bits(0, 31, 0); set_iter_bits(32, 51, 0); } - + public void copy(CSIter it) { set_iter_bits(0, 31, it.get_iter_bits(0, 31)); set_iter_bits(32, 51, it.get_iter_bits(32, 51)); } } - + private CS m_cs; private Spec m_spec; private int m_stamp; - + public CSListModel(CS cs, Spec spec) { m_cs = cs; @@ -220,25 +220,25 @@ namespace GUI assert(variant < regs.length); return (regs[variant].info.length == 0) ? 1 : regs[variant].info.length; } - + public bool get_iter(out TreeIter iter, TreePath path) { var depth = path.get_depth(); assert(depth <= 4 && depth >= 1); - + CSIter it = new CSIter(iter); it.reset(); - + int *indices = path.get_indices(); if (indices[0] >= m_cs.packets.length || indices[0] < 0) { return false; } it.packet = indices[0]; - + if (depth >= 2) { if (indices[1] > m_cs.packets[it.packet].length || indices[1] < 0) { return false; } it.dword = indices[1]; it.in_dwords = true; } - + if (depth >= 3) { if (indices[2] < 0) { return false; } if (it.dword == 0) { @@ -255,24 +255,24 @@ namespace GUI Packet0 p0 = m_cs.packets[it.packet] as Packet0; addr = p0.addr; break; - + case 1: Packet1 p1 = m_cs.packets[it.packet] as Packet1; addr = (it.dword == 1) ? p1.addr1 : p1.addr2; // 0 = header break; - + case 2: return false; - + case 3: /* TODO */ return false; } - + if (indices[2] < 0) { return false; } if (indices[2] >= get_variant_count(addr)) { return false; } it.variant = indices[2]; it.in_variants = true; - + if (depth == 4) { if (indices[3] < 0) { return false; } if (indices[3] >= get_bitfield_count(addr, it.variant)) { return false; } @@ -285,7 +285,7 @@ namespace GUI iter.stamp = m_stamp; return true; } - + public TreePath get_path(TreeIter iter) { var path = new TreePath(); @@ -301,18 +301,13 @@ namespace GUI return path; } - public uint32 get_numeric_value(TreeIter iter) - { - return 0; - } - private string translate_addr(uint32 addr) { var regs = m_spec.translate_addr((uint)addr); if (regs == null) { return addr.to_string("0x%04X"); } return (regs.length > 1) ? "Multiple" : regs[0].info.name; } - + private weak string variant_name(uint32 addr, uint variant) { var regs = m_spec.translate_addr((uint)addr); @@ -320,7 +315,7 @@ namespace GUI assert(variant < regs.length); return regs[variant].info.name; } - + private weak string bitfield_name(uint32 addr, uint variant, uint bitfield) { var regs = m_spec.translate_addr((uint)addr); @@ -332,7 +327,7 @@ namespace GUI } return "DATA_REGISTER"; } - + private uint32 bitfield_value(uint32 addr, uint variant, uint bitfield, uint32 dword) { var regs = m_spec.translate_addr((uint)addr); @@ -353,7 +348,7 @@ namespace GUI CSIter it = new CSIter(iter); PacketBase p = m_cs.packets[it.packet]; val.init(typeof(string)); - + switch (it.row_type) { case RowType.PACKET: switch (column) { @@ -369,7 +364,7 @@ namespace GUI break; } break; - + case RowType.DWORD: switch (column) { case Columns.NAME: val.set_string((it.dword-1).to_string("DWORD%u")); break; @@ -392,7 +387,7 @@ namespace GUI case Columns.TARGET: val.set_static_string(""); break; } break; - + case RowType.VARIANT: switch (column) { case Columns.NAME: val.set_static_string(variant_name(dword_addr(it.packet, it.dword), it.variant)); break; @@ -400,7 +395,7 @@ namespace GUI case Columns.TARGET: val.set_static_string(""); break; } break; - + case RowType.BITFIELD: switch (column) { case Columns.NAME: val.set_static_string(bitfield_name(dword_addr(it.packet, it.dword), it.variant, it.bitfield)); break; @@ -408,7 +403,7 @@ namespace GUI case Columns.TARGET: val.set_static_string(""); break; } break; - + case RowType.HEADER_BITFIELD: switch (column) { case Columns.NAME: val.set_static_string(packet_headers[p.type_id][it.bitfield]); break; @@ -451,7 +446,7 @@ namespace GUI break; } } - + private uint32 dword_addr(uint p, uint d) { assert(p < m_cs.packets.length); @@ -465,12 +460,12 @@ namespace GUI } return 0; } - + public bool iter_next(ref TreeIter iter) { if (iter.stamp != m_stamp) { return false; } iter.stamp = 0; - + CSIter it = new CSIter(iter); var p = it.packet; switch (it.row_type) { @@ -479,14 +474,14 @@ namespace GUI if (p >= m_cs.packets.length) { return false; } it.packet = p; break; - + case RowType.HEADER: case RowType.DWORD: var d = it.dword+1; if (d >= m_cs.packets[p].length+1) { return false; } it.dword = d; break; - + case RowType.VARIANT: var v = it.variant+1; if (v >= get_variant_count(dword_addr(p, it.dword))) { return false; } @@ -498,23 +493,23 @@ namespace GUI if (b >= get_bitfield_count(dword_addr(p, it.dword), it.variant)) { return false; } it.bitfield = b; break; - + case RowType.HEADER_BITFIELD: var b = it.bitfield+1; if (b >= packet_headers_length[m_cs.packets[p].type_id]) { return false; } it.bitfield = b; break; } - + iter.stamp = m_stamp; return true; } - + public bool iter_children(out TreeIter iter, TreeIter? parent) { CSIter it = new CSIter(iter); iter.stamp = 0; - + if (parent == null) { if (m_cs.packets.length == 0) { return false; @@ -524,7 +519,7 @@ namespace GUI return true; } if (parent.stamp != m_stamp) { return false; } - + CSIter pa = new CSIter(parent); it.copy(pa); switch (pa.row_type) { @@ -532,13 +527,13 @@ namespace GUI it.dword = 0; it.in_dwords = true; break; - + case RowType.VARIANT: case RowType.HEADER: it.bitfield = 0; it.in_bitfields = true; break; - + case RowType.DWORD: if (get_variant_count(dword_addr(pa.packet, pa.dword)) == 0) { return false; } it.variant = 0; @@ -550,7 +545,7 @@ namespace GUI default: return false; } - + iter.stamp = m_stamp; return true; } @@ -567,16 +562,16 @@ namespace GUI case RowType.BITFIELD: return false; case RowType.HEADER_BITFIELD: return false; } - + return false; } - + public int iter_n_children(TreeIter? iter) { if (iter == null) { return m_cs.packets.length; } - + if (iter.stamp != m_stamp) { return 0; } CSIter it = new CSIter(iter); switch (it.row_type) { @@ -587,7 +582,7 @@ namespace GUI case RowType.BITFIELD: return 0; case RowType.HEADER_BITFIELD: return 0; } - + return 0; } @@ -595,7 +590,7 @@ namespace GUI { CSIter it = new CSIter(iter); iter.stamp = 0; - + if (parent == null) { if (n >= m_cs.packets.length || n < 0) { return false; @@ -607,7 +602,7 @@ namespace GUI } if (parent.stamp != m_stamp) { return false; } if (n < 0) { return false; } - + CSIter pa = new CSIter(parent); it.copy(pa); switch (pa.row_type) { @@ -616,19 +611,19 @@ namespace GUI it.in_dwords = true; it.dword = n; break; - + case RowType.HEADER: if (n >= packet_headers_length[m_cs.packets[pa.packet].type_id]) { return false; } it.in_bitfields = true; it.bitfield = n; break; - + case RowType.DWORD: if (n >= get_variant_count(dword_addr(pa.packet, pa.dword))) { return false; } it.in_variants = true; it.variant = n; break; - + case RowType.VARIANT: if (n >= get_bitfield_count(dword_addr(pa.packet, pa.dword), pa.variant)) { return false; } it.in_bitfields = true; @@ -640,7 +635,7 @@ namespace GUI default: return false; } - + iter.stamp = m_stamp; return true; } @@ -649,7 +644,7 @@ namespace GUI { iter.stamp = 0; if (child.stamp != m_stamp) { return false; } - + CSIter it = new CSIter(iter); CSIter ch = new CSIter(child); it.copy(ch); @@ -666,26 +661,26 @@ namespace GUI iter.stamp = m_stamp; return true; } - + public void ref_node(TreeIter iter) { return; } public void unref_node(TreeIter iter) { return; } } - + public class CSView : Window { -// private CS m_cs; + //private CS m_cs; private Button m_pkgup; private Button m_pkgdown; private CSListModel m_pkg_store; - private ListStore m_reg_store; - private ListStore m_raw_store; + //private ListStore m_reg_store; + //private ListStore m_raw_store; private uint m_pos; - + public CSView(CS cs, Spec spec) { -// m_cs = cs; + //m_cs = cs; m_pos = 0; - + var cs_list = new TreeView(); cs_list.insert_column_with_data_func(-1, "", new Gtk.CellRendererPixbuf(), current_dword_renderer); var ec_name = new Gtk.TreeViewColumn.with_attributes("Name", new Gtk.CellRendererText(), "text", CSListModel.Columns.NAME, null); @@ -699,52 +694,52 @@ namespace GUI ec_target.resizable = true; cs_list.set_model(m_pkg_store = new CSListModel(cs, spec)); cs_list.set_expander_column(ec_name); - + var cs_sw = new ScrolledWindow(null, null); cs_sw.add(cs_list); cs_sw.shadow_type = ShadowType.ETCHED_IN; cs_sw.hscrollbar_policy = PolicyType.AUTOMATIC; cs_sw.vscrollbar_policy = PolicyType.AUTOMATIC; - + var vbl = new VBox(false, 4); vbl.pack_start(m_pkgup = new Button.from_stock("gtk-go-up"), false, true, 0); vbl.pack_start(cs_sw, true, true, 0); vbl.pack_start(m_pkgdown = new Button.from_stock("gtk-go-down"), false, true, 0); - + /*var state_reg_list = new TreeView(); state_reg_list.set_model(m_reg_store = new ListStore(2, typeof(string), typeof(uint32))); - + var sreg_sw = new ScrolledWindow(null, null); sreg_sw.add(state_reg_list); sreg_sw.shadow_type = ShadowType.ETCHED_IN; sreg_sw.hscrollbar_policy = PolicyType.AUTOMATIC; sreg_sw.vscrollbar_policy = PolicyType.AUTOMATIC; - + var state_raw_list = new TreeView(); state_raw_list.set_model(m_raw_store = new ListStore(2, typeof(string), typeof(uint32))); - + var sraw_sw = new ScrolledWindow(null, null); sraw_sw.add(state_raw_list); sraw_sw.shadow_type = ShadowType.ETCHED_IN; sraw_sw.hscrollbar_policy = PolicyType.AUTOMATIC; sraw_sw.vscrollbar_policy = PolicyType.AUTOMATIC; - + var nb = new Notebook(); nb.append_page(sreg_sw, new Label("Registers")); nb.append_page(sraw_sw, new Label("Raw")); nb.scrollable = true; - + var paned = new HPaned(); paned.add1(vbl); paned.add2(nb); paned.position = 400;*/ - + //this.add(paned); this.add(vbl); this.border_width = 10; this.set_default_size(640, 480); } - + private void current_dword_renderer(Gtk.TreeViewColumn tree_column, Gtk.CellRenderer cell, Gtk.TreeModel model, Gtk.TreeIter iter) { /*if (m_pos == (model as CSListModel).get_packet_num(iter)) { @@ -7,6 +7,8 @@ #include <gtk/gtk.h> #include <stdlib.h> #include <string.h> +#include <gdk/gdk.h> +#include <stdio.h> #include <gobject/gvaluecollector.h> @@ -100,6 +102,18 @@ typedef struct _EmulationSpecClass EmulationSpecClass; typedef struct _GUICSView GUICSView; typedef struct _GUICSViewClass GUICSViewClass; +#define TYPE_SPEC_LOAD_DIALOG (spec_load_dialog_get_type ()) +#define SPEC_LOAD_DIALOG(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), TYPE_SPEC_LOAD_DIALOG, SpecLoadDialog)) +#define SPEC_LOAD_DIALOG_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), TYPE_SPEC_LOAD_DIALOG, SpecLoadDialogClass)) +#define IS_SPEC_LOAD_DIALOG(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TYPE_SPEC_LOAD_DIALOG)) +#define IS_SPEC_LOAD_DIALOG_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), TYPE_SPEC_LOAD_DIALOG)) +#define SPEC_LOAD_DIALOG_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), TYPE_SPEC_LOAD_DIALOG, SpecLoadDialogClass)) + +typedef struct _SpecLoadDialog SpecLoadDialog; +typedef struct _SpecLoadDialogClass SpecLoadDialogClass; +#define _g_error_free0(var) ((var == NULL) ? NULL : (var = (g_error_free (var), NULL))) +typedef struct _SpecLoadDialogPrivate SpecLoadDialogPrivate; + struct _GUICActions { GObject parent_instance; GUICActionsPrivate * priv; @@ -168,6 +182,21 @@ struct _EmulationCSClass { GObjectClass parent_class; }; +struct _SpecLoadDialog { + GtkWindow parent_instance; + SpecLoadDialogPrivate * priv; +}; + +struct _SpecLoadDialogClass { + GtkWindowClass parent_class; +}; + +struct _SpecLoadDialogPrivate { + GtkLabel* loading; + GtkProgressBar* progress; + gboolean done; +}; + static gpointer gui_cactions_parent_class = NULL; static gpointer gui_cmenus_parent_class = NULL; @@ -180,6 +209,7 @@ GUICMain* gui_main = NULL; extern EmulationSpec* r300_registers; EmulationSpec* r300_registers = NULL; EmulationSpec* r500_registers = NULL; +static gpointer spec_load_dialog_parent_class = NULL; GType gui_cactions_get_type (void); enum { @@ -191,8 +221,8 @@ GType emulation_chip_get_type (void); GUICSImport* gui_cs_import_new (void); GUICSImport* gui_cs_import_construct (GType object_type); GType gui_cs_import_get_type (void); -static void _lambda10_ (GtkAction* source, GUICActions* self); -static void __lambda10__gtk_action_activate (GtkAction* _sender, gpointer self); +static void _lambda8_ (GtkAction* source, GUICActions* self); +static void __lambda8__gtk_action_activate (GtkAction* _sender, gpointer self); static GObject * gui_cactions_constructor (GType type, guint n_construct_properties, GObjectConstructParam * construct_properties); static void gui_cactions_finalize (GObject* obj); gpointer gui_cmenus_ref (gpointer instance); @@ -227,10 +257,23 @@ static void _gui_cmain_open_csview_gtk_tree_view_row_activated (GtkTreeView* _se static void _gtk_main_quit_gtk_object_destroy (GtkObject* _sender, gpointer self); static GObject * gui_cmain_constructor (GType type, guint n_construct_properties, GObjectConstructParam * construct_properties); static void gui_cmain_finalize (GObject* obj); +SpecLoadDialog* spec_load_dialog_new (GtkWindow* parent); +SpecLoadDialog* spec_load_dialog_construct (GType object_type, GtkWindow* parent); +GType spec_load_dialog_get_type (void); +void* spec_load_dialog_run (SpecLoadDialog* self); +static void* _spec_load_dialog_run_gthread_func (gpointer self); void gui_init (char*** args, int* args_length1); -EmulationSpec* emulation_spec_new (void); -EmulationSpec* emulation_spec_construct (GType object_type); -gboolean emulation_spec_load_xml (EmulationSpec* self, const char* filename, const char* variant); +#define SPEC_LOAD_DIALOG_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), TYPE_SPEC_LOAD_DIALOG, SpecLoadDialogPrivate)) +enum { + SPEC_LOAD_DIALOG_DUMMY_PROPERTY +}; +static void* spec_load_dialog_pulse_thread (SpecLoadDialog* self); +static void* _spec_load_dialog_pulse_thread_gthread_func (gpointer self); +static void* spec_load_dialog_specload_thread (SpecLoadDialog* self); +static void* _spec_load_dialog_specload_thread_gthread_func (gpointer self); +EmulationSpec* emulation_spec_new (const char* filename, const char* variant); +EmulationSpec* emulation_spec_construct (GType object_type, const char* filename, const char* variant); +static void spec_load_dialog_finalize (GObject* obj); gint _main (char** args, int args_length1); @@ -247,7 +290,7 @@ GUICActions* gui_cactions_new (void) { } -static void _lambda10_ (GtkAction* source, GUICActions* self) { +static void _lambda8_ (GtkAction* source, GUICActions* self) { GUICSImport* d; g_return_if_fail (source != NULL); d = g_object_ref_sink (gui_cs_import_new ()); @@ -256,8 +299,8 @@ static void _lambda10_ (GtkAction* source, GUICActions* self) { } -static void __lambda10__gtk_action_activate (GtkAction* _sender, gpointer self) { - _lambda10_ (_sender, self); +static void __lambda8__gtk_action_activate (GtkAction* _sender, gpointer self) { + _lambda8_ (_sender, self); } @@ -291,7 +334,7 @@ static GObject * gui_cactions_constructor (GType type, guint n_construct_propert self->EmulateR500 = (_tmp9_ = gtk_radio_action_new ("EmulateR500", "R500", "Emulate the R500 register space", NULL, (gint) EMULATION_CHIP_R500), _g_object_unref0 (self->EmulateR500), _tmp9_); gtk_radio_action_set_group (self->EmulateR500, gtk_radio_action_get_group (self->EmulateR300)); gtk_radio_action_set_current_value (self->EmulateR300, (gint) EMULATION_CHIP_R300); - g_signal_connect_object (self->ImportCS, "activate", (GCallback) __lambda10__gtk_action_activate, self, 0); + g_signal_connect_object (self->ImportCS, "activate", (GCallback) __lambda8__gtk_action_activate, self, 0); } return obj; } @@ -670,7 +713,7 @@ static GObject * gui_cmain_constructor (GType type, guint n_construct_properties _g_object_unref0 (cslist); _g_object_unref0 (sw); _g_object_unref0 (mainbox); - g_critical ("file %s: line %d: uncaught error: %s", __FILE__, __LINE__, _inner_error_->message); + g_critical ("file %s: line %d: uncaught error: %s (%s, %d)", __FILE__, __LINE__, _inner_error_->message, g_quark_to_string (_inner_error_->domain), _inner_error_->code); g_clear_error (&_inner_error_); } gtk_widget_show_all ((GtkWidget*) self); @@ -717,24 +760,246 @@ GType gui_cmain_get_type (void) { } +static void* _spec_load_dialog_run_gthread_func (gpointer self) { + return spec_load_dialog_run (self); +} + + void gui_init (char*** args, int* args_length1) { + GError * _inner_error_; GUICActions* _tmp0_; GUICMain* _tmp1_; + _inner_error_ = NULL; gtk_init (args_length1, args); gui_actions = (_tmp0_ = gui_cactions_new (), _g_object_unref0 (gui_actions), _tmp0_); gui_main = (_tmp1_ = g_object_ref_sink (gui_cmain_new ()), _g_object_unref0 (gui_main), _tmp1_); + { + SpecLoadDialog* specload; + gdk_threads_init (); + specload = g_object_ref_sink (spec_load_dialog_new ((GtkWindow*) gui_main)); + { + g_thread_create (_spec_load_dialog_run_gthread_func, specload, FALSE, &_inner_error_); + if (_inner_error_ != NULL) { + if (_inner_error_->domain == G_THREAD_ERROR) { + goto __catch0_g_thread_error; + } + _g_object_unref0 (specload); + g_critical ("file %s: line %d: unexpected error: %s (%s, %d)", __FILE__, __LINE__, _inner_error_->message, g_quark_to_string (_inner_error_->domain), _inner_error_->code); + g_clear_error (&_inner_error_); + return; + } + } + goto __finally0; + __catch0_g_thread_error: + { + GError * e; + e = _inner_error_; + _inner_error_ = NULL; + { + fprintf (stderr, "Unable to start loading thread.\n"); + g_assert (FALSE); + _g_error_free0 (e); + } + } + __finally0: + if (_inner_error_ != NULL) { + _g_object_unref0 (specload); + g_critical ("file %s: line %d: uncaught error: %s (%s, %d)", __FILE__, __LINE__, _inner_error_->message, g_quark_to_string (_inner_error_->domain), _inner_error_->code); + g_clear_error (&_inner_error_); + return; + } + _g_object_unref0 (specload); + } gtk_main (); } -gint _main (char** args, int args_length1) { - gint result; +SpecLoadDialog* spec_load_dialog_construct (GType object_type, GtkWindow* parent) { + SpecLoadDialog * self; + GtkLabel* _tmp0_; + GtkProgressBar* _tmp1_; + GtkVBox* box; + self = g_object_newv (object_type, 0, NULL); + if (parent != NULL) { + gtk_window_set_transient_for ((GtkWindow*) self, parent); + gtk_window_set_modal ((GtkWindow*) self, TRUE); + gtk_window_set_destroy_with_parent ((GtkWindow*) self, TRUE); + } + gtk_window_set_deletable ((GtkWindow*) self, FALSE); + self->priv->loading = (_tmp0_ = g_object_ref_sink ((GtkLabel*) gtk_label_new ("Loading...")), _g_object_unref0 (self->priv->loading), _tmp0_); + self->priv->progress = (_tmp1_ = g_object_ref_sink ((GtkProgressBar*) gtk_progress_bar_new ()), _g_object_unref0 (self->priv->progress), _tmp1_); + self->priv->progress->pulse_fraction = 0.1; + box = g_object_ref_sink ((GtkVBox*) gtk_vbox_new (FALSE, 5)); + gtk_box_pack_start ((GtkBox*) box, (GtkWidget*) self->priv->loading, FALSE, TRUE, (guint) 0); + gtk_box_pack_start ((GtkBox*) box, (GtkWidget*) self->priv->progress, FALSE, TRUE, (guint) 0); + gtk_container_set_border_width ((GtkContainer*) self, (guint) 10); + gtk_window_set_default_size ((GtkWindow*) self, 300, 10); + gtk_container_add ((GtkContainer*) self, (GtkWidget*) box); + _g_object_unref0 (box); + return self; +} + + +SpecLoadDialog* spec_load_dialog_new (GtkWindow* parent) { + return spec_load_dialog_construct (TYPE_SPEC_LOAD_DIALOG, parent); +} + + +static void* _spec_load_dialog_pulse_thread_gthread_func (gpointer self) { + return spec_load_dialog_pulse_thread (self); +} + + +static void* _spec_load_dialog_specload_thread_gthread_func (gpointer self) { + return spec_load_dialog_specload_thread (self); +} + + +void* spec_load_dialog_run (SpecLoadDialog* self) { + void* result; + GError * _inner_error_; + GThread* load; + GThread* pulse; + void* _result_; + g_return_val_if_fail (self != NULL, NULL); + _inner_error_ = NULL; + gdk_threads_enter (); + gtk_widget_show_all ((GtkWidget*) self); + gdk_threads_leave (); + self->priv->done = FALSE; + load = NULL; + pulse = NULL; + { + GThread* _tmp0_; + GThread* _tmp1_; + _tmp0_ = g_thread_create (_spec_load_dialog_pulse_thread_gthread_func, self, TRUE, &_inner_error_); + if (_inner_error_ != NULL) { + if (_inner_error_->domain == G_THREAD_ERROR) { + goto __catch1_g_thread_error; + } + g_critical ("file %s: line %d: unexpected error: %s (%s, %d)", __FILE__, __LINE__, _inner_error_->message, g_quark_to_string (_inner_error_->domain), _inner_error_->code); + g_clear_error (&_inner_error_); + return NULL; + } + pulse = _tmp0_; + _tmp1_ = g_thread_create (_spec_load_dialog_specload_thread_gthread_func, self, TRUE, &_inner_error_); + if (_inner_error_ != NULL) { + if (_inner_error_->domain == G_THREAD_ERROR) { + goto __catch1_g_thread_error; + } + g_critical ("file %s: line %d: unexpected error: %s (%s, %d)", __FILE__, __LINE__, _inner_error_->message, g_quark_to_string (_inner_error_->domain), _inner_error_->code); + g_clear_error (&_inner_error_); + return NULL; + } + load = _tmp1_; + } + goto __finally1; + __catch1_g_thread_error: + { + GError * e; + e = _inner_error_; + _inner_error_ = NULL; + { + fprintf (stderr, "Unable to start loading thread.\n"); + g_assert (FALSE); + result = NULL; + _g_error_free0 (e); + return result; + } + } + __finally1: + if (_inner_error_ != NULL) { + g_critical ("file %s: line %d: uncaught error: %s (%s, %d)", __FILE__, __LINE__, _inner_error_->message, g_quark_to_string (_inner_error_->domain), _inner_error_->code); + g_clear_error (&_inner_error_); + return NULL; + } + _result_ = g_thread_join (load); + self->priv->done = TRUE; + g_thread_join (pulse); + gdk_threads_enter (); + gtk_widget_hide_all ((GtkWidget*) self); + gdk_threads_leave (); + result = _result_; + return result; +} + + +static void* spec_load_dialog_pulse_thread (SpecLoadDialog* self) { + void* result; + g_return_val_if_fail (self != NULL, NULL); + while (TRUE) { + if (!(!self->priv->done)) { + break; + } + gdk_threads_enter (); + gtk_progress_bar_pulse (self->priv->progress); + gdk_threads_leave (); + g_usleep ((gulong) 50000); + } + result = NULL; + return result; +} + + +static void* spec_load_dialog_specload_thread (SpecLoadDialog* self) { + void* result; EmulationSpec* _tmp0_; EmulationSpec* _tmp1_; - r300_registers = (_tmp0_ = emulation_spec_new (), _g_object_unref0 (r300_registers), _tmp0_); - r500_registers = (_tmp1_ = emulation_spec_new (), _g_object_unref0 (r500_registers), _tmp1_); - emulation_spec_load_xml (r300_registers, "/usr/share/rsim/r300reg.xml", "r300"); - emulation_spec_load_xml (r500_registers, "/usr/share/rsim/r300reg.xml", "r500"); + g_return_val_if_fail (self != NULL, NULL); + gdk_threads_enter (); + gtk_label_set_label (self->priv->loading, "Loading r300 registers..."); + gdk_threads_leave (); + r300_registers = (_tmp0_ = emulation_spec_new ("/usr/share/rsim/r300reg.xml", "r300"), _g_object_unref0 (r300_registers), _tmp0_); + gdk_threads_enter (); + gtk_label_set_label (self->priv->loading, "Loading r500 registers..."); + gdk_threads_leave (); + r500_registers = (_tmp1_ = emulation_spec_new ("/usr/share/rsim/r300reg.xml", "r500"), _g_object_unref0 (r500_registers), _tmp1_); + gdk_threads_enter (); + gtk_label_set_label (self->priv->loading, "Done"); + gdk_threads_leave (); + result = (void*) 123; + return result; +} + + +static void spec_load_dialog_class_init (SpecLoadDialogClass * klass) { + spec_load_dialog_parent_class = g_type_class_peek_parent (klass); + g_type_class_add_private (klass, sizeof (SpecLoadDialogPrivate)); + G_OBJECT_CLASS (klass)->finalize = spec_load_dialog_finalize; +} + + +static void spec_load_dialog_instance_init (SpecLoadDialog * self) { + self->priv = SPEC_LOAD_DIALOG_GET_PRIVATE (self); +} + + +static void spec_load_dialog_finalize (GObject* obj) { + SpecLoadDialog * self; + self = SPEC_LOAD_DIALOG (obj); + _g_object_unref0 (self->priv->loading); + _g_object_unref0 (self->priv->progress); + G_OBJECT_CLASS (spec_load_dialog_parent_class)->finalize (obj); +} + + +GType spec_load_dialog_get_type (void) { + static GType spec_load_dialog_type_id = 0; + if (spec_load_dialog_type_id == 0) { + static const GTypeInfo g_define_type_info = { sizeof (SpecLoadDialogClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) spec_load_dialog_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (SpecLoadDialog), 0, (GInstanceInitFunc) spec_load_dialog_instance_init, NULL }; + spec_load_dialog_type_id = g_type_register_static (GTK_TYPE_WINDOW, "SpecLoadDialog", &g_define_type_info, 0); + } + return spec_load_dialog_type_id; +} + + +gint _main (char** args, int args_length1) { + gint result; + if (!g_thread_supported ()) { + fprintf (stderr, "Cannot run without threads.\n"); + result = 1; + return result; + } gui_init (&args, &args_length1); g_object_unref ((GObject*) r300_registers); g_object_unref ((GObject*) r500_registers); @@ -746,6 +1011,7 @@ gint _main (char** args, int args_length1) { int main (int argc, char ** argv) { + g_thread_init (NULL); g_type_init (); return _main (argv, argc); } diff --git a/src/main.vala b/src/main.vala index b9d707c..399893c 100644 --- a/src/main.vala +++ b/src/main.vala @@ -13,10 +13,10 @@ namespace GUI public Action ImportCS; public Action ExportCS; public Action Quit; - + public RadioAction EmulateR300; public RadioAction EmulateR500; - + construct { New = new Action("New", null, null, "gtk-new"); Open = new Action("Open", null, null, "gtk-open"); @@ -26,12 +26,12 @@ namespace GUI ImportCS = new Action("ImportCS", "Import", "Import a command stream to the list", "gtk-add"); ExportCS = new Action("ExportCS", "Export", "Export a CS to a file", "gtk-convert"); Quit = new Action("Quit", null, null, "gtk-quit"); - + EmulateR300 = new RadioAction("EmulateR300", "R300", "Emulate the R300 register space", null, Chip.R300); EmulateR500 = new RadioAction("EmulateR500", "R500", "Emulate the R500 register space", null, Chip.R500); EmulateR500.set_group(EmulateR300.get_group()); EmulateR300.set_current_value(Chip.R300); - + ImportCS.activate.connect((source) => { var d = new CSImport(); d.run(); }); } } @@ -49,10 +49,10 @@ namespace GUI public MenuBar menubar; public Toolbar toolbar; public ListStore cs_store; - + construct { menu = new CMenus(); - + toolbar = new Toolbar(); add_toolitem(actions.New); add_toolitem(actions.Open); @@ -61,7 +61,7 @@ namespace GUI add_toolitem(actions.RemoveCS); add_toolitem(actions.ImportCS); add_toolitem(actions.ExportCS); - + menu.file = new Menu(); menu.file.append(actions.New.create_menu_item() as MenuItem); menu.file.append(actions.Open.create_menu_item() as MenuItem); @@ -71,59 +71,59 @@ namespace GUI menu.file.append(actions.Quit.create_menu_item() as MenuItem); var menu_file_item = new MenuItem.with_label("File"); menu_file_item.submenu = menu.file; - + menu.edit = new Menu(); menu.edit.append(actions.RemoveCS.create_menu_item() as MenuItem); menu.edit.append(actions.ImportCS.create_menu_item() as MenuItem); menu.edit.append(actions.ExportCS.create_menu_item() as MenuItem); var menu_edit_item = new MenuItem.with_label("Edit"); menu_edit_item.submenu = menu.edit; - + menu.emulation = new Menu(); menu.emulation.append(actions.EmulateR300.create_menu_item() as MenuItem); menu.emulation.append(actions.EmulateR500.create_menu_item() as MenuItem); var menu_emulation_item = new MenuItem.with_label("Emulation"); menu_emulation_item.submenu = menu.emulation; - + menubar = new MenuBar(); menubar.append(menu_file_item); menubar.append(menu_edit_item); menubar.append(menu_emulation_item); - + cs_store = new ListStore(2, typeof(string), typeof(CS)); var cslist = new TreeView(); cslist.insert_column_with_data_func(-1, "DWORDs", new CellRendererText(), dwords_cellrenderer); cslist.insert_column_with_attributes(-1, "Name", new CellRendererText(), "text", 0, null); cslist.set_model(cs_store); cslist.row_activated.connect(open_csview); - + var sw = new ScrolledWindow(null, null); sw.hscrollbar_policy = PolicyType.AUTOMATIC; sw.vscrollbar_policy = PolicyType.AUTOMATIC; sw.add(cslist); - + var mainbox = new VBox(false, 0); mainbox.pack_start(menubar, false, true, 0); mainbox.pack_start(toolbar, false, true, 0); mainbox.pack_start(sw, true, true, 0); - + set_size_request(400, 200); title = "Radeon Simulator"; add(mainbox); destroy.connect(main_quit); /* XXX This shouldn't be hardcoded */ set_icon_from_file("/usr/share/pixmaps/rsim.png"); - + show_all(); } - + private void add_toolitem(Action action) { ToolItem titem = action.create_tool_item() as ToolItem; titem.set_homogeneous(false); toolbar.insert(titem, -1); } - + private void dwords_cellrenderer(TreeViewColumn tree_column, CellRenderer cell, TreeModel model, TreeIter iter) { CS cs; @@ -131,27 +131,40 @@ namespace GUI assert(cs != null); (cell as CellRendererText).text = cs.dwords.length.to_string(); } - + private void open_csview(TreePath path, TreeViewColumn column) { TreeIter iter; CS cs; cs_store.get_iter(out iter, path); cs_store.get(iter, 1, out cs, -1); - + var csv = new CSView(cs, r500_registers); csv.show_all(); } } - + public static CActions actions; public static CMain main; - static void init(ref unowned string[] args) + static void init(ref weak string[] args) { Gtk.init(ref args); actions = new CActions(); main = new CMain(); + + { + Gdk.threads_init(); + + var specload = new SpecLoadDialog(main); + try { + Thread.create(specload.run, false); + } catch (ThreadError e) { + stderr.printf("Unable to start loading thread.\n"); + assert(false); + } + } + Gtk.main(); } } @@ -159,21 +172,113 @@ namespace GUI public Spec r300_registers; public Spec r500_registers; +class SpecLoadDialog : Window +{ + private Label loading; + private ProgressBar progress; + private bool done; + + public SpecLoadDialog(Window? parent = null) + { + if (parent != null) { + set_transient_for(parent); + modal = true; + destroy_with_parent = true; + } + deletable = false; + + loading = new Label("Loading..."); + + progress = new ProgressBar(); + progress.pulse_fraction = 0.1; + + var box = new VBox(false, 5); + box.pack_start(loading, false, true, 0); + box.pack_start(progress, false, true, 0); + + border_width = 10; + set_default_size(300, 10); + + add(box); + } + + public void *run() + { + Gdk.threads_enter(); + show_all(); + Gdk.threads_leave(); + + done = false; + weak Thread load; + weak Thread pulse; + + try { + pulse = Thread.create(pulse_thread, true); + load = Thread.create(specload_thread, true); + } catch (ThreadError e) { + stderr.printf("Unable to start loading thread.\n"); + assert(false); + return null; /* appease vala */ + } + + void *result = load.join(); + done = true; + pulse.join(); + + Gdk.threads_enter(); + hide_all(); + Gdk.threads_leave(); + + return result; + } + + private void *pulse_thread() + { + while (!done) { + Gdk.threads_enter(); + progress.pulse(); + Gdk.threads_leave(); + + Thread.usleep(50000); + } + return null; + } + + private void *specload_thread() + { + /* XXX This shouldn't be hardcoded */ + Gdk.threads_enter(); + loading.label = "Loading r300 registers..."; + Gdk.threads_leave(); + r300_registers = new Spec("/usr/share/rsim/r300reg.xml", "r300"); + + Gdk.threads_enter(); + loading.label = "Loading r500 registers..."; + Gdk.threads_leave(); + r500_registers = new Spec("/usr/share/rsim/r300reg.xml", "r500"); + + Gdk.threads_enter(); + loading.label = "Done"; + Gdk.threads_leave(); + + return (void *)123; + } +} + public static int main(string[] args) { - r300_registers = new Spec(); - r500_registers = new Spec(); - - /* XXX This shouldn't be hardcoded */ - r300_registers.load_xml("/usr/share/rsim/r300reg.xml", "r300"); - r500_registers.load_xml("/usr/share/rsim/r300reg.xml", "r500"); + if (!Thread.supported()) { + stderr.printf("Cannot run without threads.\n"); + return 1; + } + GUI.init(ref args); - + /* vala doesn't unref globals */ r300_registers.unref(); r500_registers.unref(); GUI.actions.unref(); GUI.main.unref(); - + return 0; } diff --git a/src/registers.c b/src/registers.c index 0cfc92e..8ef89b6 100644 --- a/src/registers.c +++ b/src/registers.c @@ -232,8 +232,6 @@ struct _EmulationRegisterPrivate { guint _addr; guint _num; EmulationRegisterInfo* _info; - EmulationRegister* _prev; - EmulationRegister* _next; }; struct _EmulationRegisterIterator { @@ -284,7 +282,6 @@ struct _EmulationSpecParserPrivate { GHashTable* regs; GHashTable* groups_map; GHashTable* enums_map; - GHashTable* regs_last_map; xmlDoc* doc; xmlNode* root; }; @@ -435,9 +432,7 @@ enum { EMULATION_REGISTER_DUMMY_PROPERTY, EMULATION_REGISTER_ADDR, EMULATION_REGISTER_NUM, - EMULATION_REGISTER_INFO, - EMULATION_REGISTER_PREV, - EMULATION_REGISTER_NEXT + EMULATION_REGISTER_INFO }; EmulationRegister* emulation_register_new (void); EmulationRegister* emulation_register_construct (GType object_type); @@ -447,10 +442,6 @@ guint emulation_register_get_num (EmulationRegister* self); void emulation_register_set_num (EmulationRegister* self, guint value); EmulationRegisterInfo* emulation_register_get_info (EmulationRegister* self); void emulation_register_set_info (EmulationRegister* self, EmulationRegisterInfo* value); -EmulationRegister* emulation_register_get_prev (EmulationRegister* self); -void emulation_register_set_prev (EmulationRegister* self, EmulationRegister* value); -EmulationRegister* emulation_register_get_next (EmulationRegister* self); -void emulation_register_set_next (EmulationRegister* self, EmulationRegister* value); static void emulation_register_finalize (GObject* obj); static void emulation_register_get_property (GObject * object, guint property_id, GValue * value, GParamSpec * pspec); static void emulation_register_set_property (GObject * object, guint property_id, const GValue * value, GParamSpec * pspec); @@ -508,10 +499,6 @@ static void _lambda6_ (void* ptr); static void __lambda6__gdestroy_notify (void* data); static void _lambda7_ (void* ptr); static void __lambda7__gdestroy_notify (void* data); -static void _lambda8_ (void* ptr); -static void __lambda8__gdestroy_notify (void* data); -static void _lambda9_ (void* ptr); -static void __lambda9__gdestroy_notify (void* data); EmulationSpecParser* emulation_spec_parser_new (GHashTable** _info, GHashTable** _regs); EmulationSpecParser* emulation_spec_parser_construct (GType object_type, GHashTable** _info, GHashTable** _regs); static inline xmlNode* emulation_spec_parser_find_variant (EmulationSpecParser* self, const char* name); @@ -535,10 +522,9 @@ GType emulation_spec_get_type (void); enum { EMULATION_SPEC_DUMMY_PROPERTY }; -gboolean emulation_spec_load_xml (EmulationSpec* self, const char* filename, const char* variant); +EmulationSpec* emulation_spec_new (const char* filename, const char* variant); +EmulationSpec* emulation_spec_construct (GType object_type, const char* filename, const char* variant); EmulationRegisterList* emulation_spec_translate_addr (EmulationSpec* self, guint addr); -EmulationSpec* emulation_spec_new (void); -EmulationSpec* emulation_spec_construct (GType object_type); static void emulation_spec_finalize (GObject* obj); static int _vala_strcmp0 (const char * str1, const char * str2); @@ -1474,36 +1460,6 @@ void emulation_register_set_info (EmulationRegister* self, EmulationRegisterInfo } -EmulationRegister* emulation_register_get_prev (EmulationRegister* self) { - EmulationRegister* result; - g_return_val_if_fail (self != NULL, NULL); - result = self->priv->_prev; - return result; -} - - -void emulation_register_set_prev (EmulationRegister* self, EmulationRegister* value) { - g_return_if_fail (self != NULL); - self->priv->_prev = value; - g_object_notify ((GObject *) self, "prev"); -} - - -EmulationRegister* emulation_register_get_next (EmulationRegister* self) { - EmulationRegister* result; - g_return_val_if_fail (self != NULL, NULL); - result = self->priv->_next; - return result; -} - - -void emulation_register_set_next (EmulationRegister* self, EmulationRegister* value) { - g_return_if_fail (self != NULL); - self->priv->_next = value; - g_object_notify ((GObject *) self, "next"); -} - - static void emulation_register_class_init (EmulationRegisterClass * klass) { emulation_register_parent_class = g_type_class_peek_parent (klass); g_type_class_add_private (klass, sizeof (EmulationRegisterPrivate)); @@ -1513,8 +1469,6 @@ static void emulation_register_class_init (EmulationRegisterClass * klass) { g_object_class_install_property (G_OBJECT_CLASS (klass), EMULATION_REGISTER_ADDR, g_param_spec_uint ("addr", "addr", "addr", 0, G_MAXUINT, 0U, G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB | G_PARAM_READABLE | G_PARAM_WRITABLE)); g_object_class_install_property (G_OBJECT_CLASS (klass), EMULATION_REGISTER_NUM, g_param_spec_uint ("num", "num", "num", 0, G_MAXUINT, 0U, G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB | G_PARAM_READABLE | G_PARAM_WRITABLE)); g_object_class_install_property (G_OBJECT_CLASS (klass), EMULATION_REGISTER_INFO, g_param_spec_object ("info", "info", "info", EMULATION_TYPE_REGISTER_INFO, G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB | G_PARAM_READABLE | G_PARAM_WRITABLE)); - g_object_class_install_property (G_OBJECT_CLASS (klass), EMULATION_REGISTER_PREV, g_param_spec_object ("prev", "prev", "prev", EMULATION_TYPE_REGISTER, G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB | G_PARAM_READABLE | G_PARAM_WRITABLE)); - g_object_class_install_property (G_OBJECT_CLASS (klass), EMULATION_REGISTER_NEXT, g_param_spec_object ("next", "next", "next", EMULATION_TYPE_REGISTER, G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB | G_PARAM_READABLE | G_PARAM_WRITABLE)); } @@ -1553,12 +1507,6 @@ static void emulation_register_get_property (GObject * object, guint property_id case EMULATION_REGISTER_INFO: g_value_set_object (value, emulation_register_get_info (self)); break; - case EMULATION_REGISTER_PREV: - g_value_set_object (value, emulation_register_get_prev (self)); - break; - case EMULATION_REGISTER_NEXT: - g_value_set_object (value, emulation_register_get_next (self)); - break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); break; @@ -1579,12 +1527,6 @@ static void emulation_register_set_property (GObject * object, guint property_id case EMULATION_REGISTER_INFO: emulation_register_set_info (self, g_value_get_object (value)); break; - case EMULATION_REGISTER_PREV: - emulation_register_set_prev (self, g_value_get_object (value)); - break; - case EMULATION_REGISTER_NEXT: - emulation_register_set_next (self, g_value_get_object (value)); - break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); break; @@ -1946,34 +1888,12 @@ static void __lambda7__gdestroy_notify (void* data) { } -static void _lambda8_ (void* ptr) { - g_free (ptr); -} - - -static void __lambda8__gdestroy_notify (void* data) { - _lambda8_ (data); -} - - -static void _lambda9_ (void* ptr) { - void* _tmp0_; - g_object_unref ((_tmp0_ = ptr, G_IS_OBJECT (_tmp0_) ? ((GObject*) _tmp0_) : NULL)); -} - - -static void __lambda9__gdestroy_notify (void* data) { - _lambda9_ (data); -} - - EmulationSpecParser* emulation_spec_parser_construct (GType object_type, GHashTable** _info, GHashTable** _regs) { EmulationSpecParser* self; GHashTable* _tmp0_; GHashTable* _tmp1_; GHashTable* _tmp2_; GHashTable* _tmp3_; - GHashTable* _tmp4_; if (_info != NULL) { *_info = NULL; } @@ -1985,7 +1905,6 @@ EmulationSpecParser* emulation_spec_parser_construct (GType object_type, GHashTa self->priv->regs = *_regs = (_tmp1_ = g_hash_table_new_full (g_int_hash, g_int_equal, __lambda4__gdestroy_notify, __lambda5__gdestroy_notify), _g_hash_table_unref0 (*_regs), _tmp1_); self->priv->groups_map = (_tmp2_ = g_hash_table_new (g_str_hash, g_str_equal), _g_hash_table_unref0 (self->priv->groups_map), _tmp2_); self->priv->enums_map = (_tmp3_ = g_hash_table_new_full (g_str_hash, g_str_equal, __lambda6__gdestroy_notify, __lambda7__gdestroy_notify), _g_hash_table_unref0 (self->priv->enums_map), _tmp3_); - self->priv->regs_last_map = (_tmp4_ = g_hash_table_new_full (g_str_hash, g_str_equal, __lambda8__gdestroy_notify, __lambda9__gdestroy_notify), _g_hash_table_unref0 (self->priv->regs_last_map), _tmp4_); return self; } @@ -2412,7 +2331,6 @@ static void emulation_spec_parser_xmlparse_reg32 (EmulationSpecParser* self, xml EmulationRegisterInfo* reginfo; EmulationRegister* reg; guint _tmp3_; - EmulationRegister* last_reg; g_return_if_fail (self != NULL); g_return_if_fail (_name != NULL); name = g_strconcat (_name, emulation_spec_parser_get_single_attrib (self, node, "name"), NULL); @@ -2472,17 +2390,7 @@ static void emulation_spec_parser_xmlparse_reg32 (EmulationSpecParser* self, xml emulation_register_set_addr (reg, offset); emulation_register_set_num (reg, (_tmp3_ = emulation_register_info_get_count (reginfo), emulation_register_info_set_count (reginfo, _tmp3_ + 1), _tmp3_)); emulation_register_set_info (reg, reginfo); - emulation_register_set_prev (reg, NULL); - emulation_register_set_next (reg, NULL); emulation_register_list_append (regarr, reg); - last_reg = _g_object_ref0 ((EmulationRegister*) g_hash_table_lookup (self->priv->regs_last_map, name)); - if (last_reg == NULL) { - g_hash_table_insert (self->priv->regs_last_map, g_strdup (name), _g_object_ref0 (reg)); - } else { - emulation_register_set_next (last_reg, reg); - emulation_register_set_prev (reg, last_reg); - g_hash_table_replace (self->priv->regs_last_map, g_strdup (name), _g_object_ref0 (reg)); - } { xmlNode* iter; iter = node->children; @@ -2520,7 +2428,6 @@ static void emulation_spec_parser_xmlparse_reg32 (EmulationSpecParser* self, xml _g_object_unref0 (regarr); _g_object_unref0 (reginfo); _g_object_unref0 (reg); - _g_object_unref0 (last_reg); } @@ -2766,7 +2673,6 @@ static void emulation_spec_parser_finalize (EmulationSpecParser* obj) { self = EMULATION_SPEC_PARSER (obj); _g_hash_table_unref0 (self->priv->groups_map); _g_hash_table_unref0 (self->priv->enums_map); - _g_hash_table_unref0 (self->priv->regs_last_map); } @@ -2800,16 +2706,21 @@ void emulation_spec_parser_unref (gpointer instance) { } -gboolean emulation_spec_load_xml (EmulationSpec* self, const char* filename, const char* variant) { - gboolean result; +EmulationSpec* emulation_spec_construct (GType object_type, const char* filename, const char* variant) { + EmulationSpec * self; EmulationSpecParser* xml; - g_return_val_if_fail (self != NULL, FALSE); - g_return_val_if_fail (filename != NULL, FALSE); - g_return_val_if_fail (variant != NULL, FALSE); + g_return_val_if_fail (filename != NULL, NULL); + g_return_val_if_fail (variant != NULL, NULL); + self = (EmulationSpec*) g_object_new (object_type, NULL); xml = emulation_spec_parser_new (&self->priv->info, &self->priv->regs); - result = emulation_spec_parser_parse (xml, filename, variant); + emulation_spec_parser_parse (xml, filename, variant); _emulation_spec_parser_unref0 (xml); - return result; + return self; +} + + +EmulationSpec* emulation_spec_new (const char* filename, const char* variant) { + return emulation_spec_construct (EMULATION_TYPE_SPEC, filename, variant); } @@ -2821,18 +2732,6 @@ EmulationRegisterList* emulation_spec_translate_addr (EmulationSpec* self, guint } -EmulationSpec* emulation_spec_construct (GType object_type) { - EmulationSpec * self; - self = (EmulationSpec*) g_object_new (object_type, NULL); - return self; -} - - -EmulationSpec* emulation_spec_new (void) { - return emulation_spec_construct (EMULATION_TYPE_SPEC); -} - - static void emulation_spec_class_init (EmulationSpecClass * klass) { emulation_spec_parent_class = g_type_class_peek_parent (klass); g_type_class_add_private (klass, sizeof (EmulationSpecPrivate)); diff --git a/src/registers.vala b/src/registers.vala index e54e3f3..ff5c2c3 100644 --- a/src/registers.vala +++ b/src/registers.vala @@ -15,7 +15,7 @@ namespace Emulation public class BitfieldEnum : Object { private HashTable<uint32?, BitfieldValue> vals; - + construct { vals = new HashTable<uint32?, BitfieldValue>.full(int_hash, int_equal, (ptr) => { delete ptr; }, (ptr) => { (ptr as Object).unref(); }); } @@ -32,16 +32,16 @@ namespace Emulation public uint8 low { get; internal set; default = 0; } public BitfieldEnum? enu { get; internal set; default = null; } } - + public class BitfieldIterator { private weak List<Bitfield> m_list; - + public BitfieldIterator(List<Bitfield> l) { m_list = l.first(); } - + public bool next() { return (m_list.next != null); } public new weak Bitfield get() { @@ -58,13 +58,13 @@ namespace Emulation public uint addr { get; internal set; default = 0; } public uint count { get; internal set; default = 0; } public uint8 access { get; internal set; default = 0; } - + private List<Bitfield> bitfields; public uint length { get { return bitfields.length(); } } public Type extract_type { get { return typeof(Bitfield); } } public BitfieldIterator iterator() { return new BitfieldIterator(bitfields); } public new weak Bitfield get(uint index) { return bitfields.nth_data(index); } - + construct { bitfields = new List<Bitfield>(); } @@ -77,19 +77,17 @@ namespace Emulation public uint addr { get; internal set; } public uint num { get; internal set; } public weak RegisterInfo info { get; internal set; } - public weak Register? prev { get; internal set; } - public weak Register? next { get; internal set; } } - + public class RegisterIterator { private weak List<Register> m_list; - + public RegisterIterator(List<Register> l) { m_list = l.first(); } - + public bool next() { return (m_list.next != null); } public new weak Register get() { @@ -98,7 +96,7 @@ namespace Emulation return r; } } - + public class RegisterList : Object { private List<Register> regs; @@ -111,7 +109,7 @@ namespace Emulation public Type extract_type { get { return typeof(Register); } } public RegisterIterator iterator() { return new RegisterIterator(regs); } public new weak Register get(uint index) { return regs.nth_data(index); } - + internal void append(Register reg) { regs.append(reg); } } @@ -119,10 +117,9 @@ namespace Emulation { private weak HashTable<string, RegisterInfo> info; private weak HashTable<uint?, RegisterList> regs; - + private HashTable<string, Xml.Node *> groups_map; private HashTable<string, BitfieldEnum> enums_map; - private HashTable<string, Register> regs_last_map; private Xml.Doc *doc; private Xml.Node *root; @@ -132,7 +129,6 @@ namespace Emulation regs = (_regs = new HashTable<uint?, RegisterList>.full(int_hash, int_equal, (ptr) => { delete ptr; }, (ptr) => { (ptr as Object).unref(); })); groups_map = new HashTable<string, Xml.Node *>(str_hash, str_equal); enums_map = new HashTable<string, BitfieldEnum>.full(str_hash, str_equal, (ptr) => { delete ptr; }, (ptr) => { (ptr as Object).unref(); }); - regs_last_map = new HashTable<string, Register>.full(str_hash, str_equal, (ptr) => { delete ptr; }, (ptr) => { (ptr as Object).unref(); }); } public bool parse(string filename, string variant) @@ -150,31 +146,31 @@ namespace Emulation stdout.printf("Error: '%s' does not contain a root node.\n", filename); return false; } - + var vnode = find_variant(variant); if (vnode == null) { delete doc; stdout.printf("Error: Unable to find the '%s' variant.\n", variant); return false; } - + index_groups(); index_enums(); xmlparse_variant(vnode); - + delete doc; Xml.Parser.cleanup(); - + return true; } - + private inline void index_groups() { for (Xml.Node *iter = root->children; iter != null; iter = iter->next) { if (iter->type != Xml.ElementType.ELEMENT_NODE) { continue; } - + if (iter->name == "group") { - unowned string name = get_single_attrib(iter, "name"); + weak string name = get_single_attrib(iter, "name"); if (name == "") { stdout.printf("Warning: Found a group with no name.\n"); } else if (groups_map.lookup(name) != null) { @@ -185,18 +181,18 @@ namespace Emulation } } } - + private inline void index_enums() { for (Xml.Node *iter = root->children; iter != null; iter = iter->next) { if (iter->type != Xml.ElementType.ELEMENT_NODE) { continue; } - + if (iter->name == "enum") { xmlparse_enum(iter); } } } - + private inline Xml.Node *find_variant(string name) { for (Xml.Node *iter = root->children; iter != null; iter = iter->next) { @@ -208,7 +204,7 @@ namespace Emulation } return null; } - + private inline Xml.Node *find_group(string name) { Xml.Node *node = groups_map.lookup(name); @@ -217,7 +213,7 @@ namespace Emulation } return node; } - + private inline BitfieldEnum find_enum(string name) { weak BitfieldEnum e = enums_map.lookup(name); @@ -226,8 +222,8 @@ namespace Emulation } return e; } - - private inline unowned string get_single_attrib(Xml.Node *node, string attrib) + + private inline weak string get_single_attrib(Xml.Node *node, string attrib) { for (Xml.Attr *prop = node->properties; prop != null; prop = prop->next) { if (prop->name == attrib) { @@ -236,12 +232,12 @@ namespace Emulation } return ""; } - + private void xmlparse_variant(Xml.Node *node) { for (Xml.Node *iter = node->children; iter != null; iter = iter->next) { if (iter->type != Xml.ElementType.ELEMENT_NODE) { continue; } - + if (iter->name == "group") { xmlparse_group(iter, 0, ""); } else if (iter->name == "reg32") { @@ -256,14 +252,14 @@ namespace Emulation } } } - + private void xmlparse_group(Xml.Node *node, uint offset, string _name) { string name = _name + get_single_attrib(node, "prepend"); - + for (Xml.Node *iter = node->children; iter != null; iter = iter->next) { if (iter->type != Xml.ElementType.ELEMENT_NODE) { continue; } - + if (iter->name == "reg32") { xmlparse_reg32(iter, offset, name); } else if (iter->name == "stripe") { @@ -276,17 +272,17 @@ namespace Emulation } } } - + private void xmlparse_stripe(Xml.Node *node, uint offset, string _name) { string name = _name + get_single_attrib(node, "name"); uint stride = (uint)get_single_attrib(node, "stride").to_ulong(); uint length = (uint)get_single_attrib(node, "length").to_ulong(); offset += (uint)get_single_attrib(node, "offset").to_ulong(); - + for (Xml.Node *iter = node->children; iter != null; iter = iter->next) { if (iter->type != Xml.ElementType.ELEMENT_NODE) { continue; } - + if (iter->name == "reg32") { for (uint i = 0; i < length; i++) { xmlparse_reg32(iter, offset + (i * stride), name); @@ -307,18 +303,18 @@ namespace Emulation } } } - + private void xmlparse_reg32(Xml.Node *node, uint offset, string _name) { string name = _name + get_single_attrib(node, "name"); offset += (uint)get_single_attrib(node, "offset").to_ulong(); - + var regarr = regs.lookup(offset); if (regarr == null) { regs.insert(offset, new RegisterList()); regarr = regs.lookup(offset); } - + RegisterInfo reginfo = info.lookup(name); if (reginfo == null) { var ri = new RegisterInfo(); @@ -333,31 +329,20 @@ namespace Emulation case 'W': ri.access |= AccessType.WRITE; break; } } - + info.insert(name, ri); reginfo = info.lookup(name); } - + var reg = new Register(); reg.addr = offset; reg.num = reginfo.count++; reg.info = reginfo; - reg.prev = null; - reg.next = null; regarr.append(reg); - - Register last_reg = regs_last_map.lookup(name); - if (last_reg == null) { - regs_last_map.insert(name, reg); - } else { - last_reg.next = reg; - reg.prev = last_reg; - regs_last_map.replace(name, reg); - } for (Xml.Node *iter = node->children; iter != null; iter = iter->next) { if (iter->type != Xml.ElementType.ELEMENT_NODE) { continue; } - + if (iter->name == "bitfield") { xmlparse_bitfield(iter, reginfo); } else if (iter->name == "doc") { @@ -376,7 +361,7 @@ namespace Emulation for (Xml.Node *iter = node->children; iter != null; iter = iter->next) { if (iter->type != Xml.ElementType.ELEMENT_NODE) { continue; } - + if (iter->name == "value") { xmlparse_value(iter, enu); } else { @@ -384,7 +369,7 @@ namespace Emulation } } } - + private void xmlparse_bitfield(Xml.Node *node, RegisterInfo reginfo) { Bitfield b = new Bitfield(); @@ -392,10 +377,10 @@ namespace Emulation b.high = (uint8)get_single_attrib(node, "high").to_ulong(); b.low = (uint8)get_single_attrib(node, "low").to_ulong(); b.doc = ""; - + for (Xml.Node *iter = node->children; iter != null; iter = iter->next) { if (iter->type != Xml.ElementType.ELEMENT_NODE) { continue; } - + if (iter->name == "value") { if (b.enu == null) { b.enu = new BitfieldEnum(); @@ -409,10 +394,10 @@ namespace Emulation stdout.printf("Warning: Unknown rules-ng tag '%s' in bitfield.\n", iter->name); } } - + reginfo.append(b); } - + private void xmlparse_value(Xml.Node *node, BitfieldEnum enu) { BitfieldValue v = new BitfieldValue(); @@ -434,13 +419,13 @@ namespace Emulation { private HashTable<string, RegisterInfo> info; private HashTable<uint?, RegisterList> regs; - - public bool load_xml(string filename, string variant) + + public Spec(string filename, string variant) { var xml = new SpecParser(out info, out regs); - return xml.parse(filename, variant); + xml.parse(filename, variant); } - + public RegisterList translate_addr(uint addr) { return regs.lookup(addr); |