Add feature for grabbing HW key events 29/118829/1
authorWonYoung Choi <wy80.choi@samsung.com>
Tue, 14 Mar 2017 07:31:17 +0000 (16:31 +0900)
committerWonYoung Choi <wy80.choi@samsung.com>
Tue, 14 Mar 2017 07:31:17 +0000 (16:31 +0900)
Change-Id: I32483846b559a49d3b5e0bbbf207a70e10ac34e7

ElmSharp/ElmSharp.csproj [changed mode: 0755->0644]
ElmSharp/ElmSharp/EcoreEvent.cs [new file with mode: 0644]
ElmSharp/ElmSharp/EcoreKeyEventArgs.cs [new file with mode: 0644]
ElmSharp/ElmSharp/EvasObjectEvent.cs
ElmSharp/ElmSharp/Window.cs
ElmSharp/Interop/Interop.Ecore.cs
ElmSharp/Interop/Interop.Elementary.Win.cs
ElmSharp/Interop/Interop.Libdl.cs [new file with mode: 0644]
ElmSharp/Interop/Interop.Libraries.cs [changed mode: 0755->0644]
packaging/elm-sharp.spec

old mode 100755 (executable)
new mode 100644 (file)
index 2b2261d..c635261
@@ -53,6 +53,8 @@
     <Compile Include="ElmSharp\Color.cs" />
     <Compile Include="ElmSharp\ColorChangedEventArgs.cs" />
     <Compile Include="ElmSharp\ColorSelector.cs" />
+    <Compile Include="ElmSharp\EcoreEvent.cs" />
+    <Compile Include="ElmSharp\EcoreKeyEventArgs.cs" />
     <Compile Include="ElmSharp\HoverselItem.cs" />
     <Compile Include="ElmSharp\Conformant.cs" />
     <Compile Include="ElmSharp\Container.cs" />
     <Compile Include="Interop\Interop.Evas.cs" />
     <Compile Include="Interop\Interop.Evas.Image.cs" />
     <Compile Include="Interop\Interop.Libc.cs" />
+    <Compile Include="Interop\Interop.Libdl.cs" />
     <Compile Include="Interop\Interop.Libraries.cs" />
     <Compile Include="Properties\AssemblyInfo.cs" />
   </ItemGroup>
     <_FullFrameworkReferenceAssemblyPaths>$(MSBuildThisFileDirectory)</_FullFrameworkReferenceAssemblyPaths>
     <AutoUnifyAssemblyReferences>true</AutoUnifyAssemblyReferences>
   </PropertyGroup>
