1 /* 2 * libInstPatch 3 * Copyright (C) 1999-2014 Element Green <element@elementsofsound.org> 4 * 5 * This program is free software; you can redistribute it and/or 6 * modify it under the terms of the GNU Lesser General Public License 7 * as published by the Free Software Foundation; version 2.1 8 * of the License only. 9 * 10 * This library is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * GNU Lesser General Public License for more details. 14 * 15 * You should have received a copy of the GNU Lesser General Public License 16 * along with this program; if not, write to the Free Software 17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 18 * 02110-1301, USA or on the web at http://www.gnu.org. 19 */ 20 #ifndef __IPATCH_ITEM_H__ 21 #define __IPATCH_ITEM_H__ 22 23 #include <stdarg.h> 24 #include <glib.h> 25 #include <glib-object.h> 26 27 typedef struct _IpatchItem IpatchItem; 28 typedef struct _IpatchItemClass IpatchItemClass; 29 30 #include <libinstpatch/IpatchIter.h> 31 #include <libinstpatch/IpatchList.h> 32 33 #define IPATCH_TYPE_ITEM (ipatch_item_get_type ()) 34 #define IPATCH_ITEM(obj) \ 35 (G_TYPE_CHECK_INSTANCE_CAST ((obj), IPATCH_TYPE_ITEM, IpatchItem)) 36 #define IPATCH_ITEM_CLASS(klass) \ 37 (G_TYPE_CHECK_CLASS_CAST ((klass), IPATCH_TYPE_ITEM, IpatchItemClass)) 38 #define IPATCH_IS_ITEM(obj) \ 39 (G_TYPE_CHECK_INSTANCE_TYPE ((obj), IPATCH_TYPE_ITEM)) 40 #define IPATCH_IS_ITEM_CLASS(klass) \ 41 (G_TYPE_CHECK_CLASS_TYPE ((klass), IPATCH_TYPE_ITEM)) 42 #define IPATCH_ITEM_GET_CLASS(obj) \ 43 (G_TYPE_INSTANCE_GET_CLASS ((obj), IPATCH_TYPE_ITEM, IpatchItemClass)) 44 45 /** 46 * IpatchItemCopyLinkFunc: 47 * @item: Item which is being linked (contains a reference to @link). 48 * @link: The item being referenced (can be NULL). 49 * @user_data: User data supplied to copy/duplicate function. 50 * 51 * A callback function called during item copy/duplicate operations for 52 * any item link reference which needs to be resolved. An example usage 53 * is for deep duplicating an object (all references can also be duplicated). 54 * Item copy methods should call this for any linked item references which are 55 * not part of the new object. 56 * 57 * Returns: Pointer to item to use for link property (can be the @link item 58 * if the duplicated/copied item is local to the same file). 59 */ 60 typedef IpatchItem *(*IpatchItemCopyLinkFunc)(IpatchItem *item, 61 IpatchItem *link, 62 gpointer user_data); 63 64 /* Base patch item object */ 65 struct _IpatchItem 66 { 67 GObject object; 68 69 /*< private >*/ 70 71 int flags; /* flag field (atomic int ops used) */ 72 IpatchItem *parent; /* parent item or NULL if not parented or root */ 73 IpatchItem *base; /* base parent object or NULL */ 74 GStaticRecMutex *mutex; /* pointer to mutex (could be a parent's mutex) */ 75 }; 76 77 /* Base patch item class */ 78 struct _IpatchItemClass 79 { 80 GObjectClass parent_class; 81 82 /*< public >*/ 83 84 gboolean mutex_slave; /* set to TRUE to use parent thread mutex */ 85 86 /* methods */ 87 void (*item_set_property)(GObject *object, guint property_id, 88 const GValue *value, GParamSpec *pspec); 89 void (*copy)(IpatchItem *dest, IpatchItem *src, 90 IpatchItemCopyLinkFunc link_func, gpointer user_data); 91 void (*remove)(IpatchItem *item); 92 93 /** 94 * remove_full: 95 * @item: Item to remove references to/from 96 * @full: %TRUE removes all references to and from @item, %FALSE removes only references to @item 97 * 98 * Removes references to/from (depending on the value of @full) @item of other objects in the same 99 * #IpatchBase object. The remove method can be used instead for default behavior of removing item's 100 * children if it is a container and @full is TRUE. 101 * 102 * Since: 1.1.0 103 */ 104 void (*remove_full)(IpatchItem *item, gboolean full); 105 }; 106 107 typedef enum 108 { 109 IPATCH_ITEM_HOOKS_ACTIVE = 1 << 0, /* hook callbacks active? */ 110 IPATCH_ITEM_FREE_MUTEX = 1 << 1 /* TRUE if item should free its mutex */ 111 } IpatchItemFlags; 112 113 /** 114 * IPATCH_ITEM_UNUSED_FLAG_SHIFT: (skip) 115 */ 116 /* 2 flags + reserve 2 bits for future expansion */ 117 #define IPATCH_ITEM_UNUSED_FLAG_SHIFT 4 118 119 /* Multi-thread locking macros. For now there is no distinction between 120 write and read locking since GStaticRWLock is not recursive. */ 121 #define IPATCH_ITEM_WLOCK(item) \ 122 g_static_rec_mutex_lock (((IpatchItem *)(item))->mutex) 123 #define IPATCH_ITEM_WUNLOCK(item) \ 124 g_static_rec_mutex_unlock (((IpatchItem *)(item))->mutex) 125 #define IPATCH_ITEM_RLOCK(item) IPATCH_ITEM_WLOCK(item) 126 #define IPATCH_ITEM_RUNLOCK(item) IPATCH_ITEM_WUNLOCK(item) 127 128 /** 129 * IpatchItemPropNotify: 130 * @item: Item whose property changed 131 * @pspec: Parameter spec of property which changed 132 * @new_value: New value assigned to the property 133 * @old_value: Old value that the property had (can be %NULL for read only 134 * properties) 135 * @user_data: User defined pointer from when callback was added 136 * @event_ptrs: Per event data defined by users of callback system 137 * 138 * Property notify information structure. 139 */ 140 typedef struct 141 { 142 IpatchItem *item; /* item whose property changed */ 143 GParamSpec *pspec; /* property spec of the property that changed */ 144 const GValue *new_value; /* new value of the property */ 145 const GValue *old_value; /* old value of the property (can be NULL!) */ 146 gpointer user_data; /* user defined data, defined on connect */ 147 148 /* per event data */ 149 struct 150 { 151 gpointer data; /* implementation defined data per event */ 152 GDestroyNotify destroy; /* function called to cleanup for @data */ 153 } eventdata[4]; 154 } IpatchItemPropNotify; 155 156 /** 157 * IPATCH_ITEM_PROP_NOTIFY_SET_EVENT: 158 * @info: IpatchItemPropNotify pointer 159 * @index: Pointer index (0-3) 160 * @data: Data to assign to pointer field 161 * @destroy: Callback function to cleanup @data when done (or %NULL) 162 * 163 * A macro for assigning per event pointers to #IpatchItemPropNotify. 164 */ 165 #define IPATCH_ITEM_PROP_NOTIFY_SET_EVENT(info, index, data, destroy) \ 166 (info)->eventdata[index].data = data; (info)->eventdata[index].destroy = destroy 167 168 /** 169 * IpatchItemPropCallback: 170 * 171 * IpatchItem property change callback function prototype. 172 */ 173 typedef void (*IpatchItemPropCallback)(IpatchItemPropNotify *notify); 174 175 /** 176 * IpatchItemPropDisconnect: 177 * @item: Item of prop change match criteria 178 * @pspec: Parameter spec of prop change match criteria 179 * @user_data: User defined pointer from when callback was added 180 * 181 * Function prototype which gets called when a property notify callback gets 182 * disconnected. 183 */ 184 typedef void (*IpatchItemPropDisconnect)(IpatchItem *item, GParamSpec *pspec, 185 gpointer user_data); 186 187 /* Convenience macro used by IpatchItem copy methods to call a copy link 188 function, or use the link pointer directly if function is NULL */ 189 #define IPATCH_ITEM_COPY_LINK_FUNC(item, link, func, userdata) \ 190 (func ? func (item, link, userdata) : link) 191 192 /* stored publicy for added convenience to derived types */ 193 /* Useful when libinstpatch library is used as a static library. */ 194 extern GParamSpec *ipatch_item_pspec_title; 195 196 /* 197 Getter function returning title property GParamSpec as a convenience to derived type. 198 Useful when libinstpatch library is used as a shared library linked at load time. 199 */ 200 GParamSpec *ipatch_item_get_pspec_title(void); 201 202 GType ipatch_item_get_type(void); 203 int ipatch_item_get_flags(gpointer item); 204 void ipatch_item_set_flags(gpointer item, int flags); 205 void ipatch_item_clear_flags(gpointer item, int flags); 206 void ipatch_item_set_parent(IpatchItem *item, IpatchItem *parent); 207 void ipatch_item_unparent(IpatchItem *item); 208 IpatchItem *ipatch_item_get_parent(IpatchItem *item); 209 IpatchItem *ipatch_item_peek_parent(IpatchItem *item); 210 IpatchItem *ipatch_item_get_base(IpatchItem *item); 211 IpatchItem *ipatch_item_peek_base(IpatchItem *item); 212 IpatchItem *ipatch_item_get_ancestor_by_type(IpatchItem *item, 213 GType ancestor_type); 214 IpatchItem *ipatch_item_peek_ancestor_by_type(IpatchItem *item, 215 GType ancestor_type); 216 void ipatch_item_remove(IpatchItem *item); 217 void ipatch_item_remove_full(IpatchItem *item, gboolean full); 218 void ipatch_item_remove_recursive(IpatchItem *item, gboolean full); 219 void ipatch_item_changed(IpatchItem *item); 220 void ipatch_item_get_property_fast(IpatchItem *item, GParamSpec *pspec, 221 GValue *value); 222 void ipatch_item_copy(IpatchItem *dest, IpatchItem *src); 223 void ipatch_item_copy_link_func(IpatchItem *dest, IpatchItem *src, 224 IpatchItemCopyLinkFunc link_func, 225 gpointer user_data); 226 void ipatch_item_copy_replace(IpatchItem *dest, IpatchItem *src, 227 GHashTable *repl_hash); 228 IpatchItem *ipatch_item_duplicate(IpatchItem *item); 229 IpatchItem *ipatch_item_duplicate_link_func(IpatchItem *item, 230 IpatchItemCopyLinkFunc link_func, 231 gpointer user_data); 232 IpatchItem *ipatch_item_duplicate_replace(IpatchItem *item, 233 GHashTable *repl_hash); 234 IpatchList *ipatch_item_duplicate_deep(IpatchItem *item); 235 IpatchItem *ipatch_item_copy_link_func_deep(IpatchItem *item, IpatchItem *link, 236 gpointer user_data); 237 IpatchItem *ipatch_item_copy_link_func_hash(IpatchItem *item, IpatchItem *link, 238 gpointer user_data); 239 gboolean ipatch_item_type_can_conflict(GType item_type); 240 GParamSpec **ipatch_item_type_get_unique_specs(GType item_type, 241 guint32 *groups); 242 GValueArray *ipatch_item_get_unique_props(IpatchItem *item); 243 guint ipatch_item_test_conflict(IpatchItem *item1, IpatchItem *item2); 244 void ipatch_item_set_atomic(gpointer item, 245 const char *first_property_name, ...); 246 void ipatch_item_get_atomic(gpointer item, 247 const char *first_property_name, ...); 248 IpatchItem *ipatch_item_first(IpatchIter *iter); 249 IpatchItem *ipatch_item_next(IpatchIter *iter); 250 251 252 /* in IpatchItemProp.c */ 253 254 255 void ipatch_item_prop_notify(IpatchItem *item, GParamSpec *pspec, 256 const GValue *new_value, const GValue *old_value); 257 void ipatch_item_prop_notify_by_name(IpatchItem *item, const char *prop_name, 258 const GValue *new_value, 259 const GValue *old_value); 260 guint ipatch_item_prop_connect(IpatchItem *item, GParamSpec *pspec, 261 IpatchItemPropCallback callback, 262 IpatchItemPropDisconnect disconnect, 263 gpointer user_data); 264 guint ipatch_item_prop_connect_by_name(IpatchItem *item, 265 const char *prop_name, 266 IpatchItemPropCallback callback, 267 IpatchItemPropDisconnect disconnect, 268 gpointer user_data); 269 void ipatch_item_prop_disconnect(guint handler_id); 270 void ipatch_item_prop_disconnect_matched(IpatchItem *item, 271 GParamSpec *pspec, 272 IpatchItemPropCallback callback, 273 gpointer user_data); 274 void ipatch_item_prop_disconnect_by_name(IpatchItem *item, 275 const char *prop_name, 276 IpatchItemPropCallback callback, 277 gpointer user_data); 278 #endif 279