Numworks Epsilon  1.4.1
Graphing Calculator Operating System
events_keyboard.cpp
Go to the documentation of this file.
1 #include <ion/events.h>
2 #include "events_keyboard.h"
3 #include "display.h"
4 extern "C" {
5 #include <SDL/SDL.h>
6 }
7 #include <emscripten.h>
8 
9 template<typename T, int N>
10 class Queue {
11 public:
12  Queue() : m_first(&m_elements[0]), m_last(&m_elements[0]) {}
13  int size() {
14  if (m_last >= m_first) {
15  return m_last - m_first;
16  } else {
17  return m_last - (m_first - N);
18  }
19  }
20 
21  void enqueue(T element) {
22  if (size() > N) {
23  // Queue is full
24  return;
25  }
26  *m_last = element;
27  m_last = next(m_last);
28  }
29 
30  T dequeue() {
31  if (size() <= 0) {
32  // Dequeueing an empty queue
33  return T();
34  }
35  T e = *m_first;
36  m_first = next(m_first);
37  return e;
38  }
39 
40 private:
41  T * next(T * p) {
42  if (p >= m_elements + N) {
43  return m_elements;
44  } else {
45  return p + 1;
46  }
47  }
48  T * m_first;
49  T * m_last;
50  T m_elements[N];
51 };
52 
53 static Queue<Ion::Events::Event, 1024> sEventQueue;
54 
55 void IonEventsEmscriptenPushKey(int keyNumber) {
56  /* Note: This uses the *current* modifier state to generate the event. If some
57  * other modifiers were in the queue before, those won't be taken into account
58  * when the event corresponding to this key is dequeued.
59  * In practice, this should not happen because we push keys one by one. */
61  sEventQueue.enqueue(event);
62 }
63 
64 void IonEventsEmscriptenPushEvent(int eventNumber) {
65  sEventQueue.enqueue(Ion::Events::Event(eventNumber));
66 }
67 
69  // FIXME
70  // On the Emscripten platform, scan() is used in :
71  // - shouldInterrupt(), from interruptHelper.h
72  // - apps_container.cpp
73  // - apps/hardware_test/keyboard_test_controller.cpp
74  // We would like to check if there is a Back event that would interrupt the
75  // Python or Poincare computation, but it is quite difficult to get because
76  // the runLoop is blocking in JavaScript and Events do not get pushed in
77  // sEvent.
78  // We still need to override the dummy/events_keyboard.cpp function, which
79  // returns that all keys are always pressed and thus interrupts Python
80  // computations after 20000 calls.
81  return 0;
82 }
83 
84 namespace Ion {
85 namespace Events {
86 
87 static constexpr Event sEventForASCIICharAbove32[95] = {
90  Zero, One, Two, Three, Four, Five, Six, Seven,
100 };
101 
102 static bool sleepWithTimeout(int duration, int * timeout) {
103  if (*timeout >= duration) {
104  emscripten_sleep(duration);
105  *timeout -= duration;
106  return false;
107  } else {
108  emscripten_sleep(*timeout);
109  *timeout = 0;
110  return true;
111  }
112 }
113 
114 static Event eventFromSDLEvent(SDL_Event sdlEvent) {
115  if (sdlEvent.type != SDL_KEYDOWN) {
116  return None;
117  }
118  if (sdlEvent.key.keysym.mod & KMOD_CTRL) {
119  switch (sdlEvent.key.keysym.sym) {
120  case SDLK_BACKSPACE:
121  return Clear;
122  case SDLK_x:
123  return Cut;
124  case SDLK_c:
125  return Copy;
126  case SDLK_v:
127  return Paste;
128  }
129  }
130  if (sdlEvent.key.keysym.mod & KMOD_ALT) {
131  if (sdlEvent.key.keysym.mod & KMOD_SHIFT) {
132  switch (sdlEvent.key.keysym.sym) {
133  case SDLK_s:
134  return Arcsine;
135  case SDLK_c:
136  return Arccosine;
137  case SDLK_t:
138  return Arctangent;
139  }
140  }
141  switch (sdlEvent.key.keysym.sym) {
142  case SDLK_ESCAPE:
143  return Home;
144  case SDLK_RETURN:
145  return OK;
146  case SDLK_v:
147  return Var;
148  case SDLK_BACKSPACE:
149  return Clear;
150  case SDLK_x:
151  return Exp;
152  case SDLK_n:
153  return Ln;
154  case SDLK_l:
155  return Log;
156  case SDLK_i:
157  return Imaginary;
158  case SDLK_EQUALS:
159  return Sto;
160  case SDLK_s:
161  return Sine;
162  case SDLK_c:
163  return Cosine;
164  case SDLK_t:
165  return Tangent;
166  case SDLK_p:
167  return Pi;
168  case SDLK_r:
169  return Sqrt;
170  case SDLK_2:
171  return Square;
172  case SDLK_e:
173  return EE;
174  case SDLK_a:
175  return Ans;
176  }
177  }
178  switch(sdlEvent.key.keysym.sym) {
179  case SDLK_UP:
180  return Up;
181  case SDLK_DOWN:
182  return Down;
183  case SDLK_LEFT:
184  return Left;
185  case SDLK_RIGHT:
186  return Right;
187  case SDLK_RETURN:
188  return EXE;
189  case SDLK_ESCAPE:
190  return Back;
191  case SDLK_TAB:
192  return Toolbox;
193  case SDLK_BACKSPACE:
194  return Backspace;
195  }
196  if (sdlEvent.key.keysym.unicode >= 32 && sdlEvent.key.keysym.unicode < 127) {
197  return sEventForASCIICharAbove32[sdlEvent.key.keysym.unicode-32];
198  }
199  return None;
200 }
201 
202 Event getEvent(int * timeout) {
203  // If multiple events are in the queue, don't waste time refreshing the display
204  if (sEventQueue.size() <= 1) {
206  }
207 
208  while (true) {
209  // Look up events in the queue
210  if (sEventQueue.size() > 0) {
211  Event event = sEventQueue.dequeue();
212  if (event.isKeyboardEvent()) {
214  }
215  return event;
216  }
217 
218  // Or directly from browser events, converted to SDL events by Emscripten
219  SDL_Event sdlEvent;
220  SDL_PollEvent(&sdlEvent);
221  Event eventFromSDL = eventFromSDLEvent(sdlEvent);
222  if (eventFromSDL != None) {
223  return eventFromSDL;
224  }
225 
226  if (sleepWithTimeout(10, timeout)) {
227  return None;
228  }
229  }
230  return None;
231 }
232 
233 }
234 }
235 
236 namespace Ion {
237 namespace Events {
238 namespace Emscripten {
239 
240 void init() {
241  SDL_EnableUNICODE(1); // We're using Unicode values from Keyboard input
242 }
243 
244 }
245 }
246 }
constexpr Event UpperC
Definition: events.h:186
constexpr Event LowerJ
Definition: events.h:157
constexpr Event LowerL
Definition: events.h:159
constexpr Event LowerP
Definition: events.h:164
constexpr Event DoubleQuotes
Definition: events.h:145
constexpr Event Plus
Definition: events.h:107
constexpr Event Colon
Definition: events.h:143
constexpr Event UpperI
Definition: events.h:193
constexpr Event UpperR
Definition: events.h:204
constexpr Event EE
Definition: events.h:112
Event getEvent(int *timeout)
Definition: events.cpp:12
constexpr Event Four
Definition: events.h:98
constexpr Event Var
Definition: events.h:74
constexpr Event LowerW
Definition: events.h:173
constexpr Event UpperA
Definition: events.h:184
constexpr Event Underscore
Definition: events.h:131
constexpr Event Power
Definition: events.h:83
constexpr Event Arctangent
Definition: events.h:136
constexpr Event UpperY
Definition: events.h:212
constexpr Event LeftParenthesis
Definition: events.h:95
constexpr Event Tangent
Definition: events.h:87
constexpr Event Question
Definition: events.h:179
constexpr Event Square
Definition: events.h:90
constexpr Event Minus
Definition: events.h:108
constexpr Event Exp
Definition: events.h:78
constexpr Event Greater
Definition: events.h:139
constexpr Event UpperG
Definition: events.h:191
constexpr Event LowerZ
Definition: events.h:176
constexpr Event UpperE
Definition: events.h:188
constexpr Event EXE
Definition: events.h:114
constexpr Event Ln
Definition: events.h:79
constexpr Event Home
Definition: events.h:68
constexpr Event UpperD
Definition: events.h:187
#define T(x)
Definition: events.cpp:26
constexpr Event Up
Definition: events.h:62
constexpr Event Down
Definition: events.h:63
constexpr Event LowerV
Definition: events.h:171
void updateModifiersFromEvent(Event e)
constexpr Event UpperZ
Definition: events.h:213
constexpr Event None
Definition: events.h:215
constexpr Event Exclamation
Definition: events.h:180
constexpr Event Sqrt
Definition: events.h:89
constexpr Event UpperW
Definition: events.h:210
constexpr Event LowerF
Definition: events.h:152
constexpr Event RightParenthesis
Definition: events.h:96
constexpr Event RightBrace
Definition: events.h:130
constexpr Event LowerQ
Definition: events.h:165
constexpr Event Cosine
Definition: events.h:86
constexpr Event Two
Definition: events.h:105
constexpr Event LeftBracket
Definition: events.h:127
constexpr Event LowerN
Definition: events.h:162
constexpr Event Arcsine
Definition: events.h:134
constexpr Event UpperK
Definition: events.h:195
constexpr Event Comma
Definition: events.h:82
constexpr Event LowerA
Definition: events.h:147
constexpr Event Back
Definition: events.h:66
constexpr Event Pi
Definition: events.h:88
constexpr Event UpperJ
Definition: events.h:194
constexpr Event LowerM
Definition: events.h:161
constexpr Event Paste
Definition: events.h:124
void enqueue(T element)
constexpr Event Zero
Definition: events.h:110
constexpr Event Division
Definition: events.h:102
constexpr Event UpperB
Definition: events.h:185
constexpr Event Dot
Definition: events.h:111
constexpr Event Five
Definition: events.h:99
constexpr Event LowerO
Definition: events.h:163
constexpr Event UpperT
Definition: events.h:206
constexpr Event UpperP
Definition: events.h:201
constexpr Event Ans
Definition: events.h:113
int size()
constexpr Event LowerK
Definition: events.h:158
constexpr Event LowerE
Definition: events.h:151
constexpr Event LowerY
Definition: events.h:175
#define N
Definition: b_log__D.c:69
constexpr Event Space
Definition: events.h:177
constexpr Event SemiColon
Definition: events.h:144
constexpr Event UpperS
Definition: events.h:205
constexpr Event Seven
Definition: events.h:92
constexpr Event UpperO
Definition: events.h:200
constexpr Event UpperX
Definition: events.h:211
constexpr Event LowerG
Definition: events.h:154
constexpr Event UpperQ
Definition: events.h:202
constexpr Event LowerC
Definition: events.h:149
constexpr Event Equal
Definition: events.h:137
constexpr Event Eight
Definition: events.h:93
bool isAlphaActive()
constexpr Event LowerS
Definition: events.h:168
constexpr Event UpperH
Definition: events.h:192
void IonEventsEmscriptenPushKey(int keyNumber)
constexpr Event Three
Definition: events.h:106
constexpr Event Left
Definition: events.h:61
bool isShiftActive()
constexpr Event UpperF
Definition: events.h:189
constexpr Event UpperL
Definition: events.h:196
State scan()
Definition: keyboard.cpp:50
constexpr Event Arccosine
Definition: events.h:135
constexpr Event Sine
Definition: events.h:85
constexpr Event Copy
Definition: events.h:123
constexpr Event Imaginary
Definition: events.h:81
constexpr Event LowerD
Definition: events.h:150
constexpr Event Sto
Definition: events.h:132
constexpr Event LowerI
Definition: events.h:156
constexpr Event Lower
Definition: events.h:138
constexpr Event Right
Definition: events.h:64
constexpr Event UpperU
Definition: events.h:207
constexpr Event UpperN
Definition: events.h:199
constexpr Event LowerU
Definition: events.h:170
constexpr Event Multiplication
Definition: events.h:101
constexpr Event LowerX
Definition: events.h:174
constexpr Event LowerT
Definition: events.h:169
constexpr Event Cut
Definition: events.h:122
constexpr Event LeftBrace
Definition: events.h:129
constexpr Event Toolbox
Definition: events.h:75
constexpr Event LowerH
Definition: events.h:155
constexpr Event OK
Definition: events.h:65
void IonEventsEmscriptenPushEvent(int eventNumber)
Definition: backlight.h:6
constexpr Event Six
Definition: events.h:100
constexpr Event Clear
Definition: events.h:125
constexpr Event UpperV
Definition: events.h:208
constexpr Event LowerR
Definition: events.h:167
constexpr Event One
Definition: events.h:104
constexpr Event LowerB
Definition: events.h:148
constexpr Event Log
Definition: events.h:80
constexpr Event Nine
Definition: events.h:94
constexpr Event Backspace
Definition: events.h:76
constexpr Event RightBracket
Definition: events.h:128
constexpr Event UpperM
Definition: events.h:198