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 handleKeyEvent(const MirKeyboardEvent* key_event, _GLFWwindow* window)
{
    const int action    = mir_keyboard_event_action   (key_event);
    const int scan_code = mir_keyboard_event_scan_code(key_event);
    const int key_code  = mir_keyboard_event_key_code (key_event);
    const int modifiers = mir_keyboard_event_modifiers(key_event);

    const int  pressed = action == mir_keyboard_action_up ? GLFW_RELEASE : GLFW_PRESS;
    const int  mods    = mirModToGLFWMod(modifiers);
    const long text    = _glfwKeySym2Unicode(key_code);
    const int  plain   = !(mods & (GLFW_MOD_CONTROL | GLFW_MOD_ALT));

    _glfwInputKey(window, toGLFWKeyCode(scan_code), scan_code, pressed, mods);

    if (text != -1)
        _glfwInputChar(window, text, mods, plain);
}
Beispiel #4
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);
}
TEST_F(InputEventBuilder, makes_valid_key_event)
{
    MirKeyboardAction const action = mir_keyboard_action_down;
    xkb_keysym_t const key_code = 34;
    int const scan_code = 17;

   auto ev = mev::make_event(device_id, timestamp,
       mac, action, key_code, scan_code, modifiers);
   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_key, mir_input_event_get_type(ie));
   auto kev = mir_input_event_get_keyboard_event(ie);
   EXPECT_EQ(action, mir_keyboard_event_action(kev));
   EXPECT_EQ(key_code, mir_keyboard_event_key_code(kev));
   EXPECT_EQ(scan_code, mir_keyboard_event_scan_code(kev));
   EXPECT_EQ(modifiers, mir_keyboard_event_modifiers(kev));
   EXPECT_EQ(mac, mir_keyboard_event_get_cookie(kev).mac);
   EXPECT_EQ(timestamp.count(), mir_keyboard_event_get_cookie(kev).timestamp);
}
bool me::WindowManager::handle_key_event(MirKeyboardEvent const* kev)
{
    // TODO: Fix android configuration and remove static hack ~racarr
    static bool display_off = false;

    if (mir_keyboard_event_action(kev) != mir_keyboard_action_down)
        return false;

    auto modifiers = mir_keyboard_event_modifiers(kev);
    auto scan_code = mir_keyboard_event_scan_code(kev);
    
    if (modifiers & mir_input_event_modifier_alt &&
        scan_code == KEY_TAB)  // TODO: Use keycode once we support keymapping on the server side
    {
        focus_controller->focus_next_session();
        if (auto const surface = focus_controller->focused_surface())
            focus_controller->raise({surface});
        return true;
    }
    else if (modifiers & mir_input_event_modifier_alt &&
             scan_code == KEY_GRAVE)
    {
        if (auto const prev = focus_controller->focused_surface())
        {
            auto const app = focus_controller->focused_session();
            auto const next = app->surface_after(prev);
            focus_controller->set_focus_to(app, next);
            focus_controller->raise({next});
        }
        return true;
    }
    else if (modifiers & mir_input_event_modifier_alt &&
             scan_code == KEY_F4)
    {
        auto const surf = focus_controller->focused_surface();
        if (surf)
            surf->request_client_surface_close();
        return true;
    }
    else if ((modifiers & mir_input_event_modifier_alt &&
              scan_code == KEY_P) ||
             (scan_code == KEY_POWER))
    {
        compositor->stop();
        auto conf = display->configuration();
        MirPowerMode new_power_mode = display_off ?
            mir_power_mode_on : mir_power_mode_off;
        conf->for_each_output(
            [&](mg::UserDisplayConfigurationOutput& output) -> void
            {
                output.power_mode = new_power_mode;
            });
        display_off = !display_off;

        display->configure(*conf.get());
        if (!display_off)
            compositor->start();
        return true;
    }
    else if ((modifiers & mir_input_event_modifier_alt) &&
             (modifiers & mir_input_event_modifier_ctrl) &&
             (scan_code == KEY_ESC))
    {
        std::abort();
        return true;
    }
    else if ((modifiers & mir_input_event_modifier_alt) &&
             (modifiers & mir_input_event_modifier_ctrl) &&
             (scan_code == KEY_L) &&
             focus_controller)
    {
        auto const app = focus_controller->focused_session();
        if (app)
        {
            app->set_lifecycle_state(mir_lifecycle_state_will_suspend);
        }
    }
    else if ((modifiers & mir_input_event_modifier_alt) &&
             (modifiers & mir_input_event_modifier_ctrl))
    {
        MirOrientation orientation = mir_orientation_normal;
        bool rotating = true;
        int mode_change = 0;
        bool preferred_mode = false;
        switch (scan_code)
        {
        case KEY_UP:    orientation = mir_orientation_normal; break;
        case KEY_DOWN:  orientation = mir_orientation_inverted; break;
        case KEY_LEFT:  orientation = mir_orientation_left; break;
        case KEY_RIGHT: orientation = mir_orientation_right; break;
        default:        rotating = false; break;
        }
        switch (scan_code)
        {
        case KEY_MINUS: mode_change = -1;      break;
        case KEY_EQUAL: mode_change = +1;      break;
        case KEY_0:     preferred_mode = true; break;
        default:                               break;
        }
        
        if (rotating || mode_change || preferred_mode)
        {
            compositor->stop();
            auto conf = display->configuration();
            conf->for_each_output(
                [&](mg::UserDisplayConfigurationOutput& output) -> void
                {
                    // Only apply changes to the monitor the cursor is on
                    if (!output.extents().contains(old_cursor))
                        return;
                    if (rotating)
                        output.orientation = orientation;
                    if (preferred_mode)
                    {
                        output.current_mode_index =
                            output.preferred_mode_index;
                    }
                    else if (mode_change)
                    {
                        size_t nmodes = output.modes.size();
                        if (nmodes)
                            output.current_mode_index =
                                (output.current_mode_index + nmodes +
                                 mode_change) % nmodes;
                    }
                });
                                  
            display->configure(*conf);
            compositor->start();
            return true;
        }
    }
    else if ((scan_code == KEY_VOLUMEDOWN ||
              scan_code == KEY_VOLUMEUP) &&
             max_fingers == 1)
    {
        int delta = (scan_code == KEY_VOLUMEDOWN) ? -1 : +1;
        static const MirOrientation order[4] =
        {
            mir_orientation_normal,
            mir_orientation_right,
            mir_orientation_inverted,
            mir_orientation_left
        };
        compositor->stop();
        auto conf = display->configuration();
        conf->for_each_output(
            [&](mg::UserDisplayConfigurationOutput& output)
            {
                int i = 0;
                for (; i < 4; ++i)
                {
                    if (output.orientation == order[i])
                        break;
                }
                output.orientation = order[(i+4+delta) % 4];
            });
        display->configure(*conf.get());
        compositor->start();
        return true;
    }
    else if (modifiers & mir_input_event_modifier_meta &&
             scan_code == KEY_N)
    {
        toggle(inverse);
        return true;
    }
    else if (modifiers & mir_input_event_modifier_meta &&
             scan_code == KEY_C)
    {
        toggle(contrast);
        return true;
    }
    return false;
}