c6e2a04855b8e9019a29c4923233a2924c95d965
[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  mInputInterface( inputInterface ),
54  mPointerPosition( 0, 0),
55  mDepressedKeyboardModifiers(0),
56  mKeyRepeatRate( DEFAULT_KEY_REPEAT_RATE ),
57  mKeyRepeatDelay( DEFAULT_KEY_REPEAT_DELAY )
58 {
59 }
60
61 Seat::~Seat()
62 {
63   DestroyPointerInterface();
64   DestroyTouchInterface();
65   DestroyKeyboardInterface();
66 }
67
68 void Seat::SetPointerInterface( InterfaceStatus status )
69 {
70   if( status == INTERFACE_AVAILABLE )
71   {
72     if( ! mPointer )
73     {
74       WlPointer* pointerInterface = wl_seat_get_pointer( mWaylandSeat );
75
76       // store the interface and add an event listener
77       wl_pointer_add_listener( pointerInterface, Wayland::GetPointerListener(), mInputInterface );
78
79       mPointer = pointerInterface;
80     }
81   }
82   else
83   {
84     DestroyPointerInterface();
85   }
86 }
87
88 void Seat::SetTouchInterface( InterfaceStatus status )
89 {
90   if( status == INTERFACE_AVAILABLE )
91   {
92     // check if it's configured already
93     if( ! mTouch )
94     {
95       WlTouch* touchInterface = wl_seat_get_touch( mWaylandSeat );
96
97       wl_touch_add_listener( touchInterface, Wayland::GetTouchListener(), mInputInterface );
98
99       // store the interface and add an event listener
100       mTouch = touchInterface;
101     }
102   }
103   else
104   {
105     DestroyTouchInterface();
106   }
107
108 }
109
110 void Seat::SetKeyboardInterface( InterfaceStatus status )
111 {
112   if( status == INTERFACE_AVAILABLE )
113   {
114     // check if it's configured already
115     if( ! mKeyboard )
116     {
117       WlKeyboard* keyboardInterface = wl_seat_get_keyboard( mWaylandSeat );
118
119       wl_keyboard_add_listener( keyboardInterface, Wayland::GetKeyboardListener(), mInputInterface );
120
121       // store the interface and add an event listener
122       mKeyboard = keyboardInterface;
123     }
124   }
125   else
126   {
127     DestroyKeyboardInterface();
128   }
129 }
130
131 WlPointer* Seat::GetPointerInterface()
132 {
133   return mPointer;
134 }
135
136 WlTouch* Seat::GetTouchInterface()
137 {
138   return mTouch;
139 }
140
141 WlKeyboard* Seat::GetKeyboardInterface()
142 {
143   return mKeyboard;
144 }
145
146 WlSeat* Seat::GetSeatInterface()
147 {
148   return mWaylandSeat;
149 }
150
151 void Seat::DestroyPointerInterface()
152 {
153   if( mPointer )
154   {
155     wl_pointer_destroy( mPointer );
156     mPointer = NULL;
157   }
158 }
159
160 void Seat::DestroyTouchInterface()
161 {
162   if( mTouch )
163   {
164     wl_touch_destroy( mTouch );
165     mTouch = NULL;
166   }
167 }
168
169 void Seat::DestroyKeyboardInterface()
170 {
171   if( mKeyboard )
172   {
173     wl_keyboard_destroy( mKeyboard );
174     mKeyboard = NULL;
175   }
176 }
177
178 void Seat::SetName( const char* name )
179 {
180   mName = std::string( mName );
181 }
182 const std::string& Seat::GetName() const
183 {
184   return mName;
185 }
186
187 const Dali::Vector2& Seat::GetLastPointerPosition() const
188 {
189   return mPointerPosition;
190 }
191
192 void Seat::SetPointerPosition( Dali::Vector2 position)
193 {
194   mPointerPosition = position;
195 }
196
197 void Seat::KeyboardKeymap( unsigned int format, int fd, unsigned int size )
198 {
199
200   if(!mXkbData.mContext )
201   {
202     mXkbData.mContext = xkb_context_new( XKB_CONTEXT_NO_FLAGS );
203   }
204
205   // current formats defined in wayland-client-protocol.h
206   // WL_KEYBOARD_KEYMAP_FORMAT_NO_KEYMAP =0, WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1=1
207
208   if( format != WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1 )
209   {
210     DALI_LOG_ERROR("expected WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1");
211     close(fd);
212     return;
213   }
214
215   // memory map the shared region between us and XKB
216   char* map =  static_cast<char*> (mmap( NULL, size, PROT_READ, MAP_SHARED, fd, 0));
217   if( map == MAP_FAILED)
218   {
219     DALI_LOG_ERROR("mmap xkb failed");
220     close(fd);
221     return;
222   }
223
224   mXkbData.mKeymap = xkb_map_new_from_string(mXkbData.mContext, map, XKB_KEYMAP_FORMAT_TEXT_V1, XKB_KEYMAP_COMPILE_NO_FLAGS);
225
226   munmap(map, size);
227   close(fd);
228
229   if (! mXkbData.mKeymap )
230   {
231     DALI_LOG_ERROR(" xkb_map_new_from_string failed");
232     return;
233   }
234
235   mXkbData.mState =  xkb_state_new( mXkbData.mKeymap );
236
237   if( ! mXkbData.mState )
238   {
239     xkb_map_unref(mXkbData.mKeymap );
240     mXkbData.mKeymap = NULL;
241     return;
242   }
243
244   // store the bit which each mod will set when calling xkb_state_serialize_mods
245   mXkbData.mControlMask = 1 << xkb_map_mod_get_index( mXkbData.mKeymap, XKB_MOD_NAME_CTRL);
246   mXkbData.mAltMask =     1 << xkb_map_mod_get_index( mXkbData.mKeymap, XKB_MOD_NAME_ALT);
247   mXkbData.mShiftMask =   1 << xkb_map_mod_get_index( mXkbData.mKeymap, XKB_MOD_NAME_SHIFT);
248
249 }
250
251 Dali::KeyEvent Seat::GetDALiKeyEvent( unsigned int serial, unsigned int timestamp, unsigned int keycode, unsigned int state  )
252 {
253  unsigned int code( 0 );
254  unsigned int symbolCount( 0 );
255  const xkb_keysym_t* symbols( NULL );
256  xkb_keysym_t symbol = XKB_KEY_NoSymbol;
257  char key[256] = { 0 };
258  char keyName[256] = { 0 };
259
260  // X11 historically has a min keycode of 8 instead of 1, XKB follow this
261  code = keycode + 8;
262
263  //get the key symbols
264  symbolCount = xkb_key_get_syms( mXkbData.mState, code, &symbols);
265
266  if( symbolCount == 1)
267  {
268    symbol = symbols[0];
269  }
270  else
271
272  // get its name
273  xkb_keysym_get_name( symbol, key, sizeof(key));
274
275  // copy the keyname
276  memcpy(keyName, key, sizeof(keyName));
277
278  if (keyName[0] == '\0')
279  {
280    snprintf(keyName, sizeof(keyName), "Keycode-%u", code);
281  }
282
283  // todo support key repeat settings
284
285  Dali::KeyEvent keyEvent;
286
287  keyEvent.keyCode = code;
288  if( state == 1)
289  {
290    keyEvent.state = KeyEvent::Down;
291  }
292  else
293  {
294    keyEvent.state = KeyEvent::Up;
295  }
296  keyEvent.keyPressedName = keyName;
297  keyEvent.time = timestamp;
298  keyEvent.keyModifier =  mDepressedKeyboardModifiers;
299
300  return keyEvent;
301
302 }
303 unsigned int Seat::GetDepressedKeyboardModifiers() const
304 {
305   return mDepressedKeyboardModifiers;
306 }
307
308 void Seat::SetDepressedKeyboardModifiers( unsigned int modifiers)
309 {
310   mDepressedKeyboardModifiers = modifiers;
311 }
312
313 void Seat::SetKeyRepeatInfo( unsigned int rate, unsigned int delay )
314 {
315   mKeyRepeatRate = rate;
316   mKeyRepeatDelay = delay;
317 }
318
319 } // Internal
320 } // Adaptor
321 } // Dali