glib/gobject/gsourceclosure.c
changeset 18 47c74d1534e1
equal deleted inserted replaced
0:e4d67989cc36 18:47c74d1534e1
       
     1 /* GObject - GLib Type, Object, Parameter and Signal Library
       
     2  * Copyright (C) 2001 Red Hat, Inc.
       
     3  * Portions copyright (c) 2006-2009 Nokia Corporation.  All rights reserved.
       
     4  *
       
     5  * This library is free software; you can redistribute it and/or
       
     6  * modify it under the terms of the GNU Lesser General Public
       
     7  * License as published by the Free Software Foundation; either
       
     8  * version 2 of the License, or (at your option) any later version.
       
     9  *
       
    10  * This library is distributed in the hope that it will be useful,
       
    11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
       
    12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
       
    13  * Lesser General Public License for more details.
       
    14  *
       
    15  * You should have received a copy of the GNU Lesser General
       
    16  * Public License along with this library; if not, write to the
       
    17  * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
       
    18  * Boston, MA 02111-1307, USA.
       
    19  */
       
    20 
       
    21 #include "config.h"
       
    22 
       
    23 #include "gsourceclosure.h"
       
    24 #include "gboxed.h"
       
    25 #include "genums.h"
       
    26 #include "gmarshal.h"
       
    27 #include "gvalue.h"
       
    28 #include "gvaluetypes.h"
       
    29 #include "gobjectalias.h"
       
    30 
       
    31 #ifdef __SYMBIAN32__
       
    32 #include <glib_global.h>
       
    33 #include "gobject_wsd.h"
       
    34 #endif /* __SYMBIAN32__ */
       
    35 #if EMULATOR
       
    36 
       
    37 PLS(our_type ,g_io_channel_get_type ,GType)
       
    38 #define our_type  (*FUNCTION_NAME(our_type ,g_io_channel_get_type )())
       
    39 
       
    40 #endif /* EMULATOR */
       
    41 EXPORT_C GType
       
    42 g_io_channel_get_type (void)
       
    43 {
       
    44   #if !(EMULATOR)
       
    45   static GType our_type = 0;
       
    46   #endif /* EMULATOR */
       
    47   
       
    48   if (our_type == 0)
       
    49     our_type = g_boxed_type_register_static ("GIOChannel",
       
    50 					     (GBoxedCopyFunc) g_io_channel_ref,
       
    51 					     (GBoxedFreeFunc) g_io_channel_unref);
       
    52 
       
    53   return our_type;
       
    54 }
       
    55 
       
    56 #if EMULATOR
       
    57 #undef our_type 
       
    58 
       
    59 PLS(etype ,g_io_condition_get_type,GType)
       
    60 #define etype (*FUNCTION_NAME(etype,g_io_condition_get_type)())
       
    61 
       
    62 #endif /* EMULATOR */
       
    63 
       
    64 EXPORT_C GType
       
    65 g_io_condition_get_type (void)
       
    66 {
       
    67   #if !(EMULATOR)
       
    68   static GType etype = 0;
       
    69   #endif /* EMULATOR */
       
    70   if (etype == 0)
       
    71     {
       
    72       static const GFlagsValue values[] = {
       
    73 	{ G_IO_IN,   "G_IO_IN",   "in" },
       
    74 	{ G_IO_OUT,  "G_IO_OUT",  "out" },
       
    75 	{ G_IO_PRI,  "G_IO_PRI",  "pri" },
       
    76 	{ G_IO_ERR,  "G_IO_ERR",  "err" },
       
    77 	{ G_IO_HUP,  "G_IO_HUP",  "hup" },
       
    78 	{ G_IO_NVAL, "G_IO_NVAL", "nval" },
       
    79 	{ 0, NULL, NULL }
       
    80       };
       
    81       etype = g_flags_register_static ("GIOCondition", values);
       
    82     }
       
    83   return etype;
       
    84 }
       
    85 
       
    86 #if EMULATOR
       
    87 #undef etype 
       
    88 #endif /* EMULATOR */
       
    89 
       
    90 /* We need to hand-write this marshaler, since it doesn't have an
       
    91  * instance object.
       
    92  */
       
    93 static void
       
    94 source_closure_marshal_BOOLEAN__VOID (GClosure     *closure,
       
    95 				      GValue       *return_value,
       
    96 				      guint         n_param_values,
       
    97 				      const GValue *param_values,
       
    98 				      gpointer      invocation_hint,
       
    99 				      gpointer      marshal_data)
       
   100 {
       
   101   GSourceFunc callback;
       
   102   GCClosure *cc = (GCClosure*) closure;
       
   103   gboolean v_return;
       
   104 
       
   105   g_return_if_fail (return_value != NULL);
       
   106   g_return_if_fail (n_param_values == 0);
       
   107 
       
   108   callback = (GSourceFunc) (marshal_data ? marshal_data : cc->callback);
       
   109 
       
   110   v_return = callback (closure->data);
       
   111 
       
   112   g_value_set_boolean (return_value, v_return);
       
   113 }
       
   114 
       
   115 static gboolean
       
   116 io_watch_closure_callback (GIOChannel   *channel,
       
   117 			   GIOCondition  condition,
       
   118 			   gpointer      data)
       
   119 {
       
   120   GClosure *closure = data;
       
   121 
       
   122   GValue params[2] = { { 0, }, { 0, } };
       
   123   GValue result_value = { 0, };
       
   124   gboolean result;
       
   125 
       
   126   g_value_init (&result_value, G_TYPE_BOOLEAN);
       
   127   g_value_init (&params[0], G_TYPE_IO_CHANNEL);
       
   128   g_value_set_boxed (&params[0], channel);
       
   129 		     
       
   130   g_value_init (&params[1], G_TYPE_IO_CONDITION);
       
   131   g_value_set_flags (&params[1], condition);
       
   132 
       
   133   g_closure_invoke (closure, &result_value, 2, params, NULL);
       
   134 
       
   135   result = g_value_get_boolean (&result_value);
       
   136   g_value_unset (&result_value);
       
   137   g_value_unset (&params[0]);
       
   138   g_value_unset (&params[1]);
       
   139 
       
   140   return result;
       
   141 }
       
   142 
       
   143 static gboolean
       
   144 source_closure_callback (gpointer data)
       
   145 {
       
   146   GClosure *closure = data;
       
   147   GValue result_value = { 0, };
       
   148   gboolean result;
       
   149 
       
   150   g_value_init (&result_value, G_TYPE_BOOLEAN);
       
   151   
       
   152   g_closure_invoke (closure, &result_value, 0, NULL, NULL);
       
   153 
       
   154   result = g_value_get_boolean (&result_value);
       
   155   g_value_unset (&result_value);
       
   156 
       
   157   return result;
       
   158 }
       
   159 
       
   160 static void
       
   161 closure_callback_get (gpointer     cb_data,
       
   162 		      GSource     *source,
       
   163 		      GSourceFunc *func,
       
   164 		      gpointer    *data)
       
   165 {
       
   166   GSourceFunc closure_callback = source->source_funcs->closure_callback;
       
   167 
       
   168   if (!closure_callback)
       
   169     {
       
   170       if (source->source_funcs == &g_io_watch_funcs)
       
   171 	closure_callback = (GSourceFunc)io_watch_closure_callback;
       
   172       else if (source->source_funcs == &g_timeout_funcs ||
       
   173 	       source->source_funcs == &g_idle_funcs)
       
   174 	closure_callback = source_closure_callback;
       
   175     }
       
   176 
       
   177   *func = closure_callback;
       
   178   *data = cb_data;
       
   179 }
       
   180 
       
   181 #if EMULATOR
       
   182 
       
   183 PLS(closure_callback_funcs,gsourceclosure,GSourceCallbackFuncs)
       
   184 #define closure_callback_funcs (*FUNCTION_NAME(closure_callback_funcs,gsourceclosure)())
       
   185 
       
   186 const GSourceCallbackFuncs temp_closure_callback_funcs = {
       
   187   (void (*) (gpointer)) g_closure_ref,
       
   188   (void (*) (gpointer)) g_closure_unref,
       
   189   closure_callback_get
       
   190 };
       
   191 
       
   192 
       
   193 #else
       
   194 
       
   195 static GSourceCallbackFuncs closure_callback_funcs = {
       
   196   (void (*) (gpointer)) g_closure_ref,
       
   197   (void (*) (gpointer)) g_closure_unref,
       
   198   closure_callback_get
       
   199 };
       
   200 #endif /* EMULATOR */
       
   201 
       
   202 /**
       
   203  * g_source_set_closure:
       
   204  * @source: the source
       
   205  * @closure: a #GClosure
       
   206  *
       
   207  * Set the callback for a source as a #GClosure.
       
   208  *
       
   209  * If the source is not one of the standard GLib types, the @closure_callback
       
   210  * and @closure_marshal fields of the #GSourceFuncs structure must have been
       
   211  * filled in with pointers to appropriate functions.
       
   212  */
       
   213 EXPORT_C void
       
   214 g_source_set_closure (GSource  *source,
       
   215 		      GClosure *closure)
       
   216 {
       
   217   g_return_if_fail (source != NULL);
       
   218   g_return_if_fail (closure != NULL);
       
   219 
       
   220   if (!source->source_funcs->closure_callback &&
       
   221       source->source_funcs != &g_io_watch_funcs &&
       
   222       source->source_funcs != &g_timeout_funcs &&
       
   223       source->source_funcs != &g_idle_funcs)
       
   224     {
       
   225       g_critical (G_STRLOC "closure can not be set on closure without GSourceFuncs::closure_callback\n");
       
   226       return;
       
   227     }
       
   228 
       
   229   g_closure_ref (closure);
       
   230   g_closure_sink (closure);
       
   231   g_source_set_callback_indirect (source, closure, &closure_callback_funcs);
       
   232 
       
   233   if (G_CLOSURE_NEEDS_MARSHAL (closure))
       
   234     {
       
   235       GClosureMarshal marshal = (GClosureMarshal)source->source_funcs->closure_marshal;
       
   236       if (!marshal)
       
   237 	{
       
   238 	  if (source->source_funcs == &g_idle_funcs ||
       
   239 	      source->source_funcs == &g_timeout_funcs)
       
   240 	    marshal = source_closure_marshal_BOOLEAN__VOID;
       
   241 	  else if (source->source_funcs == &g_io_watch_funcs)
       
   242 	    marshal = g_cclosure_marshal_BOOLEAN__FLAGS;
       
   243 	}
       
   244       if (marshal)
       
   245 	g_closure_set_marshal (closure, marshal);
       
   246     }
       
   247 }
       
   248 
       
   249 #define __G_SOURCECLOSURE_C__
       
   250 #include "gobjectaliasdef.c"