summaryrefslogtreecommitdiff
path: root/Userland/Services/WindowServer/Event.h
blob: d5a72f364376fbd54b72a917ab1bbaf92caac941 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
/*
 * Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
 *
 * SPDX-License-Identifier: BSD-2-Clause
 */

#pragma once

#include <AK/String.h>
#include <Kernel/API/KeyCode.h>
#include <LibCore/Event.h>
#include <LibCore/MimeData.h>
#include <LibGfx/Rect.h>
#include <WindowServer/Cursor.h>
#include <WindowServer/WindowType.h>

namespace WindowServer {

class Event : public Core::Event {
public:
    enum Type {
        Invalid = 3000,
        MouseMove,
        MouseDown,
        MouseDoubleClick,
        MouseUp,
        MouseWheel,
        WindowEntered,
        WindowLeft,
        KeyDown,
        KeyUp,
        WindowActivated,
        WindowDeactivated,
        WindowInputEntered,
        WindowInputLeft,
        WindowCloseRequest,
        WindowResized,
    };

    Event() = default;
    explicit Event(Type type)
        : Core::Event(type)
    {
    }
    virtual ~Event() = default;

    bool is_mouse_event() const { return type() == MouseMove || type() == MouseDown || type() == MouseDoubleClick || type() == MouseUp || type() == MouseWheel; }
    bool is_key_event() const { return type() == KeyUp || type() == KeyDown; }
};

enum class MouseButton : u8 {
    None = 0,
    Primary = 1,
    Secondary = 2,
    Middle = 4,
    Backward = 8,
    Forward = 16,
};

class KeyEvent final : public Event {
public:
    KeyEvent(Type type, int key, u32 code_point, u8 modifiers, u32 scancode)
        : Event(type)
        , m_key(key)
        , m_code_point(code_point)
        , m_modifiers(modifiers)
        , m_scancode(scancode)
    {
    }

    int key() const { return m_key; }
    bool ctrl() const { return m_modifiers & Mod_Ctrl; }
    bool alt() const { return m_modifiers & Mod_Alt; }
    bool shift() const { return m_modifiers & Mod_Shift; }
    bool super() const { return m_modifiers & Mod_Super; }
    u8 modifiers() const { return m_modifiers; }
    u32 code_point() const { return m_code_point; }
    u32 scancode() const { return m_scancode; }

private:
    friend class EventLoop;
    friend class Screen;
    int m_key { 0 };
    u32 m_code_point { 0 };
    u8 m_modifiers { 0 };
    u32 m_scancode { 0 };
};

class MouseEvent final : public Event {
public:
    MouseEvent(Type type, const Gfx::IntPoint& position, unsigned buttons, MouseButton button, unsigned modifiers, int wheel_delta_x = 0, int wheel_delta_y = 0, int wheel_raw_delta_x = 0, int wheel_raw_delta_y = 0)
        : Event(type)
        , m_position(position)
        , m_buttons(buttons)
        , m_button(button)
        , m_modifiers(modifiers)
        , m_wheel_delta_x(wheel_delta_x)
        , m_wheel_delta_y(wheel_delta_y)
        , m_wheel_raw_delta_x(wheel_raw_delta_x)
        , m_wheel_raw_delta_y(wheel_raw_delta_y)
    {
    }

    const Gfx::IntPoint& position() const { return m_position; }
    int x() const { return m_position.x(); }
    int y() const { return m_position.y(); }
    MouseButton button() const { return m_button; }
    unsigned buttons() const { return m_buttons; }
    unsigned modifiers() const { return m_modifiers; }
    int wheel_delta_x() const { return m_wheel_delta_x; }
    int wheel_delta_y() const { return m_wheel_delta_y; }
    int wheel_raw_delta_x() const { return m_wheel_raw_delta_x; }
    int wheel_raw_delta_y() const { return m_wheel_raw_delta_y; }
    bool is_drag() const { return m_drag; }

    Vector<String> mime_types() const
    {
        if (!m_mime_data)
            return {};
        return m_mime_data->formats();
    }

    void set_drag(bool b) { m_drag = b; }
    void set_mime_data(const Core::MimeData& mime_data) { m_mime_data = mime_data; }

    MouseEvent translated(Gfx::IntPoint const& delta) const
    {
        MouseEvent event = *this;
        event.m_position = m_position.translated(delta);
        return event;
    }

private:
    Gfx::IntPoint m_position;
    unsigned m_buttons { 0 };
    MouseButton m_button { MouseButton::None };
    unsigned m_modifiers { 0 };
    int m_wheel_delta_x { 0 };
    int m_wheel_delta_y { 0 };
    int m_wheel_raw_delta_x { 0 };
    int m_wheel_raw_delta_y { 0 };
    bool m_drag { false };
    RefPtr<const Core::MimeData> m_mime_data;
};

class ResizeEvent final : public Event {
public:
    ResizeEvent(const Gfx::IntRect& rect)
        : Event(Event::WindowResized)
        , m_rect(rect)
    {
    }

    const Gfx::IntRect& rect() const { return m_rect; }

private:
    Gfx::IntRect m_rect;
};

}