Esempio n. 1
0
void mi::Validator::handle_touch_event(MirInputDeviceId id, MirTouchEvent const* ev)
{
    std::lock_guard<std::mutex> lg(state_guard);

    auto it = last_event_by_device.find(id);
    MirTouchEvent const* last_ev = nullptr;
    auto default_ev = mev::make_event(id,
        std::chrono::high_resolution_clock::now().time_since_epoch(),
        0, /* No need for a mac, since there's no pointer count for a default event */
        mir_input_event_modifier_none); 

    if (it == last_event_by_device.end())
    {
        last_event_by_device.insert(std::make_pair(id, copy_event(ev)));
        last_ev = reinterpret_cast<MirTouchEvent const*>(default_ev.get());
    }
    else
    {
        last_ev = mir_input_event_get_touch_event(mir_event_get_input_event(it->second.get()));
    }
    
    ensure_stream_validity_locked(lg, ev, last_ev);

    // Seems to be no better way to replace a non default constructible value type in an unordered_map
    // C++17 will give us insert_or_assign
    last_event_by_device.erase(id);
    last_event_by_device.insert(std::make_pair(id, copy_event(ev)));
    
    dispatch_valid_event(*reinterpret_cast<MirEvent const*>(ev));
}
Esempio n. 2
0
bool me::WindowManager::handle(MirEvent const& event)
{
    assert(focus_controller);
    assert(display);
    assert(compositor);

    if (mir_event_get_type(&event) != mir_event_type_input)
        return false;
    auto iev = mir_event_get_input_event(&event);
    auto input_type = mir_input_event_get_type(iev);
    
    if (input_type == mir_input_event_type_key)
    {
        return handle_key_event(mir_input_event_get_keyboard_event(iev));
    }
    else if (input_type == mir_input_event_type_pointer &&
             focus_controller)
    {
        return handle_pointer_event(mir_input_event_get_pointer_event(iev));
    }
    else if (input_type == mir_input_event_type_touch &&
             focus_controller)
    {
        return handle_touch_event(mir_input_event_get_touch_event(iev));
    }


    return false;
}
Esempio n. 3
0
void QMirClientInput::dispatchTouchEvent(QMirClientWindow *window, const MirInputEvent *ev)
{
    const MirTouchEvent *tev = mir_input_event_get_touch_event(ev);

    // FIXME(loicm) Max pressure is device specific. That one is for the Samsung Galaxy Nexus. That
    //     needs to be fixed as soon as the compat input lib adds query support.
    const float kMaxPressure = 1.28;
    const QRect kWindowGeometry = window->geometry();
    QList<QWindowSystemInterface::TouchPoint> touchPoints;


    // TODO: Is it worth setting the Qt::TouchPointStationary ones? Currently they are left
    //       as Qt::TouchPointMoved
    const unsigned int kPointerCount = mir_touch_event_point_count(tev);
    touchPoints.reserve(int(kPointerCount));
    for (unsigned int i = 0; i < kPointerCount; ++i) {
        QWindowSystemInterface::TouchPoint touchPoint;

        const float kX = mir_touch_event_axis_value(tev, i, mir_touch_axis_x) + kWindowGeometry.x();
        const float kY = mir_touch_event_axis_value(tev, i, mir_touch_axis_y) + kWindowGeometry.y(); // see bug lp:1346633 workaround comments elsewhere
        const float kW = mir_touch_event_axis_value(tev, i, mir_touch_axis_touch_major);
        const float kH = mir_touch_event_axis_value(tev, i, mir_touch_axis_touch_minor);
        const float kP = mir_touch_event_axis_value(tev, i, mir_touch_axis_pressure);
        touchPoint.id = mir_touch_event_id(tev, i);
        touchPoint.normalPosition = QPointF(kX / kWindowGeometry.width(), kY / kWindowGeometry.height());
        touchPoint.area = QRectF(kX - (kW / 2.0), kY - (kH / 2.0), kW, kH);
        touchPoint.pressure = kP / kMaxPressure;

        MirTouchAction touch_action = mir_touch_event_action(tev, i);
        switch (touch_action)
        {
        case mir_touch_action_down:
            mLastInputWindow = window;
            touchPoint.state = Qt::TouchPointPressed;
            break;
        case mir_touch_action_up:
            touchPoint.state = Qt::TouchPointReleased;
            break;
        case mir_touch_action_change:
            touchPoint.state = Qt::TouchPointMoved;
            break;
        default:
            Q_UNREACHABLE();
        }

        touchPoints.append(touchPoint);
    }

    ulong timestamp = mir_input_event_get_event_time(ev) / 1000000;
    QWindowSystemInterface::handleTouchEvent(window->window(), timestamp,
            mTouchDevice, touchPoints);
}
// The following three requirements can be removed as soon as we remove android::InputDispatcher, which is the
// only remaining part that relies on the difference between mir_motion_action_pointer_{up,down} and
// mir_motion_action_{up,down} and the difference between mir_motion_action_move and mir_motion_action_hover_move.
TEST_F(InputEventBuilder, maps_single_touch_down_to_motion_down)
{
    MirTouchAction action =  mir_touch_action_down;

    auto ev = mev::make_event(device_id, timestamp, mac, modifiers);
    mev::add_touch(*ev, 0, action, mir_touch_tooltype_finger, 0, 0, 0, 0, 0, 0);
    auto e = ev.get();

    EXPECT_EQ(mir_event_type_input, mir_event_get_type(e));
    auto ie = mir_event_get_input_event(e);
    EXPECT_EQ(mir_input_event_type_touch, mir_input_event_get_type(ie));
    auto tev = mir_input_event_get_touch_event(ie);

    EXPECT_EQ(action, mir_touch_event_action(tev, 0));
}
Esempio n. 5
0
// Currently we only validate touch events as they are the most problematic
void mi::Validator::validate_and_dispatch(MirEvent const& event)
{
    if (mir_event_get_type(&event) != mir_event_type_input)
    {
        dispatch_valid_event(event);
        return;
    }
    auto iev = mir_event_get_input_event(&event);
    if (mir_input_event_get_type(iev) != mir_input_event_type_touch)
    {
        dispatch_valid_event(event);
        return;
    }
    auto tev = mir_input_event_get_touch_event(iev);
    handle_touch_event(mir_input_event_get_device_id(iev), tev);

    return;
}
TEST_F(InputEventBuilder, makes_valid_touch_event)
{
    unsigned touch_count = 3;
    MirTouchId touch_ids[] = {7, 9, 4};
    MirTouchAction actions[] = { mir_touch_action_up, mir_touch_action_change, mir_touch_action_change};
    MirTouchTooltype tooltypes[] = {mir_touch_tooltype_unknown, mir_touch_tooltype_finger, mir_touch_tooltype_stylus};
    float x_axis_values[] = { 7, 14.3, 19.6 };
    float y_axis_values[] = { 3, 9, 11 };
    float pressure_values[] = {3, 9, 14.6};
    float touch_major_values[] = {11, 9, 14};
    float touch_minor_values[] = {13, 3, 9.13};
    float size_values[] = {4, 9, 6};

   auto ev = mev::make_event(device_id, timestamp,
       mac, modifiers);
   for (unsigned i = 0; i < touch_count; i++)
   {
       mev::add_touch(*ev, touch_ids[i], actions[i], tooltypes[i], x_axis_values[i], y_axis_values[i],
           pressure_values[i], touch_major_values[i], touch_minor_values[i], size_values[i]);
   }
   auto e = ev.get();

   EXPECT_EQ(mir_event_type_input, mir_event_get_type(e));
   auto ie = mir_event_get_input_event(e);
   EXPECT_EQ(mir_input_event_type_touch, mir_input_event_get_type(ie));
   auto tev = mir_input_event_get_touch_event(ie);
   EXPECT_EQ(modifiers, mir_touch_event_modifiers(tev));
   EXPECT_EQ(touch_count, mir_touch_event_point_count(tev));
   EXPECT_EQ(mac, mir_touch_event_get_cookie(tev).mac);
   EXPECT_EQ(timestamp.count(), mir_touch_event_get_cookie(tev).timestamp);

   for (unsigned i = 0; i < touch_count; i++)
   {
       EXPECT_EQ(touch_ids[i], mir_touch_event_id(tev, i));
       EXPECT_EQ(actions[i], mir_touch_event_action(tev, i));
       EXPECT_EQ(tooltypes[i], mir_touch_event_tooltype(tev, i));
       EXPECT_EQ(x_axis_values[i], mir_touch_event_axis_value(tev, i, mir_touch_axis_x));
       EXPECT_EQ(y_axis_values[i], mir_touch_event_axis_value(tev, i, mir_touch_axis_y));
       EXPECT_EQ(pressure_values[i], mir_touch_event_axis_value(tev, i, mir_touch_axis_pressure));
       EXPECT_EQ(touch_major_values[i], mir_touch_event_axis_value(tev, i, mir_touch_axis_touch_major));
       EXPECT_EQ(touch_minor_values[i], mir_touch_event_axis_value(tev, i, mir_touch_axis_touch_minor));
       EXPECT_EQ(size_values[i], mir_touch_event_axis_value(tev, i, mir_touch_axis_size));
   }   
}
Esempio n. 7
0
static void
gdk_mir_event_source_queue_event (GdkDisplay     *display,
                                  GdkWindow      *window,
                                  const MirEvent *event)
{
  const MirInputEvent *input_event;

  // FIXME: Only generate events if the window wanted them?
  switch (mir_event_get_type (event))
    {
    case mir_event_type_input:
      input_event = mir_event_get_input_event (event);

      switch (mir_input_event_get_type (input_event))
        {
        case mir_input_event_type_key:
          handle_key_event (window, input_event);
          break;
        case mir_input_event_type_touch:
          handle_touch_event (window, mir_input_event_get_touch_event (input_event));
          break;
        case mir_input_event_type_pointer:
          handle_motion_event (window, input_event);
          break;
        default:
          break;
        }

      break;
    case mir_event_type_key:
      handle_key_event (window, mir_event_get_input_event (event));
      break;
    case mir_event_type_motion:
      handle_motion_event (window, mir_event_get_input_event (event));
      break;
    case mir_event_type_window:
      handle_window_event (window, mir_event_get_window_event (event));
      break;
    case mir_event_type_resize:
      handle_resize_event (window, mir_event_get_resize_event (event));
      break;
    case mir_event_type_prompt_session_state_change:
      break;
    case mir_event_type_orientation:
      break;
    case mir_event_type_close_window:
      handle_close_event (window);
      break;
    case mir_event_type_keymap:
      break;
    case mir_event_type_window_output:
      handle_window_output_event (window, mir_event_get_window_output_event (event));
      break;
    case mir_event_type_input_device_state:
      break;
    case mir_event_type_window_placement:
      handle_window_placement_event (window, mir_event_get_window_placement_event (event));
      break;
    default:
      g_warning ("Ignoring unknown Mir event %d", mir_event_get_type (event));
      break;
    }
}