-</Project>
+</Project>
\ No newline at end of file
diff --git a/ElmSharp/ElmSharp/EcoreEvent.cs b/ElmSharp/ElmSharp/EcoreEvent.cs
new file mode 100644 (file)
index 0000000..4556747
--- /dev/null
@@ -0,0 +1,152 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Runtime.InteropServices;
+
+namespace ElmSharp
+{
+    public class EcoreEventType
+    {
+        public static readonly EcoreEventType KeyDown = new EcoreEventType(Interop.Libraries.EcoreInput, "ECORE_EVENT_KEY_DOWN");
+        public static readonly EcoreEventType KeyUp = new EcoreEventType(Interop.Libraries.EcoreInput, "ECORE_EVENT_KEY_UP");
+        public static readonly EcoreEventType MouseButtonDown = new EcoreEventType(Interop.Libraries.EcoreInput, "ECORE_EVENT_MOUSE_BUTTON_DOWN");
+        public static readonly EcoreEventType MouseButtonUp = new EcoreEventType(Interop.Libraries.EcoreInput, "ECORE_EVENT_MOUSE_BUTTON_UP");
+        public static readonly EcoreEventType MouseButtonCancel = new EcoreEventType(Interop.Libraries.EcoreInput, "ECORE_EVENT_MOUSE_BUTTON_CANCEL");
+        public static readonly EcoreEventType MouseMove = new EcoreEventType(Interop.Libraries.EcoreInput, "ECORE_EVENT_MOUSE_MOVE");
+        public static readonly EcoreEventType MouseWheel = new EcoreEventType(Interop.Libraries.EcoreInput, "ECORE_EVENT_MOUSE_WHEEL");
+        public static readonly EcoreEventType MouseIn = new EcoreEventType(Interop.Libraries.EcoreInput, "ECORE_EVENT_MOUSE_IN");
+        public static readonly EcoreEventType MouseOut = new EcoreEventType(Interop.Libraries.EcoreInput, "ECORE_EVENT_MOUSE_OUT");
+
+        private string _lib;
+        private string _name;
+        private int _typeValue;
+
+        private EcoreEventType(string lib, string name)
+        {
+            _lib = lib;
+            _name = name;
+            _typeValue = -1;
+        }
+
+        public int GetValue()
+        {
+            if (_typeValue < 0)
+            {
+                IntPtr hDll = Interop.Libdl.LoadLibrary(_lib);
+                if (hDll != IntPtr.Zero)
+                {
+                    IntPtr pValue = Interop.Libdl.GetProcAddress(hDll, _name);
+                    if (pValue != IntPtr.Zero)
+                    {
+                        _typeValue = Marshal.ReadInt32(pValue);
+                    }
+                    Interop.Libdl.FreeLibrary(hDll);
+                }
+            }
+            return _typeValue;
+        }
+    }
+
+    public class EcoreEvent<TEventArgs> : IDisposable where TEventArgs : EventArgs
+    {
+        public delegate TEventArgs EventInfoParser(IntPtr data, EcoreEventType type, IntPtr info);
+
+        private bool _disposed = false;
+        private EcoreEventType _eventType;
+        private readonly EventInfoParser _parser;
+        private readonly List<NativeCallback> _nativeCallbacks = new List<NativeCallback>();
+
+        public EcoreEvent(EcoreEventType type) : this(type, null)
+        {
+        }
+
+        public EcoreEvent(EcoreEventType type, EventInfoParser parser)
+        {
+            _eventType = type;
+            _parser = parser;
+        }
+
+        ~EcoreEvent()
+        {
+            Dispose(false);
+        }
+
+        private struct NativeCallback
+        {
+            public Interop.Ecore.EcoreEventCallback callback;
+            public IntPtr nativeHandler;
+            public EventHandler<TEventArgs> eventHandler;
+        }
+
+        public event EventHandler<TEventArgs> On
+        {
+            add
+            {
+                EventHandler<TEventArgs> handler = value;
+                var cb = new Interop.Ecore.EcoreEventCallback((data, type, info) =>
+                {
+                    TEventArgs ea = _parser == null ? (TEventArgs)EventArgs.Empty : _parser(data, _eventType, info);
+                    handler(this, ea);
+                });
+                IntPtr hNative = Interop.Ecore.ecore_event_handler_add(_eventType.GetValue(), cb, IntPtr.Zero);
+                _nativeCallbacks.Add(new NativeCallback { callback = cb, eventHandler = handler, nativeHandler = hNative });
+            }
+            remove
+            {
+                EventHandler<TEventArgs> handler = value;
+                var callbacks = _nativeCallbacks.Where(cb => cb.eventHandler == handler);
+                foreach (var cb in callbacks)
+                {
+                    Interop.Ecore.ecore_event_handler_del(cb.nativeHandler);
+                }
+            }
+        }
+
+        protected virtual void Dispose(bool disposing)
+        {
+            if (!_disposed)
+            {
+                if (disposing)
+                {
+                    // Place holder to dispose managed state (managed objects).
+                }
+                foreach (var cb in _nativeCallbacks)
+                {
+                    Interop.Ecore.ecore_event_handler_del(cb.nativeHandler);
+                }
+                _nativeCallbacks.Clear();
+                _disposed = true;
+            }
+        }
+
+        public void Dispose()
+        {
+            Dispose(true);
+            GC.SuppressFinalize(this);
+        }
+    }
+
+    public class EcoreEvent : EcoreEvent<EventArgs>
+    {
+        public EcoreEvent(EcoreEventType type) : base(type)
+        {
+        }
+    }
+}
+
diff --git a/ElmSharp/ElmSharp/EcoreKeyEventArgs.cs b/ElmSharp/ElmSharp/EcoreKeyEventArgs.cs
new file mode 100644 (file)
index 0000000..ad26b00
--- /dev/null
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Runtime.InteropServices;
+
+namespace ElmSharp
+{
+    public class EcoreKeyEventArgs : EventArgs
+    {
+        public string KeyName { get; private set; }
+        public int KeyCode { get; private set; }
+
+        public static EcoreKeyEventArgs Create(IntPtr data, EcoreEventType type, IntPtr info)
+        {
+            var evt = Marshal.PtrToStructure<EcoreEventKey>(info);
+            return new EcoreKeyEventArgs { KeyName = evt.keyname, KeyCode = (int)evt.keycode };
+        }
+
+        [StructLayout(LayoutKind.Sequential)]
+        struct EcoreEventKey
+        {
+            public string keyname;
+            public string key;
+            public string str;
+            public string compose;
+            public IntPtr window;
+            public IntPtr root_window;
+            public IntPtr event_window;
+            public uint timestamp;
+            public uint modifiers;
+            public int same_screen;
+            public uint keycode;
+            public IntPtr data;
+            public IntPtr dev;
+        }
+    }
+}
index 23c0b53..eebea05 100644 (file)
@@ -24,6 +24,7 @@ namespace ElmSharp
     {
         void MakeInvalidate();
     }
