/* diversity-equipment.c - DiversityEquipment * * Copyright 2008 OpenMoko, Inc. * Authored by Chia-I Wu * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include #include "diversity-marshal.h" enum { CONFIG_CHANGED, LAST_SIGNAL }; enum { PROP_0, PROP_NAME, }; #define DIVERSITY_EQUIPMENT_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE((o), DIVERSITY_TYPE_EQUIPMENT, DiversityEquipmentPrivate)) typedef struct _DiversityEquipmentPrivate DiversityEquipmentPrivate; struct _DiversityEquipmentPrivate { gchar *name; DiversityBard *owner; }; static guint equipment_signals[LAST_SIGNAL] = { 0 }; G_DEFINE_TYPE(DiversityEquipment, diversity_equipment, G_TYPE_OBJECT); static void diversity_equipment_finalize(GObject *obj) { DiversityEquipmentPrivate *priv = DIVERSITY_EQUIPMENT_GET_PRIVATE(obj); if (priv->name) g_free(priv->name); ((GObjectClass *) diversity_equipment_parent_class)->finalize(obj); } static void diversity_equipment_dispose(GObject *obj) { DiversityEquipmentPrivate *priv = DIVERSITY_EQUIPMENT_GET_PRIVATE(obj); if (priv->owner) { g_object_unref(priv->owner); priv->owner = NULL; } ((GObjectClass *) diversity_equipment_parent_class)->dispose(obj); } static void diversity_equipment_set_property(GObject *obj, guint prop_id, const GValue *value, GParamSpec *pspec) { DiversityEquipmentPrivate *priv = DIVERSITY_EQUIPMENT_GET_PRIVATE(obj); switch (prop_id) { case PROP_NAME: if (priv->name) g_free(priv->name); priv->name = g_value_dup_string(value); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, prop_id, pspec); break; } } static void diversity_equipment_get_property(GObject *obj, guint prop_id, GValue *value, GParamSpec *pspec) { DiversityEquipmentPrivate *priv = DIVERSITY_EQUIPMENT_GET_PRIVATE(obj); switch (prop_id) { case PROP_NAME: g_value_set_string(value, priv->name); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, prop_id, pspec); break; } } static void diversity_equipment_class_init(DiversityEquipmentClass *klass) { GObjectClass *o_class = (GObjectClass *) klass; o_class->finalize = diversity_equipment_finalize; o_class->dispose = diversity_equipment_dispose; o_class->set_property = diversity_equipment_set_property; o_class->get_property = diversity_equipment_get_property; g_type_class_add_private(klass, sizeof(DiversityEquipmentPrivate)); g_object_class_install_property(o_class, PROP_NAME, g_param_spec_string("name", "Name", "Equipment name", "", G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); equipment_signals[CONFIG_CHANGED] = g_signal_new("config-changed", G_TYPE_FROM_CLASS(klass), G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED, G_STRUCT_OFFSET(DiversityEquipmentClass, config_changed), NULL, NULL, _diversity_marshal_VOID__STRING_BOXED, G_TYPE_NONE, 2, G_TYPE_STRING | G_SIGNAL_TYPE_STATIC_SCOPE, G_TYPE_VALUE | G_SIGNAL_TYPE_STATIC_SCOPE); } static void diversity_equipment_init(DiversityEquipment *eqp) { DiversityEquipmentPrivate *priv = DIVERSITY_EQUIPMENT_GET_PRIVATE(eqp); priv->name = NULL; priv->owner = NULL; } static void on_owner_finalized(gpointer data, GObject *owner) { DiversityEquipment *eqp = data; DiversityEquipmentPrivate *priv = DIVERSITY_EQUIPMENT_GET_PRIVATE(eqp); if (priv->owner) diversity_equipment_unequip(eqp); } const gchar *diversity_equipment_get_name(DiversityEquipment *eqp) { DiversityEquipmentPrivate *priv = DIVERSITY_EQUIPMENT_GET_PRIVATE(eqp); return priv->name; } gboolean diversity_equipment_equip(DiversityEquipment *eqp, DiversityBard *bard) { DiversityEquipmentPrivate *priv = DIVERSITY_EQUIPMENT_GET_PRIVATE(eqp); gboolean ret = TRUE; if (priv->owner != bard) { if (priv->owner) diversity_equipment_unequip(eqp); priv->owner = bard; ret = DIVERSITY_EQUIPMENT_GET_CLASS(eqp)->equip(eqp); if (ret) g_object_weak_ref(G_OBJECT(priv->owner), on_owner_finalized, eqp); else priv->owner = NULL; } return ret; } void diversity_equipment_unequip(DiversityEquipment *eqp) { DiversityEquipmentPrivate *priv = DIVERSITY_EQUIPMENT_GET_PRIVATE(eqp); if (priv->owner) { g_object_weak_unref(G_OBJECT(priv->owner), on_owner_finalized, eqp); priv->owner = NULL; DIVERSITY_EQUIPMENT_GET_CLASS(eqp)->unequip(eqp); } } gboolean diversity_equipment_set_config(DiversityEquipment *eqp, const gchar *key, const GValue *val) { gboolean success; if (!key || !val) return FALSE; success = DIVERSITY_EQUIPMENT_GET_CLASS(eqp)->set_config(eqp, key, val); if (success) g_signal_emit(eqp, equipment_signals[CONFIG_CHANGED], g_quark_from_string(key), key, val); return success; } gboolean diversity_equipment_get_config(DiversityEquipment *eqp, const gchar *key, GValue *val) { if (!key || !val) return FALSE; return DIVERSITY_EQUIPMENT_GET_CLASS(eqp)->get_config(eqp, key, val); } DiversityBard *diversity_equipment_get_equipper(DiversityEquipment *eqp) { DiversityEquipmentPrivate *priv = DIVERSITY_EQUIPMENT_GET_PRIVATE(eqp); return priv->owner; }