glib/libgobject/src/gsourceclosure.c
changeset 0 e4d67989cc36
equal deleted inserted replaced
-1:000000000000 0:e4d67989cc36
       
     1 /* GObject - GLib Type, Object, Parameter and Signal Library
       
     2  * Copyright (C) 2001 Red Hat, Inc.
       
     3  * Portions copyright (c) 2006 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 "gsourceclosure.h"
       
    22 #include "gboxed.h"
       
    23 #include "genums.h"
       
    24 #include "gmarshal.h"
       
    25 #include "gvalue.h"
       
    26 #include "gvaluetypes.h"
       
    27 #include "gobjectalias.h"
       
    28 
       
    29 #ifdef __SYMBIAN32__
       
    30 #include <glib_global.h>
       
    31 #include <gobject_wsd.h>
       
    32 #endif /* __SYMBIAN32__ */
       
    33 #if EMULATOR
       
    34 
       
    35 PLS(our_type ,g_io_channel_get_type ,GType)
       
    36 #define our_type  (*FUNCTION_NAME(our_type ,g_io_channel_get_type )())
       
    37 
       
    38 #endif /* EMULATOR */
       
    39 EXPORT_C GType
       
    40 g_io_channel_get_type (void)
       
    41 {
       
    42   #if !(EMULATOR)
       
    43   static GType our_type = 0;
       
    44   #endif /* EMULATOR */
       
    45   
       
    46   if (our_type == 0)
       
    47     our_type = g_boxed_type_register_static ("GIOChannel",
       
    48 					     (GBoxedCopyFunc) g_io_channel_ref,
       
    49 					     (GBoxedFreeFunc) g_io_channel_unref);
       
    50 
       
    51   return our_type;
       
    52 }
       
    53 
       
    54 #if EMULATOR
       
    55 #undef our_type 
       
    56 
       
    57 PLS(etype ,g_io_condition_get_type,GType)
       
    58 #define etype (*FUNCTION_NAME(etype,g_io_condition_get_type)())
       
    59 
       
    60 #endif /* EMULATOR */
       
    61 
       
    62 EXPORT_C GType
       
    63 g_io_condition_get_type (void)
       
    64 {
       
    65   #if !(EMULATOR)
       
    66   static GType etype = 0;
       
    67   #endif /* EMULATOR */
       
    68   if (etype == 0)
       
    69     {
       
    70       static const GFlagsValue values[] = {
       
    71 	{ G_IO_IN,   "G_IO_IN",   "in" },
       
    72 	{ G_IO_OUT,  "G_IO_OUT",  "out" },
       
    73 	{ G_IO_PRI,  "G_IO_PRI",  "pri" },
       
    74 	{ G_IO_ERR,  "G_IO_ERR",  "err" },
       
    75 	{ G_IO_HUP,  "G_IO_HUP",  "hup" },
       
    76 	{ G_IO_NVAL, "G_IO_NVAL", "nval" },
       
    77 	{ 0, NULL, NULL }
       
    78       };
       
    79       etype = g_flags_register_static ("GIOCondition", values);
       
    80     }
       
    81   return etype;
       
    82 }
       
    83 
       
    84 #if EMULATOR
       
    85 #undef etype 
       
    86 #endif /* EMULATOR */
       
    87 
       
    88 /* We need to hand-write this marshaler, since it doesn't have an
       
    89  * instance object.
       
    90  */
       
    91 static void
       
    92 source_closure_marshal_BOOLEAN__VOID (GClosure     *closure,
       
    93 				      GValue       *return_value,
       
    94 				      guint         n_param_values,
       
    95 				      const GValue *param_values,
       
    96 				      gpointer      invocation_hint,
       
    97 				      gpointer      marshal_data)
       
    98 {
       
    99   GSourceFunc callback;
       
   100   GCClosure *cc = (GCClosure*) closure;
       
   101   gboolean v_return;
       
   102 
       
   103   g_return_if_fail (return_value != NULL);
       
   104   g_return_if_fail (n_param_values == 0);
       
   105 
       
   106   callback = (GSourceFunc) (marshal_data ? marshal_data : cc->callback);
       
   107 
       
   108   v_return = callback (closure->data);
       
   109 
       
   110   g_value_set_boolean (return_value, v_return);
       
   111 }
       
   112 
       
   113 static gboolean
       
   114 io_watch_closure_callback (GIOChannel   *channel,
       
   115 			   GIOCondition  condition,
       
   116 			   gpointer      data)
       
   117 {
       
   118   GClosure *closure = data;
       
   119 
       
   120   GValue params[2] = { { 0, }, { 0, } };
       
   121   GValue result_value = { 0, };
       
   122   gboolean result;
       
   123 
       
   124   g_value_init (&result_value, G_TYPE_BOOLEAN);
       
   125   g_value_init (&params[0], G_TYPE_IO_CHANNEL);
       
   126   g_value_set_boxed (&params[0], channel);
       
   127 		     
       
   128   g_value_init (&params[1], G_TYPE_IO_CONDITION);
       
   129   g_value_set_flags (&params[1], condition);
       
   130 
       
   131   g_closure_invoke (closure, &result_value, 2, params, NULL);
       
   132 
       
   133   result = g_value_get_boolean (&result_value);
       
   134   g_value_unset (&result_value);
       
   135   g_value_unset (&params[0]);
       
   136   g_value_unset (&params[1]);
       
   137 
       
   138   return result;
       
   139 }
       
   140 
       
   141 static gboolean
       
   142 source_closure_callback (gpointer data)
       
   143 {
       
   144   GClosure *closure = data;
       
   145   GValue result_value = { 0, };
       
   146   gboolean result;
       
   147 
       
   148   g_value_init (&result_value, G_TYPE_BOOLEAN);
       
   149   
       
   150   g_closure_invoke (closure, &result_value, 0, NULL, NULL);
       
   151 
       
   152   result = g_value_get_boolean (&result_value);
       
   153   g_value_unset (&result_value);
       
   154 
       
   155   return result;
       
   156 }
       
   157 
       
   158 static void
       
   159 closure_callback_get (gpointer     cb_data,
       
   160 		      GSource     *source,
       
   161 		      GSourceFunc *func,
       
   162 		      gpointer    *data)
       
   163 {
       
   164   GSourceFunc closure_callback = source->source_funcs->closure_callback;
       
   165 
       
   166   if (!closure_callback)
       
   167     {
       
   168       if (source->source_funcs == &g_io_watch_funcs)
       
   169 	closure_callback = (GSourceFunc)io_watch_closure_callback;
       
   170       else if (source->source_funcs == &g_timeout_funcs ||
       
   171 	       source->source_funcs == &g_idle_funcs)
       
   172 	closure_callback = source_closure_callback;
       
   173     }
       
   174 
       
   175   *func = closure_callback;
       
   176   *data = cb_data;
       
   177 }
       
   178 
       
   179 #if EMULATOR
       
   180 
       
   181 PLS(closure_callback_funcs,gsourceclosure,GSourceCallbackFuncs)
       
   182 #define closure_callback_funcs (*FUNCTION_NAME(closure_callback_funcs,gsourceclosure)())
       
   183 
       
   184 const GSourceCallbackFuncs temp_closure_callback_funcs = {
       
   185   (void (*) (gpointer)) g_closure_ref,
       
   186   (void (*) (gpointer)) g_closure_unref,
       
   187   closure_callback_get
       
   188 };
       
   189 
       
   190 
       
   191 #else
       
   192 
       
   193 static GSourceCallbackFuncs closure_callback_funcs = {
       
   194   (void (*) (gpointer)) g_closure_ref,
       
   195   (void (*) (gpointer)) g_closure_unref,
       
   196   closure_callback_get
       
   197 };
       
   198 
       
   199 #endif /* EMULATOR */
       
   200 
       
   201 EXPORT_C void
       
   202 g_source_set_closure (GSource  *source,
       
   203 		      GClosure *closure)
       
   204 {
       
   205   g_return_if_fail (source != NULL);
       
   206   g_return_if_fail (closure != NULL);
       
   207 
       
   208   if (!source->source_funcs->closure_callback &&
       
   209       source->source_funcs != &g_io_watch_funcs &&
       
   210       source->source_funcs != &g_timeout_funcs &&
       
   211       source->source_funcs != &g_idle_funcs)
       
   212     {
       
   213       g_critical (G_STRLOC "closure can not be set on closure without GSourceFuncs::closure_callback\n");
       
   214       return;
       
   215     }
       
   216 
       
   217   g_closure_ref (closure);
       
   218   g_closure_sink (closure);
       
   219   g_source_set_callback_indirect (source, closure, &closure_callback_funcs);
       
   220 
       
   221   if (G_CLOSURE_NEEDS_MARSHAL (closure))
       
   222     {
       
   223       GClosureMarshal marshal = (GClosureMarshal)source->source_funcs->closure_marshal;
       
   224       if (!marshal)
       
   225 	{
       
   226 	  if (source->source_funcs == &g_idle_funcs ||
       
   227 	      source->source_funcs == &g_timeout_funcs)
       
   228 	    marshal = source_closure_marshal_BOOLEAN__VOID;
       
   229 	  else if (source->source_funcs == &g_io_watch_funcs)
       
   230 	    marshal = g_cclosure_marshal_BOOLEAN__FLAGS;
       
   231 	}
       
   232       if (marshal)
       
   233 	g_closure_set_marshal (closure, marshal);
       
   234     }
       
   235 }
       
   236 
       
   237 #define __G_SOURCECLOSURE_C__
       
   238 #include "gobjectaliasdef.c"