~ubuntu-branches/ubuntu/wily/mir/wily-proposed

« back to all changes in this revision

Viewing changes to src/common/input/input_event.cpp

  • Committer: Package Import Robot
  • Author(s): CI Train Bot
  • Date: 2015-05-12 13:12:55 UTC
  • mto: This revision was merged to the branch mainline in revision 96.
  • Revision ID: package-import@ubuntu.com-20150512131255-y7z12i8n4pbvo70x
Tags: upstream-0.13.0+15.10.20150512
ImportĀ upstreamĀ versionĀ 0.13.0+15.10.20150512

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
 * Copyright Ā© 2014 Canonical Ltd.
3
 
 *
4
 
 * This program is free software: you can redistribute it and/or modify it
5
 
 * under the terms of the GNU Lesser General Public License version 3,
6
 
 * as published by the Free Software Foundation.
7
 
 *
8
 
 * This program is distributed in the hope that it will be useful,
9
 
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10
 
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11
 
 * GNU Lesser General Public License for more details.
12
 
 *
13
 
 * You should have received a copy of the GNU Lesser General Public License
14
 
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
15
 
 *
16
 
 * Authored by: Robert Carr <robert.carr@canonical.com>
17
 
 */
18
 
 
19
 
#define MIR_INCLUDE_DEPRECATED_EVENT_HEADER
20
 
 
21
 
#define MIR_LOGGING_COMPONENT "input-event-access"
22
 
 
23
 
#include "mir/event_type_to_string.h"
24
 
#include "mir/log.h"
25
 
 
26
 
#include "mir_toolkit/events/input/input_event.h"
27
 
 
28
 
#include <assert.h>
29
 
#include <stdlib.h>
30
 
 
31
 
// See: https://bugs.launchpad.net/mir/+bug/1311699
32
 
#define MIR_EVENT_ACTION_MASK 0xff
33
 
#define MIR_EVENT_ACTION_POINTER_INDEX_MASK 0xff00
34
 
#define MIR_EVENT_ACTION_POINTER_INDEX_SHIFT 8;
35
 
 
36
 
namespace ml = mir::logging;
37
 
 
38
 
namespace
39
 
