1.1 --- a/epoc32/include/stdapis/glib-2.0/gobject/gobjectnotifyqueue.c Tue Nov 24 13:55:44 2009 +0000
1.2 +++ b/epoc32/include/stdapis/glib-2.0/gobject/gobjectnotifyqueue.c Tue Mar 16 16:12:26 2010 +0000
1.3 @@ -1,1 +1,170 @@
1.4 -gobjectnotifyqueue.c
1.5 +/* GObject - GLib Type, Object, Parameter and Signal Library
1.6 + * Copyright (C) 1998-1999, 2000-2001 Tim Janik and Red Hat, Inc.
1.7 + * Portions copyright (c) 2006 Nokia Corporation. All rights reserved.
1.8 + *
1.9 + * This library is free software; you can redistribute it and/or
1.10 + * modify it under the terms of the GNU Lesser General Public
1.11 + * License as published by the Free Software Foundation; either
1.12 + * version 2 of the License, or (at your option) any later version.
1.13 + *
1.14 + * This library is distributed in the hope that it will be useful,
1.15 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
1.16 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
1.17 + * Lesser General Public License for more details.
1.18 + *
1.19 + * You should have received a copy of the GNU Lesser General
1.20 + * Public License along with this library; if not, write to the
1.21 + * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
1.22 + * Boston, MA 02111-1307, USA.
1.23 + */
1.24 +#ifndef __G_NOTIFY_H__
1.25 +#define __G_NOTIFY_H__
1.26 +
1.27 +#include <string.h> /* memset */
1.28 +#include <glib-object.h>
1.29 +
1.30 +G_BEGIN_DECLS
1.31 +
1.32 +
1.33 +/* --- typedefs --- */
1.34 +#if !(EMULATOR)
1.35 +typedef struct _GObjectNotifyContext GObjectNotifyContext;
1.36 +typedef void (*GObjectNotifyQueueDispatcher) (GObject *object,
1.37 + guint n_pspecs,
1.38 + GParamSpec **pspecs);
1.39 +#endif /* EMULATOR */
1.40 +
1.41 +typedef struct _GObjectNotifyQueue GObjectNotifyQueue;
1.42 +
1.43 +/* --- structures --- */
1.44 +#if !(EMULATOR)
1.45 +struct _GObjectNotifyContext
1.46 +{
1.47 + GQuark quark_notify_queue;
1.48 + GObjectNotifyQueueDispatcher dispatcher;
1.49 + GTrashStack *_nqueue_trash; /* unused */
1.50 +};
1.51 +#endif /* EMULATOR */
1.52 +struct _GObjectNotifyQueue
1.53 +{
1.54 + GObjectNotifyContext *context;
1.55 + GSList *pspecs;
1.56 + guint16 n_pspecs;
1.57 + guint16 freeze_count;
1.58 + /* currently, this structure abuses the GList allocation chain and thus
1.59 + * must be <= sizeof (GList)
1.60 + */
1.61 +};
1.62 +
1.63 +/* --- functions --- */
1.64 +static void
1.65 +g_object_notify_queue_free (gpointer data)
1.66 +{
1.67 + GObjectNotifyQueue *nqueue = data;
1.68 +
1.69 + g_slist_free (nqueue->pspecs);
1.70 + g_list_free_1 ((void*) nqueue);
1.71 +}
1.72 +
1.73 +static inline GObjectNotifyQueue*
1.74 +g_object_notify_queue_freeze (GObject *object,
1.75 + GObjectNotifyContext *context)
1.76 +{
1.77 + GObjectNotifyQueue *nqueue;
1.78 +
1.79 + nqueue = g_datalist_id_get_data (&object->qdata, context->quark_notify_queue);
1.80 + if (!nqueue)
1.81 + {
1.82 + nqueue = (void*) g_list_alloc ();
1.83 + memset (nqueue, 0, sizeof (*nqueue));
1.84 + nqueue->context = context;
1.85 + g_datalist_id_set_data_full (&object->qdata, context->quark_notify_queue,
1.86 + nqueue, g_object_notify_queue_free);
1.87 + }
1.88 +
1.89 + g_return_val_if_fail (nqueue->freeze_count < 65535, nqueue);
1.90 + nqueue->freeze_count++;
1.91 +
1.92 + return nqueue;
1.93 +}
1.94 +
1.95 +static inline void
1.96 +g_object_notify_queue_thaw (GObject *object,
1.97 + GObjectNotifyQueue *nqueue)
1.98 +{
1.99 + GObjectNotifyContext *context = nqueue->context;
1.100 + GParamSpec *pspecs_mem[16], **pspecs, **free_me = NULL;
1.101 + GSList *slist;
1.102 + guint n_pspecs = 0;
1.103 +
1.104 + g_return_if_fail (nqueue->freeze_count > 0);
1.105 +
1.106 + nqueue->freeze_count--;
1.107 + if (nqueue->freeze_count)
1.108 + return;
1.109 + g_return_if_fail (object->ref_count > 0);
1.110 + pspecs = nqueue->n_pspecs > 16 ? free_me = g_new (GParamSpec*, nqueue->n_pspecs) : pspecs_mem;
1.111 + /* set first entry to NULL since it's checked unconditionally */
1.112 + pspecs[0] = NULL;
1.113 + for (slist = nqueue->pspecs; slist; slist = slist->next)
1.114 + {
1.115 + GParamSpec *pspec = slist->data;
1.116 + guint i = 0;
1.117 +
1.118 + /* dedup, make pspecs in the list unique */
1.119 + redo_dedup_check:
1.120 + if (pspecs[i] == pspec)
1.121 + continue;
1.122 + if (++i < n_pspecs)
1.123 + goto redo_dedup_check;
1.124 +
1.125 + pspecs[n_pspecs++] = pspec;
1.126 + }
1.127 + g_datalist_id_set_data (&object->qdata, context->quark_notify_queue, NULL);
1.128 +
1.129 + if (n_pspecs)
1.130 + context->dispatcher (object, n_pspecs, pspecs);
1.131 + g_free (free_me);
1.132 +}
1.133 +
1.134 +static inline void
1.135 +g_object_notify_queue_clear (GObject *object,
1.136 + GObjectNotifyQueue *nqueue)
1.137 +{
1.138 + g_return_if_fail (nqueue->freeze_count > 0);
1.139 +
1.140 + g_slist_free (nqueue->pspecs);
1.141 + nqueue->pspecs = NULL;
1.142 + nqueue->n_pspecs = 0;
1.143 +}
1.144 +
1.145 +static inline void
1.146 +g_object_notify_queue_add (GObject *object,
1.147 + GObjectNotifyQueue *nqueue,
1.148 + GParamSpec *pspec)
1.149 +{
1.150 + if (pspec->flags & G_PARAM_READABLE)
1.151 + {
1.152 + GParamSpec *redirect;
1.153 +
1.154 + g_return_if_fail (nqueue->n_pspecs < 65535);
1.155 +
1.156 + redirect = g_param_spec_get_redirect_target (pspec);
1.157 + if (redirect)
1.158 + pspec = redirect;
1.159 +
1.160 + /* we do the deduping in _thaw */
1.161 + nqueue->pspecs = g_slist_prepend (nqueue->pspecs, pspec);
1.162 + nqueue->n_pspecs++;
1.163 + }
1.164 +}
1.165 +
1.166 +static inline GObjectNotifyQueue*
1.167 +g_object_notify_queue_from_object (GObject *object,
1.168 + GObjectNotifyContext *context)
1.169 +{
1.170 + return g_datalist_id_get_data (&object->qdata, context->quark_notify_queue);
1.171 +}
1.172 +G_END_DECLS
1.173 +
1.174 +#endif /* __G_NOTIFY_H__ */