st-handler.c
来自「linux下网络收音机的源码」· C语言 代码 · 共 1,838 行 · 第 1/4 页
C
1,838 行
/* * Copyright (c) 2002, 2003, 2004 Jean-Yves Lefort * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of Jean-Yves Lefort nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */#include "config.h"#include <string.h>#include <glib/gi18n.h>#include <gtk/gtk.h>#include "st-category-bag.h"#include "st-handler.h"#include "st-handler-field.h"#include "sg-util.h"#include "st-stream-bag.h"#include "st-category-store.h"#include "st-stream-store.h"#include "st-dialog-api.h"#include "st-plugin.h"/*** type definitions ********************************************************/enum { PROP_0, PROP_NAME, PROP_DUMMY}; typedef struct{ gpointer cb; gpointer data;} STHandlerCallback;struct _STHandlerPrivate{ gboolean dummy; char *name; char *label; char *description; char *home; GdkPixbuf *pixbuf; GSList *fields; GNode *stock_categories; STHandlerFlags flags; int stream_version; STHandlerCallback callbacks[ST_HANDLER_N_EVENTS]; STCategoryStore *categories; /* * We don't need a categories mutex (in the current design, the * store is never accessed by multiple threads concurrently). */ GHashTable *streams; GMutex *streams_mutex; int fields_sort_index; int fields_sort_order; int paned_position; GHashTable *config; GMutex *config_mutex;};typedef struct{ const char *name; STCategoryBag *category_bag;} GetStockCategoryInfo;typedef struct{ STHandler *handler; GHashTable *stream_bag_lists;} StreamListsToBagsInfo;typedef struct{ STHandlerConfigForeachCallback cb; gpointer data;} ConfigForeachInfo;typedef struct{ GParamSpec *pspec; GValue value;} ConfigEntry;/*** function declarations ***************************************************/static void st_handler_class_init (STHandlerClass *class);static void st_handler_init (STHandler *handler);static GObject *st_handler_constructor (GType type, unsigned int n_construct_properties, GObjectConstructParam *construct_params);static void st_handler_set_property (GObject *object, unsigned int prop_id, const GValue *value, GParamSpec *pspec);static STCategory *st_handler_category_new_default_cb (gpointer data);static void st_handler_category_free_default_cb (STCategory *category, gpointer data);static STStream *st_handler_stream_new_default_cb (gpointer data);static void st_handler_stream_free_default_cb (STStream *stream, gpointer data);static gboolean st_handler_set_stock_categories_cb (GNode *node, gpointer data);static gboolean st_handler_get_stock_category_cb (GNode *node, gpointer data);static void st_handler_reload_multiple_cb (gpointer key, gpointer value, gpointer user_data);static gboolean st_handler_reload_single (STHandler *handler, STCategoryBag *category_bag, GNode **category_bags, GSList **stream_bags, GError **err);static gboolean st_handler_reload_multiple (STHandler *handler, GNode **category_bags, GHashTable **stream_bag_lists, GError **err);static GNode *st_handler_categories_to_bags (STHandler *handler, GNode *categories);static gboolean st_handler_categories_to_bags_cb (GNode *node, gpointer data);static void st_handler_categories_free (STHandler *handler, GNode *categories);static gboolean st_handler_categories_free_cb (GNode *node, gpointer data);static GSList *st_handler_streams_to_bags (STHandler *handler, GList *streams);static void st_handler_streams_free (STHandler *handler, GList *streams);static GHashTable *st_handler_stream_lists_to_bags (STHandler *handler, GHashTable *stream_lists);static void st_handler_stream_lists_to_bags_cb (gpointer key, gpointer value, gpointer user_data);static void st_handler_stream_lists_free (STHandler *handler, GHashTable *stream_lists);static void st_handler_stream_lists_free_cb (gpointer key, gpointer value, gpointer user_data);static gboolean st_handler_get_selected_category_cb (STCategoryStore *store, STCategoryBag *bag, STCategoryBag *parent, gpointer data);static void st_handler_config_foreach_cb (gpointer key, gpointer value, gpointer user_data);/*** variable declarations ***************************************************/static GObjectClass *parent_class = NULL;/*** API implementation ******************************************************/GTypest_handler_get_type (void){ static GType handler_type = 0; if (! handler_type) { static const GTypeInfo handler_info = { sizeof(STHandlerClass), NULL, NULL, (GClassInitFunc) st_handler_class_init, NULL, NULL, sizeof(STHandler), 0, (GInstanceInitFunc) st_handler_init, }; handler_type = g_type_register_static(G_TYPE_OBJECT, "STHandler", &handler_info, 0); } return handler_type;}/** * st_handler_new: * @name: the name of the handler. * * Creates a new #STHandler. After creating the handler, you must set * its label using st_handler_set_label(), add your stream fields * using st_handler_add_field(), and bind functions to events using * st_handler_bind(). * * Functions must be bound to #ST_HANDLER_EVENT_STREAM_FIELD_GET and * #ST_HANDLER_EVENT_STREAM_FIELD_SET. Additionally, if one of the * fields added with st_handler_add_field() has the * #ST_HANDLER_FIELD_EDITABLE flag set, a function must be bound to * #ST_HANDLER_EVENT_STREAM_MODIFY. * * Return value: the newly created #STHandler. **/STHandler *st_handler_new (const char *name){ g_return_val_if_fail(name != NULL, NULL); return g_object_new(ST_TYPE_HANDLER, "name", name, NULL);}/** * st_handler_new_from_plugin: * @plugin: a plugin to take the name, label and icon from. * * Creates a new #STHandler, using the name, label and icon of * @plugin. You must set the name and label of @plugin before calling * this function. * * Return value: the newly created #STHandler. **/STHandler *st_handler_new_from_plugin (STPlugin *plugin){ STHandler *handler; g_return_val_if_fail(ST_IS_PLUGIN(plugin), NULL); handler = st_handler_new(st_plugin_get_name(plugin)); handler->priv->label = g_strdup(st_plugin_get_label(plugin)); handler->priv->pixbuf = st_plugin_get_pixbuf(plugin); if (handler->priv->pixbuf) g_object_ref(handler->priv->pixbuf); return handler;}static STCategory *st_handler_category_new_default_cb (gpointer data){ return g_new0(STCategory, 1);}static voidst_handler_category_free_default_cb (STCategory *category, gpointer data){ st_category_free(category);}static STStream *st_handler_stream_new_default_cb (gpointer data){ return g_new0(STStream, 1);}static voidst_handler_stream_free_default_cb (STStream *stream, gpointer data){ st_stream_free(stream);}/** * st_handler_set_label: * @handler: a handler. * @label: the handler label. * * Sets the handler label, which will be used in the handler tab, and * in various other places of the user interface. **/voidst_handler_set_label (STHandler *handler, const char *label){ g_return_if_fail(ST_IS_HANDLER(handler)); g_return_if_fail(label != NULL); g_free(handler->priv->label); handler->priv->label = g_strdup(label);}/** * st_handler_set_description: * @handler: a handler. * @description: the handler description. * * Sets the handler description, which will be displayed in the * toolbar when the handler is selected. **/voidst_handler_set_description (STHandler *handler, const char *description){ g_return_if_fail(ST_IS_HANDLER(handler)); g_return_if_fail(description != NULL); g_free(handler->priv->description); handler->priv->description = g_strdup(description);}/** * st_handler_set_home: * @handler: a handler. * @home: the handler home page URL. * * Sets the home page URL of the directory handled by * @handler. Setting the home page URL will allow the user to visit * the page by clicking on the toolbar link. **/voidst_handler_set_home (STHandler *handler, const char *home){ g_return_if_fail(ST_IS_HANDLER(handler)); g_return_if_fail(home != NULL); g_free(handler->priv->home); handler->priv->home = g_strdup(home);}/* * Deprecated */voidst_handler_set_copyright (STHandler *handler, const char *copyright){ g_return_if_fail(ST_IS_HANDLER(handler)); g_return_if_fail(copyright != NULL); /* nop */}/* * Deprecated */voidst_handler_set_info (STHandler *handler, const char *label, const char *copyright){ g_return_if_fail(ST_IS_HANDLER(handler)); g_return_if_fail(label != NULL); g_return_if_fail(copyright != NULL); st_handler_set_label(handler, label);}/** * st_handler_set_icon_from_pixbuf: * @handler: a handler. * @pixbuf: an icon. * * Sets the handler icon from a #GdkPixbuf. **/voidst_handler_set_icon_from_pixbuf (STHandler *handler, GdkPixbuf *pixbuf){ g_return_if_fail(ST_IS_HANDLER(handler)); g_return_if_fail(GDK_IS_PIXBUF(pixbuf)); if (handler->priv->pixbuf) g_object_unref(handler->priv->pixbuf); handler->priv->pixbuf = g_object_ref(pixbuf);}/** * st_handler_set_icon_from_inline: * @handler: a handler. * @size: the size of the inline data. * @data: the inline data. * * Sets the handler icon using inline data. See the * gdk_pixbuf_new_from_inline() documentation. **/voidst_handler_set_icon_from_inline (STHandler *handler, int size, const guint8 *data){ g_return_if_fail(ST_IS_HANDLER(handler)); g_return_if_fail(size > 0); g_return_if_fail(data != NULL); if (handler->priv->pixbuf) g_object_unref(handler->priv->pixbuf); handler->priv->pixbuf = gdk_pixbuf_new_from_inline(size, data, FALSE, NULL); g_return_if_fail(GDK_IS_PIXBUF(handler->priv->pixbuf));}/** * st_handler_set_icon_from_file: * @handler: a handler. * @filename: an icon file. * @err: a location to store errors, or %NULL. * * Sets the handler icon using an external file. See the * gdk_pixbuf_new_from_file() documentation. * * Return value: %FALSE if the file could not be loaded. In such case * @err will be set. **/gbooleanst_handler_set_icon_from_file (STHandler *handler, const char *filename, GError **err){ g_return_val_if_fail(ST_IS_HANDLER(handler), FALSE); g_return_val_if_fail(filename != NULL, FALSE); g_return_val_if_fail(handler->priv->pixbuf == NULL, FALSE); if (handler->priv->pixbuf) g_object_unref(handler->priv->pixbuf); handler->priv->pixbuf = gdk_pixbuf_new_from_file(filename, err); return handler->priv->pixbuf != NULL;}/* * Deprecated. */voidst_handler_set_icon (STHandler *handler, int size, const guint8 *data){ g_return_if_fail(ST_IS_HANDLER(handler));
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?