{
40
 
void expect_old_event_type(MirEvent const* ev, MirEventType t)
41
 
{
42
 
    if (ev->type != t)
43
 
    {
44
 
        mir::log_critical("Expected " + mir::event_type_to_string(t) + " but event is of type " +
45
 
            mir::event_type_to_string(ev->type));
46
 
        abort();
47
 
    }
48
 
}
49
 
 
50
 
std::string input_event_type_to_string(MirInputEventType input_event_type)
51
 
{
52
 
    switch (input_event_type)
53
 
    {
54
 
        case mir_input_event_type_key:
55
 
            return "mir_input_event_type_key";
56
 
        case mir_input_event_type_touch:
57
 
            return "mir_input_event_type_touch";
58
 
        default:
59
 
            abort();
60
 
    }
61
 
}
62
 
 
63
 
// Never exposed in old event, so lets avoid leaking it in to a header now.
64
 
enum 
65
 
{
66
 
    AINPUT_SOURCE_CLASS_MASK = 0x000000ff,
67
 
 
68
 
    AINPUT_SOURCE_CLASS_BUTTON = 0x00000001,
69
 
    AINPUT_SOURCE_CLASS_POINTER = 0x00000002,
70
 
    AINPUT_SOURCE_CLASS_NAVIGATION = 0x00000004,
71
 
    AINPUT_SOURCE_CLASS_POSITION = 0x00000008,
72
 
    AINPUT_SOURCE_CLASS_JOYSTICK = 0x00000010
73
 
};
74
 
enum 
75
 
{
76
 
    AINPUT_SOURCE_UNKNOWN = 0x00000000,
77
 
 
78
 
    AINPUT_SOURCE_KEYBOARD = 0x00000100 | AINPUT_SOURCE_CLASS_BUTTON,
79
 
    AINPUT_SOURCE_DPAD = 0x00000200 | AINPUT_SOURCE_CLASS_BUTTON,
80
 
    AINPUT_SOURCE_GAMEPAD = 0x00000400 | AINPUT_SOURCE_CLASS_BUTTON,
81
 
    AINPUT_SOURCE_TOUCHSCREEN = 0x00001000 | AINPUT_SOURCE_CLASS_POINTER,
82
 
    AINPUT_SOURCE_MOUSE = 0x00002000 | AINPUT_SOURCE_CLASS_POINTER,
83
 
    AINPUT_SOURCE_STYLUS = 0x00004000 | AINPUT_SOURCE_CLASS_POINTER,
84
 
    AINPUT_SOURCE_TRACKBALL = 0x00010000 | AINPUT_SOURCE_CLASS_NAVIGATION,
85
 
    AINPUT_SOURCE_TOUCHPAD = 0x00100000 | AINPUT_SOURCE_CLASS_POSITION,
86
 
    AINPUT_SOURCE_JOYSTICK = 0x01000000 | AINPUT_SOURCE_CLASS_JOYSTICK,
87
 
 
88
 
    AINPUT_SOURCE_ANY = 0xffffff00
89
 
};
90
 
 
91
 
MirEvent const* old_ev_from_new(MirInputEvent const* ev)
92
 
{
93
 
    return reinterpret_cast<MirEvent const*>(ev);
94
 
}
95
 
 
96
 
MirKeyEvent const& old_kev_from_new(MirKeyInputEvent const* ev)
97
 
{
98
 
    auto old_ev = reinterpret_cast<MirEvent const*>(ev);
99
 
    expect_old_event_type(old_ev, mir_event_type_key);
100
 
    return old_ev->key;
101
 
}
102
 
 
103
 
MirMotionEvent const& old_mev_from_new(MirTouchInputEvent const* ev)
104
 
{
105
 
    auto old_ev = reinterpret_cast<MirEvent const*>(ev);
106
 
    expect_old_event_type(old_ev, mir_event_type_motion);
107
 
    return old_ev->motion;
108
 
}
109
 
 
110
 
MirMotionEvent const& old_mev_from_new(MirPointerInputEvent const* ev)
111
 
{
112
 
    auto old_ev = reinterpret_cast<MirEvent const*>(ev);
113
 
    expect_old_event_type(old_ev, mir_event_type_motion);
114
 
    return old_ev->motion;
115
 
}
116
 
 
117
 
// Differentiate between MirTouchInputEvents and MirPointerInputEvents based on old device class
118
 
MirInputEventType type_from_device_class(int32_t source_class)
119
 
{
120
 
    switch (source_class)
121
 
    {
122
 
    case AINPUT_SOURCE_MOUSE:
123
 
    case AINPUT_SOURCE_TRACKBALL:
124
 
    case AINPUT_SOURCE_TOUCHPAD:
125
 
        return mir_input_event_type_pointer;
126
 
    // Realistically touch events should only come from Stylus and Touchscreen
127
 
    // device classes...practically its not clear this is a safe assumption.
128
 
    default:
129
 
        return mir_input_event_type_touch;
130
 
    }
131
 
}
132
 
}
133
 
 
134
 
MirInputEventType mir_input_event_get_type(MirInputEvent const* ev)
135
 
{
136
 
    auto old_ev = old_ev_from_new(ev);
137
 
    
138
 
    if (old_ev->type != mir_event_type_key && old_ev->type != mir_event_type_motion)
139
 
    {
140
 
        mir::log_critical("expected input event but event was of type " + mir::event_type_to_string(old_ev->type));
141
 
        abort();
142
 
    }
143
 
 
144
 
    switch (old_ev->type)
145
 
    {
146
 
    case mir_event_type_key:
147
 
        return mir_input_event_type_key;
148
 
    case mir_event_type_motion:
149
 
        return type_from_device_class(old_ev->motion.source_id);
150
 
    default:
151
 
        abort();
152
 
    }
153
 
}
154
 
 
155
 
MirInputDeviceId mir_input_event_get_device_id(MirInputEvent const* ev)
156
 
