⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 fen-helper.c

📁 this is a glib for c language
💻 C
字号:
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- *//* vim:set expandtab ts=4 shiftwidth=4: *//*  * Copyright (C) 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General * Public License along with this library; if not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307, USA. * * Authors: Lin Ma <lin.ma@sun.com> */#include "config.h"#include <glib.h>#include "fen-data.h"#include "fen-helper.h"#include "fen-kernel.h"#ifdef GIO_COMPILATION#include "gfilemonitor.h"#else#include "gam_event.h"#include "gam_server.h"#include "gam_protocol.h"#endif#ifdef GIO_COMPILATION#define FH_W if (fh_debug_enabled) g_warningstatic gboolean fh_debug_enabled = FALSE;#else#include "gam_error.h"#define FH_W(...) GAM_DEBUG(DEBUG_INFO, __VA_ARGS__)#endifG_LOCK_EXTERN (fen_lock);static void default_emit_event_cb (fdata *f, int events);static void default_emit_once_event_cb (fdata *f, int events, gpointer sub);static int default_event_converter (int event);static voidscan_children_init (node_t *f, gpointer sub){	GDir *dir;	GError *err = NULL;    node_op_t op = {NULL, NULL, pre_del_cb, NULL};    fdata* pdata;        FH_W ("%s %s [0x%p]\n", __func__, NODE_NAME(f), f);    pdata = node_get_data (f);    dir = g_dir_open (NODE_NAME(f), 0, &err);    if (dir) {        const char *basename;                while ((basename = g_dir_read_name (dir)))        {            node_t *childf = NULL;            fdata* data;            GList *idx;            childf = children_find (f, basename);            if (childf == NULL) {                gchar *filename;                            filename = g_build_filename (NODE_NAME(f), basename, NULL);                childf = add_node (f, filename);                g_assert (childf);                g_free (filename);            }            if ((data = node_get_data (childf)) == NULL) {                data = fdata_new (childf, FALSE);            }                        if (is_monitoring (data)) {                /* Ignored */            } else if (/* !is_ported (data) && */                port_add (&data->fobj, &data->len, data)) {                /* Emit created to all other subs */                fdata_emit_events (data, FN_EVENT_CREATED);            }            /* Emit created to the new sub */#ifdef GIO_COMPILATION            /* fdata_emit_events_once (data, FN_EVENT_CREATED, sub); */#else            gam_server_emit_one_event (NODE_NAME(childf),              gam_subscription_is_dir (sub), GAMIN_EVENT_EXISTS, sub, 1);#endif        }        g_dir_close (dir);    } else {        FH_W (err->message);        g_error_free (err);    }}/** * fen_add *  * Won't hold a ref, we have a timout callback to clean unused fdata. * If there is no value for a key, add it and return it; else return the old * one. */voidfen_add (const gchar *filename, gpointer sub, gboolean is_mondir){    node_op_t op = {NULL, add_missing_cb, pre_del_cb, (gpointer)filename};	node_t* f;    fdata* data;        g_assert (filename);    g_assert (sub);    G_LOCK (fen_lock);	f = find_node_full (filename, &op);    FH_W ("[ %s ] f[0x%p] sub[0x%p] %s\n", __func__, f, sub, filename);    g_assert (f);    data = node_get_data (f);    if (data == NULL) {        data = fdata_new (f, is_mondir);    }    if (is_mondir) {        data->mon_dir_num ++;    }        /* Change to active */#ifdef GIO_COMPILATION    if (port_add (&data->fobj, &data->len, data) ||      g_file_test (FN_NAME(data), G_FILE_TEST_EXISTS)) {        if (is_mondir) {            scan_children_init (f, sub);        }        fdata_sub_add (data, sub);    } else {        fdata_sub_add (data, sub);        fdata_adjust_deleted (data);    }#else    if (port_add (&data->fobj, &data->len, data) ||      g_file_test (FN_NAME(data), G_FILE_TEST_EXISTS)) {        gam_server_emit_one_event (FN_NAME(data),          gam_subscription_is_dir (sub), GAMIN_EVENT_EXISTS, sub, 1);        if (is_mondir) {            scan_children_init (f, sub);        }        gam_server_emit_one_event (FN_NAME(data),          gam_subscription_is_dir (sub), GAMIN_EVENT_ENDEXISTS, sub, 1);        fdata_sub_add (data, sub);    } else {        fdata_sub_add (data, sub);        gam_server_emit_one_event (FN_NAME(data),          gam_subscription_is_dir (sub), GAMIN_EVENT_DELETED, sub, 1);        fdata_adjust_deleted (data);        gam_server_emit_one_event (FN_NAME(data),          gam_subscription_is_dir (sub), GAMIN_EVENT_ENDEXISTS, sub, 1);    }#endif    G_UNLOCK (fen_lock);}voidfen_remove (const gchar *filename, gpointer sub, gboolean is_mondir){    node_op_t op = {NULL, add_missing_cb, pre_del_cb, (gpointer)filename};    node_t* f;    fdata* data;        g_assert (filename);    g_assert (sub);    G_LOCK (fen_lock);	f = find_node (filename);    FH_W ("[ %s ] f[0x%p] sub[0x%p] %s\n", __func__, f, sub, filename);    g_assert (f);    data = node_get_data (f);    g_assert (data);        if (is_mondir) {        data->mon_dir_num --;    }    fdata_sub_remove (data, sub);    if (FN_IS_PASSIVE(data)) {#ifdef GIO_COMPILATION        pending_remove_node (f, &op);#else        remove_node (f, &op);#endif    }    G_UNLOCK (fen_lock);}static gbooleanfen_init_once_func (gpointer data){    FH_W ("%s\n", __func__);    if (!node_class_init ()) {        FH_W ("node_class_init failed.");        return FALSE;    }    if (!fdata_class_init (default_emit_event_cb,          default_emit_once_event_cb,          default_event_converter)) {        FH_W ("fdata_class_init failed.");        return FALSE;    }    return TRUE;}gbooleanfen_init (){#ifdef GIO_COMPILATION    static GOnce fen_init_once = G_ONCE_INIT;    g_once (&fen_init_once, (GThreadFunc)fen_init_once_func, NULL);    return (gboolean)fen_init_once.retval;#else    return fen_init_once_func (NULL);#endif}static voiddefault_emit_once_event_cb (fdata *f, int events, gpointer sub){#ifdef GIO_COMPILATION    GFile* child;    fen_sub* _sub = (fen_sub*)sub;    child = g_file_new_for_path (FN_NAME(f));    g_file_monitor_emit_event (G_FILE_MONITOR (_sub->user_data),      child, NULL, events);    g_object_unref (child);#else    gam_server_emit_one_event (FN_NAME(f),      gam_subscription_is_dir (sub), events, sub, 1);#endif}static voiddefault_emit_event_cb (fdata *f, int events){    GList* i;    fdata* pdata;    #ifdef GIO_COMPILATION    GFile* child;    child = g_file_new_for_path (FN_NAME(f));    for (i = f->subs; i; i = i->next) {        fen_sub* sub = (fen_sub*)i->data;        gboolean file_is_dir = sub->is_mondir;        if ((events != G_FILE_MONITOR_EVENT_CHANGED &&              events != G_FILE_MONITOR_EVENT_ATTRIBUTE_CHANGED) ||          !file_is_dir) {            g_file_monitor_emit_event (G_FILE_MONITOR (sub->user_data),              child, NULL, events);        }    }    if ((pdata = get_parent_data (f)) != NULL) {        for (i = pdata->subs; i; i = i->next) {            fen_sub* sub = (fen_sub*)i->data;            gboolean file_is_dir = sub->is_mondir;            g_file_monitor_emit_event (G_FILE_MONITOR (sub->user_data),              child, NULL, events);        }    }    g_object_unref (child);#else    for (i = f->subs; i; i = i->next) {        gboolean file_is_dir = gam_subscription_is_dir (i->data);        if (events != GAMIN_EVENT_CHANGED || !file_is_dir) {            gam_server_emit_one_event (FN_NAME(f), file_is_dir, events, i->data, 1);        }    }    if ((pdata = get_parent_data (f)) != NULL) {        for (i = pdata->subs; i; i = i->next) {            gboolean file_is_dir = gam_subscription_is_dir (i->data);            gam_server_emit_one_event (FN_NAME(f), file_is_dir, events, i->data, 1);        }    }#endif}static intdefault_event_converter (int event){#ifdef GIO_COMPILATION    switch (event) {    case FN_EVENT_CREATED:        return G_FILE_MONITOR_EVENT_CREATED;    case FILE_DELETE:    case FILE_RENAME_FROM:        return G_FILE_MONITOR_EVENT_DELETED;    case UNMOUNTED:        return G_FILE_MONITOR_EVENT_UNMOUNTED;    case FILE_ATTRIB:        return G_FILE_MONITOR_EVENT_ATTRIBUTE_CHANGED;    case MOUNTEDOVER:    case FILE_MODIFIED:    case FILE_RENAME_TO:        return G_FILE_MONITOR_EVENT_CHANGED;    default:        /* case FILE_ACCESS: */        g_assert_not_reached ();        return -1;    }#else    switch (event) {    case FN_EVENT_CREATED:        return GAMIN_EVENT_CREATED;    case FILE_DELETE:    case FILE_RENAME_FROM:        return GAMIN_EVENT_DELETED;    case FILE_ATTRIB:    case MOUNTEDOVER:    case UNMOUNTED:    case FILE_MODIFIED:    case FILE_RENAME_TO:        return GAMIN_EVENT_CHANGED;    default:        /* case FILE_ACCESS: */        g_assert_not_reached ();        return -1;    }#endif}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -