[3.0]Change the location of checking NULL of mContext
[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");
230     close(fd);
231     return;
232   }
233   // current formats defined in wayland-client-protocol.h
234   // WL_KEYBOARD_KEYMAP_FORMAT_NO_KEYMAP =0, WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1=1
235
236   if( format != WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1 )
237   {
238     DALI_LOG_ERROR("expected WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1");
239     close(fd);
240     return;
241   }
242
243   // memory map the shared region between us and XKB
244   char* map =  static_cast<char*> (mmap( NULL, size, PROT_READ, MAP_SHARED, fd, 0));
245   if( map == MAP_FAILED)
246   {
247     DALI_LOG_ERROR("mmap xkb failed");
248     close(fd);
249     return;
250   }
251
252   mXkbData.mKeymap = xkb_map_new_from_string(mXkbData.mContext, map, XKB_KEYMAP_FORMAT_TEXT_V1, XKB_KEYMAP_COMPILE_NO_FLAGS);
253
254   munmap(map, size);
255   close(fd);
256
257   if (! mXkbData.mKeymap )
258   {
259     DALI_LOG_ERROR(" xkb_map_new_from_string failed");
260     return;
261   }
262
263   mXkbData.mState =  xkb_state_new( mXkbData.mKeymap );
264
265   if( ! mXkbData.mState )
266   {
267     xkb_map_unref(mXkbData.mKeymap );
268     mXkbData.mKeymap = NULL;
269     return;
270   }
271
272   // store the bit which each mod will set when calling xkb_state_serialize_mods
273   mXkbData.mControlMask = 1 << xkb_map_mod_get_index( mXkbData.mKeymap, XKB_MOD_NAME_CTRL);
274   mXkbData.mAltMask =     1 << xkb_map_mod_get_index( mXkbData.mKeymap, XKB_MOD_NAME_ALT);
275   mXkbData.mShiftMask =   1 << xkb_map_mod_get_index( mXkbData.mKeymap, XKB_MOD_NAME_SHIFT);
276
277 }
278
279 Dali::KeyEvent Seat::GetDALiKeyEventFromSymbol( unsigned int serial,
280                                       unsigned int timestamp,
281                                       unsigned int symbol,
282                                       unsigned int state,
283                                       unsigned int modifiers )
284 {
285  char key[256] = { 0 };
286  char keyName[256] = { 0 };
287
288  // get its name
289  xkb_keysym_get_name( symbol, key, sizeof(key));
290
291  // copy the keyname
292  memcpy(keyName, key, sizeof(keyName));
293
294  if (keyName[0] == '\0')
295  {
296    snprintf(keyName, sizeof(keyName), "Keycode-%u", symbol);
297  }
298
299  Dali::KeyEvent keyEvent;
300
301  keyEvent.keyCode = symbol; // we don't get the keycode so just the symbol
302  if( state == 1)
303  {
304    keyEvent.state = KeyEvent::Down;
305  }
306  else
307  {
308    keyEvent.state = KeyEvent::Up;
309  }
310
311  keyEvent.keyPressed = keyName;
312  keyEvent.keyPressedName = keyName;
313  keyEvent.time = timestamp;
314  keyEvent.keyModifier =  modifiers;
315
316  return keyEvent;
317
318 }
319
320
321 Dali::KeyEvent Seat::GetDALiKeyEvent( unsigned int serial, unsigned int timestamp, unsigned int keycode, unsigned int state  )
322 {
323  unsigned int code( 0 );
324  unsigned int symbolCount( 0 );
325  const xkb_keysym_t* symbols( NULL );
326  xkb_keysym_t symbol = XKB_KEY_NoSymbol;
327  char key[256] = { 0 };
328  char keyName[256] = { 0 };
329
330  // X11 historically has a min keycode of 8 instead of 1, XKB follow this
331  code = keycode + 8;
332
333  //get the key symbols
334  symbolCount = xkb_key_get_syms( mXkbData.mState, code, &symbols);
335
336  if( symbolCount == 1)
337  {
338    symbol = symbols[0];
339  }
340
341  // get its name
342  xkb_keysym_get_name( symbol, key, sizeof(key));
343
344  // copy the keyname
345  memcpy(keyName, key, sizeof(keyName));
346
347  if (keyName[0] == '\0')
348  {
349    snprintf(keyName, sizeof(keyName), "Keycode-%u", code);
350  }
351
352  // todo support key repeat settings
353
354  Dali::KeyEvent keyEvent;
355
356  keyEvent.keyCode = code;
357  if( state == 1)
358  {
359    keyEvent.state = KeyEvent::Down;
360  }
361  else
362  {
363    keyEvent.state = KeyEvent::Up;
364  }
365  keyEvent.keyPressed = keyName;
366  keyEvent.keyPressedName = keyName;
367  keyEvent.time = timestamp;
368  keyEvent.keyModifier =  mDepressedKeyboardModifiers;
369
370  return keyEvent;
371
372 }
373 unsigned int Seat::GetDepressedKeyboardModifiers() const
374 {
375   return mDepressedKeyboardModifiers;
376 }
377
378 void Seat::SetDepressedKeyboardModifiers( unsigned int modifiers)
379 {
380   mDepressedKeyboardModifiers = modifiers;
381 }
382
383 void Seat::SetKeyRepeatInfo( unsigned int rate, unsigned int delay )
384 {
385   mKeyRepeatRate = rate;
386   mKeyRepeatDelay = delay;
387 }
388
389 } // Internal
390 } // Adaptor
391 } // Dali