Merge "Set proper locale to harfbuzz" into devel/master
[platform/core/uifw/dali-adaptor.git] / adaptors / wayland / input / seat.cpp
1 /*
2  * Copyright (c) 2015 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 "seat.h"
20
21 // EXTERNAL INCLUDES
22 #include <dali/integration-api/debug.h>
23 #include <cctype>
24 #include <sys/mman.h>
25 #include <unistd.h>
26 #include <stdio.h>
27 #include <cstring>
28
29 // INTERNAL INCLUDES
30 #include "input-listeners.h"
31
32
33 namespace Dali
34 {
35
36 namespace Internal
37 {
38
39 namespace Adaptor
40 {
41
42 namespace
43 {
44 const unsigned int DEFAULT_KEY_REPEAT_RATE = 25;
45 const unsigned int DEFAULT_KEY_REPEAT_DELAY = 400;
46 }
47
48 Seat::Seat( InputInterface* inputInterface,  WlSeat* seatInterface )
49 :mPointer( NULL ),
50  mKeyboard( NULL ),
51  mTouch( NULL ),
52  mWaylandSeat( seatInterface ),
53  mTextInput( NULL ),
54  mSurface( NULL ),
55  mInputInterface( inputInterface ),
56  mPointerPosition( 0, 0),
57  mDepressedKeyboardModifiers(0),
58  mKeyRepeatRate( DEFAULT_KEY_REPEAT_RATE ),
59  mKeyRepeatDelay( DEFAULT_KEY_REPEAT_DELAY )
60 {
61 }
62
63 Seat::~Seat()
64 {
65   DestroyPointerInterface();
66   DestroyTouchInterface();
67   DestroyKeyboardInterface();
68 }
69
70 void Seat::SetTextInputInterface( WlTextInput* textInput )
71 {
72   mTextInput = textInput;
73 }
74
75 void Seat::SetSurfaceInterface( WlSurface* surface )
76 {
77   mSurface = surface;
78 }
79
80 void Seat::SetPointerInterface( InterfaceStatus status )
81 {
82   if( status == INTERFACE_AVAILABLE )
83   {
84     if( ! mPointer )
85     {
86       WlPointer* pointerInterface = wl_seat_get_pointer( mWaylandSeat );
87
88       // store the interface and add an event listener
89       wl_pointer_add_listener( pointerInterface, Wayland::GetPointerListener(), mInputInterface );
90
91       mPointer = pointerInterface;
92     }
93   }
94   else
95   {
96     DestroyPointerInterface();
97   }
98 }
99
100 void Seat::SetTouchInterface( InterfaceStatus status )
101 {
102   if( status == INTERFACE_AVAILABLE )
103   {
104     // check if it's configured already
105     if( ! mTouch )
106     {
107       WlTouch* touchInterface = wl_seat_get_touch( mWaylandSeat );
108
109       wl_touch_add_listener( touchInterface, Wayland::GetTouchListener(), mInputInterface );
110
111       // store the interface and add an event listener
112       mTouch = touchInterface;
113     }
114   }
115   else
116   {
117     DestroyTouchInterface();
118   }
119
120 }
121
122 void Seat::SetKeyboardInterface( InterfaceStatus status )
123 {
124   if( status == INTERFACE_AVAILABLE )
125   {
126     // check if it's configured already
127     if( ! mKeyboard )
128     {
129       WlKeyboard* keyboardInterface = wl_seat_get_keyboard( mWaylandSeat );
130
131       wl_keyboard_add_listener( keyboardInterface, Wayland::GetKeyboardListener(), mInputInterface );
132
133       // store the interface and add an event listener
134       mKeyboard = keyboardInterface;
135     }
136   }
137   else
138   {
139     DestroyKeyboardInterface();
140   }
141 }
142
143 WlPointer* Seat::GetPointerInterface()
144 {
145   return mPointer;
146 }
147
148 WlTouch* Seat::GetTouchInterface()
149 {
150   return mTouch;
151 }
152
153 WlKeyboard* Seat::GetKeyboardInterface()
154 {
155   return mKeyboard;
156 }
157
158 WlSeat* Seat::GetSeatInterface()
159 {
160   return mWaylandSeat;
161 }
162
163 WlTextInput* Seat::GetTextInputInterface()
164 {
165   return mTextInput;
166 }
167
168 WlSurface* Seat::GetSurface()
169 {
170   return mSurface;
171 }
172
173 void Seat::DestroyPointerInterface()
174 {
175   if( mPointer )
176   {
177     wl_pointer_destroy( mPointer );
178     mPointer = NULL;
179   }
180 }
181
182 void Seat::DestroyTouchInterface()
183 {
184   if( mTouch )
185   {
186     wl_touch_destroy( mTouch );
187     mTouch = NULL;
188   }
189 }
190
191 void Seat::DestroyKeyboardInterface()
192 {
193   if( mKeyboard )
194   {
195     wl_keyboard_destroy( mKeyboard );
196     mKeyboard = NULL;
197   }
198 }
199
200 void Seat::SetName( const char* name )
201 {
202   mName = std::string( mName );
203 }
204 const std::string& Seat::GetName() const
205 {
206   return mName;
207 }
208
209 const Dali::Vector2& Seat::GetLastPointerPosition() const
210 {
211   return mPointerPosition;
212 }
213
214 void Seat::SetPointerPosition( Dali::Vector2 position)
215 {
216   mPointerPosition = position;
217 }
218
219 void Seat::KeyboardKeymap( unsigned int format, int fd, unsigned int size )
220 {
221
222   if( !mXkbData.mContext )
223   {
224     mXkbData.mContext = xkb_context_new( XKB_CONTEXT_NO_FLAGS );
225   }
226
227   if( !mXkbData.mContext )
228   {
229     DALI_LOG_ERROR("xkb_context_new failed\n");
230     close(fd);
231     return;
232   }
233
234   // current formats defined in wayland-client-protocol.h
235   // WL_KEYBOARD_KEYMAP_FORMAT_NO_KEYMAP =0, WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1=1
236
237   if( format != WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1 )
238   {
239     DALI_LOG_ERROR("expected WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1\n");
240     close(fd);
241     return;
242   }
243
244   // memory map the shared region between us and XKB
245   char* map =  static_cast<char*> (mmap( NULL, size, PROT_READ, MAP_SHARED, fd, 0));
246   if( map == MAP_FAILED)
247   {
248     DALI_LOG_ERROR("mmap xkb failed\n");
249     close(fd);
250     return;
251   }
252
253   mXkbData.mKeymap = xkb_map_new_from_string(mXkbData.mContext, map, XKB_KEYMAP_FORMAT_TEXT_V1, XKB_KEYMAP_COMPILE_NO_FLAGS);
254
255   munmap(map, size);
256   close(fd);
257
258   if (! mXkbData.mKeymap )
259   {
260     DALI_LOG_ERROR(" xkb_map_new_from_string failed\n");
261     return;
262   }
263
264   mXkbData.mState =  xkb_state_new( mXkbData.mKeymap );
265
266   if( ! mXkbData.mState )
267   {
268     xkb_map_unref(mXkbData.mKeymap );
269     mXkbData.mKeymap = NULL;
270     return;
271   }
272
273   // store the bit which each mod will set when calling xkb_state_serialize_mods
274   mXkbData.mControlMask = 1 << xkb_map_mod_get_index( mXkbData.mKeymap, XKB_MOD_NAME_CTRL);
275   mXkbData.mAltMask =     1 << xkb_map_mod_get_index( mXkbData.mKeymap, XKB_MOD_NAME_ALT);
276   mXkbData.mShiftMask =   1 << xkb_map_mod_get_index( mXkbData.mKeymap, XKB_MOD_NAME_SHIFT);
277
278 }
279
280 Dali::KeyEvent Seat::GetDALiKeyEventFromSymbol( unsigned int serial,
281                                       unsigned int timestamp,
282                                       unsigned int symbol,
283                                       unsigned int state,
284                                       unsigned int modifiers )
285 {
286  char key[256] = { 0 };
287  char keyName[256] = { 0 };
288
289  // get its name
290  xkb_keysym_get_name( symbol, key, sizeof(key));
291
292  // copy the keyname
293  memcpy(keyName, key, sizeof(keyName));
294
295  if (keyName[0] == '\0')
296  {
297    snprintf(keyName, sizeof(keyName), "Keycode-%u", symbol);
298  }
299
300  Dali::KeyEvent keyEvent;
301
302  keyEvent.keyCode = symbol; // we don't get the keycode so just the symbol
303  if( state == 1)
304  {
305    keyEvent.state = KeyEvent::Down;
306  }
307  else
308  {
309    keyEvent.state = KeyEvent::Up;
310  }
311
312  keyEvent.keyPressed = keyName;
313  keyEvent.keyPressedName = keyName;
314  keyEvent.time = timestamp;
315  keyEvent.keyModifier =  modifiers;
316
317  return keyEvent;
318
319 }
320
321
322 Dali::KeyEvent Seat::GetDALiKeyEvent( unsigned int serial, unsigned int timestamp, unsigned int keycode, unsigned int state  )
323 {
324  unsigned int code( 0 );
325  unsigned int symbolCount( 0 );
326  const xkb_keysym_t* symbols( NULL );
327  xkb_keysym_t symbol = XKB_KEY_NoSymbol;
328  char key[256] = { 0 };
329  char keyName[256] = { 0 };
330
331  // X11 historically has a min keycode of 8 instead of 1, XKB follow this
332  code = keycode + 8;
333
334  //get the key symbols
335  symbolCount = xkb_key_get_syms( mXkbData.mState, code, &symbols);
336
337  if( symbolCount == 1)
338  {
339    symbol = symbols[0];
340  }
341
342  // get its name
343  xkb_keysym_get_name( symbol, key, sizeof(key));
344
345  // copy the keyname
346  memcpy(keyName, key, sizeof(keyName));
347
348  if (keyName[0] == '\0')
349  {
350    snprintf(keyName, sizeof(keyName), "Keycode-%u", code);
351  }
352
353  // todo support key repeat settings
354
355  Dali::KeyEvent keyEvent;
356
357  keyEvent.keyCode = code;
358  if( state == 1)
359  {
360    keyEvent.state = KeyEvent::Down;
361  }
362  else
363  {
364    keyEvent.state = KeyEvent::Up;
365  }
366  keyEvent.keyPressed = keyName;
367  keyEvent.keyPressedName = keyName;
368  keyEvent.time = timestamp;
369  keyEvent.keyModifier =  mDepressedKeyboardModifiers;
370
371  return keyEvent;
372
373 }
374 unsigned int Seat::GetDepressedKeyboardModifiers() const
375 {
376   return mDepressedKeyboardModifiers;
377 }
378
379 void Seat::SetDepressedKeyboardModifiers( unsigned int modifiers)
380 {
381   mDepressedKeyboardModifiers = modifiers;
382 }
383
384 void Seat::SetKeyRepeatInfo( unsigned int rate, unsigned int delay )
385 {
386   mKeyRepeatRate = rate;
387   mKeyRepeatDelay = delay;
388 }
389
390 } // Internal
391 } // Adaptor
392 } // Dali