{
157
 
    auto old_ev = old_ev_from_new(ev);
158
 
 
159
 
    if(mir_event_get_type(old_ev) != mir_event_type_input)
160
 
    {
161
 
        mir::log_critical("expected input event but event was of type " + mir::event_type_to_string(old_ev->type));
162
 
        abort();
163
 
    }
164
 
 
165
 
    switch (old_ev->type)
166
 
    {
167
 
    case mir_event_type_motion:
168
 
        return old_ev->motion.device_id;
169
 
    case mir_event_type_key:
170
 
        return old_ev->key.device_id;
171
 
    default:
172
 
        abort();
173
 
    }
174
 
}
175
 
 
176
 
int64_t mir_input_event_get_event_time(MirInputEvent const* ev)
177
 
{
178
 
    auto old_ev = old_ev_from_new(ev);
179
 
    if(mir_event_get_type(old_ev) != mir_event_type_input)
180
 
    {
181
 
        mir::log_critical("expected input event but event was of type " + mir::event_type_to_string(old_ev->type));
182
 
        abort();
183
 
    }
184
 
 
185
 
    switch (old_ev->type)
186
 
    {
187
 
    case mir_event_type_motion:
188
 
        return old_ev->motion.event_time;
189
 
    case mir_event_type_key:
190
 
        return old_ev->key.event_time;
191
 
    default:
192
 
        abort();
193
 
    }
194
 
}
195
 
 
196
 
/* Key event accessors */
197
 
 
198
 
MirKeyInputEvent const* mir_input_event_get_key_input_event(MirInputEvent const* ev)
199
 
{
200
 
    if (mir_input_event_get_type(ev) != mir_input_event_type_key)
201
 
    {
202
 
        mir::log_critical("expected key input event but event was of type " +
203
 
            input_event_type_to_string(mir_input_event_get_type(ev)));
204
 
        abort();
205
 
    }
206
 
    
207
 
    return reinterpret_cast<MirKeyInputEvent const*>(ev);
208
 
}
209
 
 
210
 
MirKeyInputEventAction mir_key_input_event_get_action(MirKeyInputEvent const* kev)
211
 
{
212
 
    auto const& old_kev = old_kev_from_new(kev);
213
 
    
214
 
    switch (old_kev.action)
215
 
    {
216
 
    case mir_key_action_down:
217
 
        if (old_kev.repeat_count != 0)
218
 
            return mir_key_input_event_action_repeat;
219
 
        else
220
 
            return mir_key_input_event_action_down;
221
 
    case mir_key_action_up:
222
 
        return mir_key_input_event_action_up;
223
 
    default:
224
 
        // TODO:? This means we got key_action_multiple which I dont think is 
225
 
        // actually emitted yet (and never will be as in the future it would fall under text
226
 
        // event in the new model).
227
 
        return mir_key_input_event_action_down;
228
 
    }
229
 
}
230
 
 
231
 
xkb_keysym_t mir_key_input_event_get_key_code(MirKeyInputEvent const* kev)
232
 
{
233
 
    auto const& old_kev = old_kev_from_new(kev);
234
 
    return old_kev.key_code;
235
 
}
236
 
 
237
 
int mir_key_input_event_get_scan_code(MirKeyInputEvent const* kev)
238
 
{
239
 
    auto const& old_kev = old_kev_from_new(kev);
240
 
    return old_kev.scan_code;
241
 
}
242
 
 
243
 
namespace
244
 
