stub out the Projection classes as well as duplicating the disgusting hack used for...
[moon.git] / class / System.Windows / Mono / NativeDependencyObjectHelper.cs
blobbdb6bd65cc52b7d437b80f7e191d81cdb72e0d11
1 //
2 // INativeDependencyObjectWrapper.cs
3 //
4 // Contact:
5 // Moonlight List (moonlight-list@lists.ximian.com)
6 //
7 // Copyright 2008 Novell, Inc.
8 //
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:
16 //
17 // The above copyright notice and this permission notice shall be
18 // included in all copies or substantial portions of the Software.
19 //
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.
29 using System;
30 using Microsoft.Internal;
31 using System.Runtime.InteropServices;
32 using System.Windows;
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;
49 namespace Mono {
51 internal static class NativeDependencyObjectHelper {
52 #region "helpers for the INativeDependencyObjectWrapper interface"
53 public static object GetValue (INativeDependencyObjectWrapper wrapper, DependencyProperty dp)
55 object result = null;
57 if (dp == null)
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;
71 return result;
74 public static void SetValue (INativeDependencyObjectWrapper wrapper, DependencyProperty dp, object value)
76 Type object_type;
77 Value v;
79 if (dp == null)
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));
89 if (value == null) {
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);
95 return;
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;
111 while (t != null) {
112 if (dp.PropertyType.IsAssignableFrom (t)) {
113 type_valid = true;
114 break;
117 if (t.IsGenericType && !t.IsGenericTypeDefinition)
118 t = t.GetGenericTypeDefinition ();
119 else
120 t = t.BaseType;
123 else {
124 type_valid = dp.PropertyType.IsAssignableFrom (object_type);
127 if (!type_valid) {
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);
132 try {
133 NativeMethods.dependency_object_set_value (wrapper.NativeHandle, dp.Native, ref v);
134 } finally {
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;
144 } else {
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);
160 #endregion
162 /* accessed from several threads, all usage must use a lock */
163 internal static Dictionary<IntPtr, ToggleRef> objects = new Dictionary<IntPtr, ToggleRef> ();
166 /* thread-safe */
167 public static bool AddNativeMapping (IntPtr native, INativeEventObjectWrapper wrapper)
169 ToggleRef tref;
171 if (native == IntPtr.Zero)
172 return false;
174 lock (objects) {
175 if (objects.ContainsKey (native)) {
176 #if DEBUG
177 throw new ExecutionEngineException ("multiple mappings registered for the same unmanaged peer");
178 #endif
179 Console.WriteLine ("multiple mappings registered for the same unmanaged peer 0x{0:x}, type = {1}", native, wrapper.GetType());
180 Console.WriteLine (Environment.StackTrace);
181 return false;
184 tref = new ToggleRef (wrapper);
185 objects[native] = tref;
187 tref.Initialize ();
188 return true;
191 /* thread-safe */
192 public static void FreeNativeMapping (INativeEventObjectWrapper wrapper)
194 ToggleRef tref;
195 IntPtr native = wrapper.NativeHandle;
197 if (native == IntPtr.Zero)
198 return;
200 lock (objects) {
201 if (objects.TryGetValue (native, out tref))
202 objects.Remove (native);
204 if (tref != null)
205 tref.Free ();
206 GC.SuppressFinalize (wrapper);
210 // This is mostly copied from Gtk#'s Object.GetObject
211 // we need to take into account in the future:
212 // WeakReferences
213 // ToggleReferences (talk to Mike)
215 // Thread-safe.
216 internal static INativeEventObjectWrapper Lookup (Kind k, IntPtr ptr)
218 if (ptr == IntPtr.Zero)
219 return null;
221 ToggleRef reference;
222 lock (objects) {
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
228 // info if you do.
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);
235 return wrapper;
238 internal static INativeEventObjectWrapper FromIntPtr (IntPtr ptr)
240 if (ptr == IntPtr.Zero)
241 return null;
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,
250 // we return null
251 // Thread-safe
252 internal static INativeEventObjectWrapper Lookup (IntPtr ptr)
254 if (ptr == IntPtr.Zero)
255 return null;
257 ToggleRef tref;
258 lock (objects) {
259 if (objects.TryGetValue (ptr, out tref))
260 return tref.Target;
262 return null;
265 static object CreateObject (Kind k, IntPtr raw)
267 switch (k){
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);
420 case Kind.CACHEMODE:
421 case Kind.CLOCKGROUP:
422 case Kind.ANIMATIONCLOCK:
423 case Kind.CLOCK:
424 case Kind.NAMESCOPE:
425 case Kind.TRIGGERACTION:
426 case Kind.KEYFRAME_COLLECTION:
427 case Kind.UIELEMENT:
428 case Kind.PANEL:
429 case Kind.TIMELINE:
430 case Kind.FRAMEWORKELEMENT:
431 case Kind.BRUSH:
432 case Kind.EFFECT:
433 case Kind.SHADEREFFECT:
434 case Kind.TILEBRUSH:
435 case Kind.GENERALTRANSFORM:
436 case Kind.TRANSFORM:
437 case Kind.PROJECTION:
438 case Kind.SHAPE:
439 case Kind.GEOMETRY:
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));
446 default:
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");