Exemplo n.º 1
0
Arquivo: Value.cs Projeto: shana/moon
		//
		// How do we support "null" values, should the caller take care of that?
		//
		// The caller is responsible for calling value_free_value on the returned Value
		public static Value FromObject (object v, bool box_value_types)
		{
			Value value = new Value ();
			
			unsafe {
				// get rid of this case right away.
				if (box_value_types && v.GetType().IsValueType) {
					//Console.WriteLine ("Boxing a value of type {0}:", v.GetType());

					GCHandle handle = GCHandle.Alloc (v);
					value.k = Deployment.Current.Types.TypeToKind (v.GetType ());
					value.IsGCHandle = true;
					value.u.p = GCHandle.ToIntPtr (handle);
					return value;
				}

				if (v is IEasingFunction && !(v is EasingFunctionBase))
					v = new EasingFunctionWrapper (v as IEasingFunction);

				if (v is INativeEventObjectWrapper) {
					INativeEventObjectWrapper dov = (INativeEventObjectWrapper) v;

					if (dov.NativeHandle == IntPtr.Zero)
						throw new Exception (String.Format (
							"Object {0} has not set its native property", dov.GetType()));

					NativeMethods.event_object_ref (dov.NativeHandle);

					value.k = dov.GetKind ();
					value.u.p = dov.NativeHandle;

				} else if (v is DependencyProperty) {
					value.k = Kind.DEPENDENCYPROPERTY;
					value.u.p = ((DependencyProperty)v).Native;
				}
				else if (v is int || (v.GetType ().IsEnum && Enum.GetUnderlyingType (v.GetType()) == typeof(int))) {
					value.k = Deployment.Current.Types.TypeToKind (v.GetType ());
					value.u.i32 = (int) v;
				}
				else if (v is bool) {
					value.k = Kind.BOOL;
					value.u.i32 = ((bool) v) ? 1 : 0;
				}
				else if (v is double) {
					value.k = Kind.DOUBLE;
					value.u.d = (double) v;
				}
				else if (v is float) {
					value.k = Kind.FLOAT;
					value.u.f = (float) v;
				}
				else if (v is long) {
					value.k = Kind.INT64;
					value.u.i64 = (long) v;
				}
				else if (v is TimeSpan) {
					TimeSpan ts = (TimeSpan) v;
					value.k = Kind.TIMESPAN;
					value.u.i64 = ts.Ticks;
				}
				else if (v is ulong) {
					value.k = Kind.UINT64;
					value.u.ui64 = (ulong) v;
				}
				else if (v is uint) {
					value.k = Kind.UINT32;
					value.u.ui32 = (uint) v;
				}
				else if (v is char) {
					value.k = Kind.CHAR;
					value.u.ui32 = (uint) (char) v;
				}
				else if (v is string) {
					value.k = Kind.STRING;

					value.u.p = StringToIntPtr ((string) v);
				}
				else if (v is Rect) {
					Rect rect = (Rect) v;
					value.k = Kind.RECT;
					value.u.p = Marshal.AllocHGlobal (sizeof (Rect));
					Marshal.StructureToPtr (rect, value.u.p, false); // Unmanaged and managed structure layout is equal.
				}
				else if (v is Size) {
					Size size = (Size) v;
					value.k = Kind.SIZE;
					value.u.p = Marshal.AllocHGlobal (sizeof (Size));
					Marshal.StructureToPtr (size, value.u.p, false); // Unmanaged and managed structure layout is equal.
				}
				else if (v is CornerRadius) {
					CornerRadius corner = (CornerRadius) v;
					value.k = Kind.CORNERRADIUS;
					value.u.p = Marshal.AllocHGlobal (sizeof (CornerRadius));
					Marshal.StructureToPtr (corner, value.u.p, false); // Unmanaged and managed structure layout is equal.
				}
				else if (v is AudioFormat) {
					AudioFormat f = (AudioFormat) v;
					value.k = Kind.AUDIOFORMAT;
					value.u.p = Marshal.AllocHGlobal (sizeof (UnmanagedAudioFormat));
					UnmanagedAudioFormat *format = (UnmanagedAudioFormat*) value.u.p;
					format->bitsPerSample = f.BitsPerSample;
					format->channels = f.Channels;
					format->samplesPerSecond = f.SamplesPerSecond;
					format->waveFormat = f.WaveFormat;
				}
				else if (v is VideoFormat) {
					VideoFormat f = (VideoFormat) v;
					value.k = Kind.VIDEOFORMAT;
					value.u.p = Marshal.AllocHGlobal (sizeof (UnmanagedVideoFormat));
					UnmanagedVideoFormat *format = (UnmanagedVideoFormat*) value.u.p;
					format->framesPerSecond = f.FramesPerSecond;
					format->height = f.PixelHeight;
					format->width = f.PixelWidth;
					format->stride = f.Stride;
					format->pixelFormat = f.PixelFormat;
				}
				else if (v is Point) {
					Point pnt = (Point) v;
					value.k = Kind.POINT;
					value.u.p = Marshal.AllocHGlobal (sizeof (Point));
					Marshal.StructureToPtr (pnt, value.u.p, false); // Unmanaged and managed structure layout is equal.
				}
				else if (v is Thickness) {
					Thickness thickness = (Thickness)v;
					value.k = Kind.THICKNESS;
					value.u.p = Marshal.AllocHGlobal (sizeof (Thickness));
					Marshal.StructureToPtr (thickness, value.u.p, false); // Unmanaged and managed structure layout is equal.
				}
				else if (v is Color) {
					Color c = (Color) v;
					value.k = Kind.COLOR;
					value.u.p = Marshal.AllocHGlobal (sizeof (UnmanagedColor));
					UnmanagedColor* color = (UnmanagedColor*) value.u.p;
					color->r = c.R / 255.0f;
					color->g = c.G / 255.0f;
					color->b = c.B / 255.0f;
					color->a = c.A / 255.0f;
				}
				else if (v is Matrix) {
					// hack around the fact that managed Matrix is a struct while unmanaged Matrix is a DO
					// i.e. the unmanaged and managed structure layouts ARE NOT equal
					return FromObject (new UnmanagedMatrix ((Matrix) v), box_value_types);
				}
				else if (v is StylusPoint) {
					return FromObject (new UnmanagedStylusPoint ((StylusPoint) v), box_value_types);
				}
				else if (v is Matrix3D) {
					// hack around the fact that managed Matrix3D is a struct while unmanaged Matrix3D is a DO
					// i.e. the unmanaged and managed structure layouts ARE NOT equal
					return FromObject (new UnmanagedMatrix3D ((Matrix3D) v), box_value_types);
				}
				else if (v is Duration) {
					Duration d = (Duration) v;
					value.k = Kind.DURATION;
					value.u.p = Marshal.AllocHGlobal (sizeof (Duration));
					Marshal.StructureToPtr (d, value.u.p, false); // Unmanaged and managed structure layout is equal.
				}
				else if (v is KeyTime) {
					KeyTime k = (KeyTime) v;
					value.k = Kind.KEYTIME;
					value.u.p = Marshal.AllocHGlobal (sizeof (KeyTime));
					Marshal.StructureToPtr (k, value.u.p, false); // Unmanaged and managed structure layout is equal.
				}
				else if (v is RepeatBehavior) {
					RepeatBehavior d = (RepeatBehavior) v;
					value.k = Kind.REPEATBEHAVIOR;
					value.u.p = Marshal.AllocHGlobal (sizeof (RepeatBehavior));
					Marshal.StructureToPtr (d, value.u.p, false); // Unmanaged and managed structure layout is equal.
				}
				else if (v is FontFamily) {
					FontFamily family = (FontFamily) v;
					value.k = Kind.FONTFAMILY;
					value.u.p = Marshal.AllocHGlobal (sizeof (UnmanagedFontFamily));
					Marshal.StructureToPtr (family, value.u.p, false); // Unmanaged and managed structure layout is equal.
				}

				else if (v is FontSource) {
					FontSource source = (FontSource) v;
					
					value.k = Kind.FONTSOURCE;
					
					if (source.wrapper != null || source.typeface != null) {
						value.u.p = Marshal.AllocHGlobal (sizeof (UnmanagedFontSource));
						UnmanagedFontSource *ufs = (UnmanagedFontSource *) value.u.p;
						ufs->type = source.type;
						
						switch (source.type) {
						case FontSourceType.ManagedStream:
							ManagedStreamCallbacks callbacks = source.wrapper.GetCallbacks ();
							ufs->source.stream = Marshal.AllocHGlobal (sizeof (UnmanagedStreamCallbacks));
							Marshal.StructureToPtr (callbacks, ufs->source.stream, false);
							break;
						case FontSourceType.GlyphTypeface:
							ufs->source.typeface = source.typeface.Native;
							break;
						}
					} else {
						value.IsNull = true;
					}
				}

				else if (v is PropertyPath) {
					PropertyPath propertypath = (PropertyPath) v;
					value.k = Kind.PROPERTYPATH;
					value.u.p = Marshal.AllocHGlobal (sizeof (UnmanagedPropertyPath));

					UnmanagedPropertyPath *upp = (UnmanagedPropertyPath *) value.u.p;
					upp->property = propertypath.NativeDP;
					if (upp->property == IntPtr.Zero)
						upp->pathString = StringToIntPtr (propertypath.Path);
					else
						upp->pathString = IntPtr.Zero;
					upp->expandedPathString = IntPtr.Zero;
				}
				else if (v is Uri) {
					Uri uri = (Uri) v;

					value.k = Kind.URI;
					value.u.p = UnmanagedUri.FromUri (uri);
				}
				else if (v is XmlLanguage) {
					XmlLanguage lang = (XmlLanguage) v;
					
					value.k = Kind.STRING;
					
					value.u.p = StringToIntPtr (lang.IetfLanguageTag);
				}
				else if (v is Cursor) {
					Cursor c = (Cursor) v;

					value.k = Kind.CURSORTYPE;
					value.u.i32 = (int)c.cursor;
				}
				else if (v is GridLength) {
					GridLength gl = (GridLength) v;
					value.k = Kind.GRIDLENGTH;
					value.u.p = Marshal.AllocHGlobal (sizeof (GridLength));
					Marshal.StructureToPtr (gl, value.u.p, false); // Unmanaged and managed structure layout is equal.
				}
				else if (v is FontStretch) {
					FontStretch stretch = (FontStretch) v;
					value.k = Kind.FONTSTRETCH;
					value.u.p = Marshal.AllocHGlobal (sizeof (UnmanagedFontStretch));
					Marshal.StructureToPtr (stretch, value.u.p, false); // Unmanaged and managed structure layout is equal.
				}
				else if (v is FontStyle) {
					FontStyle style = (FontStyle) v;
					value.k = Kind.FONTSTYLE;
					value.u.p = Marshal.AllocHGlobal (sizeof (UnmanagedFontStyle));
					Marshal.StructureToPtr (style, value.u.p, false); // Unmanaged and managed structure layout is equal.
				}
				else if (v is FontWeight) {
					FontWeight weight = (FontWeight) v;
					value.k = Kind.FONTWEIGHT;
					value.u.p = Marshal.AllocHGlobal (sizeof (UnmanagedFontWeight));
					Marshal.StructureToPtr (weight, value.u.p, false); // Unmanaged and managed structure layout is equal.
				}
				else if (v is TextDecorationCollection) {
					value.k = Kind.TEXTDECORATIONS;
					value.u.i32 = (int) (v as TextDecorationCollection).Kind;
				}
				else if (v is Type) {
					Type t = v as Type;
					ManagedTypeInfo mti = new ManagedTypeInfo ();
					mti.full_name = StringToIntPtr (t.FullName);
					mti.Kind = Deployment.Current.Types.TypeToKind (t);

					value.k = Kind.MANAGEDTYPEINFO;
					value.u.p = Marshal.AllocHGlobal (sizeof (ManagedTypeInfo));
					Marshal.StructureToPtr (mti, value.u.p, false);
				}
				else {
					//Console.WriteLine ("Do not know how to encode {0} yet, boxing it", v.GetType ());

					// TODO: We probably need to marshal types that can animate as the 
					// corresponding type (Point, Double, Color, etc).
					// TODO: We need to store the GCHandle somewhere so that we can free it,
					// or register a callback on the surface for the unmanaged code to call.
					GCHandle handle = GCHandle.Alloc (v);
					value.IsGCHandle = true;
					value.k = Deployment.Current.Types.TypeToKind (v.GetType ());
					value.u.p = GCHandle.ToIntPtr (handle);
				}
			}
			return value;
		}
