summaryrefslogtreecommitdiff
path: root/WindowServer/WSScreen.cpp
blob: 65b5c33d0bde636b9b2ec5d36edc87eb05551061 (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
#include "WSScreen.h"
#include "WSEventLoop.h"
#include "WSEvent.h"
#include "WSWindowManager.h"
#include <AK/Assertions.h>

static WSScreen* s_the;

void WSScreen::initialize()
{
    s_the = nullptr;
}

WSScreen& WSScreen::the()
{
    ASSERT(s_the);
    return *s_the;
}

WSScreen::WSScreen(RGBA32* framebuffer, unsigned width, unsigned height)
    : m_framebuffer(framebuffer)
    , m_width(width)
    , m_height(height)
{
    ASSERT(!s_the);
    s_the = this;

    m_cursor_location = rect().center();
}

WSScreen::~WSScreen()
{
}

void WSScreen::on_receive_mouse_data(int dx, int dy, bool left_button, bool right_button)
{
    auto prev_location = m_cursor_location;
    m_cursor_location.move_by(dx, dy);
    m_cursor_location.constrain(rect());
    if (m_cursor_location.x() >= width())
        m_cursor_location.set_x(width() - 1);
    if (m_cursor_location.y() >= height())
        m_cursor_location.set_y(height() - 1);
    unsigned buttons = 0;
    if (left_button)
        buttons |= (unsigned)MouseButton::Left;
    if (right_button)
        buttons |= (unsigned)MouseButton::Right;
    if (m_cursor_location != prev_location) {
        auto event = make<MouseEvent>(WSEvent::MouseMove, m_cursor_location, buttons);
        WSEventLoop::the().post_event(&WSWindowManager::the(), move(event));
    }
    bool prev_left_button = m_left_mouse_button_pressed;
    bool prev_right_button = m_right_mouse_button_pressed;
    m_left_mouse_button_pressed = left_button;
    m_right_mouse_button_pressed = right_button;
    if (prev_left_button != left_button) {
        auto event = make<MouseEvent>(left_button ? WSEvent::MouseDown : WSEvent::MouseUp, m_cursor_location, buttons, MouseButton::Left);
        WSEventLoop::the().post_event(&WSWindowManager::the(), move(event));
    }
    if (prev_right_button != right_button) {
        auto event = make<MouseEvent>(right_button ? WSEvent::MouseDown : WSEvent::MouseUp, m_cursor_location, buttons, MouseButton::Right);
        WSEventLoop::the().post_event(&WSWindowManager::the(), move(event));
    }
    if (m_cursor_location != prev_location || prev_left_button != left_button)
        WSWindowManager::the().draw_cursor();
}

void WSScreen::on_receive_keyboard_data(Keyboard::Key key)
{
    auto event = make<KeyEvent>(WSEvent::KeyDown, 0);
    int key_code = 0;

    switch (key.character) {
    case 8: key_code = KeyboardKey::Backspace; break;
    case 10: key_code = KeyboardKey::Return; break;
    }
    event->m_key = key_code;

    if (key.character) {
        char buf[] = { 0, 0 };
        char& ch = buf[0];
        ch = key.character;
        if (key.shift()) {
            if (ch >= 'a' && ch <= 'z') {
                ch &= ~0x20;
            } else {
                switch (ch) {
                case '1': ch = '!'; break;
                case '2': ch = '@'; break;
                case '3': ch = '#'; break;
                case '4': ch = '$'; break;
                case '5': ch = '%'; break;
                case '6': ch = '^'; break;
                case '7': ch = '&'; break;
                case '8': ch = '*'; break;
                case '9': ch = '('; break;
                case '0': ch = ')'; break;
                case '-': ch = '_'; break;
                case '=': ch = '+'; break;
                case '`': ch = '~'; break;
                case ',': ch = '<'; break;
                case '.': ch = '>'; break;
                case '/': ch = '?'; break;
                case '[': ch = '{'; break;
                case ']': ch = '}'; break;
                case '\\': ch = '|'; break;
                case '\'': ch = '"'; break;
                case ';': ch = ':'; break;
                }
            }
        }
        event->m_text = buf;
    }

    event->m_shift = key.shift();
    event->m_ctrl = key.ctrl();
    event->m_alt = key.alt();

    WSEventLoop::the().post_event(&WSWindowManager::the(), move(event));
}