d50b52e39358a888dfcb3e3d99e9ef7e9fef026f
[platform/core/uifw/dali-adaptor.git] / adaptors / common / key-impl.cpp
1 /*
2  * Copyright (c) 2014 Samsung Electronics Co., Ltd.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *
16  */
17
18 // CLASS HEADER
19 #include "key-impl.h"
20
21 // EXTERNAL INCLUDES
22 #include <dlfcn.h>
23 #include <map>
24 #include <string.h>
25 #include <iostream>
26
27 #include <dali/integration-api/debug.h>
28
29 namespace Dali
30 {
31
32 namespace Internal
33 {
34
35 namespace Adaptor
36 {
37
38 namespace KeyLookup
39 {
40
41 namespace
42 {
43 #if defined(DEBUG_ENABLED)
44 Debug::Filter* gKeyExtensionLogFilter = Debug::Filter::New(Debug::NoLogging, false, "LOG_KEY_EXTENSION");
45 #endif
46
47 // Path for loading extension keys
48 const char* KEY_EXTENSION_PLUGIN_SO( "libdali-key-extension.so" );
49
50 class KeyMap
51 {
52   public:
53
54   KeyMap():
55   mExtensionKeyLookupTable(NULL),
56   mPlugin(NULL),
57   mHandle(NULL),
58   mCreateKeyExtensionPluginPtr(NULL),
59   mDestroyKeyExtensionPluginPtr(NULL),
60   mLookup( cmpString ),
61   mExtensionLookup( cmpString ),
62   mExtensionLookupCount(0),
63   mIsLookupTableInitialized( false ),
64   mIsExtensionLookupTableInitialized( false )
65   {
66   }
67
68   ~KeyMap()
69   {
70     if( mHandle != NULL )
71     {
72       if( mDestroyKeyExtensionPluginPtr != NULL )
73       {
74         mDestroyKeyExtensionPluginPtr( mPlugin );
75       }
76
77       dlclose( mHandle );
78     }
79   }
80
81   int GetDaliKeyEnum( const char* keyName )
82   {
83     // If lookup table is not initialized, initialize lookup table
84     if( !mIsLookupTableInitialized )
85     {
86       InitializeLookupTable();
87     }
88
89     Lookup::const_iterator i = mLookup.find( keyName );
90
91     if( i == mLookup.end() )
92     {
93       // If cannot find target, find it at the extension
94       // If extension lookup table is not initialized, initialize extension lookup table
95       if( !mIsExtensionLookupTableInitialized )
96       {
97         InitializeExtensionLookupTable();
98       }
99
100       // Find at extension
101       i = mExtensionLookup.find( keyName );
102
103       if( i == mExtensionLookup.end() )
104       {
105         return -1;
106       }
107       else
108       {
109         return (*i).second.first;
110       }
111     }
112     else
113     {
114       return (*i).second.first;
115     }
116   }
117
118   const char* GetKeyName( int daliKeyCode )
119   {
120     // If lookup table is not initialized, initialize lookup table
121     if( !mIsLookupTableInitialized )
122     {
123       InitializeLookupTable();
124     }
125
126     for( size_t i = 0; i < KEY_LOOKUP_COUNT ; ++i )
127     {
128       if( KeyLookupTable[i].daliKeyCode == daliKeyCode )
129       {
130         return KeyLookupTable[i].keyName;
131       }
132     }
133
134     // If extension lookup table is not initialized, initialize extension lookup table
135     if( !mIsExtensionLookupTableInitialized )
136     {
137       InitializeExtensionLookupTable();
138     }
139
140     for( size_t i = 0; i < mExtensionLookupCount ; ++i )
141     {
142       if( mExtensionKeyLookupTable[i].daliKeyCode == daliKeyCode )
143       {
144         return mExtensionKeyLookupTable[i].keyName;
145       }
146     }
147
148     return NULL;
149   }
150
151   bool IsDeviceButton( const char* keyName )
152   {
153     // If lookup table is not initialized, initialize lookup table
154     if( !mIsLookupTableInitialized )
155     {
156       InitializeLookupTable();
157     }
158
159     Lookup::const_iterator i = mLookup.find( keyName );
160     if( i == mLookup.end() )
161     {
162       // If cannot find target, find it at the extension.
163       // If extension lookup table is not initialized, initialize extension lookup table
164       if( !mIsExtensionLookupTableInitialized )
165       {
166         InitializeExtensionLookupTable();
167       }
168
169       // Find at extension
170       i = mExtensionLookup.find( keyName );
171
172       if( i == mExtensionLookup.end() )
173       {
174         return false;
175       }
176       else
177       {
178         return (*i).second.second;
179       }
180     }
181     else
182     {
183       return (*i).second.second;
184     }
185
186     return false;
187   }
188
189
190   private:
191
192   void InitializeLookupTable()
193   {
194     // create the lookup
195     for( size_t i = 0; i < KEY_LOOKUP_COUNT ; ++i )
196     {
197       mLookup[ KeyLookupTable[i].keyName ] = DaliKeyType( KeyLookupTable[i].daliKeyCode, KeyLookupTable[i].deviceButton );
198     }
199
200     mIsLookupTableInitialized = true;
201   }
202
203   void InitializeExtensionLookupTable()
204   {
205     // Try to load extension keys
206     char* error = NULL;
207     mHandle = dlopen( KEY_EXTENSION_PLUGIN_SO, RTLD_NOW );
208     error = dlerror();
209
210     if( mHandle == NULL )
211     {
212       DALI_LOG_INFO( gKeyExtensionLogFilter, Debug::General, "Failed to get handle from libdali-key-extension.so\n" );
213       return;
214     }
215
216     if( error != NULL )
217     {
218       DALI_LOG_INFO( gKeyExtensionLogFilter, Debug::General, "dlopen got error: %s  \n", error );
219       return;
220     }
221
222     mCreateKeyExtensionPluginPtr = reinterpret_cast< CreateKeyExtensionPluginFunction >( dlsym( mHandle, "CreateKeyExtensionPlugin" ) );
223     if( mCreateKeyExtensionPluginPtr == NULL )
224     {
225       DALI_LOG_INFO( gKeyExtensionLogFilter, Debug::General, "Failed to get CreateKeyExtensionPlugin function\n" );
226       return;
227     }
228
229     mPlugin = mCreateKeyExtensionPluginPtr();
230     if( mPlugin == NULL )
231     {
232       DALI_LOG_INFO( gKeyExtensionLogFilter, Debug::General, "Failed to create plugin object\n" );
233       return;
234     }
235
236     mDestroyKeyExtensionPluginPtr = reinterpret_cast< DestroyKeyExtensionPluginFunction >( dlsym( mHandle, "DestroyKeyExtensionPlugin" ) );
237     if( mDestroyKeyExtensionPluginPtr == NULL )
238     {
239       DALI_LOG_INFO( gKeyExtensionLogFilter, Debug::General, "Failed to get DestroyKeyExtensionPlugin function\n" );
240       return;
241     }
242
243     mExtensionKeyLookupTable = mPlugin->GetKeyLookupTable();
244     mExtensionLookupCount = mPlugin->GetKeyLookupTableCount();
245
246     // Add extension keys to lookup
247     for( size_t i = 0; i < mExtensionLookupCount ; ++i )
248     {
249       mExtensionLookup[ mExtensionKeyLookupTable[i].keyName  ] = DaliKeyType( mExtensionKeyLookupTable[i].daliKeyCode, mExtensionKeyLookupTable[i].deviceButton );
250     }
251
252     mIsExtensionLookupTableInitialized = true;
253   }
254
255   /**
256    * compare function, to compare string by pointer
257    */
258   static bool cmpString( const char* a, const char* b)
259   {
260     return strcmp(a, b) < 0;
261   }
262
263   KeyExtensionPlugin::KeyLookup* mExtensionKeyLookupTable;                               ///< Lookup table for extension keys
264   Dali::KeyExtensionPlugin* mPlugin;                                                     ///< Key extension plugin handle
265   void* mHandle;                                                                         ///< Handle for the loaded library
266   typedef Dali::KeyExtensionPlugin* (*CreateKeyExtensionPluginFunction)();               ///< Type of function pointer to get KeyExtensionPlugin object
267   typedef void (*DestroyKeyExtensionPluginFunction)( Dali::KeyExtensionPlugin* plugin ); ///< Type of function pointer to delete KeyExtensionPlugin object
268   CreateKeyExtensionPluginFunction mCreateKeyExtensionPluginPtr;                         ///< Function pointer to get KeyExtensionPlugin object
269   DestroyKeyExtensionPluginFunction mDestroyKeyExtensionPluginPtr;                       ///< Function pointer to delete KeyExtensionPlugin object
270
271   typedef std::pair< int, bool > DaliKeyType;
272   typedef std::map<const char* /* key name */, DaliKeyType /* key code */, bool(*) ( char const* a, char const* b) > Lookup;
273   Lookup mLookup;
274   Lookup mExtensionLookup;
275   size_t mExtensionLookupCount;                                                          ///< count of extension lookup table
276   bool mIsLookupTableInitialized;                                                        ///< flag for basic lookup table initialization
277   bool mIsExtensionLookupTableInitialized;                                               ///< flag for extension lookup table initialization
278 };
279 KeyMap globalKeyLookup;
280
281 } // un-named name space
282
283 bool IsKey( const Dali::KeyEvent& keyEvent, Dali::KEY daliKey)
284 {
285   int key = globalKeyLookup.GetDaliKeyEnum( keyEvent.keyPressedName.c_str() );
286   return daliKey == key;
287 }
288
289 bool IsDeviceButton( const char* keyName )
290 {
291   return globalKeyLookup.IsDeviceButton( keyName );
292 }
293
294 const char* GetKeyName( Dali::KEY daliKey )
295 {
296   return globalKeyLookup.GetKeyName( daliKey );
297 }
298
299 int GetDaliKeyCode( const char* keyName )
300 {
301   return globalKeyLookup.GetDaliKeyEnum( keyName );
302 }
303
304 } // namespace KeyLookup
305
306 } // namespace Adaptor
307
308 } // namespace Internal
309
310 } // namespace Dali