C++程序  |  306行  |  9.13 KB

/*
 * Copyright 2017 The Chromium Authors.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice (including the next
 * paragraph) shall be included in all copies or substantial portions of the
 * Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 * DEALINGS IN THE SOFTWARE.
 */
#ifndef _RUNTIME_ARC_INPUT_BRIDGE_PROTOCOL_H
#define _RUNTIME_ARC_INPUT_BRIDGE_PROTOCOL_H

#include <cstdint>

// Hack: major/minor may be defined by stdlib in error.
// see https://sourceware.org/bugzilla/show_bug.cgi?id=19239
#undef major
#undef minor

namespace arc {

// Location of the named pipe for communicating events
static const char* kArcInputBridgePipe = "/var/run/inputbridge/inputbridge";

enum class InputEventType {
    RESET = 0,

    POINTER_ENTER,
    POINTER_MOVE,
    POINTER_LEAVE,
    POINTER_BUTTON,
    POINTER_SCROLL_X,
    POINTER_SCROLL_Y,
    POINTER_SCROLL_DISCRETE,
    POINTER_SCROLL_STOP,
    POINTER_FRAME,

    TOUCH_DOWN,
    TOUCH_MOVE,
    TOUCH_UP,
    TOUCH_CANCEL,
    TOUCH_SHAPE,
    TOUCH_TOOL_TYPE,
    TOUCH_FORCE,
    TOUCH_TILT,
    TOUCH_FRAME,

    GESTURE_PINCH_BEGIN,
    GESTURE_PINCH_UPDATE,
    GESTURE_PINCH_END,

    GESTURE_SWIPE_BEGIN,
    GESTURE_SWIPE_UPDATE,
    GESTURE_SWIPE_END,

    KEY,
    KEY_MODIFIERS,
    KEY_RESET,

    GAMEPAD_CONNECTED,
    GAMEPAD_DISCONNECTED,
    GAMEPAD_AXIS,
    GAMEPAD_BUTTON,
    GAMEPAD_FRAME,

    // event for reporting the state of a switch, such as a lid switch
    SWITCH,

    // event for reporting dimensions and properties of the display
    DISPLAY_METRICS
} __attribute__((packed));

struct PointerArgs {
    float x;
    float y;
    bool discrete;
} __attribute__((packed));

struct KeyArgs {
    // Android AKEYCODE_ code after application of keyboard layout.
    uint32_t keyCode;
    // Linux KEY_ scan code as it was received from the kernel.
    uint32_t scanCode;
    // 0 = released, 1 = pressed.
    uint32_t state;
    // serial number of this key events in wayland.
    uint32_t serial;
} __attribute__((packed));

struct MetaArgs {
    // Android AMETA_ bitmask of meta state.
    uint32_t metaState;
};

struct ButtonArgs {
    // Android AMOTION_EVENT_BUTTON_ code
    uint32_t code;
    // 0 = released, 1 = pressed.
    uint32_t state;
};

enum class TouchToolType { TOUCH = 0, PEN, ERASER } __attribute__((packed));

struct TouchArgs {
    int32_t id;
    union {
        float x;
        float major;
        float force;
        TouchToolType tool;
    };
    union {
        float y;
        float minor;
    };
} __attribute__((packed));

struct GestureArgs {
    uint32_t fingers;
    bool cancelled;
} __attribute__((packed));

struct GesturePinchArgs {
    float scale;
} __attribute__((packed));

struct GestureSwipeArgs {
    float dx;
    float dy;
} __attribute__((packed));

struct GamepadArgs {
    int32_t id;
    union {
        // Used by GAMEPAD_BUTTON and GAMEPAD_AXIS respectively
        int32_t button;
        int32_t axis;
    };
    bool pressed;
    float value;
} __attribute__((packed));

struct SwitchArgs {
    // Switch ID defined at bionic/libc/kernel/uapi/linux/input.h.
    int32_t switchCode;
    // Switch value defined at frameworks/native/include/android/input.h.
    int32_t state;
} __attribute__((packed));

struct DisplayMetricsArgs {
    int32_t width;
    int32_t height;
    float ui_scale;
} __attribute__((packed));


// Union-like class describing an event. The InputEventType describes which
// of member of the union contains the data of this event.
struct BridgeInputEvent {
    uint64_t timestamp;
    int32_t taskId;
    int32_t windowId;

    InputEventType type;

    union {
        PointerArgs pointer;
        KeyArgs key;
        TouchArgs touch;
        MetaArgs meta;
        ButtonArgs button;
        GestureArgs gesture;
        GesturePinchArgs gesture_pinch;
        GestureSwipeArgs gesture_swipe;
        GamepadArgs gamepad;
        SwitchArgs switches;
        DisplayMetricsArgs display_metrics;
    };

    static BridgeInputEvent ResetEvent(uint64_t timestamp) {
        return {timestamp, -1, 0, InputEventType::RESET, {}};
    }