{
245
 
MirInputEventModifiers old_modifiers_to_new(unsigned int old_modifier)
246
 
{
247
 
    MirInputEventModifiers modifier = 0;
248
 
 
249
 
    if (old_modifier & mir_key_modifier_none)
250
 
        modifier |= mir_input_event_modifier_none;
251
 
    if (old_modifier & mir_key_modifier_alt)
252
 
        modifier |= mir_input_event_modifier_alt;
253
 
    if (old_modifier & mir_key_modifier_alt_left)
254
 
        modifier |= mir_input_event_modifier_alt_left;
255
 
    if (old_modifier & mir_key_modifier_alt_right)
256
 
        modifier |= mir_input_event_modifier_alt_right;
257
 
    if (old_modifier & mir_key_modifier_shift)
258
 
        modifier |= mir_input_event_modifier_shift;
259
 
    if (old_modifier & mir_key_modifier_shift_left)
260
 
        modifier |= mir_input_event_modifier_shift_left;
261
 
    if (old_modifier & mir_key_modifier_shift_right)
262
 
        modifier |= mir_input_event_modifier_shift_right;
263
 
    if (old_modifier & mir_key_modifier_sym)
264
 
        modifier |= mir_input_event_modifier_sym;
265
 
    if (old_modifier & mir_key_modifier_function)
266
 
        modifier |= mir_input_event_modifier_function;
267
 
    if (old_modifier & mir_key_modifier_ctrl)
268
 
        modifier |= mir_input_event_modifier_ctrl;
269
 
    if (old_modifier & mir_key_modifier_ctrl_left)
270
 
        modifier |= mir_input_event_modifier_ctrl_left;
271
 
    if (old_modifier & mir_key_modifier_ctrl_right)
272
 
        modifier |= mir_input_event_modifier_ctrl_right;
273
 
    if (old_modifier & mir_key_modifier_meta)
274
 
        modifier |= mir_input_event_modifier_meta;
275
 
    if (old_modifier & mir_key_modifier_meta_left)
276
 
        modifier |= mir_input_event_modifier_meta_left;
277
 
    if (old_modifier & mir_key_modifier_meta_right)
278
 
        modifier |= mir_input_event_modifier_meta_right;
279
 
    if (old_modifier & mir_key_modifier_caps_lock)
280
 
        modifier |= mir_input_event_modifier_caps_lock;
281
 
    if (old_modifier & mir_key_modifier_num_lock)
282
 
        modifier |= mir_input_event_modifier_num_lock;
283
 
    if (old_modifier & mir_key_modifier_scroll_lock)
284
 
        modifier |= mir_input_event_modifier_scroll_lock;
285
 
 
286
 
    if (modifier)
287
 
        return modifier;
288
 
    return mir_input_event_modifier_none;
289
 
}
290
 
}
291
 
MirInputEventModifiers mir_key_input_event_get_modifiers(MirKeyInputEvent const* kev)
292
 
{    
293
 
    auto const& old_kev = old_kev_from_new(kev);
294
 
    return old_modifiers_to_new(old_kev.modifiers);
295
 
}
296
 
/* Touch event accessors */
297
 
 
298
 
MirInputEventModifiers mir_touch_input_event_get_modifiers(MirTouchInputEvent const* tev)
299
 
{    
300
 
    auto const& old_mev = old_mev_from_new(tev);
301
 
    return old_modifiers_to_new(old_mev.modifiers);
302
 
}
303
 
 
304
 
MirTouchInputEvent const* mir_input_event_get_touch_input_event(MirInputEvent const* ev)
305
 
{
306
 
    if(mir_input_event_get_type(ev) != mir_input_event_type_touch)
307
 
    {
308
 
        mir::log_critical("expected touch input event but event was of type " +
309
 
            input_event_type_to_string(mir_input_event_get_type(ev)));
310
 
        abort();
311
 
    }
312
 
 
313
 
    return reinterpret_cast<MirTouchInputEvent const*>(ev);
314
 
}
315
 
 
316
 
unsigned int mir_touch_input_event_get_touch_count(MirTouchInputEvent const* event)
317
 
{
318
 
    auto const& old_mev = reinterpret_cast<MirEvent const*>(event)->motion;
319
 
    return old_mev.pointer_count;
320
 
}
321
 
 
322
 
MirTouchInputEventTouchId mir_touch_input_event_get_touch_id(MirTouchInputEvent const* event, size_t touch_index)
323
 
{
324
 
    auto const& old_mev = old_mev_from_new(event);
325
 
 
326
 
    if (touch_index >= old_mev.pointer_count)
327
 
    {
328
 
        mir::log_critical("touch index is greater than pointer count");
329
 
        abort();
330
 
    }
331
 
 
332
 
    return old_mev.pointer_coordinates[touch_index].id;
333
 
}
334
 
 
335
 
MirTouchInputEventTouchAction mir_touch_input_event_get_touch_action(MirTouchInputEvent const* event, size_t touch_index)
336
 
