[Pkg-mono-svn-commits] [SCM] mono-uia branch, master, updated. debian/2.1-2
Jo Shields
directhex at apebox.org
Mon Jan 23 19:18:02 UTC 2012
The following commit has been merged in the master branch:
commit e4c547fed9b3dc2d6bb5edde43c2b100b2babdc6
Author: Jo Shields <directhex at apebox.org>
Date: Mon Jan 23 19:02:09 2012 +0000
Add a stripped down version of upstream 379d89f7ab15ee443d9a164d193f5e9bf3285b69 to fix building with Mono 2.8+
diff --git a/debian/patches/0001-UIAutomationClient-AutomationElement.FromLocalProvid.patch b/debian/patches/0001-UIAutomationClient-AutomationElement.FromLocalProvid.patch
new file mode 100644
index 0000000..abb9491
--- /dev/null
+++ b/debian/patches/0001-UIAutomationClient-AutomationElement.FromLocalProvid.patch
@@ -0,0 +1,1814 @@
+From 379d89f7ab15ee443d9a164d193f5e9bf3285b69 Mon Sep 17 00:00:00 2001
+From: Mario Carrion <mcarrion at novell.com>
+Date: Tue, 16 Nov 2010 17:01:32 -0500
+Subject: [UIAutomationClient] AutomationElement.FromLocalProvider
+ implementation.
+
+Fixes BNC #489388 and building with Mono 2.8
+---
+ MoonAtkBridge/MoonAtkBridge.sln | 5 +-
+ UIAutomation/UIAutomationBridge/Makefile.am | 1 +
+ .../Mono.UIAutomation.Services/ArgumentCheck.cs | 42 ++
+ .../UIAutomationBridge/UIAutomationBridge.csproj | 1 +
+ UIAutomation/UIAutomationClient/Makefile.am | 7 +
+ .../ClientAutomationBridge.cs | 87 ++++
+ .../ClientAutomationSource.cs | 184 +++++++
+ .../ClientElement.cs | 514 ++++++++++++++++++++
+ .../ClientEventManager.cs | 250 ++++++++++
+ .../ClientInvokePattern.cs | 50 ++
+ .../System.Windows.Automation/Automation.cs | 60 +--
+ .../System.Windows.Automation/AutomationElement.cs | 14 +-
+ .../System.Windows.Automation/ClientSettings.cs | 4 +-
+ .../ClientSideProviderDescription.cs | 26 +-
+ .../System.Windows.Automation/SourceManager.cs | 2 +
+ .../UIAutomationClient/UIAutomationClient.csproj | 8 +
+ .../UIAutomationClientTests/BaseTest.cs | 2 +
+ .../UIAutomationClientTests/LocalProviderTest.cs | 172 ++++++-
+ .../UIAutomationClientTests.csproj | 15 +-
+ .../AutomationInteropProvider.cs | 7 +-
+ .../AutomationIdentifier.cs | 6 +-
+ UiaAtkBridge/Test/AtkTest/AtkTest.csproj | 1 +
+ UiaAtkBridge/Test/GailTestApp/gtk-gui/generated.cs | 55 +--
+ .../Wrappers/ProviderElementWrapper.cs | 16 +-
+ UiaDbus/UiaDbusSource/UiaDbusElement.cs | 2 +-
+ uia2atk.mdw | 2 +-
+ 26 files changed, 1419 insertions(+), 114 deletions(-)
+ create mode 100644 UIAutomation/UIAutomationBridge/Mono.UIAutomation.Services/ArgumentCheck.cs
+ create mode 100644 UIAutomation/UIAutomationClient/Mono.UIAutomation.ClientSource/ClientAutomationBridge.cs
+ create mode 100644 UIAutomation/UIAutomationClient/Mono.UIAutomation.ClientSource/ClientAutomationSource.cs
+ create mode 100644 UIAutomation/UIAutomationClient/Mono.UIAutomation.ClientSource/ClientElement.cs
+ create mode 100644 UIAutomation/UIAutomationClient/Mono.UIAutomation.ClientSource/ClientEventManager.cs
+ create mode 100644 UIAutomation/UIAutomationClient/Mono.UIAutomation.ClientSource/ClientInvokePattern.cs
+
+Index: mono-uia.git/UIAutomationBridge/Makefile.am
+===================================================================
+--- mono-uia.git.orig/UIAutomationBridge/Makefile.am 2012-01-23 18:58:34.192473338 +0000
++++ mono-uia.git/UIAutomationBridge/Makefile.am 2012-01-23 18:58:44.776520265 +0000
+@@ -28,6 +28,7 @@
+ PROJECT_SOURCE_FILES = \
+ Mono.UIAutomation.Bridge/IAutomationBridge.cs \
+ Mono.UIAutomation.Bridge/IHypertext.cs \
++ Mono.UIAutomation.Services/ArgumentCheck.cs \
+ Mono.UIAutomation.Services/Log.cs
+
+ FILES = \
+Index: mono-uia.git/UIAutomationBridge/Mono.UIAutomation.Services/ArgumentCheck.cs
+===================================================================
+--- /dev/null 1970-01-01 00:00:00.000000000 +0000
++++ mono-uia.git/UIAutomationBridge/Mono.UIAutomation.Services/ArgumentCheck.cs 2012-01-23 18:58:44.776520265 +0000
+@@ -0,0 +1,42 @@
++// Permission is hereby granted, free of charge, to any person obtaining
++// a copy of this software and associated documentation files (the
++// "Software"), to deal in the Software without restriction, including
++// without limitation the rights to use, copy, modify, merge, publish,
++// distribute, sublicense, and/or sell copies of the Software, and to
++// permit persons to whom the Software is furnished to do so, subject to
++// the following conditions:
++//
++// The above copyright notice and this permission notice shall be
++// included in all copies or substantial portions of the Software.
++//
++// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
++// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
++// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
++// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
++// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
++// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
++// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
++//
++// Copyright (c) 2010 Novell, Inc. (http://www.novell.com)
++//
++// Authors:
++// Matt Guo <matt at mattguo.com>
++//
++
++using System;
++
++namespace Mono.UIAutomation.Services
++{
++ public static class ArgumentCheck
++ {
++ public static void NotNull<T> (T arg, string argName) where T : class {
++ if (arg == null)
++ throw new ArgumentNullException (argName);
++ }
++
++ public static void Assert<T> (T arg, Predicate<T> condition, string errorMessage) {
++ if (!condition (arg))
++ throw new ArgumentException (errorMessage);
++ }
++ }
++}
+Index: mono-uia.git/UIAutomationClient/Makefile.am
+===================================================================
+--- mono-uia.git.orig/UIAutomationClient/Makefile.am 2012-01-23 18:58:34.192473338 +0000
++++ mono-uia.git/UIAutomationClient/Makefile.am 2012-01-23 18:58:44.780520283 +0000
+@@ -31,6 +31,11 @@
+ all: $(ASSEMBLY) $(PROGRAMFILES)
+
+ PROJECT_SOURCE_FILES = \
++ Mono.UIAutomation.ClientSource/ClientAutomationBridge.cs \
++ Mono.UIAutomation.ClientSource/ClientAutomationSource.cs \
++ Mono.UIAutomation.ClientSource/ClientElement.cs \
++ Mono.UIAutomation.ClientSource/ClientEventManager.cs \
++ Mono.UIAutomation.ClientSource/ClientInvokePattern.cs \
+ System.Windows.Automation.Text/TextPatternRange.cs \
+ System.Windows.Automation/AndCondition.cs \
+ System.Windows.Automation/Automation.cs \
+@@ -84,6 +89,8 @@
+ REFERENCES = \
+ WindowsBase \
+ System \
++ System.Core \
++ Mono.Posix \
+ $(GTK_SHARP_20_LIBS)
+
+ DLL_REFERENCES =
+Index: mono-uia.git/UIAutomationClient/Mono.UIAutomation.ClientSource/ClientAutomationBridge.cs
+===================================================================
+--- /dev/null 1970-01-01 00:00:00.000000000 +0000
++++ mono-uia.git/UIAutomationClient/Mono.UIAutomation.ClientSource/ClientAutomationBridge.cs 2012-01-23 18:58:44.780520283 +0000
+@@ -0,0 +1,87 @@
++// Permission is hereby granted, free of charge, to any person obtaining
++// a copy of this software and associated documentation files (the
++// "Software"), to deal in the Software without restriction, including
++// without limitation the rights to use, copy, modify, merge, publish,
++// distribute, sublicense, and/or sell copies of the Software, and to
++// permit persons to whom the Software is furnished to do so, subject to
++// the following conditions:
++//
++// The above copyright notice and this permission notice shall be
++// included in all copies or substantial portions of the Software.
++//
++// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
++// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
++// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
++// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
++// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
++// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
++// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
++//
++// Copyright (c) 2010 Novell, Inc. (http://www.novell.com)
++//
++// Authors:
++// Matt Guo <matt at mattguo.com>
++//
++
++using System;
++using System.Windows.Automation;
++using System.Windows.Automation.Provider;
++using Mono.UIAutomation.Bridge;
++
++namespace Mono.UIAutomation.ClientSource
++{
++ internal class ClientAutomationBridge : IAutomationBridge
++ {
++ #region IAutomationBridge implementation
++ public object HostProviderFromHandle (IntPtr hwnd)
++ {
++ return null;
++ }
++
++ public void RaiseAutomationEvent (AutomationEvent eventId, object provider, AutomationEventArgs e)
++ {
++ var providerSimple = provider as IRawElementProviderSimple;
++ if (providerSimple == null)
++ return;
++ ClientEventManager.RaiseAutomationEvent (eventId, providerSimple, e);
++ }
++
++ public void RaiseAutomationPropertyChangedEvent (object provider, AutomationPropertyChangedEventArgs e)
++ {
++ var providerSimple = provider as IRawElementProviderSimple;
++ if (providerSimple == null)
++ return;
++ ClientEventManager.RaiseAutomationPropertyChangedEvent (providerSimple, e);
++ }
++
++ public void RaiseStructureChangedEvent (object provider, StructureChangedEventArgs e)
++ {
++ var providerSimple = provider as IRawElementProviderSimple;
++ if (providerSimple == null)
++ return;
++ ClientEventManager.RaiseStructureChangedEvent (providerSimple, e);
++ }
++
++ public void Initialize ()
++ {
++ }
++
++ public void Terminate ()
++ {
++ }
++
++ public bool IsAccessibilityEnabled {
++ get {
++ return true;
++ }
++ }
++
++ public bool ClientsAreListening {
++ get {
++ return true;
++ }
++ }
++
++ #endregion
++ }
++}
+Index: mono-uia.git/UIAutomationClient/Mono.UIAutomation.ClientSource/ClientAutomationSource.cs
+===================================================================
+--- /dev/null 1970-01-01 00:00:00.000000000 +0000
++++ mono-uia.git/UIAutomationClient/Mono.UIAutomation.ClientSource/ClientAutomationSource.cs 2012-01-23 18:58:44.780520283 +0000
+@@ -0,0 +1,184 @@
++// Permission is hereby granted, free of charge, to any person obtaining
++// a copy of this software and associated documentation files (the
++// "Software"), to deal in the Software without restriction, including
++// without limitation the rights to use, copy, modify, merge, publish,
++// distribute, sublicense, and/or sell copies of the Software, and to
++// permit persons to whom the Software is furnished to do so, subject to
++// the following conditions:
++//
++// The above copyright notice and this permission notice shall be
++// included in all copies or substantial portions of the Software.
++//
++// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
++// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
++// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
++// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
++// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
++// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
++// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
++//
++// Copyright (c) 2010 Novell, Inc. (http://www.novell.com)
++//
++// Authors:
++// Matt Guo <matt at mattguo.com>
++//
++
++using System;
++using System.Threading;
++using System.Windows.Automation;
++using System.Windows.Automation.Provider;
++using Mono.UIAutomation.Source;
++using Mono.UIAutomation.Services;
++
++namespace Mono.UIAutomation.ClientSource
++{
++ internal class ClientAutomationSource : IAutomationSource
++ {
++ private static ClientAutomationSource instance = null;
++ private static object staticLock = new object ();
++ public static ClientAutomationSource Instance {
++ get {
++ if (instance == null)
++ lock (staticLock)
++ if (instance == null)
++ instance = new ClientAutomationSource ();
++ return instance;
++ }
++ }
++
++ #region IAutomationSource implementation
++ public event EventHandler RootElementsChanged;
++
++ public void Initialize ()
++ {
++ }
++
++ public IElement [] GetRootElements ()
++ {
++ return new IElement [0];
++ }
++
++ public IElement GetFocusedElement ()
++ {
++ return null;
++ }
++
++ public IElement GetElementFromHandle (IntPtr handle)
++ {
++ return null;
++ }
++
++ public void AddAutomationEventHandler (AutomationEvent eventId, IElement element, TreeScope scope, AutomationEventHandler eventHandler)
++ {
++ if (element == null)
++ // elements from local providers are not descendants of the RootElement.
++ return;
++ ClientElement clientElement = element as ClientElement;
++ if (clientElement == null) {
++ Log.Error ("[ClientAutomationSource.AddAutomationEventHandler] Not ClientElement");
++ return;
++ }
++ ClientEventManager.AddAutomationEventHandler (eventId,
++ clientElement.Provider, scope, eventHandler);
++ }
++
++ public void AddAutomationPropertyChangedEventHandler (IElement element, TreeScope scope, AutomationPropertyChangedEventHandler eventHandler, AutomationProperty[] properties)
++ {
++ if (element == null)
++ return;
++ ClientElement clientElement = element as ClientElement;
++ if (clientElement == null) {
++ Log.Error ("[ClientAutomationSource.AddAutomationPropertyChangedEventHandler] Not ClientElement");
++ return;
++ }
++ int [] propertyIds = Array.ConvertAll (properties, p => p.Id);
++ ClientEventManager.AddAutomationPropertyChangedEventHandler (
++ clientElement.Provider, scope, eventHandler, propertyIds);
++ }
++
++ public void AddStructureChangedEventHandler (IElement element, TreeScope scope, StructureChangedEventHandler eventHandler)
++ {
++ if (element == null)
++ return;
++ ClientElement clientElement = element as ClientElement;
++ if (clientElement == null) {
++ Log.Error ("[ClientAutomationSource.AddStructureChangedEventHandler] Not ClientElement");
++ return;
++ }
++ ClientEventManager.AddStructureChangedEventHandler (clientElement.Provider,
++ scope, eventHandler);
++ }
++
++ public void AddAutomationFocusChangedEventHandler (FocusChangedEventHandler eventHandler)
++ {
++ // client provider never fires FocusChangedEvent.
++ return;
++ }
++
++ public void RemoveAutomationEventHandler (AutomationEvent eventId, IElement element, AutomationEventHandler eventHandler)
++ {
++ if (element == null)
++ return;
++ ClientElement clientElement = element as ClientElement;
++ if (clientElement == null) {
++ Log.Error ("[ClientAutomationSource.RemoveAutomationEventHandler] Not ClientElement");
++ return;
++ }
++ ClientEventManager.RemoveAutomationEventHandler (eventId,
++ clientElement.Provider, eventHandler);
++ }
++
++ public void RemoveAutomationPropertyChangedEventHandler (IElement element, AutomationPropertyChangedEventHandler eventHandler)
++ {
++ if (element == null)
++ return;
++ ClientElement clientElement = element as ClientElement;
++ if (clientElement == null) {
++ Log.Error ("[ClientAutomationSource.RemoveAutomationPropertyChangedEventHandler] Not ClientElement");
++ return;
++ }
++ ClientEventManager.RemoveAutomationPropertyChangedEventHandler (
++ clientElement.Provider, eventHandler);
++ }
++
++ public void RemoveStructureChangedEventHandler (IElement element, StructureChangedEventHandler eventHandler)
++ {
++ if (element == null)
++ return;
++ ClientElement clientElement = element as ClientElement;
++ if (clientElement == null) {
++ Log.Error ("[ClientAutomationSource.RemoveStructureChangedEventHandler] Not ClientElement");
++ return;
++ }
++ ClientEventManager.RemoveStructureChangedEventHandler (
++ clientElement.Provider, eventHandler);
++ }
++
++ public void RemoveAutomationFocusChangedEventHandler (FocusChangedEventHandler eventHandler)
++ {
++ // client provider never fires FocusChangedEvent.
++ return;
++ }
++
++ public void RemoveAllEventHandlers ()
++ {
++ ClientEventManager.RemoveAllEventHandlers ();
++ }
++
++ public bool IsAccessibilityEnabled {
++ get {
++ return true;
++ }
++ }
++
++ #endregion
++
++ public ClientElement GetOrCreateElement (IRawElementProviderSimple provider)
++ {
++ if (provider == null)
++ return null;
++ //?????
++ return new ClientElement (this, provider);
++ }
++ }
++}
+\ No newline at end of file
+Index: mono-uia.git/UIAutomationClient/Mono.UIAutomation.ClientSource/ClientElement.cs
+===================================================================
+--- /dev/null 1970-01-01 00:00:00.000000000 +0000
++++ mono-uia.git/UIAutomationClient/Mono.UIAutomation.ClientSource/ClientElement.cs 2012-01-23 18:58:44.780520283 +0000
+@@ -0,0 +1,514 @@
++// Permission is hereby granted, free of charge, to any person obtaining
++// a copy of this software and associated documentation files (the
++// "Software"), to deal in the Software without restriction, including
++// without limitation the rights to use, copy, modify, merge, publish,
++// distribute, sublicense, and/or sell copies of the Software, and to
++// permit persons to whom the Software is furnished to do so, subject to
++// the following conditions:
++//
++// The above copyright notice and this permission notice shall be
++// included in all copies or substantial portions of the Software.
++//
++// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
++// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
++// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
++// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
++// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
++// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
++// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
++//
++// Copyright (c) 2010 Novell, Inc. (http://www.novell.com)
++//
++// Authors:
++// Matt Guo <matt at mattguo.com>
++//
++
++using System;
++using System.Windows;
++using System.Windows.Automation;
++using System.Windows.Automation.Provider;
++using Mono.UIAutomation.Source;
++using AEIds = System.Windows.Automation.AutomationElementIdentifiers;
++using System.Collections.Generic;
++using Mono.Unix;
++using Mono.UIAutomation.Services;
++using System.Linq;
++
++namespace Mono.UIAutomation.ClientSource
++{
++ // TODO the ClientElement class shares many common code with UiaDbusBridge.ProviderElementWrapper,
++ // Any change to refactor and merge these code?
++ internal class ClientElement : IElement
++ {
++ #region All patterns and properties
++ private static int [] allPatternIds = {
++ ExpandCollapsePatternIdentifiers.Pattern.Id,
++ GridItemPatternIdentifiers.Pattern.Id,
++ GridPatternIdentifiers.Pattern.Id,
++ InvokePatternIdentifiers.Pattern.Id,
++ MultipleViewPatternIdentifiers.Pattern.Id,
++ RangeValuePatternIdentifiers.Pattern.Id,
++ ScrollPatternIdentifiers.Pattern.Id,
++ SelectionItemPatternIdentifiers.Pattern.Id,
++ SelectionPatternIdentifiers.Pattern.Id,
++ TablePatternIdentifiers.Pattern.Id,
++ TextPatternIdentifiers.Pattern.Id,
++ TogglePatternIdentifiers.Pattern.Id,
++ TransformPatternIdentifiers.Pattern.Id,
++ ValuePatternIdentifiers.Pattern.Id,
++ WindowPatternIdentifiers.Pattern.Id,
++ ScrollItemPatternIdentifiers.Pattern.Id,
++ DockPatternIdentifiers.Pattern.Id,
++ TableItemPatternIdentifiers.Pattern.Id
++ };
++
++ private static int [] allPropertyIds = {
++ AutomationElementIdentifiers.IsControlElementProperty.Id,
++ AutomationElementIdentifiers.ControlTypeProperty.Id,
++ AutomationElementIdentifiers.IsContentElementProperty.Id,
++ AutomationElementIdentifiers.LabeledByProperty.Id,
++ AutomationElementIdentifiers.NativeWindowHandleProperty.Id,
++ AutomationElementIdentifiers.AutomationIdProperty.Id,
++ AutomationElementIdentifiers.ItemTypeProperty.Id,
++ AutomationElementIdentifiers.IsPasswordProperty.Id,
++ AutomationElementIdentifiers.LocalizedControlTypeProperty.Id,
++ AutomationElementIdentifiers.NameProperty.Id,
++ AutomationElementIdentifiers.AcceleratorKeyProperty.Id,
++ AutomationElementIdentifiers.AccessKeyProperty.Id,
++ AutomationElementIdentifiers.HasKeyboardFocusProperty.Id,
++ AutomationElementIdentifiers.IsKeyboardFocusableProperty.Id,
++ AutomationElementIdentifiers.IsEnabledProperty.Id,
++ AutomationElementIdentifiers.BoundingRectangleProperty.Id,
++ AutomationElementIdentifiers.ProcessIdProperty.Id,
++ AutomationElementIdentifiers.RuntimeIdProperty.Id,
++ AutomationElementIdentifiers.ClassNameProperty.Id,
++ AutomationElementIdentifiers.HelpTextProperty.Id,
++ AutomationElementIdentifiers.ClickablePointProperty.Id,
++ AutomationElementIdentifiers.CultureProperty.Id,
++ AutomationElementIdentifiers.IsOffscreenProperty.Id,
++ AutomationElementIdentifiers.OrientationProperty.Id,
++ AutomationElementIdentifiers.FrameworkIdProperty.Id,
++ AutomationElementIdentifiers.IsRequiredForFormProperty.Id,
++ AutomationElementIdentifiers.ItemStatusProperty.Id,
++ // Comment Is*PatternAvailableProperty since MS.Net never include those
++ // properties in the return value of AutomationElement.GetSupportedProperties ()
++ //AutomationElementIdentifiers.IsDockPatternAvailableProperty.Id,
++ //AutomationElementIdentifiers.IsExpandCollapsePatternAvailableProperty.Id,
++ //AutomationElementIdentifiers.IsGridItemPatternAvailableProperty.Id,
++ //AutomationElementIdentifiers.IsGridPatternAvailableProperty.Id,
++ //AutomationElementIdentifiers.IsInvokePatternAvailableProperty.Id,
++ //AutomationElementIdentifiers.IsMultipleViewPatternAvailableProperty.Id,
++ //AutomationElementIdentifiers.IsRangeValuePatternAvailableProperty.Id,
++ //AutomationElementIdentifiers.IsSelectionItemPatternAvailableProperty.Id,
++ //AutomationElementIdentifiers.IsSelectionPatternAvailableProperty.Id,
++ //AutomationElementIdentifiers.IsScrollPatternAvailableProperty.Id,
++ //AutomationElementIdentifiers.IsScrollItemPatternAvailableProperty.Id,
++ //AutomationElementIdentifiers.IsTablePatternAvailableProperty.Id,
++ //AutomationElementIdentifiers.IsTableItemPatternAvailableProperty.Id,
++ //AutomationElementIdentifiers.IsTextPatternAvailableProperty.Id,
++ //AutomationElementIdentifiers.IsTogglePatternAvailableProperty.Id,
++ //AutomationElementIdentifiers.IsTransformPatternAvailableProperty.Id,
++ //AutomationElementIdentifiers.IsValuePatternAvailableProperty.Id,
++ //AutomationElementIdentifiers.IsWindowPatternAvailableProperty.Id,
++ ExpandCollapsePatternIdentifiers.ExpandCollapseStateProperty.Id,
++ GridItemPatternIdentifiers.RowProperty.Id,
++ GridItemPatternIdentifiers.ColumnProperty.Id,
++ GridItemPatternIdentifiers.RowSpanProperty.Id,
++ GridItemPatternIdentifiers.ColumnSpanProperty.Id,
++ GridItemPatternIdentifiers.ContainingGridProperty.Id,
++ GridPatternIdentifiers.RowCountProperty.Id,
++ GridPatternIdentifiers.ColumnCountProperty.Id,
++ MultipleViewPatternIdentifiers.CurrentViewProperty.Id,
++ MultipleViewPatternIdentifiers.SupportedViewsProperty.Id,
++ RangeValuePatternIdentifiers.ValueProperty.Id,
++ RangeValuePatternIdentifiers.IsReadOnlyProperty.Id,
++ RangeValuePatternIdentifiers.MinimumProperty.Id,
++ RangeValuePatternIdentifiers.MaximumProperty.Id,
++ RangeValuePatternIdentifiers.LargeChangeProperty.Id,
++ RangeValuePatternIdentifiers.SmallChangeProperty.Id,
++ ScrollPatternIdentifiers.HorizontalScrollPercentProperty.Id,
++ ScrollPatternIdentifiers.HorizontalViewSizeProperty.Id,
++ ScrollPatternIdentifiers.VerticalScrollPercentProperty.Id,
++ ScrollPatternIdentifiers.VerticalViewSizeProperty.Id,
++ ScrollPatternIdentifiers.HorizontallyScrollableProperty.Id,
++ ScrollPatternIdentifiers.VerticallyScrollableProperty.Id,
++ SelectionItemPatternIdentifiers.IsSelectedProperty.Id,
++ SelectionItemPatternIdentifiers.SelectionContainerProperty.Id,
++ SelectionPatternIdentifiers.SelectionProperty.Id,
++ SelectionPatternIdentifiers.CanSelectMultipleProperty.Id,
++ SelectionPatternIdentifiers.IsSelectionRequiredProperty.Id,
++ TablePatternIdentifiers.RowHeadersProperty.Id,
++ TablePatternIdentifiers.ColumnHeadersProperty.Id,
++ TablePatternIdentifiers.RowOrColumnMajorProperty.Id,
++ TogglePatternIdentifiers.ToggleStateProperty.Id,
++ TransformPatternIdentifiers.CanMoveProperty.Id,
++ TransformPatternIdentifiers.CanResizeProperty.Id,
++ TransformPatternIdentifiers.CanRotateProperty.Id,
++ ValuePatternIdentifiers.ValueProperty.Id,
++ ValuePatternIdentifiers.IsReadOnlyProperty.Id,
++ WindowPatternIdentifiers.CanMaximizeProperty.Id,
++ WindowPatternIdentifiers.CanMinimizeProperty.Id,
++ WindowPatternIdentifiers.IsModalProperty.Id,
++ WindowPatternIdentifiers.WindowVisualStateProperty.Id,
++ WindowPatternIdentifiers.WindowInteractionStateProperty.Id,
++ WindowPatternIdentifiers.IsTopmostProperty.Id,
++ DockPatternIdentifiers.DockPositionProperty.Id,
++ TableItemPatternIdentifiers.RowHeaderItemsProperty.Id,
++ TableItemPatternIdentifiers.ColumnHeaderItemsProperty.Id
++ };
++ #endregion
++
++ #region Private FIelds
++
++ private ClientAutomationSource source = null;
++ private IRawElementProviderSimple provider = null;
++ private IRawElementProviderFragment providerFragment = null;
++ private IRawElementProviderFragmentRoot providerFragmentRoot = null;
++
++ #endregion
++
++ #region Constructor
++
++ public ClientElement (ClientAutomationSource source, IRawElementProviderSimple provider)
++ {
++ ArgumentCheck.NotNull (source, "source");
++ ArgumentCheck.NotNull (provider, "provider");
++
++ this.source = source;
++ this.provider = provider;
++ providerFragment = provider as IRawElementProviderFragment;
++ providerFragmentRoot = provider as IRawElementProviderFragmentRoot;
++ }
++
++ #endregion
++
++ internal IRawElementProviderSimple Provider {
++ get { return provider; }
++ }
++
++ #region IElement implementation
++
++ public bool SupportsProperty (AutomationProperty property)
++ {
++ ArgumentCheck.NotNull (property, "property");
++
++ object val = provider.GetPropertyValue (property.Id);
++ return val != null && val != AEIds.NotSupported;
++ }
++
++ public object GetCurrentPattern (AutomationPattern pattern)
++ {
++ ArgumentCheck.NotNull (pattern, "pattern");
++
++ var patternProvider = provider.GetPatternProvider (pattern.Id);
++ if (patternProvider == null)
++ throw new InvalidOperationException ();
++ object ret = null;
++ if (pattern == InvokePattern.Pattern)
++ ret = new ClientInvokePattern ((IInvokeProvider) patternProvider);
++ // TODO implement
++ // we still have more pattern to implement
++ else
++ throw new System.InvalidOperationException ();
++ return ret;
++ }
++
++ public AutomationPattern[] GetSupportedPatterns ()
++ {
++ return (from patternId in allPatternIds
++ where provider.GetPatternProvider (patternId) != null
++ select AutomationPattern.LookupById (patternId)).ToArray ();
++ }
++
++ public AutomationProperty[] GetSupportedProperties ()
++ {
++ return (from propertyId in allPropertyIds
++ let val = provider.GetPropertyValue (propertyId)
++ where val != null && val != AEIds.NotSupported
++ select AutomationProperty.LookupById (propertyId)).ToArray ();
++ }
++
++ public void SetFocus ()
++ {
++ if (!IsKeyboardFocusable)
++ // as tested on Windows, the InvalidOperationException hasn't any error message
++ throw new InvalidOperationException ();
++ if (providerFragment != null)
++ providerFragment.SetFocus ();
++ }
++
++ public IElement GetDescendantFromPoint (double x, double y)
++ {
++ if (providerFragmentRoot != null) {
++ var childProvider =
++ providerFragmentRoot.ElementProviderFromPoint (x, y);
++ return source.GetOrCreateElement (childProvider);
++ }
++ return null;
++ }
++
++ public string AcceleratorKey {
++ get {
++ return provider.GetPropertyValue (AEIds.AcceleratorKeyProperty.Id)
++ as string ?? string.Empty;
++ }
++ }
++
++ public string AccessKey {
++ get {
++ return provider.GetPropertyValue (AEIds.AccessKeyProperty.Id)
++ as string ?? string.Empty;
++ }
++ }
++
++ public string AutomationId {
++ get {
++ return provider.GetPropertyValue (AEIds.AutomationIdProperty.Id)
++ as string ?? string.Empty;
++ }
++ }
++
++ public Rect BoundingRectangle {
++ get {
++ // As tested on Windows, runtime id is solely decided
++ // by providerFragment.BoundingRectangle, and is irrelevant with
++ // IRawElementProviderSimple.GetPropertyValue (AEIds.BoundingRectangleProperty)
++
++ if (providerFragment != null)
++ return providerFragment.BoundingRectangle;
++ else
++ return Rect.Empty;
++ }
++ }
++
++ public string ClassName {
++ get {
++ return provider.GetPropertyValue (AEIds.ClassNameProperty.Id)
++ as string ?? string.Empty;
++ }
++ }
++
++ public Point ClickablePoint {
++ get {
++ object obj = provider.GetPropertyValue (AEIds.ClickablePointProperty.Id);
++ return (obj != null) ? (Point) obj :
++ new Point (double.NegativeInfinity, double.NegativeInfinity);
++ }
++ }
++
++ public ControlType ControlType {
++ get {
++ object obj = provider.GetPropertyValue (AEIds.ControlTypeProperty.Id);
++ return (obj != null) ? ControlType.LookupById ((int) obj) : ControlType.Custom;
++ }
++ }
++
++ public string FrameworkId {
++ get {
++ return provider.GetPropertyValue (AEIds.FrameworkIdProperty.Id)
++ as string ?? string.Empty;
++ }
++ }
++
++ public bool HasKeyboardFocus {
++ get {
++ object obj = provider.GetPropertyValue (AEIds.HasKeyboardFocusProperty.Id);
++ return (obj != null) ? (bool) obj : false;
++ }
++ }
++
++ public string HelpText {
++ get {
++ return provider.GetPropertyValue (AEIds.HelpTextProperty.Id)
++ as string ?? string.Empty;
++ }
++ }
++
++ public bool IsContentElement {
++ get {
++ object obj = provider.GetPropertyValue (AEIds.IsContentElementProperty.Id);
++ return (obj != null) ? (bool) obj : false;
++ }
++ }
++
++ public bool IsControlElement {
++ get {
++ object obj = provider.GetPropertyValue (AEIds.IsControlElementProperty.Id);
++ return (obj != null) ? (bool) obj : false;
++ }
++ }
++
++ public bool IsEnabled {
++ get {
++ object obj = provider.GetPropertyValue (AEIds.IsEnabledProperty.Id);
++ return (obj != null) ? (bool) obj : false;
++ }
++ }
++
++ public bool IsKeyboardFocusable {
++ get {
++ object obj = provider.GetPropertyValue (AEIds.IsKeyboardFocusableProperty.Id);
++ return (obj != null) ? (bool) obj : false;
++ }
++ }
++
++ public bool IsOffscreen {
++ get {
++ object obj = provider.GetPropertyValue (AEIds.IsOffscreenProperty.Id);
++ return (obj != null) ? (bool) obj : false;
++ }
++ }
++
++ public bool IsPassword {
++ get {
++ object obj = provider.GetPropertyValue (AEIds.IsPasswordProperty.Id);
++ return (obj != null) ? (bool) obj : false;
++ }
++ }
++
++ public bool IsRequiredForForm {
++ get {
++ object obj = provider.GetPropertyValue (AEIds.IsRequiredForFormProperty.Id);
++ return (obj != null) ? (bool) obj : false;
++ }
++ }
++
++ public string ItemStatus {
++ get {
++ return provider.GetPropertyValue (AEIds.ItemStatusProperty.Id)
++ as string ?? string.Empty;
++ }
++ }
++
++ public string ItemType {
++ get {
++ return provider.GetPropertyValue (AEIds.ItemTypeProperty.Id)
++ as string ?? string.Empty;
++ }
++ }
++
++ public IElement LabeledBy {
++ get {
++ var labeledBy = provider.GetPropertyValue (AEIds.LabeledByProperty.Id)
++ as IRawElementProviderSimple;
++ return (labeledBy != null) ? source.GetOrCreateElement (labeledBy) : null;
++ }
++ }
++
++ public string LocalizedControlType {
++ get {
++ var controlType = this.ControlType;
++ if (controlType == ControlType.DataGrid)
++ return Catalog.GetString ("data grid");
++ else if (controlType == ControlType.DataItem)
++ return Catalog.GetString ("data item");
++ else if (controlType == ControlType.List)
++ return Catalog.GetString ("list");
++ else
++ return controlType.LocalizedControlType;
++ }
++ }
++
++ public string Name {
++ get {
++ return provider.GetPropertyValue (AEIds.NameProperty.Id)
++ as string ?? string.Empty;
++ }
++ }
++
++ public int NativeWindowHandle {
++ get {
++ object obj = provider.GetPropertyValue (AEIds.NativeWindowHandleProperty.Id);
++ return (obj != null) ? (int) obj : 0;
++ }
++ }
++
++ public OrientationType Orientation {
++ get {
++ object obj = provider.GetPropertyValue (AEIds.OrientationProperty.Id);
++ return (obj != null) ? (OrientationType) obj : OrientationType.None;
++ }
++ }
++
++ public int ProcessId {
++ get {
++ object obj = provider.GetPropertyValue (AEIds.ProcessIdProperty.Id);
++ return (obj != null) ? (int) obj : 0;
++ }
++ }
++
++ public int[] RuntimeId {
++ get {
++ // As tested on Windows, runtime id is solely decided
++ // by providerFragment.GetRuntimeId, and is irrelevant with
++ // IRawElementProviderSimple.GetPropertyValue (AEIds.RuntimeIdProperty)
++ //
++ // An expcetion: if the runtime id is not explicitly provided, while
++ // native handle is provided, then UIA will generate a runtime id for the provider,
++ // on Windows 7 the runtime id is [42, NativeHandleValue]
++ int [] runtimeId = null;
++ if (providerFragment != null)
++ runtimeId = providerFragment.GetRuntimeId ();
++ else {
++ int hwnd = this.NativeWindowHandle;
++ if (hwnd != 0)
++ runtimeId = new int [] {42, hwnd};
++ }
++ return runtimeId;
++ }
++ }
++
++ public IElement Parent {
++ get {
++ if (providerFragment == null)
++ return null;
++ return source.GetOrCreateElement (
++ providerFragment.Navigate (NavigateDirection.Parent));
++ }
++ }
++
++ public IElement FirstChild {
++ get {
++ if (providerFragment == null)
++ return null;
++ return source.GetOrCreateElement (
++ providerFragment.Navigate (NavigateDirection.FirstChild));
++ }
++ }
++
++ public IElement LastChild {
++ get {
++ if (providerFragment == null)
++ return null;
++ return source.GetOrCreateElement (
++ providerFragment.Navigate (NavigateDirection.LastChild));
++ }
++ }
++
++ public IElement NextSibling {
++ get {
++ if (providerFragment == null)
++ return null;
++ return source.GetOrCreateElement (
++ providerFragment.Navigate (NavigateDirection.NextSibling));
++ }
++ }
++
++ public IElement PreviousSibling {
++ get {
++ if (providerFragment == null)
++ return null;
++ return source.GetOrCreateElement (
++ providerFragment.Navigate (NavigateDirection.PreviousSibling));
++ }
++ }
++
++ public IAutomationSource AutomationSource {
++ get {
++ return source;
++ }
++ }
++
++ #endregion
++ }
++}
+Index: mono-uia.git/UIAutomationClient/Mono.UIAutomation.ClientSource/ClientEventManager.cs
+===================================================================
+--- /dev/null 1970-01-01 00:00:00.000000000 +0000
++++ mono-uia.git/UIAutomationClient/Mono.UIAutomation.ClientSource/ClientEventManager.cs 2012-01-23 18:58:44.780520283 +0000
+@@ -0,0 +1,250 @@
++// Permission is hereby granted, free of charge, to any person obtaining
++// a copy of this software and associated documentation files (the
++// "Software"), to deal in the Software without restriction, including
++// without limitation the rights to use, copy, modify, merge, publish,
++// distribute, sublicense, and/or sell copies of the Software, and to
++// permit persons to whom the Software is furnished to do so, subject to
++// the following conditions:
++//
++// The above copyright notice and this permission notice shall be
++// included in all copies or substantial portions of the Software.
++//
++// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
++// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
++// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
++// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
++// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
++// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
++// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
++//
++// Copyright (c) 2010 Novell, Inc. (http://www.novell.com)
++//
++// Authors:
++// Matt Guo <matt at mattguo.com>
++//
++
++using System;
++using System.Collections.Generic;
++using System.Windows.Automation;
++using System.Windows.Automation.Provider;
++using Mono.UIAutomation.Source;
++
++namespace Mono.UIAutomation.ClientSource
++{
++ internal static class ClientEventManager
++ {
++ private static List<PropertyChangedEventEntry> propertyChangedEventEntries
++ = new List<PropertyChangedEventEntry> ();
++ private static List<AutomationEventEntry> automationEventEntries
++ = new List<AutomationEventEntry> ();
++ private static List<StructureChangedEventEntry> structureChangedEventEntries
++ = new List<StructureChangedEventEntry> ();
++
++ public static void AddAutomationEventHandler (AutomationEvent eventId,
++ IRawElementProviderSimple provider, TreeScope scope,
++ AutomationEventHandler eventHandler)
++ {
++ var entry = new AutomationEventEntry (eventId, provider, scope, eventHandler);
++ lock (automationEventEntries)
++ automationEventEntries.Add (entry);
++ }
++
++ public static void AddAutomationPropertyChangedEventHandler (
++ IRawElementProviderSimple provider, TreeScope scope,
++ AutomationPropertyChangedEventHandler eventHandler,
++ int [] properties)
++ {
++ var entry = new PropertyChangedEventEntry (provider, scope, properties, eventHandler);
++ lock (propertyChangedEventEntries)
++ propertyChangedEventEntries.Add (entry);
++ }
++
++ public static void AddStructureChangedEventHandler (
++ IRawElementProviderSimple provider, TreeScope scope,
++ StructureChangedEventHandler eventHandler)
++ {
++ var entry = new StructureChangedEventEntry (provider, scope, eventHandler);
++ lock (structureChangedEventEntries)
++ structureChangedEventEntries.Add (entry);
++ }
++
++ public static void RemoveAutomationEventHandler (AutomationEvent eventId, IRawElementProviderSimple provider, AutomationEventHandler eventHandler)
++ {
++ lock (automationEventEntries)
++ automationEventEntries.RemoveAll (e =>
++ e.EventId == eventId &&
++ e.Provider == provider &&
++ e.Handler == eventHandler);
++ }
++
++ public static void RemoveAutomationPropertyChangedEventHandler (IRawElementProviderSimple provider, AutomationPropertyChangedEventHandler eventHandler)
++ {
++ lock (propertyChangedEventEntries)
++ propertyChangedEventEntries.RemoveAll (e =>
++ e.Provider == provider &&
++ e.Handler == eventHandler);
++ }
++
++ public static void RemoveStructureChangedEventHandler (IRawElementProviderSimple provider, StructureChangedEventHandler eventHandler)
++ {
++ lock (structureChangedEventEntries)
++ structureChangedEventEntries.RemoveAll (e =>
++ e.Provider == provider &&
++ e.Handler == eventHandler);
++ }
++
++ public static void RemoveAllEventHandlers ()
++ {
++ lock (automationEventEntries)
++ automationEventEntries.Clear ();
++ lock (structureChangedEventEntries)
++ structureChangedEventEntries.Clear ();
++ lock (propertyChangedEventEntries)
++ propertyChangedEventEntries.Clear ();
++ }
++
++ public static void RaiseAutomationEvent (AutomationEvent eventId,
++ IRawElementProviderSimple provider, AutomationEventArgs e)
++ {
++ lock (automationEventEntries)
++ foreach (var entry in automationEventEntries)
++ if (entry.EventId == eventId &&
++ IsProviderInScope (provider, entry.Provider, entry.Scope)) {
++ var clientElement =
++ ClientAutomationSource.Instance.GetOrCreateElement (provider);
++ var element = SourceManager.GetOrCreateAutomationElement (clientElement);
++ entry.Handler (element, e);
++ }
++ }
++
++ public static void RaiseAutomationPropertyChangedEvent (IRawElementProviderSimple provider,
++ AutomationPropertyChangedEventArgs e)
++ {
++ lock (propertyChangedEventEntries)
++ foreach (var entry in propertyChangedEventEntries)
++ if (IsProviderInScope (provider, entry.Provider, entry.Scope) &&
++ Array.Exists (entry.Properties, i => i == e.Property.Id)) {
++ var clientElement =
++ ClientAutomationSource.Instance.GetOrCreateElement (provider);
++ var element = SourceManager.GetOrCreateAutomationElement (clientElement);
++ // TODO implement
++ // Translate e.NewValue && e.OldValue
++ entry.Handler (element, e);
++ }
++ }
++
++ public static void RaiseStructureChangedEvent (IRawElementProviderSimple provider,
++ StructureChangedEventArgs e)
++ {
++ lock (structureChangedEventEntries)
++ foreach (var entry in structureChangedEventEntries)
++ if (IsProviderInScope (provider, entry.Provider, entry.Scope)) {
++ var clientElement =
++ ClientAutomationSource.Instance.GetOrCreateElement (provider);
++ var element = SourceManager.GetOrCreateAutomationElement (clientElement);
++ entry.Handler (element, e);
++ }
++ }
++
++ private static bool IsProviderInScope (IRawElementProviderSimple target,
++ IRawElementProviderSimple element, TreeScope scope)
++ {
++ if ((scope & TreeScope.Element) == TreeScope.Element && target == element)
++ return true;
++
++ IRawElementProviderFragment targetFragment = target as IRawElementProviderFragment;
++ IRawElementProviderFragment elementFragment = element as IRawElementProviderFragment;
++ if (targetFragment == null || elementFragment == null)
++ return false;
++
++ IRawElementProviderFragment targetFragmentRoot =
++ targetFragment.Navigate (NavigateDirection.Parent);
++ if ((scope & TreeScope.Children) == TreeScope.Children &&
++ targetFragmentRoot != null &&
++ targetFragmentRoot == elementFragment)
++ return true;
++ if ((scope & TreeScope.Descendants) == TreeScope.Descendants) {
++ while (targetFragmentRoot != null) {
++ if (targetFragmentRoot == elementFragment)
++ return true;
++ targetFragmentRoot = targetFragmentRoot.Navigate (NavigateDirection.Parent);
++ }
++ }
++
++ IRawElementProviderFragment elementFragmentRoot =
++ elementFragment.Navigate (NavigateDirection.Parent);
++ if ((scope & TreeScope.Parent) == TreeScope.Parent &&
++ elementFragmentRoot != null &&
++ elementFragmentRoot == targetFragment)
++ return true;
++ if ((scope & TreeScope.Ancestors) == TreeScope.Ancestors) {
++ while (elementFragmentRoot != null) {
++ if (elementFragmentRoot == targetFragment)
++ return true;
++ elementFragmentRoot = elementFragmentRoot.Navigate (NavigateDirection.Parent);
++ }
++ }
++
++ return false;
++ }
++#region Internal Classes
++
++ private class AutomationEventEntryBase
++ {
++ public AutomationEventEntryBase (IRawElementProviderSimple provider,
++ TreeScope scope)
++ {
++ this.Provider = provider;
++ this.Scope = scope;
++ }
++
++ public IRawElementProviderSimple Provider { get; private set; }
++ public TreeScope Scope { get; private set; }
++ }
++
++ private class StructureChangedEventEntry : AutomationEventEntryBase
++ {
++ public StructureChangedEventEntry (IRawElementProviderSimple provider,
++ TreeScope scope,
++ StructureChangedEventHandler handler)
++ : base (provider, scope)
++ {
++ this.Handler = handler;
++ }
++ public StructureChangedEventHandler Handler { get; private set; }
++ }
++
++ private class AutomationEventEntry : AutomationEventEntryBase
++ {
++ public AutomationEventEntry (AutomationEvent eventId,
++ IRawElementProviderSimple provider,
++ TreeScope scope,
++ AutomationEventHandler handler)
++ : base (provider, scope)
++ {
++ this.EventId = eventId;
++ this.Handler = handler;
++ }
++
++ public AutomationEvent EventId { get; private set; }
++ public AutomationEventHandler Handler { get; private set; }
++ }
++
++ private class PropertyChangedEventEntry : AutomationEventEntryBase
++ {
++ public PropertyChangedEventEntry (IRawElementProviderSimple provider,
++ TreeScope scope,
++ int [] properties,
++ AutomationPropertyChangedEventHandler handler)
++ : base (provider, scope)
++ {
++ this.Properties = properties;
++ this.Handler = handler;
++ }
++
++ public int [] Properties { get; private set; }
++ public AutomationPropertyChangedEventHandler Handler { get; private set; }
++ }
++#endregion
++ }
++}
+Index: mono-uia.git/UIAutomationClient/Mono.UIAutomation.ClientSource/ClientInvokePattern.cs
+===================================================================
+--- /dev/null 1970-01-01 00:00:00.000000000 +0000
++++ mono-uia.git/UIAutomationClient/Mono.UIAutomation.ClientSource/ClientInvokePattern.cs 2012-01-23 18:58:44.780520283 +0000
+@@ -0,0 +1,50 @@
++// Permission is hereby granted, free of charge, to any person obtaining
++// a copy of this software and associated documentation files (the
++// "Software"), to deal in the Software without restriction, including
++// without limitation the rights to use, copy, modify, merge, publish,
++// distribute, sublicense, and/or sell copies of the Software, and to
++// permit persons to whom the Software is furnished to do so, subject to
++// the following conditions:
++//
++// The above copyright notice and this permission notice shall be
++// included in all copies or substantial portions of the Software.
++//
++// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
++// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
++// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
++// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
++// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
++// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
++// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
++//
++// Copyright (c) 2010 Novell, Inc. (http://www.novell.com)
++//
++// Authors:
++// Matt Guo <matt at mattguo.com>
++//
++
++using System;
++using System.Windows.Automation;
++using System.Windows.Automation.Provider;
++using Mono.UIAutomation.Source;
++
++namespace Mono.UIAutomation.ClientSource
++{
++ internal class ClientInvokePattern : IInvokePattern
++ {
++ private IInvokeProvider provider = null;
++
++ public ClientInvokePattern (IInvokeProvider provider)
++ {
++ this.provider = provider;
++ }
++
++ #region IInvokePattern implementation
++ public void Invoke ()
++ {
++ provider.Invoke ();
++ }
++
++ #endregion
++ }
++}
+Index: mono-uia.git/UIAutomationClient/System.Windows.Automation/Automation.cs
+===================================================================
+--- mono-uia.git.orig/UIAutomationClient/System.Windows.Automation/Automation.cs 2011-03-06 12:25:27.000000000 +0000
++++ mono-uia.git/UIAutomationClient/System.Windows.Automation/Automation.cs 2012-01-23 18:58:44.780520283 +0000
+@@ -28,6 +28,7 @@
+
+ using AEIds = System.Windows.Automation.AutomationElementIdentifiers;
+ using MUS = Mono.UIAutomation.Source;
++using Mono.UIAutomation.Services;
+
+ namespace System.Windows.Automation
+ {
+@@ -309,14 +310,13 @@
+ TreeScope scope,
+ AutomationEventHandler eventHandler)
+ {
+- if (element == null)
+- throw new ArgumentNullException ("element");
+- if (eventHandler == null)
+- throw new ArgumentNullException ("eventHandler");
++ CheckAutomationEventId (eventId);
++ ArgumentCheck.NotNull (element, "element");
++ ArgumentCheck.NotNull (eventHandler, "eventHandler");
++
+ //TODO In theory we shall also check scope not equals to Parent or Ancestors,
+ //but .Net didn't test/throw exceptions for "scope"
+
+- CheckAutomationEventId (eventId.Id);
+ if (element == AutomationElement.RootElement)
+ foreach (var source in SourceManager.GetAutomationSources ())
+ source.AddAutomationEventHandler (
+@@ -330,8 +330,7 @@
+
+ public static void AddAutomationFocusChangedEventHandler (AutomationFocusChangedEventHandler eventHandler)
+ {
+- if (eventHandler == null)
+- throw new ArgumentNullException ("eventHandler");
++ ArgumentCheck.NotNull (eventHandler, "eventHandler");
+
+ MUS.FocusChangedEventHandler sourceHandler;
+ //according to the spec, all static methods in the UIA lib shall be thread safe.
+@@ -352,10 +351,8 @@
+ AutomationPropertyChangedEventHandler eventHandler,
+ params AutomationProperty [] properties)
+ {
+- if (element == null)
+- throw new ArgumentNullException ("element");
+- if (eventHandler == null)
+- throw new ArgumentNullException ("eventHandler");
++ ArgumentCheck.NotNull (element, "element");
++ ArgumentCheck.NotNull (eventHandler, "eventHandler");
+
+ if (element == AutomationElement.RootElement)
+ foreach (var source in SourceManager.GetAutomationSources ())
+@@ -372,10 +369,8 @@
+ TreeScope scope,
+ StructureChangedEventHandler eventHandler)
+ {
+- if (element == null)
+- throw new ArgumentNullException ("element");
+- if (eventHandler == null)
+- throw new ArgumentNullException ("eventHandler");
++ ArgumentCheck.NotNull (element, "element");
++ ArgumentCheck.NotNull (eventHandler, "eventHandler");
+
+ if (element == AutomationElement.RootElement)
+ foreach (var source in SourceManager.GetAutomationSources ())
+@@ -402,12 +397,9 @@
+ AutomationElement element,
+ AutomationEventHandler eventHandler)
+ {
+- if (element == null)
+- throw new ArgumentNullException ("element");
+- if (eventHandler == null)
+- throw new ArgumentNullException ("eventHandler");
+-
+- CheckAutomationEventId (eventId.Id);
++ CheckAutomationEventId (eventId);
++ ArgumentCheck.NotNull (element, "element");
++ ArgumentCheck.NotNull (eventHandler, "eventHandler");
+
+ if (element == AutomationElement.RootElement)
+ foreach (var source in SourceManager.GetAutomationSources ())
+@@ -421,8 +413,7 @@
+
+ public static void RemoveAutomationFocusChangedEventHandler (AutomationFocusChangedEventHandler eventHandler)
+ {
+- if (eventHandler == null)
+- throw new ArgumentNullException ("eventHandler");
++ ArgumentCheck.NotNull (eventHandler, "eventHandler");
+
+ MUS.FocusChangedEventHandler sourceHandler;
+ lock (focusHandlerMapping) {
+@@ -437,10 +428,8 @@
+ public static void RemoveAutomationPropertyChangedEventHandler (
+ AutomationElement element, AutomationPropertyChangedEventHandler eventHandler)
+ {
+- if (element == null)
+- throw new ArgumentNullException ("element");
+- if (eventHandler == null)
+- throw new ArgumentNullException ("eventHandler");
++ ArgumentCheck.NotNull (element, "element");
++ ArgumentCheck.NotNull (eventHandler, "eventHandler");
+
+ if (element == AutomationElement.RootElement)
+ foreach (var source in SourceManager.GetAutomationSources ())
+@@ -456,10 +445,8 @@
+ public static void RemoveStructureChangedEventHandler (
+ AutomationElement element, StructureChangedEventHandler eventHandler)
+ {
+- if (element == null)
+- throw new ArgumentNullException ("element");
+- if (eventHandler == null)
+- throw new ArgumentNullException ("eventHandler");
++ ArgumentCheck.NotNull (element, "element");
++ ArgumentCheck.NotNull (eventHandler, "eventHandler");
+
+ if (element == AutomationElement.RootElement)
+ foreach (var source in SourceManager.GetAutomationSources ())
+@@ -472,12 +459,13 @@
+ }
+ }
+
+- private static void CheckAutomationEventId (int eventId)
++ private static void CheckAutomationEventId (AutomationEvent eventId)
+ {
+- if (AutomationElementIdentifiers.AutomationFocusChangedEvent.Id == eventId
+- || AutomationElementIdentifiers.AutomationFocusChangedEvent.Id == eventId
+- || AutomationElementIdentifiers.AutomationPropertyChangedEvent.Id == eventId
+- || AutomationElementIdentifiers.StructureChangedEvent.Id == eventId)
++ ArgumentCheck.NotNull (eventId, "eventId");
++ if (AutomationElementIdentifiers.AutomationFocusChangedEvent == eventId
++ || AutomationElementIdentifiers.AutomationFocusChangedEvent == eventId
++ || AutomationElementIdentifiers.AutomationPropertyChangedEvent == eventId
++ || AutomationElementIdentifiers.StructureChangedEvent == eventId)
+ throw new ArgumentException ("eventId");
+ }
+
+Index: mono-uia.git/UIAutomationClient/System.Windows.Automation/AutomationElement.cs
+===================================================================
+--- mono-uia.git.orig/UIAutomationClient/System.Windows.Automation/AutomationElement.cs 2011-03-06 12:25:27.000000000 +0000
++++ mono-uia.git/UIAutomationClient/System.Windows.Automation/AutomationElement.cs 2012-01-23 18:58:44.780520283 +0000
+@@ -523,8 +523,7 @@
+ #region Public Static Methods
+ public static AutomationElement FromHandle (IntPtr hwnd)
+ {
+- if (hwnd == (IntPtr) null || hwnd == IntPtr.Zero)
+- throw new ArgumentException ("hwnd");
++ ArgumentCheck.Assert (hwnd, (h => h != IntPtr.Zero), "hwnd");
+ if (hwnd == NativeMethods.RootWindowHandle)
+ return RootElement;
+ AutomationElement element = null;
+@@ -542,7 +541,9 @@
+
+ public static AutomationElement FromLocalProvider (IRawElementProviderSimple localImpl)
+ {
+- throw new NotImplementedException ();
++ IElement sourceElement = Mono.UIAutomation.ClientSource.ClientAutomationSource.Instance
++ .GetOrCreateElement (localImpl);
++ return new AutomationElement (sourceElement);
+ }
+
+ public static AutomationElement FromPoint (Point pt)
+@@ -550,7 +551,12 @@
+ IntPtr handle = NativeMethods.WindowAtPosition ((int) pt.X, (int) pt.Y);
+ if (handle == IntPtr.Zero)
+ return RootElement;
+- AutomationElement startElement = FromHandle (handle);
++ AutomationElement startElement = null;
++ try {
++ startElement = FromHandle (handle);
++ } catch (ElementNotAvailableException) {
++ return RootElement;
++ }
+ if (startElement == RootElement)
+ return RootElement;
+ //Keep searching the descendant element which are not native window
+Index: mono-uia.git/UIAutomationClient/System.Windows.Automation/ClientSettings.cs
+===================================================================
+--- mono-uia.git.orig/UIAutomationClient/System.Windows.Automation/ClientSettings.cs 2011-03-06 12:25:27.000000000 +0000
++++ mono-uia.git/UIAutomationClient/System.Windows.Automation/ClientSettings.cs 2012-01-23 18:58:44.780520283 +0000
+@@ -26,6 +26,7 @@
+ using System;
+ using System.Reflection;
+ using System.IO;
++using Mono.UIAutomation.Services;
+
+ namespace System.Windows.Automation
+ {
+@@ -33,8 +34,7 @@
+ {
+ public static void RegisterClientSideProviderAssembly (AssemblyName assemblyName)
+ {
+- if (assemblyName == null)
+- throw new ArgumentNullException ("assemblyName");
++ ArgumentCheck.NotNull (assemblyName, "assemblyName");
+
+ Assembly assembly = null;
+ // TODO, wrap exception messages into Catalog.GetString
+Index: mono-uia.git/UIAutomationClient/System.Windows.Automation/ClientSideProviderDescription.cs
+===================================================================
+--- mono-uia.git.orig/UIAutomationClient/System.Windows.Automation/ClientSideProviderDescription.cs 2011-03-06 12:25:27.000000000 +0000
++++ mono-uia.git/UIAutomationClient/System.Windows.Automation/ClientSideProviderDescription.cs 2012-01-23 18:58:44.780520283 +0000
+@@ -44,16 +44,23 @@
+ string imageName,
+ ClientSideProviderMatchIndicator flags)
+ {
+- this.ClientSideProviderFactoryCallback = clientSideProviderFactoryCallback;
+- this.ClassName = className;
+- this.ImageName = imageName;
+- this.Flags = flags;
++ this.clientSideProviderFactoryCallback = clientSideProviderFactoryCallback;
++ this.className = className;
++ this.imageName = imageName;
++ this.flags = flags;
+ }
+
+- public string ClassName { get; private set; }
+- public ClientSideProviderMatchIndicator Flags { get; private set; }
+- public string ImageName { get; private set; }
+- public ClientSideProviderFactoryCallback ClientSideProviderFactoryCallback { get; private set; }
++ public string ClassName { get { return className; } }
++ public ClientSideProviderMatchIndicator Flags { get { return flags; } }
++ public string ImageName { get { return imageName; } }
++ public ClientSideProviderFactoryCallback ClientSideProviderFactoryCallback {
++ get { return clientSideProviderFactoryCallback; }
++ }
++
++ private string className;
++ private ClientSideProviderFactoryCallback clientSideProviderFactoryCallback;
++ private ClientSideProviderMatchIndicator flags;
++ private string imageName;
+ }
+
+ [Flags]
+@@ -64,5 +71,6 @@
+ DisallowBaseClassNameMatch
+ }
+
+- public delegate IRawElementProviderSimple ClientSideProviderFactoryCallback (IntPtr hwnd, int idChild, int idObject);
++ public delegate IRawElementProviderSimple ClientSideProviderFactoryCallback (
++ IntPtr hwnd, int idChild, int idObject);
+ }
+Index: mono-uia.git/UIAutomationClient/System.Windows.Automation/SourceManager.cs
+===================================================================
+--- mono-uia.git.orig/UIAutomationClient/System.Windows.Automation/SourceManager.cs 2011-03-06 12:25:27.000000000 +0000
++++ mono-uia.git/UIAutomationClient/System.Windows.Automation/SourceManager.cs 2012-01-23 18:58:44.780520283 +0000
+@@ -29,6 +29,7 @@
+
+ using Mono.UIAutomation.Source;
+ using Mono.UIAutomation.Services;
++using Mono.UIAutomation.ClientSource;
+
+ namespace System.Windows.Automation
+ {
+@@ -63,6 +64,7 @@
+ if (source != null)
+ sourcesList.Add (source);
+ }
++ sourcesList.Add (ClientAutomationSource.Instance);
+ sources = sourcesList.ToArray ();
+ }
+ }
+Index: mono-uia.git/UIAutomationClientTests/UIAutomationClientTests/BaseTest.cs
+===================================================================
+--- mono-uia.git.orig/UIAutomationClientTests/UIAutomationClientTests/BaseTest.cs 2011-03-06 12:25:27.000000000 +0000
++++ mono-uia.git/UIAutomationClientTests/UIAutomationClientTests/BaseTest.cs 2012-01-23 18:58:44.780520283 +0000
+@@ -471,6 +471,8 @@
+
+ public static string PrintRuntimeId (int [] runtimeId)
+ {
++ if (runtimeId == null)
++ return "(null)";
+ StringBuilder sb = new StringBuilder();
+ sb.Append ("[");
+ foreach (int id in runtimeId)
+Index: mono-uia.git/UIAutomationClientTests/UIAutomationClientTests/LocalProviderTest.cs
+===================================================================
+--- mono-uia.git.orig/UIAutomationClientTests/UIAutomationClientTests/LocalProviderTest.cs 2011-03-06 12:25:27.000000000 +0000
++++ mono-uia.git/UIAutomationClientTests/UIAutomationClientTests/LocalProviderTest.cs 2012-01-23 19:01:38.121289614 +0000
+@@ -38,17 +38,27 @@
+ [TestFixture]
+ public class LocalProviderTest
+ {
++ const int FakeHandle = 12345;
++
++ private AutomationElement simple = null;
++ private AutomationElement simple2 = null;
+ private AutomationElement child = null;
+ private AutomationElement root = null;
++ private CustomProviderSimple simpleProvider =null;
++ private CustomProviderSimple simpleProvider2 =null;
+ private CustomProviderFragment childProvider =null;
+ private CustomProviderRoot rootProvider =null;
+
+ [TestFixtureSetUp]
+ public virtual void FixtureSetUp ()
+ {
++ simpleProvider = new CustomProviderSimple ();
++ simpleProvider2 = new CustomProviderSimple (FakeHandle);
+ childProvider = new CustomProviderFragment (null);
+- rootProvider = new CustomProviderRoot(childProvider);
++ rootProvider = new CustomProviderRoot (childProvider);
+ childProvider.Root = rootProvider;
++ simple = AutomationElement.FromLocalProvider (simpleProvider);
++ simple2 = AutomationElement.FromLocalProvider (simpleProvider2);
+ child = AutomationElement.FromLocalProvider(childProvider);
+ root = AutomationElement.FromLocalProvider(rootProvider);
+ }
+@@ -57,12 +67,93 @@
+ [Test]
+ public void PropertyTest ()
+ {
+- Assert.AreEqual ("Custom Simple", child.Current.Name);
++ Assert.AreEqual ("Custom Child", child.Current.Name);
+ Assert.AreEqual (ControlType.TabItem, child.Current.ControlType);
+ Assert.AreEqual ("Custom Root", root.Current.Name);
+ Assert.AreEqual (ControlType.Tab, root.Current.ControlType);
+ }
+
++ // IRawElementFragment's GetRuntimeId method will override
++ // the value returned by GetPropertyValue
++ [Test]
++ public void RuntimeIdOverrideTest ()
++ {
++ var rid1 = root.GetRuntimeId ();
++ var rid2 = (int []) root.GetCurrentPropertyValue (AEIds.RuntimeIdProperty);
++ Assert.AreEqual (rid1, rid2, "rid1 == rid2");
++ Assert.AreEqual (CustomProviderBase.CustomRuntimeIdPrefix, rid1 [0], "Check rid1");
++ Assert.AreEqual (CustomProviderBase.CustomRuntimeIdPrefix, rid2 [0], "Check rid2");
++
++ // RuntimeId is null even if it is explicitly returned by
++ // IRawElementSimple.GetPropertyValue
++ Assert.IsNull (simple.GetRuntimeId (), "simple.GetRuntimeId ()" );
++ Assert.IsNull (simple.GetCurrentPropertyValue (AEIds.RuntimeIdProperty),
++ "simple.GetGetCurrentPropertyValue (RuntimeId)" );
++
++ // However if the IRawElementSimple has NativeHandleProperty,
++ // then UIA will generate a runtime id for the provider,
++ // on Windows 7 the runtime id is [42, NativeHandleValue]
++ Assert.IsNotNull (simple2.GetRuntimeId (), "simple2.GetRuntimeId ()" );
++ }
++
++ // IRawElementFragment's BoundingRectangle property will override
++ // the value returned by GetPropertyValue
++ [Test]
++ public void BoundingRectangleOverrideTest ()
++ {
++ var bound = root.Current.BoundingRectangle;
++ Assert.AreEqual (200.0, bound.Width, "bound.Width");
++
++ // BoundingRectangle is empty even if it is explicitly returned by
++ // IRawElementSimple.GetPropertyValue
++ Assert.IsTrue (simple.Current.BoundingRectangle.IsEmpty);
++ }
++
++ [Test]
++ public void DefaultPropertyValueTest ()
++ {
++ // LocalizedControlType is compatible with the ControlType though
++ // LocalizedControlType is not explicitly returned by ControlType
++ Assert.AreEqual (ControlType.Tab.LocalizedControlType, root.Current.LocalizedControlType,
++ "root.LocalizedControlType");
++ // IsInvokePatternAvailableProperty is automatically set to true as long as
++ // the pattern can be returned by GetPatternProvider
++ Assert.IsTrue ((bool) child.GetCurrentPropertyValue (AEIds.IsInvokePatternAvailableProperty),
++ "child.IsInvokePatternAvailable");
++ Assert.IsFalse ((bool) root.GetCurrentPropertyValue (AEIds.IsInvokePatternAvailableProperty),
++ "root.IsInvokePatternAvailable");
++ }
++
++ [Test]
++ public void FromPointTest ()
++ {
++ var element = AutomationElement.FromPoint (new SW.Point (100, 100));
++ // though child and root defined their bounds, they won't be returned by
++ // AutomationElement.FromPoint, actually on Windows what returned is the
++ // "Desktop" element.
++ Assert.AreNotEqual (element, child, "child is never returned by FromPoint");
++ Assert.AreNotEqual (element, root, "root is never returned by FromPoint");
++ }
++
++ [Test]
++ public void FromHandleTest ()
++ {
++ BaseTest.AssertRaises <ElementNotAvailableException> (
++ () => AutomationElement.FromHandle (new IntPtr (FakeHandle)),
++ "simple2 is never returned by FromHandle");
++ }
++
++ [Test]
++ public void FocusedElementTest ()
++ {
++ BaseTest.AssertRaises <InvalidOperationException> (
++ () => child.SetFocus (), "child.IsKeyboardFocusable is not set");
++ // root.IsKeyboardFocusable is set to ture, so no exception
++ root.SetFocus ();
++ Assert.AreNotEqual (AutomationElement.FocusedElement, root,
++ "root is never returned by FocusedElement");
++ }
++
+ [Test]
+ public void PatternTest ()
+ {
+@@ -112,10 +203,58 @@
+ #endregion
+ }
+
++ internal class CustomProviderSimple : IRawElementProviderSimple
++ {
++ private int handle = -1;
++
++ public CustomProviderSimple ()
++ {
++ }
++
++ public CustomProviderSimple (int handle)
++ {
++ this.handle = handle;
++ }
++
++ #region IRawElementProviderSimple Members
++
++ public virtual object GetPatternProvider (int patternId)
++ {
++ return null;
++ }
++
++ public virtual object GetPropertyValue (int propertyId)
++ {
++ if (propertyId == AEIds.NameProperty.Id)
++ return "Custom Simple";
++ if (propertyId == AEIds.ControlTypeProperty.Id)
++ return ControlType.Pane.Id;
++ else if (propertyId == AEIds.RuntimeIdProperty.Id)
++ return new int[] {1, 2, 3, 4, 5};
++ else if (propertyId == AEIds.BoundingRectangleProperty.Id)
++ return new SW.Rect (0, 0, 1000, 1000);
++ else if (propertyId == AEIds.NativeWindowHandleProperty.Id && handle != -1)
++ return handle;
++ else
++ return null;
++ }
++
++ public IRawElementProviderSimple HostRawElementProvider {
++ get { return null; }
++ }
++
++ public ProviderOptions ProviderOptions {
++ get { return ProviderOptions.ClientSideProvider; }
++ }
++
++ #endregion
++ }
++
+ internal class CustomProviderBase : IRawElementProviderFragment
+ {
++ public const int CustomRuntimeIdPrefix = 8888;
+ private int[] runtimeId = null;
+- private SW.Rect rect = new SW.Rect (100.0, 100.0, 200.0, 200.0);
++ private SW.Rect bound = new SW.Rect (50.0, 50.0, 200.0, 200.0);
+
+ public CustomProviderBase (IRawElementProviderFragmentRoot root)
+ {
+@@ -127,7 +266,7 @@
+ #region IRawElementProviderFragment Members
+
+ public SW.Rect BoundingRectangle {
+- get { return rect; }
++ get { return bound; }
+ }
+
+ public IRawElementProviderFragmentRoot FragmentRoot {
+@@ -139,13 +278,12 @@
+ return new IRawElementProviderSimple[0];
+ }
+
+- public int [] GetRuntimeId ()
++ public int[] GetRuntimeId ()
+ {
+- const int CustomPrefix = 8888;
+ if (runtimeId == null) {
+- byte [] bytes = new Guid ().ToByteArray ();
++ byte [] bytes = Guid.NewGuid ().ToByteArray ();
+ runtimeId = new int [bytes.Length + 1];
+- runtimeId [0] = CustomPrefix;
++ runtimeId [0] = CustomRuntimeIdPrefix;
+ for (int i = 0; i < bytes.Length; i++)
+ runtimeId [i + 1] = bytes [i];
+ }
+@@ -198,11 +336,10 @@
+ }
+
+ public int ClickCount { get; set; }
+-
+- public void PerformInvoke ()
++ public void PerformInvoke()
+ {
+ ClickCount++;
+- AutomationInteropProvider.RaiseAutomationEvent(InvokePattern.InvokedEvent, this,
++ AutomationInteropProvider.RaiseAutomationEvent (InvokePattern.InvokedEvent, this,
+ new AutomationEventArgs(InvokePattern.InvokedEvent));
+ }
+
+@@ -216,7 +353,7 @@
+ public override object GetPropertyValue (int propertyId)
+ {
+ if (propertyId == AEIds.NameProperty.Id)
+- return "Custom Simple";
++ return "Custom Child";
+ else if (propertyId == AEIds.ControlTypeProperty.Id)
+ return ControlType.TabItem.Id;
+ else
+@@ -283,6 +420,14 @@
+ return "Custom Root";
+ else if (propertyId == AEIds.ControlTypeProperty.Id)
+ return ControlType.Tab.Id;
++ else if (propertyId == AEIds.RuntimeIdProperty.Id)
++ // this return value won't be effective since the base class defined GetRuntimeId method
++ return new int[] {1, 2, 3, 4, 5};
++ else if (propertyId == AEIds.BoundingRectangleProperty.Id)
++ // this return value won't be effective since the base class defined BoundingRectangle property
++ return new SW.Rect (0, 0, 1000, 1000);
++ else if (propertyId == AEIds.IsKeyboardFocusableProperty.Id)
++ return true;
+ else
+ return base.GetPropertyValue (propertyId);
+ }
+Index: mono-uia.git/UIAutomationProvider/System.Windows.Automation.Provider/AutomationInteropProvider.cs
+===================================================================
+--- mono-uia.git.orig/UIAutomationProvider/System.Windows.Automation.Provider/AutomationInteropProvider.cs 2011-03-06 12:25:27.000000000 +0000
++++ mono-uia.git/UIAutomationProvider/System.Windows.Automation.Provider/AutomationInteropProvider.cs 2012-01-23 18:58:44.784520301 +0000
+@@ -123,11 +123,13 @@
+ "UiaAtkBridge, Version=1.0.0.0, Culture=neutral, PublicKeyToken=f4ceacb585d99812";
+ private static string UiaDbusBridgeAssembly =
+ "UiaDbusBridge, Version=1.0.0.0, Culture=neutral, PublicKeyToken=f4ceacb585d99812";
++ private static string clientBridgeAssembly =
++ "UIAutomationClient, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35";
+
+ public static IList<IAutomationBridge> GetAutomationBridges ()
+ {
+ List<IAutomationBridge> bridges = new List<IAutomationBridge> ();
+-
++
+ // Let MONO_UIA_BRIDGE env var override default bridge
+ string bridgeAssemblyNames =
+ Environment.GetEnvironmentVariable ("MONO_UIA_BRIDGE");
+@@ -135,7 +137,8 @@
+ if (string.IsNullOrEmpty (bridgeAssemblyNames))
+ bridgeAssemblyNames =
+ UiaAtkBridgeAssembly + ";" + UiaDbusBridgeAssembly;
+-
++ bridgeAssemblyNames += ";" + clientBridgeAssembly;
++
+ foreach (string bridgeAssembly in bridgeAssemblyNames.Split (';')) {
+ if (string.IsNullOrEmpty (bridgeAssembly))
+ continue;
+Index: mono-uia.git/UIAutomationTypes/System.Windows.Automation/AutomationIdentifier.cs
+===================================================================
+--- mono-uia.git.orig/UIAutomationTypes/System.Windows.Automation/AutomationIdentifier.cs 2011-03-06 12:25:27.000000000 +0000
++++ mono-uia.git/UIAutomationTypes/System.Windows.Automation/AutomationIdentifier.cs 2012-01-23 18:58:44.784520301 +0000
+@@ -57,10 +57,14 @@
+
+ public int CompareTo (object obj)
+ {
++ if (obj == null)
++ throw new ArgumentNullException ("obj");
+ AutomationIdentifier other =
+ obj as AutomationIdentifier;
+ if (other == null)
+- return 1; // TODO: What?
++ // As tested on Windows, when the object is not an AutomationIdentifier,
++ // a strange large integer will be returned, so we just return the MaxValue.
++ return int.MaxValue;
+ return id.CompareTo (other.Id);
+ }
+
diff --git a/debian/patches/series b/debian/patches/series
index 44313aa..d868d09 100644
--- a/debian/patches/series
+++ b/debian/patches/series
@@ -1 +1,2 @@
0001-uia-Fix-building-with-Mono-2.8.patch
+0001-UIAutomationClient-AutomationElement.FromLocalProvid.patch
--
mono-uia
More information about the Pkg-mono-svn-commits
mailing list