Fix build error.
[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 #if _GLIBCXX_USE_CXX11_ABI
49 const char* KEY_EXTENSION_PLUGIN_SO( "libdali-key-extension.so" );
50 #else
51 const char* KEY_EXTENSION_PLUGIN_SO( "libdali-key-extension-cxx03.so" );
52 #endif
53
54 class KeyMap
55 {
56   public:
57
58   KeyMap():
59   mExtensionKeyLookupTable(NULL),
60   mPlugin(NULL),
61   mHandle(NULL),
62   mCreateKeyExtensionPluginPtr(NULL),
63   mDestroyKeyExtensionPluginPtr(NULL),
64   mLookup( cmpString ),
65   mExtensionLookup( cmpString ),
66   mExtensionLookupCount(0),
67   mIsLookupTableInitialized( false ),
68   mIsExtensionLookupTableInitialized( false )
69   {
70   }
71
72   ~KeyMap()
73   {
74     if( mHandle != NULL )
75     {
76       if( mDestroyKeyExtensionPluginPtr != NULL )
77       {
78         mDestroyKeyExtensionPluginPtr( mPlugin );
79       }
80
81       dlclose( mHandle );
82     }
83   }
84
85   int GetDaliKeyEnum( const char* keyName )
86   {
87     // If lookup table is not initialized, initialize lookup table
88     if( !mIsLookupTableInitialized )
89     {
90       InitializeLookupTable();
91     }
92
93     Lookup::const_iterator i = mLookup.find( keyName );
94
95     if( i == mLookup.end() )
96     {
97       // If cannot find target, find it at the extension
98       // If extension lookup table is not initialized, initialize extension lookup table
99       if( !mIsExtensionLookupTableInitialized )
100       {
101         InitializeExtensionLookupTable();
102       }
103
104       // Find at extension
105       i = mExtensionLookup.find( keyName );
106
107       if( i == mExtensionLookup.end() )
108       {
109         return -1;
110       }
111       else
112       {
113         return (*i).second.first;
114       }
115     }
116     else
117     {
118       return (*i).second.first;
119     }
120   }
121
122   const char* GetKeyName( int daliKeyCode )
123   {
124     // If lookup table is not initialized, initialize lookup table
125     if( !mIsLookupTableInitialized )
126     {
127       InitializeLookupTable();
128     }
129
130     for( size_t i = 0; i < KEY_LOOKUP_COUNT ; ++i )
131     {
132       if( KeyLookupTable[i].daliKeyCode == daliKeyCode )
133       {
134         return KeyLookupTable[i].keyName;
135       }
136     }
137
138     // If extension lookup table is not initialized, initialize extension lookup table
139     if( !mIsExtensionLookupTableInitialized )
140     {
141       InitializeExtensionLookupTable();
142     }
143
144     for( size_t i = 0; i < mExtensionLookupCount ; ++i )
145     {
146       if( mExtensionKeyLookupTable[i].daliKeyCode == daliKeyCode )
147       {
148         return mExtensionKeyLookupTable[i].keyName;
149       }
150     }
151
152     return NULL;
153   }
154
155   bool IsDeviceButton( const char* keyName )
156   {
157     // If lookup table is not initialized, initialize lookup table
158     if( !mIsLookupTableInitialized )
159     {
160       InitializeLookupTable();
161     }
162
163     Lookup::const_iterator i = mLookup.find( keyName );
164     if( i == mLookup.end() )
165     {
166       // If cannot find target, find it at the extension.
167       // If extension lookup table is not initialized, initialize extension lookup table
168       if( !mIsExtensionLookupTableInitialized )
169       {
170         InitializeExtensionLookupTable();
171       }
172
173       // Find at extension
174       i = mExtensionLookup.find( keyName );
175
176       if( i == mExtensionLookup.end() )
177       {
178         return false;
179       }
180       else
181       {
182         return (*i).second.second;
183       }
184     }
185     else
186     {
187       return (*i).second.second;
188     }
189
190     return false;
191   }
192
193
194   private:
195
196   void InitializeLookupTable()
197   {
198     // create the lookup
199     for( size_t i = 0; i < KEY_LOOKUP_COUNT ; ++i )
200     {
201       mLookup[ KeyLookupTable[i].keyName ] = DaliKeyType( KeyLookupTable[i].daliKeyCode, KeyLookupTable[i].deviceButton );
202     }
203
204     mIsLookupTableInitialized = true;
205   }
206
207   void InitializeExtensionLookupTable()
208   {
209     // Try to load extension keys
210     char* error = NULL;
211     mHandle = dlopen( KEY_EXTENSION_PLUGIN_SO, RTLD_NOW );
212     error = dlerror();
213
214     if( mHandle == NULL )
215     {
216       DALI_LOG_INFO( gKeyExtensionLogFilter, Debug::General, "Failed to get handle from libdali-key-extension.so\n" );
217       return;
218     }
219
220     if( error != NULL )
221     {
222       DALI_LOG_INFO( gKeyExtensionLogFilter, Debug::General, "dlopen got error: %s  \n", error );
223       return;
224     }
225
226     mCreateKeyExtensionPluginPtr = reinterpret_cast< CreateKeyExtensionPluginFunction >( dlsym( mHandle, "CreateKeyExtensionPlugin" ) );
227     if( mCreateKeyExtensionPluginPtr == NULL )
228     {
229       DALI_LOG_INFO( gKeyExtensionLogFilter, Debug::General, "Failed to get CreateKeyExtensionPlugin function\n" );
230       return;
231     }
232
233     mPlugin = mCreateKeyExtensionPluginPtr();
234     if( mPlugin == NULL )
235     {
236       DALI_LOG_INFO( gKeyExtensionLogFilter, Debug::General, "Failed to create plugin object\n" );
237       return;
238     }
239
240     mDestroyKeyExtensionPluginPtr = reinterpret_cast< DestroyKeyExtensionPluginFunction >( dlsym( mHandle, "DestroyKeyExtensionPlugin" ) );
241     if( mDestroyKeyExtensionPluginPtr == NULL )
242     {
243       DALI_LOG_INFO( gKeyExtensionLogFilter, Debug::General, "Failed to get DestroyKeyExtensionPlugin function\n" );
244       return;
245     }
246
247     mExtensionKeyLookupTable = mPlugin->GetKeyLookupTable();
248     mExtensionLookupCount = mPlugin->GetKeyLookupTableCount();
249
250     // Add extension keys to lookup
251     for( size_t i = 0; i < mExtensionLookupCount ; ++i )
252     {
253       mExtensionLookup[ mExtensionKeyLookupTable[i].keyName  ] = DaliKeyType( mExtensionKeyLookupTable[i].daliKeyCode, mExtensionKeyLookupTable[i].deviceButton );
254     }
255
256     mIsExtensionLookupTableInitialized = true;
257   }
258
259   /**
260    * compare function, to compare string by pointer
261    */
262   static bool cmpString( const char* a, const char* b)
263   {
264     return strcmp(a, b) < 0;
265   }
266
267   KeyExtensionPlugin::KeyLookup* mExtensionKeyLookupTable;                               ///< Lookup table for extension keys
268   Dali::KeyExtensionPlugin* mPlugin;                                                     ///< Key extension plugin handle
269   void* mHandle;                                                                         ///< Handle for the loaded library
270   typedef Dali::KeyExtensionPlugin* (*CreateKeyExtensionPluginFunction)();               ///< Type of function pointer to get KeyExtensionPlugin object
271   typedef void (*DestroyKeyExtensionPluginFunction)( Dali::KeyExtensionPlugin* plugin ); ///< Type of function pointer to delete KeyExtensionPlugin object
272   CreateKeyExtensionPluginFunction mCreateKeyExtensionPluginPtr;                         ///< Function pointer to get KeyExtensionPlugin object
273   DestroyKeyExtensionPluginFunction mDestroyKeyExtensionPluginPtr;                       ///< Function pointer to delete KeyExtensionPlugin object
274
275   typedef std::pair< int, bool > DaliKeyType;
276   typedef std::map<const char* /* key name */, DaliKeyType /* key code */, bool(*) ( char const* a, char const* b) > Lookup;
277   Lookup mLookup;
278   Lookup mExtensionLookup;
279   size_t mExtensionLookupCount;                                                          ///< count of extension lookup table
280   bool mIsLookupTableInitialized;                                                        ///< flag for basic lookup table initialization
281   bool mIsExtensionLookupTableInitialized;                                               ///< flag for extension lookup table initialization
282 };
283 KeyMap globalKeyLookup;
284
285 } // un-named name space
286
287 bool IsKey( const Dali::KeyEvent& keyEvent, Dali::KEY daliKey)
288 {
289   int key = globalKeyLookup.GetDaliKeyEnum( keyEvent.keyPressedName.c_str() );
290   return daliKey == key;
291 }
292
293 bool IsDeviceButton( const char* keyName )
294 {
295   return globalKeyLookup.IsDeviceButton( keyName );
296 }
297
298 const char* GetKeyName( Dali::KEY daliKey )
299 {
300   return globalKeyLookup.GetKeyName( daliKey );
301 }
302
303 int GetDaliKeyCode( const char* keyName )
304 {
305   return globalKeyLookup.GetDaliKeyEnum( keyName );
306 }
307
308 } // namespace KeyLookup
309
310 } // namespace Adaptor
311
312 } // namespace Internal
313
314 } // namespace Dali