{
337
 
    auto const& old_mev = old_mev_from_new(event);
338
 
 
339
 
    if(touch_index > old_mev.pointer_count)
340
 
    {
341
 
        mir::log_critical("touch index is greater than pointer count");
342
 
        abort();
343
 
    }
344
 
    
345
 
    auto masked_action = old_mev.action & MIR_EVENT_ACTION_MASK;
346
 
    size_t masked_index = (old_mev.action & MIR_EVENT_ACTION_POINTER_INDEX_MASK) >> MIR_EVENT_ACTION_POINTER_INDEX_SHIFT;
347
 
 
348
 
    switch (masked_action)
349
 
    {
350
 
    // For the next two cases we could assert pc=1...because a gesture must
351
 
    // be starting or ending.
352
 
    case mir_motion_action_down:
353
 
        return mir_touch_input_event_action_down;
354
 
    case mir_motion_action_up:
355
 
        return mir_touch_input_event_action_up;
356
 
    // We can't tell which touches have actually moved without tracking state
357
 
    // so we report all touchpoints as changed.
358
 
    case mir_motion_action_move:
359
 
    case mir_motion_action_hover_move:
360
 
        return mir_touch_input_event_action_change;
361
 
    // All touch points are handled at once so we don't know the index
362
 
    case mir_motion_action_pointer_down:
363
 
        if (touch_index == masked_index)
364
 
            return mir_touch_input_event_action_down;
365
 
        else
366
 
            return mir_touch_input_event_action_change;
367
 
    case mir_motion_action_pointer_up:
368
 
        if (touch_index == masked_index)
369
 
            return mir_touch_input_event_action_up;
370
 
        else
371
 
            return mir_touch_input_event_action_change;
372
 
    // TODO: How to deal with these?
373
 
    case mir_motion_action_cancel:
374
 
    case mir_motion_action_outside:
375
 
    case mir_motion_action_scroll:
376
 
    case mir_motion_action_hover_enter:
377
 
    case mir_motion_action_hover_exit:
378
 
    default:
379
 
        return mir_touch_input_event_action_change;
380
 
    }
381
 
}
382
 
 
383
 
MirTouchInputEventTouchTooltype mir_touch_input_event_get_touch_tooltype(MirTouchInputEvent const* event,
384
 
    size_t touch_index)
385
 
{
386
 
    auto const& old_mev = old_mev_from_new(event);
387
 
 
388
 
    if(touch_index > old_mev.pointer_count)
389
 
    {
390
 
        mir::log_critical("touch index is greater than pointer count");
391
 
        abort();
392
 
    }
393
 
 
394
 
    switch (old_mev.pointer_coordinates[touch_index].tool_type)
395
 
    {
396
 
    case mir_motion_tool_type_finger:
397
 
        return mir_touch_input_tool_type_finger;
398
 
    case mir_motion_tool_type_stylus:
399
 
    case mir_motion_tool_type_eraser:
400
 
        return mir_touch_input_tool_type_stylus;
401
 
    case mir_motion_tool_type_mouse:
402
 
    case mir_motion_tool_type_unknown:
403
 
    default:
404
 
        return mir_touch_input_tool_type_unknown;
405
 
    }
406
 
}
407
 
 
408
 
float mir_touch_input_event_get_touch_axis_value(MirTouchInputEvent const* event,
409
 
    size_t touch_index, MirTouchInputEventTouchAxis axis)
410
 
{
411
 
    auto const& old_mev = old_mev_from_new(event);
412
 
 
413
 
    if(touch_index > old_mev.pointer_count)
414
 
    {
415
 
        mir::log_critical("touch index is greater than pointer count");
416
 
        abort();
417
 
    }
418
 
 
419
 
    auto const& old_pc = old_mev.pointer_coordinates[touch_index];
420
 
    switch (axis)
421
 
    {
422
 
    case mir_touch_input_axis_x:
423
 
        return old_pc.x;
424
 
    case mir_touch_input_axis_y:
425
 
        return old_pc.y;
426
 
    case mir_touch_input_axis_pressure:
427
 
        return old_pc.pressure;
428
 
    case mir_touch_input_axis_touch_major:
429
 
        return old_pc.touch_major;
430
 
    case mir_touch_input_axis_touch_minor:
431
 
        return old_pc.touch_minor;
432
 
    case mir_touch_input_axis_size:
433
 
        return old_pc.size;
434
 
    default:
435
 
        return -1;
436
 
    }
437
 
}                                                                            
438
 
 
439
 
