Beispiel #1
0
static void
handle_key_event (GdkWindow *window, const MirInputEvent *event)
{
  const MirKeyboardEvent *keyboard_event = mir_input_event_get_keyboard_event (event);
  GdkMirWindowImpl *impl = GDK_MIR_WINDOW_IMPL (window->impl);
  GdkKeymap *keymap;
  guint modifier_state;
  guint button_state;

  if (!keyboard_event)
    return;

  switch (mir_keyboard_event_action (keyboard_event))
    {
    case mir_keyboard_action_up:
    case mir_keyboard_action_down:
      // FIXME: Convert keycode
      _gdk_mir_window_impl_get_cursor_state (impl, NULL, NULL, NULL, &button_state);
      modifier_state = get_modifier_state (mir_keyboard_event_modifiers (keyboard_event), button_state);
      keymap = gdk_keymap_get_for_display (gdk_window_get_display (window));

      generate_key_event (window,
                          mir_keyboard_event_action (keyboard_event) == mir_keyboard_action_down ? GDK_KEY_PRESS : GDK_KEY_RELEASE,
                          modifier_state,
                          mir_keyboard_event_key_code (keyboard_event),
                          mir_keyboard_event_scan_code (keyboard_event),
                          _gdk_mir_keymap_key_is_modifier (keymap, mir_keyboard_event_key_code (keyboard_event)),
                          NANO_TO_MILLI (mir_input_event_get_event_time (event)));
      break;
    default:
    //case mir_key_action_multiple:
      // FIXME
      break;
    }
}
Beispiel #2
0
void
_gdk_mir_print_key_event (const MirInputEvent *event)
{
  const MirKeyboardEvent *keyboard_event = mir_input_event_get_keyboard_event (event);

  if (!keyboard_event)
    return;

  g_printerr ("KEY\n");
  g_printerr (" Device %lld\n", (long long int) mir_input_event_get_device_id (event));
  g_printerr (" Action ");
  switch (mir_keyboard_event_action (keyboard_event))
    {
    case mir_keyboard_action_down:
      g_printerr ("down");
      break;
    case mir_keyboard_action_up:
      g_printerr ("up");
      break;
    case mir_keyboard_action_repeat:
      g_printerr ("repeat");
      break;
    default:
      g_printerr ("%u", mir_keyboard_event_action (keyboard_event));
      break;
    }
  g_printerr ("\n");
  _gdk_mir_print_modifiers (mir_keyboard_event_modifiers (keyboard_event));
  g_printerr (" Key Code %i\n", mir_keyboard_event_key_code (keyboard_event));
  g_printerr (" Scan Code %i\n", mir_keyboard_event_scan_code (keyboard_event));
  g_printerr (" Event Time %lli\n", (long long int) mir_input_event_get_event_time (event));
}
Beispiel #3
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);
    }
}
Beispiel #4
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);
}
Beispiel #5
0
void
_gdk_mir_print_motion_event (const MirInputEvent *event)
{
  const MirPointerEvent *pointer_event = mir_input_event_get_pointer_event (event);

  if (!pointer_event)
    return;

  g_printerr ("MOTION\n");
  g_printerr (" Device %lld\n", (long long int) mir_input_event_get_device_id (event));
  g_printerr (" Action ");
  switch (mir_pointer_event_action (pointer_event))
    {
    case mir_pointer_action_button_down:
      g_printerr ("down");
      break;
    case mir_pointer_action_button_up:
      g_printerr ("up");
      break;
    case mir_pointer_action_enter:
      g_printerr ("enter");
      break;
    case mir_pointer_action_leave:
      g_printerr ("leave");
      break;
    case mir_pointer_action_motion:
      g_printerr ("motion");
      break;
    default:
      g_printerr ("%u", mir_pointer_event_action (pointer_event));
    }
  g_printerr ("\n");
  _gdk_mir_print_modifiers (mir_pointer_event_modifiers (pointer_event));
  g_printerr (" Button State");
  if (mir_pointer_event_button_state (pointer_event, mir_pointer_button_primary))
    g_printerr (" primary");
  if (mir_pointer_event_button_state (pointer_event, mir_pointer_button_secondary))
    g_printerr (" secondary");
  if (mir_pointer_event_button_state (pointer_event, mir_pointer_button_tertiary))
    g_printerr (" tertiary");
  if (mir_pointer_event_button_state (pointer_event, mir_pointer_button_back))
    g_printerr (" back");
  if (mir_pointer_event_button_state (pointer_event, mir_pointer_button_forward))
    g_printerr (" forward");
  g_printerr ("\n");
  g_printerr (" Offset (%f, %f)\n", mir_pointer_event_axis_value (pointer_event, mir_pointer_axis_x),
                                    mir_pointer_event_axis_value (pointer_event, mir_pointer_axis_y));
  g_printerr (" Event Time %lli\n", (long long int) mir_input_event_get_event_time (event));
}
Beispiel #6
0
void QMirClientInput::dispatchKeyEvent(QMirClientWindow *window, const MirInputEvent *event)
{
    const MirKeyboardEvent *key_event = mir_input_event_get_keyboard_event(event);

    ulong timestamp = mir_input_event_get_event_time(event) / 1000000;
    xkb_keysym_t xk_sym = mir_keyboard_event_key_code(key_event);
    quint32 scan_code = mir_keyboard_event_scan_code(key_event);
    quint32 native_modifiers = mir_keyboard_event_modifiers(key_event);

    // Key modifier and unicode index mapping.
    auto modifiers = qt_modifiers_from_mir(native_modifiers);

    MirKeyboardAction action = mir_keyboard_event_action(key_event);
    QEvent::Type keyType = action == mir_keyboard_action_up
        ? QEvent::KeyRelease : QEvent::KeyPress;

    if (action == mir_keyboard_action_down)
        mLastInputWindow = window;

    QString text;
    QVarLengthArray<char, 32> chars(32);
    {
        int result = xkb_keysym_to_utf8(xk_sym, chars.data(), chars.size());

        if (result > 0) {
            text = QString::fromUtf8(chars.constData());
        }
    }
    int sym = translateKeysym(xk_sym, text);

    bool is_auto_rep = action == mir_keyboard_action_repeat;

    QPlatformInputContext *context = QGuiApplicationPrivate::platformIntegration()->inputContext();
    if (context) {
        QKeyEvent qKeyEvent(keyType, sym, modifiers, scan_code, xk_sym, native_modifiers, text, is_auto_rep);
        qKeyEvent.setTimestamp(timestamp);
        if (context->filterEvent(&qKeyEvent)) {
            qCDebug(mirclient, "key event filtered out by input context");
            return;
        }
    }

    QWindowSystemInterface::handleExtendedKeyEvent(window->window(), timestamp, keyType, sym, modifiers, scan_code, xk_sym, native_modifiers, text, is_auto_rep);
}
Beispiel #7
0
void QMirClientInput::dispatchPointerEvent(QMirClientWindow *platformWindow, const MirInputEvent *ev)
{
    const auto window = platformWindow->window();
    const auto timestamp = mir_input_event_get_event_time(ev) / 1000000;

    const auto pev = mir_input_event_get_pointer_event(ev);
    const auto action = mir_pointer_event_action(pev);

    const auto modifiers = qt_modifiers_from_mir(mir_pointer_event_modifiers(pev));
    const auto localPoint = QPointF(mir_pointer_event_axis_value(pev, mir_pointer_axis_x),
                                    mir_pointer_event_axis_value(pev, mir_pointer_axis_y));

    mLastInputWindow = platformWindow;

    switch (action) {
    case mir_pointer_action_button_up:
    case mir_pointer_action_button_down:
    case mir_pointer_action_motion:
    {
        const float hDelta = mir_pointer_event_axis_value(pev, mir_pointer_axis_hscroll);
        const float vDelta = mir_pointer_event_axis_value(pev, mir_pointer_axis_vscroll);

        if (hDelta != 0 || vDelta != 0) {
            // QWheelEvent::DefaultDeltasPerStep = 120 but doesn't exist on vivid
            const QPoint angleDelta(120 * hDelta, 120 * vDelta);
            QWindowSystemInterface::handleWheelEvent(window, timestamp, localPoint, window->position() + localPoint,
                                                     QPoint(), angleDelta, modifiers, Qt::ScrollUpdate);
        }
        auto buttons = extract_buttons(pev);
        QWindowSystemInterface::handleMouseEvent(window, timestamp, localPoint, window->position() + localPoint /* Should we omit global point instead? */,
                                                 buttons, modifiers);
        break;
    }
    case mir_pointer_action_enter:
        QWindowSystemInterface::handleEnterEvent(window, localPoint, window->position() + localPoint);
        break;
    case mir_pointer_action_leave:
        QWindowSystemInterface::handleLeaveEvent(window);
        break;
    default:
        Q_UNREACHABLE();
    }
}
Beispiel #8
0
static void
handle_motion_event (GdkWindow *window, const MirInputEvent *event)
{
  const MirPointerEvent *pointer_event = mir_input_event_get_pointer_event (event);
  GdkMirWindowImpl *impl = GDK_MIR_WINDOW_IMPL (window->impl);
  gdouble x, y;
  gboolean cursor_inside;
  guint button_state;
  guint modifier_state;
  guint32 event_time;
  GdkEventType event_type;
  guint changed_button_state;

  if (!pointer_event)
    return;

  _gdk_mir_window_impl_get_cursor_state (impl, &x, &y, &cursor_inside, &button_state);
  modifier_state = get_modifier_state (mir_pointer_event_modifiers (pointer_event), mir_pointer_event_get_button_state (pointer_event));
  event_time = NANO_TO_MILLI (mir_input_event_get_event_time (event));

  /* TODO: Remove once we have proper transient window support. */
  if (mir_pointer_event_action (pointer_event) == mir_pointer_action_leave)
    {
      LeaveInfo info;

      info.x = x;
      info.y = y;
      info.time = event_time;
      info.except = window;

      /* Leave all transient children from leaf to root, except the root since we do it later. */
      _gdk_mir_window_transient_children_foreach (window, leave_windows_except, &info);
    }
  else
    {
      LeaveInfo info;

      info.x = x;
      info.y = y;
      info.time = event_time;
      info.except = _gdk_mir_window_get_visible_transient_child (window, x, y, &x, &y);

      /* Leave all transient children from leaf to root, except the pointer window since we enter it. */
      _gdk_mir_window_transient_children_foreach (window, leave_windows_except, &info);

      window = info.except;

      if (window)
        {
          /* Enter the pointer window. */
          gboolean cursor_inside_pointer_window;

          impl = GDK_MIR_WINDOW_IMPL (window->impl);
          _gdk_mir_window_impl_get_cursor_state (impl, NULL, NULL, &cursor_inside_pointer_window, NULL);

          if (!cursor_inside_pointer_window)
            {
              generate_crossing_event (window, GDK_ENTER_NOTIFY, x, y, event_time);
              _gdk_mir_window_impl_set_cursor_state (impl, x, y, TRUE, mir_pointer_event_get_button_state (pointer_event));
            }
        }
    }

  if (window)
    {
      gdouble new_x;
      gdouble new_y;
      gdouble hscroll;
      gdouble vscroll;

      /* Update which window has focus */
      _gdk_mir_pointer_set_location (get_pointer (window), x, y, window, modifier_state);
      switch (mir_pointer_event_action (pointer_event))
        {
        case mir_pointer_action_button_up:
        case mir_pointer_action_button_down:
          event_type = mir_pointer_event_action (pointer_event) == mir_pointer_action_button_down ? GDK_BUTTON_PRESS : GDK_BUTTON_RELEASE;
          changed_button_state = button_state ^ mir_pointer_event_get_button_state (pointer_event);
          if (changed_button_state == 0 || (changed_button_state & mir_pointer_button_primary) != 0)
            generate_button_event (window, event_type, x, y, GDK_BUTTON_PRIMARY, modifier_state, event_time);
          if ((changed_button_state & mir_pointer_button_secondary) != 0)
            generate_button_event (window, event_type, x, y, GDK_BUTTON_SECONDARY, modifier_state, event_time);
          if ((changed_button_state & mir_pointer_button_tertiary) != 0)
            generate_button_event (window, event_type, x, y, GDK_BUTTON_MIDDLE, modifier_state, event_time);
          button_state = mir_pointer_event_get_button_state (pointer_event);
          break;
        case mir_pointer_action_motion:
          new_x = mir_pointer_event_axis_value (pointer_event, mir_pointer_axis_x);
          new_y = mir_pointer_event_axis_value (pointer_event, mir_pointer_axis_y);
          hscroll = mir_pointer_event_axis_value (pointer_event, mir_pointer_axis_hscroll);
          vscroll = mir_pointer_event_axis_value (pointer_event, mir_pointer_axis_vscroll);

          if (hscroll > 0.5 || vscroll > 0.5)
            generate_scroll_event (window, x, y, hscroll, vscroll, modifier_state, event_time);
          if (ABS (new_x - x) > 0.5 || ABS (new_y - y) > 0.5)
            generate_motion_event (window, new_x, new_y, modifier_state, event_time);

          break;
        case mir_pointer_action_leave:
          if (cursor_inside)
            {
              cursor_inside = FALSE;
              generate_crossing_event (window, GDK_LEAVE_NOTIFY, x, y, event_time);
            }
          break;
        default:
          break;
        }

      _gdk_mir_window_impl_set_cursor_state (impl, x, y, cursor_inside, button_state);
    }
}
Beispiel #9
0
static void
handle_motion_event (GdkWindow *window, const MirInputEvent *event)
{
  const MirPointerEvent *pointer_event = mir_input_event_get_pointer_event (event);
  GdkMirWindowImpl *impl = GDK_MIR_WINDOW_IMPL (window->impl);
  gdouble x, y;
  gboolean cursor_inside;
  guint button_state;
  guint new_button_state;
  guint modifier_state;
  guint32 event_time;
  GdkEventType event_type;
  guint changed_button_state;

  if (!pointer_event)
    return;

  _gdk_mir_window_impl_get_cursor_state (impl, &x, &y, &cursor_inside, &button_state);
  new_button_state = get_button_state (pointer_event);
  modifier_state = get_modifier_state (mir_pointer_event_modifiers (pointer_event), new_button_state);
  event_time = NANO_TO_MILLI (mir_input_event_get_event_time (event));

  if (window)
    {
      gdouble new_x;
      gdouble new_y;
      gdouble hscroll;
      gdouble vscroll;

      /* Update which window has focus */
      _gdk_mir_pointer_set_location (get_pointer (window), x, y, window, modifier_state);
      switch (mir_pointer_event_action (pointer_event))
        {
        case mir_pointer_action_button_up:
        case mir_pointer_action_button_down:
          event_type = mir_pointer_event_action (pointer_event) == mir_pointer_action_button_down ? GDK_BUTTON_PRESS : GDK_BUTTON_RELEASE;
          changed_button_state = button_state ^ new_button_state;
          if (changed_button_state == 0 || (changed_button_state & GDK_BUTTON1_MASK) != 0)
            generate_button_event (window, event_type, x, y, GDK_BUTTON_PRIMARY, modifier_state, event_time);
          if ((changed_button_state & GDK_BUTTON2_MASK) != 0)
            generate_button_event (window, event_type, x, y, GDK_BUTTON_MIDDLE, modifier_state, event_time);
          if ((changed_button_state & GDK_BUTTON3_MASK) != 0)
            generate_button_event (window, event_type, x, y, GDK_BUTTON_SECONDARY, modifier_state, event_time);
          button_state = new_button_state;
          break;
        case mir_pointer_action_motion:
          new_x = mir_pointer_event_axis_value (pointer_event, mir_pointer_axis_x);
          new_y = mir_pointer_event_axis_value (pointer_event, mir_pointer_axis_y);
          hscroll = mir_pointer_event_axis_value (pointer_event, mir_pointer_axis_hscroll);
          vscroll = mir_pointer_event_axis_value (pointer_event, mir_pointer_axis_vscroll);

          if (hscroll != 0.0 || vscroll != 0.0)
            generate_scroll_event (window, x, y, hscroll, vscroll, modifier_state, event_time);
          if (ABS (new_x - x) > 0.5 || ABS (new_y - y) > 0.5)
            {
              generate_motion_event (window, new_x, new_y, modifier_state, event_time);
              x = new_x;
              y = new_y;
            }

          break;
        case mir_pointer_action_enter:
          if (!cursor_inside)
            {
              cursor_inside = TRUE;
              generate_crossing_event (window, GDK_ENTER_NOTIFY, x, y, event_time);
            }
          break;
        case mir_pointer_action_leave:
          if (cursor_inside)
            {
              cursor_inside = FALSE;
              generate_crossing_event (window, GDK_LEAVE_NOTIFY, x, y, event_time);
            }
          break;
        default:
          break;
        }

      _gdk_mir_window_impl_set_cursor_state (impl, x, y, cursor_inside, button_state);
    }
}