+
     public enum EvasObjectCallbackType
     {
         MouseIn,
index be5a376..dc9f790 100644 (file)
@@ -195,6 +195,16 @@ namespace ElmSharp
             Interop.Elementary.elm_win_resize_object_add(Handle, obj);
         }
 
+        public void KeyGrabEx(string keyname)
+        {
+            Interop.Elementary.eext_win_keygrab_set(RealHandle, keyname);
+        }
+
+        public void KeyUngrabEx(string keyname)
+        {
+            Interop.Elementary.eext_win_keygrab_unset(RealHandle, keyname);
+        }
+
         protected override IntPtr CreateHandle(EvasObject parent)
         {
             Interop.Elementary.elm_config_accel_preference_set("3d");
index 65255cd..99b9ee1 100644 (file)
@@ -23,6 +23,7 @@ internal static partial class Interop
     {
         internal delegate void EcoreCallback(IntPtr data);
         internal delegate bool EcoreTaskCallback(IntPtr data);
+        internal delegate void EcoreEventCallback(IntPtr data, int type, IntPtr evt);
 
         [DllImport(Libraries.Ecore)]
         internal static extern int ecore_init();
@@ -65,5 +66,11 @@ internal static partial class Interop
 
         [DllImport(Libraries.Ecore)]
         internal static extern double ecore_time_get();
+
+        [DllImport(Libraries.Ecore)]
+        internal static extern IntPtr ecore_event_handler_add(int type, EcoreEventCallback func, IntPtr data);
+
+        [DllImport(Libraries.Ecore)]
+        internal static extern IntPtr ecore_event_handler_del(IntPtr handler);
     }
 }
index f139430..959f867 100644 (file)
@@ -136,5 +136,12 @@ internal static partial class Interop
 
         [DllImport(Libraries.Elementary)]
         internal static extern void elm_win_screen_dpi_get(IntPtr obj, out int xdpi, out int ydpi);
+
+        [DllImport(Libraries.Eext)]
+        internal static extern bool eext_win_keygrab_set(IntPtr obj, string key);
+
+        [DllImport(Libraries.Eext)]
+        internal static extern bool eext_win_keygrab_unset(IntPtr obj, string key);
+
     }
 }
diff --git a/ElmSharp/Interop/Interop.Libdl.cs b/ElmSharp/Interop/Interop.Libdl.cs
new file mode 100644 (file)
index 0000000..4f233f8
--- /dev/null
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Runtime.InteropServices;
+
+internal static partial class Interop
+{
+    internal static partial class Libdl
+    {
+        private const int RTLD_NOW = 2;
+
+        [DllImport(Libraries.Libdl)]
+        private static extern IntPtr dlopen(string filename, int flags);
+
+        [DllImport(Libraries.Libdl)]
+        private static extern int dlclose(IntPtr handle);
+
+        [DllImport(Libraries.Libdl)]
+        private static extern IntPtr dlsym(IntPtr handle, string symbol);
+
+        [DllImport(Libraries.Libdl)]
+        private static extern IntPtr dlerror();
+
+        internal static IntPtr LoadLibrary(string filename)
+        {
+            return dlopen(filename, RTLD_NOW);
+        }
+
+        internal static void FreeLibrary(IntPtr handle)
+        {
+            dlclose(handle);
+        }
+
+        internal static IntPtr GetProcAddress(IntPtr handle, string name)
+        {
+            dlerror();
+            var res = dlsym(handle, name);
+            var errPtr = dlerror();
+            if (errPtr != IntPtr.Zero)
+            {
+                throw new Exception("dlsym : " + Marshal.PtrToStringAnsi(errPtr));
+            }
+            return res;
+        }
+    }
+}
old mode 100755 (executable)
new mode 100644 (file)
index fe6ae2e..7f1ca6a
 
 internal static partial class Interop
 {
-    private static class Libraries
+    internal static class Libraries
     {
         internal const string Libc = "libc.so.6";
+        internal const string Libdl = "libdl.so.2";
         internal const string Evas = "libevas.so.1";
         internal const string Elementary = "libelementary.so.1";
         internal const string Eina = "libeina.so.1";
         internal const string Ecore = "libecore.so.1";
+        internal const string EcoreInput = "libecore_input.so.1";
         internal const string Eo = "libeo.so.1";
         internal const string Eext = "libefl-extension.so.0";
     }
index db91c15..ce78fb3 100644 (file)
@@ -1,4 +1,4 @@
-%define DEV_VERSION beta-013
+%define DEV_VERSION beta-014
 
 Name:       elm-sharp
 Summary:    C# Binding for Elementary