/* Pointer event accessors */
440
 
MirPointerInputEvent const* mir_input_event_get_pointer_input_event(MirInputEvent const* ev)
441
 
{
442
 
    if(mir_input_event_get_type(ev) != mir_input_event_type_pointer)
443
 
    {
444
 
        mir::log_critical("expected pointer input event but event was of type " +
445
 
            input_event_type_to_string(mir_input_event_get_type(ev)));
446
 
        abort();
447
 
    }
448
 
 
449
 
    return reinterpret_cast<MirPointerInputEvent const*>(ev);
450
 
}
451
 
 
452
 
MirInputEventModifiers mir_pointer_input_event_get_modifiers(MirPointerInputEvent const* pev)
453
 
{    
454
 
    auto const& old_mev = old_mev_from_new(pev);
455
 
    return old_modifiers_to_new(old_mev.modifiers);
456
 
}
457
 
 
458
 
MirPointerInputEventAction mir_pointer_input_event_get_action(MirPointerInputEvent const* pev)
459
 
{    
460
 
    auto const& old_mev = old_mev_from_new(pev);
461
 
    auto masked_action = old_mev.action & MIR_EVENT_ACTION_MASK;
462
 
    switch (masked_action)
463
 
    {
464
 
    case mir_motion_action_up:
465
 
    case mir_motion_action_pointer_up:
466
 
        return mir_pointer_input_event_action_button_up;
467
 
    case mir_motion_action_down:
468
 
    case mir_motion_action_pointer_down:
469
 
        return mir_pointer_input_event_action_button_down;
470
 
    case mir_motion_action_hover_enter:
471
 
        return mir_pointer_input_event_action_enter;
472
 
    case mir_motion_action_hover_exit:
473
 
        return mir_pointer_input_event_action_leave;
474
 
    case mir_motion_action_move:
475
 
    case mir_motion_action_hover_move:
476
 
    case mir_motion_action_outside:
477
 
    default:
478
 
        return mir_pointer_input_event_action_motion;
479
 
    }
480
 
}
481
 
 
482
 
bool mir_pointer_input_event_get_button_state(MirPointerInputEvent const* pev,
483
 
    MirPointerInputEventButton button)
484
 
{
485
 
   auto const& old_mev = old_mev_from_new(pev);
486
 
   switch (button)
487
 
   {
488
 
   case mir_pointer_input_button_primary:
489
 
       return old_mev.button_state & mir_motion_button_primary;
490
 
   case mir_pointer_input_button_secondary:
491
 
       return old_mev.button_state & mir_motion_button_secondary;
492
 
   case mir_pointer_input_button_tertiary:
493
 
       return old_mev.button_state & mir_motion_button_tertiary;
494
 
   case mir_pointer_input_button_back:
495
 
       return old_mev.button_state & mir_motion_button_back;
496
 
   case mir_pointer_input_button_forward:
497
 
       return old_mev.button_state & mir_motion_button_forward;
498
 
   default:
499
 
       return false;
500
 
   }
501
 
}
502
 
 
503
 
float mir_pointer_input_event_get_axis_value(MirPointerInputEvent const* pev, MirPointerInputEventAxis axis)
504
 
{
505
 
   auto const& old_mev = old_mev_from_new(pev);
506
 
   switch (axis)
507
 
   {
508
 
   case mir_pointer_input_axis_x:
509
 
       return old_mev.pointer_coordinates[0].x;
510
 
   case mir_pointer_input_axis_y:
511
 
       return old_mev.pointer_coordinates[0].y;
512
 
   case mir_pointer_input_axis_vscroll:
513
 
       return old_mev.pointer_coordinates[0].vscroll;
514
 
   case mir_pointer_input_axis_hscroll:
515
 
       return old_mev.pointer_coordinates[0].hscroll;
516
 
   default:
517
 
       mir::log_critical("Invalid axis enumeration " + std::to_string(axis));
518
 
       abort();
519
 
   }
520
 
}