Exemplo n.º 2
0
Arquivo: Value.cs Projeto: ynkbt/moon
        //
        // How do we support "null" values, should the caller take care of that?
        //
        // The caller is responsible for calling value_free_value on the returned Value
        public static Value FromObject(object v, bool box_value_types)
        {
            Value value = new Value();

            unsafe {
                if (box_value_types && (v is ValueType || v is string))
                {
                    value.boxed_valuetype = GCHandle.Alloc(v);
                }

                if (v is IEasingFunction && !(v is EasingFunctionBase))
                {
                    v = new EasingFunctionWrapper(v as IEasingFunction);
                }

                if (v is INativeEventObjectWrapper)
                {
                    INativeEventObjectWrapper dov = (INativeEventObjectWrapper)v;

                    if (dov.NativeHandle == IntPtr.Zero)
                    {
                        throw new Exception(String.Format(
                                                "Object {0} has not set its native property", dov.GetType()));
                    }

                    NativeMethods.event_object_ref(dov.NativeHandle);

                    value.Kind = dov.GetKind();
                    value.u.p  = dov.NativeHandle;
                }
                else if (v is DependencyProperty)
                {
                    value.Kind = Kind.DEPENDENCYPROPERTY;
                    value.u.p  = ((DependencyProperty)v).Native;
                }
                else if (v is int || (v.GetType().IsEnum&& Enum.GetUnderlyingType(v.GetType()) == typeof(int)))
                {
                    value.Kind  = Deployment.Current.Types.TypeToKind(v.GetType());
                    value.u.i32 = (int)v;
                }
                else if (v is byte || (v.GetType().IsEnum&& Enum.GetUnderlyingType(v.GetType()) == typeof(byte)))
                {
                    value.Kind  = Deployment.Current.Types.TypeToKind(v.GetType());
                    value.u.i32 = (byte)v;
                }
                else if (v is bool)
                {
                    value.Kind  = Kind.BOOL;
                    value.u.i32 = ((bool)v) ? 1 : 0;
                }
                else if (v is double)
                {
                    value.Kind = Kind.DOUBLE;
                    value.u.d  = (double)v;
                }
                else if (v is float)
                {
                    value.Kind = Kind.FLOAT;
                    value.u.f  = (float)v;
                }
                else if (v is long)
                {
                    value.Kind  = Kind.INT64;
                    value.u.i64 = (long)v;
                }
                else if (v is TimeSpan)
                {
                    TimeSpan ts = (TimeSpan)v;
                    value.Kind  = Kind.TIMESPAN;
                    value.u.i64 = ts.Ticks;
                }
                else if (v is ulong)
                {
                    value.Kind   = Kind.UINT64;
                    value.u.ui64 = (ulong)v;
                }
                else if (v is uint)
                {
                    value.Kind   = Kind.UINT32;
                    value.u.ui32 = (uint)v;
                }
                else if (v is char)
                {
                    value.Kind   = Kind.CHAR;
                    value.u.ui32 = (uint)(char)v;
                }
                else if (v is string)
                {
                    value.Kind = Kind.STRING;

                    value.u.p = StringToIntPtr((string)v);
                }
                else if (v is Rect)
                {
                    Rect rect = (Rect)v;
                    value.Kind = Kind.RECT;
                    value.u.p  = Marshal.AllocHGlobal(sizeof(Rect));
                    Marshal.StructureToPtr(rect, value.u.p, false);                      // Unmanaged and managed structure layout is equal.
                }
                else if (v is Size)
                {
                    Size size = (Size)v;
                    value.Kind = Kind.SIZE;
                    value.u.p  = Marshal.AllocHGlobal(sizeof(Size));
                    Marshal.StructureToPtr(size, value.u.p, false);                      // Unmanaged and managed structure layout is equal.
                }
                else if (v is CornerRadius)
                {
                    CornerRadius corner = (CornerRadius)v;
                    value.Kind = Kind.CORNERRADIUS;
                    value.u.p  = Marshal.AllocHGlobal(sizeof(CornerRadius));
                    Marshal.StructureToPtr(corner, value.u.p, false);                      // Unmanaged and managed structure layout is equal.
                }
                else if (v is AudioFormat)
                {
                    AudioFormat f = (AudioFormat)v;
                    value.Kind = Kind.AUDIOFORMAT;
                    value.u.p  = Marshal.AllocHGlobal(sizeof(UnmanagedAudioFormat));
                    UnmanagedAudioFormat *format = (UnmanagedAudioFormat *)value.u.p;
                    format->bitsPerSample    = f.BitsPerSample;
                    format->channels         = f.Channels;
                    format->samplesPerSecond = f.SamplesPerSecond;
                    format->waveFormat       = f.WaveFormat;
                }
                else if (v is VideoFormat)
                {
                    VideoFormat f = (VideoFormat)v;
                    value.Kind = Kind.VIDEOFORMAT;
                    value.u.p  = Marshal.AllocHGlobal(sizeof(UnmanagedVideoFormat));
                    UnmanagedVideoFormat *format = (UnmanagedVideoFormat *)value.u.p;
                    format->framesPerSecond = f.FramesPerSecond;
                    format->height          = f.PixelHeight;
                    format->width           = f.PixelWidth;
                    format->stride          = f.Stride;
                    format->pixelFormat     = f.PixelFormat;
                }
                else if (v is Point)
                {
                    Point pnt = (Point)v;
                    value.Kind = Kind.POINT;
                    value.u.p  = Marshal.AllocHGlobal(sizeof(Point));
                    Marshal.StructureToPtr(pnt, value.u.p, false);                      // Unmanaged and managed structure layout is equal.
                }
                else if (v is Thickness)
                {
                    Thickness thickness = (Thickness)v;
                    value.Kind = Kind.THICKNESS;
                    value.u.p  = Marshal.AllocHGlobal(sizeof(Thickness));
                    Marshal.StructureToPtr(thickness, value.u.p, false);                      // Unmanaged and managed structure layout is equal.
                }
                else if (v is Color)
                {
                    Color c = (Color)v;
                    value.Kind = Kind.COLOR;
                    value.u.p  = Marshal.AllocHGlobal(sizeof(UnmanagedColor));
                    UnmanagedColor *color = (UnmanagedColor *)value.u.p;
                    color->r = c.R / 255.0f;
                    color->g = c.G / 255.0f;
                    color->b = c.B / 255.0f;
                    color->a = c.A / 255.0f;
                }
                else if (v is Matrix)
                {
                    // hack around the fact that managed Matrix is a struct while unmanaged Matrix is a DO
                    // i.e. the unmanaged and managed structure layouts ARE NOT equal
                    return(FromObject(new UnmanagedMatrix((Matrix)v), box_value_types));
                }
                else if (v is StylusPoint)
                {
                    return(FromObject(new UnmanagedStylusPoint((StylusPoint)v), box_value_types));
                }
                else if (v is Matrix3D)
                {
                    // hack around the fact that managed Matrix3D is a struct while unmanaged Matrix3D is a DO
                    // i.e. the unmanaged and managed structure layouts ARE NOT equal
                    return(FromObject(new UnmanagedMatrix3D((Matrix3D)v), box_value_types));
                }
                else if (v is Duration)
                {
                    Duration d = (Duration)v;
                    value.Kind = Kind.DURATION;
                    value.u.p  = Marshal.AllocHGlobal(sizeof(Duration));
                    Marshal.StructureToPtr(d, value.u.p, false);                      // Unmanaged and managed structure layout is equal.
                }
                else if (v is KeyTime)
                {
                    KeyTime k = (KeyTime)v;
                    value.Kind = Kind.KEYTIME;
                    value.u.p  = Marshal.AllocHGlobal(sizeof(KeyTime));
                    Marshal.StructureToPtr(k, value.u.p, false);                      // Unmanaged and managed structure layout is equal.
                }
                else if (v is RepeatBehavior)
                {
                    RepeatBehavior d = (RepeatBehavior)v;
                    value.Kind = Kind.REPEATBEHAVIOR;
                    value.u.p  = Marshal.AllocHGlobal(sizeof(RepeatBehavior));
                    Marshal.StructureToPtr(d, value.u.p, false);                      // Unmanaged and managed structure layout is equal.
                }
                else if (v is FontFamily)
                {
                    FontFamily family = (FontFamily)v;
                    value.Kind = Kind.FONTFAMILY;
                    value.u.p  = Marshal.AllocHGlobal(sizeof(UnmanagedFontFamily));
                    Marshal.StructureToPtr(family, value.u.p, false);                      // Unmanaged and managed structure layout is equal.
                }

                else if (v is FontSource)
                {
                    FontSource source = (FontSource)v;

                    value.Kind = Kind.FONTSOURCE;

                    if (source.wrapper != null || source.typeface != null)
                    {
                        value.u.p = Marshal.AllocHGlobal(sizeof(UnmanagedFontSource));
                        UnmanagedFontSource *ufs = (UnmanagedFontSource *)value.u.p;
                        ufs->type = source.type;

                        switch (source.type)
                        {
                        case FontSourceType.ManagedStream:
                            ManagedStreamCallbacks callbacks = source.wrapper.GetCallbacks();
                            ufs->source.stream = Marshal.AllocHGlobal(sizeof(UnmanagedStreamCallbacks));
                            Marshal.StructureToPtr(callbacks, ufs->source.stream, false);
                            break;

                        case FontSourceType.GlyphTypeface:
                            ufs->source.typeface = source.typeface.Native;
                            break;
                        }
                    }
                    else
                    {
                        value.IsNull = true;
                    }
                }

                else if (v is PropertyPath)
                {
                    PropertyPath propertypath = (PropertyPath)v;
                    value.Kind = Kind.PROPERTYPATH;
                    value.u.p  = Marshal.AllocHGlobal(sizeof(UnmanagedPropertyPath));

                    UnmanagedPropertyPath *upp = (UnmanagedPropertyPath *)value.u.p;
                    upp->property = propertypath.NativeDP;
                    if (upp->property == IntPtr.Zero)
                    {
                        upp->pathString         = StringToIntPtr(propertypath.Path);
                        upp->expandedPathString = StringToIntPtr(propertypath.ExpandedPath);
                    }
                    else
                    {
                        upp->pathString         = IntPtr.Zero;
                        upp->expandedPathString = IntPtr.Zero;
                    }
                }
                else if (v is Uri)
                {
                    Uri uri = (Uri)v;

                    value.Kind = Kind.URI;
                    value.u.p  = UriHelper.ToNativeUri(uri);
                }
                else if (v is XmlLanguage)
                {
                    XmlLanguage lang = (XmlLanguage)v;

                    value.Kind = Kind.XMLLANGUAGE;
                    value.u.p  = StringToIntPtr(lang.IetfLanguageTag);
                }
                else if (v is Cursor)
                {
                    Cursor c = (Cursor)v;

                    value.Kind  = Kind.CURSORTYPE;
                    value.u.i32 = (int)c.cursor;
                }
                else if (v is GridLength)
                {
                    GridLength gl = (GridLength)v;
                    value.Kind = Kind.GRIDLENGTH;
                    value.u.p  = Marshal.AllocHGlobal(sizeof(GridLength));
                    Marshal.StructureToPtr(gl, value.u.p, false);                      // Unmanaged and managed structure layout is equal.
                }
                else if (v is FontStretch)
                {
                    FontStretch stretch = (FontStretch)v;
                    value.Kind = Kind.FONTSTRETCH;
                    value.u.p  = Marshal.AllocHGlobal(sizeof(UnmanagedFontStretch));
                    Marshal.StructureToPtr(stretch, value.u.p, false);                      // Unmanaged and managed structure layout is equal.
                }
                else if (v is FontStyle)
                {
                    FontStyle style = (FontStyle)v;
                    value.Kind = Kind.FONTSTYLE;
                    value.u.p  = Marshal.AllocHGlobal(sizeof(UnmanagedFontStyle));
                    Marshal.StructureToPtr(style, value.u.p, false);                      // Unmanaged and managed structure layout is equal.
                }
                else if (v is FontWeight)
                {
                    FontWeight weight = (FontWeight)v;
                    value.Kind = Kind.FONTWEIGHT;
                    value.u.p  = Marshal.AllocHGlobal(sizeof(UnmanagedFontWeight));
                    Marshal.StructureToPtr(weight, value.u.p, false);                      // Unmanaged and managed structure layout is equal.
                }
                else if (v is TextDecorationCollection)
                {
                    value.Kind  = Kind.TEXTDECORATIONS;
                    value.u.i32 = (int)(v as TextDecorationCollection).Kind;
                }
                else if (v is Type)
                {
                    Type t = v as Type;
                    value.Kind = Kind.MANAGEDTYPEINFO;
                    value.u.p  = NativeMethods.managed_type_info_new(Deployment.Current.Types.TypeToKind(t));
                }
                else if (v is Value)
                {
                    throw new InvalidOperationException("You can not create a Mono.Value from a Mono.Value.");
                }
                else
                {
                    //Console.WriteLine ("Do not know how to encode {0} yet, boxing it", v.GetType ());

                    // TODO: We probably need to marshal types that can animate as the
                    // corresponding type (Point, Double, Color, etc).
                    // TODO: We need to store the GCHandle somewhere so that we can free it,
                    // or register a callback on the surface for the unmanaged code to call.
                    GCHandle handle = GCHandle.Alloc(v);
                    value.IsGCHandle = true;
                    value.Kind       = Deployment.Current.Types.TypeToKind(v.GetType());
                    value.u.p        = GCHandle.ToIntPtr(handle);
                }
            }
            return(value);
        }