Audacious
$Id:Doxyfile42802007-03-2104:39:00Znenolod$
|
00001 /* Audacious 00002 * Copyright (c) 2006-2007 William Pitcock 00003 * 00004 * This program is free software; you can redistribute it and/or modify 00005 * it under the terms of the GNU General Public License as published by 00006 * the Free Software Foundation; under version 3 of the License. 00007 * 00008 * This program is distributed in the hope that it will be useful, 00009 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00010 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00011 * GNU General Public License for more details. 00012 * 00013 * You should have received a copy of the GNU General Public License 00014 * along with this program. If not, see <http://www.gnu.org/licenses>. 00015 * 00016 * The Audacious team does not consider modular code linking to 00017 * Audacious or using our public API to be a derived work. 00018 */ 00019 00020 #include <stdio.h> 00021 #include <string.h> 00022 00023 #include <glib.h> 00024 #include "hook.h" 00025 00026 static GThread * hook_thread; 00027 static GSList *hook_list; 00028 00029 void hook_init (void) 00030 { 00031 hook_thread = g_thread_self (); 00032 } 00033 00034 static Hook * 00035 hook_find(const gchar *name) 00036 { 00037 GSList *list; 00038 00039 for (list = hook_list; list != NULL; list = g_slist_next(list)) 00040 { 00041 Hook *hook = (Hook *) list->data; 00042 00043 if (!g_ascii_strcasecmp(hook->name, name)) 00044 return hook; 00045 } 00046 00047 return NULL; 00048 } 00049 00050 void 00051 hook_register(const gchar *name) 00052 { 00053 Hook *hook; 00054 00055 g_return_if_fail(name != NULL); 00056 00057 if (hook_find(name) != NULL) 00058 return; 00059 00060 hook = g_new0(Hook, 1); 00061 hook->name = g_strdup(name); 00062 hook->items = NULL; 00063 00064 hook_list = g_slist_append(hook_list, hook); 00065 } 00066 00067 gint 00068 hook_associate(const gchar *name, HookFunction func, gpointer user_data) 00069 { 00070 Hook *hook; 00071 HookItem *hookitem; 00072 00073 g_return_val_if_fail(name != NULL, -1); 00074 g_return_val_if_fail(func != NULL, -1); 00075 00076 hook = hook_find(name); 00077 00078 if (hook == NULL) 00079 { 00080 hook_register(name); 00081 hook = hook_find(name); 00082 } 00083 00084 /* this *cant* happen */ 00085 g_return_val_if_fail(hook != NULL, -1); 00086 00087 hookitem = g_new0(HookItem, 1); 00088 hookitem->func = func; 00089 hookitem->user_data = user_data; 00090 00091 hook->items = g_slist_append(hook->items, hookitem); 00092 return 0; 00093 } 00094 00095 gint 00096 hook_dissociate(const gchar *name, HookFunction func) 00097 { 00098 Hook *hook; 00099 GSList *iter; 00100 00101 g_return_val_if_fail(name != NULL, -1); 00102 g_return_val_if_fail(func != NULL, -1); 00103 00104 hook = hook_find(name); 00105 00106 if (hook == NULL) 00107 return -1; 00108 00109 iter = hook->items; 00110 while (iter != NULL) 00111 { 00112 HookItem *hookitem = (HookItem*)iter->data; 00113 if (hookitem->func == func) 00114 { 00115 hook->items = g_slist_delete_link(hook->items, iter); 00116 g_free( hookitem ); 00117 return 0; 00118 } 00119 iter = g_slist_next(iter); 00120 } 00121 return -1; 00122 } 00123 00124 gint 00125 hook_dissociate_full(const gchar *name, HookFunction func, gpointer user_data) 00126 { 00127 Hook *hook; 00128 GSList *iter; 00129 00130 g_return_val_if_fail(name != NULL, -1); 00131 g_return_val_if_fail(func != NULL, -1); 00132 00133 hook = hook_find(name); 00134 00135 if (hook == NULL) 00136 return -1; 00137 00138 iter = hook->items; 00139 while (iter != NULL) 00140 { 00141 HookItem *hookitem = (HookItem*)iter->data; 00142 if (hookitem->func == func && hookitem->user_data == user_data) 00143 { 00144 hook->items = g_slist_delete_link(hook->items, iter); 00145 g_free( hookitem ); 00146 return 0; 00147 } 00148 iter = g_slist_next(iter); 00149 } 00150 return -1; 00151 } 00152 00153 void 00154 hook_call(const gchar *name, gpointer hook_data) 00155 { 00156 Hook *hook; 00157 GSList *iter; 00158 00159 // Some plugins (skins, cdaudio-ng, maybe others) set up hooks that are not 00160 // thread safe. We can disagree about whether that's the way it should be; 00161 // but that's the way it is, so live with it. -jlindgren 00162 if (g_thread_self () != hook_thread) 00163 { 00164 fprintf (stderr, "Warning: Unsafe hook_call of \"%s\" from secondary " 00165 "thread. (Use event_queue instead.)\n", name); 00166 return; 00167 } 00168 00169 hook = hook_find(name); 00170 00171 if (hook == NULL) 00172 return; 00173 00174 for (iter = hook->items; iter != NULL; iter = g_slist_next(iter)) 00175 { 00176 HookItem *hookitem = (HookItem*)iter->data; 00177 00178 g_return_if_fail(hookitem->func != NULL); 00179 00180 hookitem->func(hook_data, hookitem->user_data); 00181 } 00182 }