2 // INativeDependencyObjectWrapper.cs
5 // Moonlight List (moonlight-list@lists.ximian.com)
7 // Copyright 2008 Novell, Inc.
9 // Permission is hereby granted, free of charge, to any person obtaining
10 // a copy of this software and associated documentation files (the
11 // "Software"), to deal in the Software without restriction, including
12 // without limitation the rights to use, copy, modify, merge, publish,
13 // distribute, sublicense, and/or sell copies of the Software, and to
14 // permit persons to whom the Software is furnished to do so, subject to
15 // the following conditions:
17 // The above copyright notice and this permission notice shall be
18 // included in all copies or substantial portions of the Software.
20 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
21 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
23 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
24 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
25 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
26 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
30 using Microsoft
.Internal
;
31 using System
.Runtime
.InteropServices
;
33 using System
.Windows
.Controls
;
34 using System
.Windows
.Controls
.Primitives
;
35 using System
.Windows
.Data
;
36 using System
.Windows
.Ink
;
37 using System
.Windows
.Input
;
38 using System
.Windows
.Markup
;
39 using System
.Windows
.Media
;
40 using System
.Windows
.Media
.Animation
;
41 using System
.Windows
.Media
.Effects
;
42 using System
.Windows
.Media
.Imaging
;
43 using System
.Windows
.Shapes
;
44 using System
.Windows
.Documents
;
45 using System
.Windows
.Threading
;
46 using System
.Threading
;
47 using System
.Collections
.Generic
;
48 using System
.Linq
.Expressions
;
51 internal static class NativeDependencyObjectHelper
{
52 #region "helpers for the INativeDependencyObjectWrapper interface"
53 public static object GetValue (INativeDependencyObjectWrapper wrapper
, DependencyProperty dp
)
58 throw new ArgumentNullException ("property");
60 // CheckNativeAndThread (wrapper);
62 IntPtr val
= NativeMethods
.dependency_object_get_value (wrapper
.NativeHandle
, Deployment
.Current
.Types
.TypeToKind (wrapper
.GetType ()), dp
.Native
);
63 if (val
== IntPtr
.Zero
)
64 return dp
.DefaultValue
;
66 result
= Value
.ToObject (dp
.PropertyType
, val
);
68 if (result
== null && dp
.PropertyType
.IsValueType
&& !dp
.IsNullable
)
69 result
= dp
.DefaultValue
;
74 public static void SetValue (INativeDependencyObjectWrapper wrapper
, DependencyProperty dp
, object value)
80 throw new ArgumentNullException ("property");
82 CheckNativeAndThread (wrapper
);
84 if (dp
.DeclaringType
!= null && !dp
.IsAttached
) {
85 if (!dp
.DeclaringType
.IsAssignableFrom (wrapper
.GetType ()))
86 throw new System
.ArgumentException (string.Format ("The DependencyProperty '{2}', registered on type {0} can't be used to set a value on an object of type {1}", dp
.DeclaringType
.AssemblyQualifiedName
, wrapper
.GetType ().AssemblyQualifiedName
, dp
.Name
));
90 if (dp
.PropertyType
.IsValueType
&& !dp
.IsNullable
)
91 throw new System
.ArgumentException (string.Format ("null is not a valid value for '{0}'.", dp
.Name
));
93 v
= new Value { k = NativeMethods.dependency_property_get_property_type(dp.Native), IsNull = true }
;
94 NativeMethods
.dependency_object_set_value (wrapper
.NativeHandle
, dp
.Native
, ref v
);
98 // XXX we need this to work with all
99 // INativeDependencyObjectWrapper, I expect..
100 // but right now the only one other than DO is
101 // Application, which doesn't have any
102 // settable properties, so we're safe for now.
103 if (wrapper
is DependencyObject
)
104 dp
.Validate ((DependencyObject
)wrapper
, dp
, value);
106 object_type
= value.GetType ();
108 bool type_valid
= false;
109 if (dp
.PropertyType
.IsGenericTypeDefinition
) {
110 Type t
= object_type
;
112 if (dp
.PropertyType
.IsAssignableFrom (t
)) {
117 if (t
.IsGenericType
&& !t
.IsGenericTypeDefinition
)
118 t
= t
.GetGenericTypeDefinition ();
124 type_valid
= dp
.PropertyType
.IsAssignableFrom (object_type
);
128 throw new ArgumentException (string.Format ("The DependencyProperty '{3}.{2}', whose property type is {0} can't be set to value whose type is {1}", dp
.PropertyType
.FullName
, object_type
.FullName
, dp
.Name
, dp
.DeclaringType
.FullName
));
131 v
= Value
.FromObject (value, dp
.PropertyType
== typeof(object) && dp
.BoxValueTypes
);
133 NativeMethods
.dependency_object_set_value (wrapper
.NativeHandle
, dp
.Native
, ref v
);
135 NativeMethods
.value_free_value (ref v
);
139 public static object ReadLocalValue (INativeDependencyObjectWrapper wrapper
, DependencyProperty dp
)
141 IntPtr val
= NativeMethods
.dependency_object_read_local_value (wrapper
.NativeHandle
, dp
.Native
);
142 if (val
== IntPtr
.Zero
) {
143 return DependencyProperty
.UnsetValue
;
145 // We can get a style or bindingexpression or something else here
146 // so the Value* will not always be of type 'DP.PropertyType'.
147 return Value
.ToObject (dp
.PropertyType
, val
);
151 public static object GetAnimationBaseValue (INativeDependencyObjectWrapper wrapper
, DependencyProperty dp
)
153 throw new NotImplementedException ();
156 public static void ClearValue (INativeDependencyObjectWrapper wrapper
, DependencyProperty dp
)
158 NativeMethods
.dependency_object_clear_value (wrapper
.NativeHandle
, dp
.Native
, true);
162 /* accessed from several threads, all usage must use a lock */
163 internal static Dictionary
<IntPtr
, ToggleRef
> objects
= new Dictionary
<IntPtr
, ToggleRef
> ();
167 public static bool AddNativeMapping (IntPtr native
, INativeEventObjectWrapper wrapper
)
171 if (native
== IntPtr
.Zero
)
175 if (objects
.ContainsKey (native
)) {
177 throw new ExecutionEngineException ("multiple mappings registered for the same unmanaged peer");
179 Console
.WriteLine ("multiple mappings registered for the same unmanaged peer 0x{0:x}, type = {1}", native
, wrapper
.GetType());
180 Console
.WriteLine (Environment
.StackTrace
);
184 tref
= new ToggleRef (wrapper
);
185 objects
[native
] = tref
;
192 public static void FreeNativeMapping (INativeEventObjectWrapper wrapper
)
195 IntPtr native
= wrapper
.NativeHandle
;
197 if (native
== IntPtr
.Zero
)
201 if (objects
.TryGetValue (native
, out tref
))
202 objects
.Remove (native
);
206 GC
.SuppressFinalize (wrapper
);
210 // This is mostly copied from Gtk#'s Object.GetObject
211 // we need to take into account in the future:
213 // ToggleReferences (talk to Mike)
216 internal static INativeEventObjectWrapper
Lookup (Kind k
, IntPtr ptr
)
218 if (ptr
== IntPtr
.Zero
)
223 if (objects
.TryGetValue (ptr
, out reference
))
224 return reference
.Target
;
226 // don't change this to a cast (as opposed to
227 // using 'as') since we can lose important
229 INativeEventObjectWrapper wrapper
= CreateObject (k
, ptr
) as INativeEventObjectWrapper
;
230 if (wrapper
== null){
231 Report
.Warning ("System.Windows: Returning a null object, did not know how to construct {0}", k
);
232 Report
.Warning (Environment
.StackTrace
);
238 internal static INativeEventObjectWrapper
FromIntPtr (IntPtr ptr
)
240 if (ptr
== IntPtr
.Zero
)
243 Kind k
= NativeMethods
.event_object_get_object_type (ptr
);
245 return Lookup (k
, ptr
);
249 // This version only looks up the object, if it has not been exposed,
252 internal static INativeEventObjectWrapper
Lookup (IntPtr ptr
)
254 if (ptr
== IntPtr
.Zero
)
259 if (objects
.TryGetValue (ptr
, out tref
))
265 static object CreateObject (Kind k
, IntPtr raw
)
268 case Kind
.ARCSEGMENT
: return new ArcSegment (raw
, false);
269 case Kind
.APPLICATION
: return new Application (raw
);
270 case Kind
.ASSEMBLYPART
: return new AssemblyPart (raw
, false);
271 case Kind
.ASSEMBLYPART_COLLECTION
: return new AssemblyPartCollection (raw
, false);
272 case Kind
.BACKEASE
: return new BackEase (raw
, false);
273 case Kind
.BEGINSTORYBOARD
: return new BeginStoryboard (raw
, false);
274 case Kind
.BEZIERSEGMENT
: return new BezierSegment (raw
, false);
275 // case Kind.BINDINGEXPRESSION: return new BindingExpression (raw, false);
276 case Kind
.BITMAPCACHE
: return new BitmapCache (raw
, false);
277 case Kind
.BITMAPIMAGE
: return new BitmapImage (raw
, false);
278 case Kind
.BITMAPSOURCE
: return new BitmapSource (raw
, false);
279 case Kind
.BLUREFFECT
: return new BlurEffect (raw
, false);
280 case Kind
.BOUNCEEASE
: return new BounceEase (raw
, false);
281 case Kind
.BORDER
: return new Border (raw
, false);
282 case Kind
.CANVAS
: return new Canvas (raw
, false);
283 case Kind
.CIRCLEEASE
: return new CircleEase (raw
, false);
284 case Kind
.COLORANIMATION
: return new ColorAnimation (raw
, false);
285 case Kind
.COLORANIMATIONUSINGKEYFRAMES
: return new ColorAnimationUsingKeyFrames (raw
, false);
286 case Kind
.COLORKEYFRAME_COLLECTION
: return new ColorKeyFrameCollection (raw
, false);
287 case Kind
.COLUMNDEFINITION
: return new ColumnDefinition (raw
, false);
288 case Kind
.COLUMNDEFINITION_COLLECTION
: return new ColumnDefinitionCollection (raw
, false);
289 case Kind
.CONTENTCONTROL
: return new ContentControl (raw
, false);
290 case Kind
.CONTROLTEMPLATE
: return new ControlTemplate (raw
, false);
291 case Kind
.CUBICEASE
: return new CubicEase (raw
, false);
292 case Kind
.DATATEMPLATE
: return new DataTemplate (raw
, false);
293 case Kind
.DEEPZOOMIMAGETILESOURCE
: return new DeepZoomImageTileSource (raw
, false);
294 case Kind
.DEPLOYMENT
: return new Deployment (raw
, false);
295 case Kind
.DISCRETECOLORKEYFRAME
: return new DiscreteColorKeyFrame (raw
, false);
296 case Kind
.DISCRETEDOUBLEKEYFRAME
: return new DiscreteDoubleKeyFrame (raw
, false);
297 case Kind
.DISCRETEPOINTKEYFRAME
: return new DiscretePointKeyFrame (raw
, false);
298 case Kind
.DISCRETEOBJECTKEYFRAME
: return new DiscreteObjectKeyFrame (raw
, false);
299 case Kind
.DOUBLEANIMATION
: return new DoubleAnimation (raw
, false);
300 case Kind
.DOUBLEANIMATIONUSINGKEYFRAMES
: return new DoubleAnimationUsingKeyFrames (raw
, false);
301 case Kind
.DOUBLEKEYFRAME_COLLECTION
: return new DoubleKeyFrameCollection (raw
, false);
302 case Kind
.DOUBLE_COLLECTION
: return new DoubleCollection (raw
, false);
303 case Kind
.DRAWINGATTRIBUTES
: return new DrawingAttributes (raw
, false);
304 case Kind
.DROPSHADOWEFFECT
: return new DropShadowEffect (raw
, false);
305 case Kind
.EASINGCOLORKEYFRAME
: return new EasingColorKeyFrame (raw
, false);
306 case Kind
.EASINGDOUBLEKEYFRAME
: return new EasingDoubleKeyFrame (raw
, false);
307 case Kind
.EASINGPOINTKEYFRAME
: return new EasingPointKeyFrame (raw
, false);
308 case Kind
.ELASTICEASE
: return new ElasticEase (raw
, false);
309 case Kind
.ELLIPSEGEOMETRY
: return new EllipseGeometry (raw
, false);
310 case Kind
.ELLIPSE
: return new Ellipse (raw
, false);
311 case Kind
.EVENTTRIGGER
: return new EventTrigger (raw
, false);
312 case Kind
.EXPONENTIALEASE
: return new ExponentialEase (raw
, false);
313 case Kind
.EXTENSIONPART
: return new ExtensionPart (raw
, false);
314 case Kind
.EXTERNALPART_COLLECTION
: return new ExternalPartCollection (raw
, false);
315 case Kind
.GEOMETRY_COLLECTION
: return new GeometryCollection (raw
, false);
316 case Kind
.GEOMETRYGROUP
: return new GeometryGroup (raw
, false);
317 case Kind
.GLYPHS
: return new Glyphs (raw
, false);
318 case Kind
.GRADIENTSTOP_COLLECTION
: return new GradientStopCollection (raw
, false);
319 case Kind
.GRADIENTSTOP
: return new GradientStop (raw
, false);
320 case Kind
.GRID
: return new Grid (raw
, false);
321 case Kind
.ICON
: return new Icon (raw
, false);
322 case Kind
.ICON_COLLECTION
: return new IconCollection (raw
, false);
323 case Kind
.IMAGEBRUSH
: return new ImageBrush (raw
, false);
324 case Kind
.IMAGE
: return new Image (raw
, false);
325 case Kind
.INLINE_COLLECTION
: return new InlineCollection (raw
, false);
326 case Kind
.INKPRESENTER
: return new InkPresenter (raw
, false);
327 case Kind
.INPUTMETHOD
: return new InputMethod (raw
, false);
328 case Kind
.KEYEVENTARGS
: return new KeyEventArgs(raw
);
329 case Kind
.KEYSPLINE
: return new KeySpline(raw
, false);
330 case Kind
.LINEARGRADIENTBRUSH
: return new LinearGradientBrush (raw
, false);
331 case Kind
.LINEBREAK
: return new LineBreak (raw
, false);
332 case Kind
.LINEGEOMETRY
: return new LineGeometry (raw
, false);
333 case Kind
.LINE
: return new Line (raw
, false);
334 case Kind
.LINEARCOLORKEYFRAME
: return new LinearColorKeyFrame (raw
, false);
335 case Kind
.LINEARDOUBLEKEYFRAME
: return new LinearDoubleKeyFrame (raw
, false);
336 case Kind
.LINEARPOINTKEYFRAME
: return new LinearPointKeyFrame (raw
, false);
337 case Kind
.LINESEGMENT
: return new LineSegment (raw
, false);
338 case Kind
.MATRIXTRANSFORM
: return new MatrixTransform (raw
, false);
339 case Kind
.MATRIX3DPROJECTION
: return new Matrix3DProjection (raw
, false);
340 case Kind
.TIMELINEMARKERROUTEDEVENTARGS
: return new TimelineMarkerRoutedEventArgs (raw
, false);
341 case Kind
.MEDIAATTRIBUTE
: return new MediaAttribute (raw
, false);
342 case Kind
.MEDIAATTRIBUTE_COLLECTION
: return new MediaAttributeCollection (raw
, false);
343 case Kind
.MEDIAELEMENT
: return new MediaElement (raw
, false);
344 case Kind
.MOUSEEVENTARGS
: return new MouseEventArgs (raw
);
345 case Kind
.MOUSEBUTTONEVENTARGS
: return new MouseButtonEventArgs (raw
);
346 case Kind
.MOUSEWHEELEVENTARGS
: return new MouseWheelEventArgs (raw
);
347 case Kind
.MULTISCALEIMAGE
: return new MultiScaleImage (raw
, false);
348 case Kind
.MULTISCALESUBIMAGE
: return new MultiScaleSubImage (raw
, false);
349 case Kind
.MULTISCALESUBIMAGE_COLLECTION
: return new MultiScaleSubImageCollection (raw
, false);
350 case Kind
.OBJECTANIMATIONUSINGKEYFRAMES
: return new ObjectAnimationUsingKeyFrames (raw
, false);
351 case Kind
.OBJECTKEYFRAME_COLLECTION
: return new ObjectKeyFrameCollection (raw
, false);
352 case Kind
.OUTOFBROWSERSETTINGS
: return new OutOfBrowserSettings (raw
, false);
353 case Kind
.PASSWORDBOX
: return new PasswordBox (raw
, false);
354 case Kind
.PATHFIGURE_COLLECTION
: return new PathFigureCollection (raw
, false);
355 case Kind
.PATHFIGURE
: return new PathFigure (raw
, false);
356 case Kind
.PATHGEOMETRY
: return new PathGeometry (raw
, false);
357 case Kind
.PATH
: return new Path (raw
, false);
358 case Kind
.PATHSEGMENT_COLLECTION
: return new PathSegmentCollection (raw
, false);
359 case Kind
.PIXELSHADER
: return new PixelShader (raw
, false);
360 case Kind
.PLANEPROJECTION
: return new PlaneProjection (raw
, false);
361 case Kind
.POINTANIMATION
: return new PointAnimation (raw
, false);
362 case Kind
.POINTANIMATIONUSINGKEYFRAMES
: return new PointAnimationUsingKeyFrames (raw
, false);
363 case Kind
.POINTKEYFRAME_COLLECTION
: return new PointKeyFrameCollection (raw
, false);
364 case Kind
.POINT_COLLECTION
: return new PointCollection (raw
, false);
365 case Kind
.POLYBEZIERSEGMENT
: return new PolyBezierSegment (raw
, false);
366 case Kind
.POLYGON
: return new Polygon (raw
, false);
367 case Kind
.POLYLINE
: return new Polyline (raw
, false);
368 case Kind
.POLYLINESEGMENT
: return new PolyLineSegment (raw
, false);
369 case Kind
.POLYQUADRATICBEZIERSEGMENT
: return new PolyQuadraticBezierSegment (raw
, false);
370 case Kind
.POPUP
: return new Popup (raw
, false);
371 case Kind
.POWEREASE
: return new PowerEase (raw
, false);
372 case Kind
.QUADRATICBEZIERSEGMENT
: return new QuadraticBezierSegment (raw
, false);
373 case Kind
.QUADRATICEASE
: return new QuadraticEase (raw
, false);
374 case Kind
.QUARTICEASE
: return new QuarticEase (raw
, false);
375 case Kind
.QUINTICEASE
: return new QuinticEase (raw
, false);
376 case Kind
.RADIALGRADIENTBRUSH
: return new RadialGradientBrush (raw
, false);
377 case Kind
.RECTANGLEGEOMETRY
: return new RectangleGeometry (raw
, false);
378 case Kind
.RECTANGLE
: return new Rectangle (raw
, false);
379 case Kind
.RESOURCE_DICTIONARY
: return new ResourceDictionary (raw
, false);
380 case Kind
.ROTATETRANSFORM
: return new RotateTransform (raw
, false);
381 case Kind
.ROUTEDEVENTARGS
: return new RoutedEventArgs (raw
, false);
382 case Kind
.ROWDEFINITION
: return new RowDefinition (raw
, false);
383 case Kind
.ROWDEFINITION_COLLECTION
: return new RowDefinitionCollection (raw
, false);
384 case Kind
.RUN
: return new Run (raw
, false);
385 case Kind
.SETTERBASE_COLLECTION
: return new SetterBaseCollection (raw
, false);
386 case Kind
.SETTER
: return new Setter (raw
, false);
387 case Kind
.SCALETRANSFORM
: return new ScaleTransform (raw
, false);
388 case Kind
.SINEEASE
: return new SineEase (raw
, false);
389 case Kind
.SIZECHANGEDEVENTARGS
: return new SizeChangedEventArgs (raw
);
390 case Kind
.SKEWTRANSFORM
: return new SkewTransform (raw
, false);
391 case Kind
.SOLIDCOLORBRUSH
: return new SolidColorBrush (raw
, false);
392 case Kind
.SPLINECOLORKEYFRAME
: return new SplineColorKeyFrame (raw
, false);
393 case Kind
.SPLINEDOUBLEKEYFRAME
: return new SplineDoubleKeyFrame (raw
, false);
394 case Kind
.SPLINEPOINTKEYFRAME
: return new SplinePointKeyFrame (raw
, false);
395 case Kind
.STORYBOARD
: return new Storyboard (raw
, false);
396 case Kind
.STROKE_COLLECTION
: return new StrokeCollection (raw
, false);
397 case Kind
.STYLE
: return new Style (raw
, false);
398 case Kind
.STYLUSINFO
: return new StylusInfo (raw
, false);
399 case Kind
.STYLUSPOINT_COLLECTION
: return new StylusPointCollection (raw
, false);
400 case Kind
.STYLUSPOINT
: return new StylusPoint (raw
);
401 case Kind
.SURFACE
: return new Surface (raw
, false);
402 case Kind
.TEXTBLOCK
: return new TextBlock (raw
, false);
403 case Kind
.TEXTBOX
: return new TextBox (raw
, false);
404 case Kind
.TEXTCHANGEDEVENTARGS
: return new TextChangedEventArgs (raw
);
405 case Kind
.TEXTBOXVIEW
: return new TextBoxView (raw
, false);
406 case Kind
.TIMELINE_COLLECTION
: return new TimelineCollection (raw
, false);
407 case Kind
.TIMELINEMARKER
: return new TimelineMarker (raw
, false);
408 case Kind
.TIMELINEMARKER_COLLECTION
: return new TimelineMarkerCollection (raw
, false);
409 case Kind
.TRANSFORM_COLLECTION
: return new TransformCollection (raw
, false);
410 case Kind
.TRANSFORMGROUP
: return new TransformGroup (raw
, false);
411 case Kind
.TRANSLATETRANSFORM
: return new TranslateTransform (raw
, false);
412 case Kind
.TRIGGERACTION_COLLECTION
: return new TriggerActionCollection (raw
, false);
413 case Kind
.TRIGGER_COLLECTION
: return new TriggerCollection (raw
, false);
414 case Kind
.UIELEMENT_COLLECTION
: return new UIElementCollection (raw
, false);
415 case Kind
.USERCONTROL
: return new UserControl (raw
, false);
416 case Kind
.VIDEOBRUSH
: return new VideoBrush (raw
, false);
417 case Kind
.WINDOWSETTINGS
: return new WindowSettings (raw
, false);
418 case Kind
.WRITEABLEBITMAP
: return new WriteableBitmap (raw
, false);
421 case Kind
.CLOCKGROUP
:
422 case Kind
.ANIMATIONCLOCK
:
425 case Kind
.TRIGGERACTION
:
426 case Kind
.KEYFRAME_COLLECTION
:
430 case Kind
.FRAMEWORKELEMENT
:
433 case Kind
.SHADEREFFECT
:
435 case Kind
.GENERALTRANSFORM
:
437 case Kind
.PROJECTION
:
440 case Kind
.SETTERBASE
:
441 case Kind
.FRAMEWORKTEMPLATE
:
442 case Kind
.EASINGFUNCTIONBASE
:
443 throw new Exception (
444 String
.Format ("Should never get an abstract class from unmanaged code {0}", k
));
447 throw new Exception (
448 String
.Format ("NativeDependencyObjectHelper::CreateObject(): Kind missing from switch: {0}", k
));
452 private static void CheckNativeAndThread (INativeDependencyObjectWrapper wrapper
)
454 if (wrapper
.NativeHandle
== IntPtr
.Zero
) {
455 throw new Exception (
456 string.Format ("Uninitialized object: this object ({0}) has not set its native handle set", wrapper
.GetType ().FullName
));
459 if (!wrapper
.CheckAccess ())
460 throw new UnauthorizedAccessException ("Invalid access of Moonlight from an external thread");