-
Notifications
You must be signed in to change notification settings - Fork 0
/
input.cpp
177 lines (141 loc) · 5.5 KB
/
input.cpp
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
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
#include "moonlight.hpp"
#include "ppapi/c/ppb_input_event.h"
#include "ppapi/cpp/input_event.h"
#include <Limelight.h>
#define KEY_PREFIX 0x80
static int ConvertPPButtonToLiButton(PP_InputEvent_MouseButton ppButton) {
switch (ppButton) {
case PP_INPUTEVENT_MOUSEBUTTON_LEFT:
return BUTTON_LEFT;
case PP_INPUTEVENT_MOUSEBUTTON_MIDDLE:
return BUTTON_MIDDLE;
case PP_INPUTEVENT_MOUSEBUTTON_RIGHT:
return BUTTON_RIGHT;
default:
return 0;
}
}
void MoonlightInstance::DidLockMouse(int32_t result) {
m_MouseLocked = (result == PP_OK);
if (m_MouseLocked) {
// Request an IDR frame to dump the frame queue that may have
// built up from the GL pipeline being stalled.
g_Instance->m_RequestIdrFrame = true;
}
}
void MoonlightInstance::MouseLockLost() {
m_MouseLocked = false;
}
static char GetModifierFlags(const pp::InputEvent& event) {
uint32_t modifiers = event.GetModifiers();
char flags = 0;
if (modifiers & PP_INPUTEVENT_MODIFIER_SHIFTKEY) {
flags |= MODIFIER_SHIFT;
}
if (modifiers & PP_INPUTEVENT_MODIFIER_CONTROLKEY) {
flags |= MODIFIER_CTRL;
}
if (modifiers & PP_INPUTEVENT_MODIFIER_ALTKEY) {
flags |= MODIFIER_ALT;
}
return flags;
}
void MoonlightInstance::ReportMouseMovement() {
if (m_MouseDeltaX != 0 || m_MouseDeltaY != 0) {
LiSendMouseMoveEvent(m_MouseDeltaX, m_MouseDeltaY);
m_MouseDeltaX = m_MouseDeltaY = 0;
}
}
bool MoonlightInstance::HandleInputEvent(const pp::InputEvent& event) {
switch (event.GetType()) {
case PP_INPUTEVENT_TYPE_MOUSEDOWN: {
// Lock the mouse cursor when the user clicks on the stream
if (!m_MouseLocked) {
LockMouse(m_CallbackFactory.NewCallback(&MoonlightInstance::DidLockMouse));
// Assume it worked until we get a callback telling us otherwise
m_MouseLocked = true;
return true;
}
pp::MouseInputEvent mouseEvent(event);
LiSendMouseButtonEvent(BUTTON_ACTION_PRESS, ConvertPPButtonToLiButton(mouseEvent.GetButton()));
return true;
}
case PP_INPUTEVENT_TYPE_MOUSEMOVE: {
if (!m_MouseLocked) {
return false;
}
pp::MouseInputEvent mouseEvent(event);
pp::Point posDelta = mouseEvent.GetMovement();
// Wait to report mouse movement until the next input polling window
// to allow batching to occur which reduces overall input lag.
m_MouseDeltaX += posDelta.x();
m_MouseDeltaY += posDelta.y();
return true;
}
case PP_INPUTEVENT_TYPE_MOUSEUP: {
if (!m_MouseLocked) {
return false;
}
pp::MouseInputEvent mouseEvent(event);
LiSendMouseButtonEvent(BUTTON_ACTION_RELEASE, ConvertPPButtonToLiButton(mouseEvent.GetButton()));
return true;
}
case PP_INPUTEVENT_TYPE_WHEEL: {
signed char fullTicks;
if (!m_MouseLocked) {
return false;
}
pp::WheelInputEvent wheelEvent(event);
// Accumulate the current tick value
m_AccumulatedTicks += wheelEvent.GetTicks().y();
// Compute the number of full ticks
fullTicks = (signed char) m_AccumulatedTicks;
// Send a scroll event if we've completed a full tick
if (fullTicks != 0) {
LiSendScrollEvent(fullTicks);
m_AccumulatedTicks -= fullTicks;
}
return true;
}
case PP_INPUTEVENT_TYPE_KEYDOWN: {
if (!m_MouseLocked) {
return false;
}
pp::KeyboardInputEvent keyboardEvent(event);
char modifiers = GetModifierFlags(event);
if (modifiers == (MODIFIER_ALT | MODIFIER_CTRL | MODIFIER_SHIFT)) {
if (keyboardEvent.GetKeyCode() == 0x51) { // Q key
// Terminate the connection
StopConnection();
return true;
}
else {
// Wait until these keys come up to unlock the mouse
m_WaitingForAllModifiersUp = true;
}
}
LiSendKeyboardEvent(KEY_PREFIX << 8 | keyboardEvent.GetKeyCode(),
KEY_ACTION_DOWN, modifiers);
return true;
}
case PP_INPUTEVENT_TYPE_KEYUP: {
if (!m_MouseLocked) {
return false;
}
pp::KeyboardInputEvent keyboardEvent(event);
char modifiers = GetModifierFlags(event);
// Check if all modifiers are up now
if (m_WaitingForAllModifiersUp && modifiers == 0) {
UnlockMouse();
m_MouseLocked = false;
m_WaitingForAllModifiersUp = false;
}
LiSendKeyboardEvent(KEY_PREFIX << 8 | keyboardEvent.GetKeyCode(),
KEY_ACTION_UP, modifiers);
return true;
}
default: {
return false;
}
}
}