epoc32/include/stdapis/glib-2.0/gobject/gobjectnotifyqueue.c
branchSymbian2
changeset 2 2fe1408b6811
parent 0 061f57f2323e
     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__ */