    static BridgeInputEvent KeyEvent(uint64_t timestamp, uint32_t keyCode, uint32_t scanCode,
                                     uint32_t state, uint32_t serial) {
        BridgeInputEvent event{timestamp, -1, 0, InputEventType::KEY, {}};
        event.key = {keyCode, scanCode, state, serial};
        return event;
    }

    static BridgeInputEvent KeyModifiersEvent(uint64_t timestamp, uint32_t modifiers) {
        BridgeInputEvent event{timestamp, -1, 0, InputEventType::KEY_MODIFIERS, {}};
        event.meta = {modifiers};
        return event;
    }

    static BridgeInputEvent PointerEvent(uint64_t timestamp, InputEventType type, float x = 0,
                                         float y = 0, bool discrete = false) {
        BridgeInputEvent event{timestamp, -1, 0, type, {}};
        event.pointer = {x, y, discrete};
        return event;
    }

    static BridgeInputEvent PointerButtonEvent(uint64_t timestamp, uint32_t code, uint32_t state) {
        BridgeInputEvent event{timestamp, -1, 0, InputEventType::POINTER_BUTTON, {}};
        event.button = {code, state};
        return event;
    }

    static BridgeInputEvent PinchBeginEvent(uint64_t timestamp) {
        return {timestamp, -1, 0, InputEventType::GESTURE_PINCH_BEGIN, {}};
    }

    static BridgeInputEvent PinchUpdateEvent(uint64_t timestamp, float scale) {
        BridgeInputEvent event{timestamp, -1, 0, InputEventType::GESTURE_PINCH_UPDATE, {}};
        event.gesture_pinch.scale = scale;
        return event;
    }

    static BridgeInputEvent PinchEndEvent(uint64_t timestamp, bool cancelled) {
        BridgeInputEvent event{timestamp, -1, 0, InputEventType::GESTURE_PINCH_END, {}};
        event.gesture.cancelled = cancelled;
        return event;
    }

    static BridgeInputEvent SwipeBeginEvent(uint64_t timestamp, uint32_t fingers) {
        BridgeInputEvent event{timestamp, -1, 0, InputEventType::GESTURE_SWIPE_BEGIN, {}};
        event.gesture.fingers = fingers;
        return event;
    }

    static BridgeInputEvent SwipeUpdateEvent(uint64_t timestamp, float dx, float dy) {
        BridgeInputEvent event{timestamp, -1, 0, InputEventType::GESTURE_SWIPE_UPDATE, {}};
        event.gesture_swipe.dx = dx;
        event.gesture_swipe.dy = dy;
        return event;
    }

    static BridgeInputEvent SwipeEndEvent(uint64_t timestamp, bool cancelled) {
        BridgeInputEvent event{timestamp, -1, 0, InputEventType::GESTURE_SWIPE_END, {}};
        event.gesture.cancelled = cancelled;
        return event;
    }

    static BridgeInputEvent GamepadConnectedEvent(int32_t id) {
        BridgeInputEvent event{0, -1, 0, InputEventType::GAMEPAD_CONNECTED, {}};
        event.gamepad.id = id;
        return event;
    }

    static BridgeInputEvent GamepadDisconnectedEvent(int32_t id) {
        BridgeInputEvent event{0, -1, 0, InputEventType::GAMEPAD_DISCONNECTED, {}};
        event.gamepad.id = id;
        return event;
    }

    static BridgeInputEvent GamepadAxisEvent(uint64_t timestamp, int32_t id, int32_t axis,
                                             float value) {
        BridgeInputEvent event{timestamp, -1, 0, InputEventType::GAMEPAD_AXIS, {}};
        event.gamepad.id = id;
        event.gamepad.axis = axis;
        event.gamepad.value = value;
        return event;
    }

    static BridgeInputEvent GamepadButtonEvent(uint64_t timestamp, int32_t id, int32_t button,
                                               bool pressed, float value) {
        BridgeInputEvent event{timestamp, -1, 0, InputEventType::GAMEPAD_BUTTON, {}};
        event.gamepad.id = id;
        event.gamepad.button = button;
        event.gamepad.pressed = pressed;
        event.gamepad.value = value;
        return event;
    }

    static BridgeInputEvent GamepadFrameEvent(uint64_t timestamp, int32_t id) {
        BridgeInputEvent event{timestamp, -1, 0, InputEventType::GAMEPAD_FRAME, {}};
        event.gamepad.id = id;
        return event;
    }

    static BridgeInputEvent SwitchEvent(uint64_t timestamp, int32_t switchCode, int32_t state) {
        BridgeInputEvent event{timestamp, -1, 0, InputEventType::SWITCH, {}};
        event.switches.switchCode = switchCode;
        event.switches.state = state;
        return event;
    }
} __attribute__((packed));

}  // namespace arc

#endif  // _RUNTIME_ARC_INPUT_BRIDGE_PROTOCOL_H