Esempio n. 1
0
static void
handle_touch_event (GdkWindow           *window,
                    const MirTouchEvent *mir_touch_event)
{
  const MirInputEvent *mir_input_event = mir_touch_event_input_event (mir_touch_event);
  guint n = mir_touch_event_point_count (mir_touch_event);
  GdkEvent *gdk_event;
  guint i;

  for (i = 0; i < n; i++)
    {
      MirTouchAction action = mir_touch_event_action (mir_touch_event, i);
      if (action == mir_touch_action_up)
        gdk_event = gdk_event_new (GDK_TOUCH_END);
      else if (action == mir_touch_action_down)
        gdk_event = gdk_event_new (GDK_TOUCH_BEGIN);
      else
        gdk_event = gdk_event_new (GDK_TOUCH_UPDATE);

      gdk_event->touch.window = window;
      gdk_event->touch.sequence = GINT_TO_POINTER (mir_touch_event_id (mir_touch_event, i));
      gdk_event->touch.time = mir_input_event_get_event_time (mir_input_event);
      gdk_event->touch.state = get_modifier_state (mir_touch_event_modifiers (mir_touch_event), 0);
      gdk_event->touch.x = mir_touch_event_axis_value (mir_touch_event, i, mir_touch_axis_x);
      gdk_event->touch.y = mir_touch_event_axis_value (mir_touch_event, i, mir_touch_axis_y);
      gdk_event->touch.x_root = mir_touch_event_axis_value (mir_touch_event, i, mir_touch_axis_x);
      gdk_event->touch.y_root = mir_touch_event_axis_value (mir_touch_event, i, mir_touch_axis_y);
      gdk_event->touch.emulating_pointer = TRUE;
      gdk_event_set_pointer_emulated (gdk_event, TRUE);

      send_event (window, get_pointer (window), gdk_event);
    }
}
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. 3
0
bool me::WindowManager::handle_touch_event(MirTouchEvent const* tev)
{
    bool handled = false;
    geometry::Point cursor = average_pointer(tev);

    auto const& modifiers = mir_touch_event_modifiers(tev);

    int fingers = mir_touch_event_point_count(tev);

    if (fingers > max_fingers)
        max_fingers = fingers;

    auto const surf = focus_controller->focused_surface();
    if (surf &&
        (modifiers & mir_input_event_modifier_alt ||
         fingers >= 3))
    {
        geometry::Displacement pinch_dir;
        auto pinch_diam =
            measure_pinch(tev, pinch_dir);

        // Start of a gesture: When the latest finger/button goes down
        if (any_touches_went_down(tev))
        {
            click = cursor;
            save_edges(*surf, click);
            handled = true;
        }
        else if(max_fingers <= 3)  // Avoid accidental movement
        {
            geometry::Displacement drag = cursor - old_cursor;

            surf->move_to(old_pos + drag);

            if (fingers == 3)
            {  // Resize by pinch/zoom
                float diam_delta = pinch_diam - old_pinch_diam;
                /*
                 * Resize vector (dx,dy) has length=diam_delta and
                 * direction=pinch_dir, so solve for (dx,dy)...
                 */
                float lenlen = diam_delta * diam_delta;
                int x = pinch_dir.dx.as_int();
                int y = pinch_dir.dy.as_int();
                int xx = x * x;
                int yy = y * y;
                int xxyy = xx + yy;
                int dx = sqrtf(lenlen * xx / xxyy);
                int dy = sqrtf(lenlen * yy / xxyy);
                if (diam_delta < 0.0f)
                {
                    dx = -dx;
                    dy = -dy;
                }

                int width = old_size.width.as_int() + dx;
                int height = old_size.height.as_int() + dy;
                surf->resize({width, height});
            }

            handled = true;
        }

        old_pos = surf->top_left();
        old_size = surf->size();
        old_pinch_diam = pinch_diam;
    }

    auto gesture_ended = last_touch_released(tev);

    if (max_fingers == 4 && gesture_ended)
    { // Four fingers released
        geometry::Displacement dir = cursor - click;
        if (abs(dir.dx.as_int()) >= min_swipe_distance)
        {
            focus_controller->focus_next_session();
            if (auto const surface = focus_controller->focused_surface())
                focus_controller->raise({surface});
            handled = true;
        }
    }

    if (fingers == 1 && gesture_ended)
        max_fingers = 0;

    old_cursor = cursor;
    return handled;
}