• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //
2 // Copyright 2014 The ANGLE Project Authors. All rights reserved.
3 // Use of this source code is governed by a BSD-style license that can be
4 // found in the LICENSE file.
5 //
6 
7 #include "OSWindow.h"
8 
9 #include <fstream>
10 #include <iostream>
11 #include <sstream>
12 
13 #include "common/debug.h"
14 #include "common/system_utils.h"
15 
16 #if defined(ANGLE_PLATFORM_ANDROID)
17 #    include "util/android/AndroidWindow.h"
18 #endif  // defined(ANGLE_PLATFORM_ANDROID)
19 
20 #ifndef DEBUG_EVENTS
21 #    define DEBUG_EVENTS 0
22 #endif
23 
24 #if DEBUG_EVENTS
MouseButtonName(MouseButton button)25 static const char *MouseButtonName(MouseButton button)
26 {
27     switch (button)
28     {
29         case MOUSEBUTTON_UNKNOWN:
30             return "Unknown";
31         case MOUSEBUTTON_LEFT:
32             return "Left";
33         case MOUSEBUTTON_RIGHT:
34             return "Right";
35         case MOUSEBUTTON_MIDDLE:
36             return "Middle";
37         case MOUSEBUTTON_BUTTON4:
38             return "Button4";
39         case MOUSEBUTTON_BUTTON5:
40             return "Button5";
41         default:
42             UNREACHABLE();
43             return nullptr;
44     }
45 }
46 
KeyName(Key key)47 static const char *KeyName(Key key)
48 {
49     switch (key)
50     {
51         case KEY_UNKNOWN:
52             return "Unknown";
53         case KEY_A:
54             return "A";
55         case KEY_B:
56             return "B";
57         case KEY_C:
58             return "C";
59         case KEY_D:
60             return "D";
61         case KEY_E:
62             return "E";
63         case KEY_F:
64             return "F";
65         case KEY_G:
66             return "G";
67         case KEY_H:
68             return "H";
69         case KEY_I:
70             return "I";
71         case KEY_J:
72             return "J";
73         case KEY_K:
74             return "K";
75         case KEY_L:
76             return "L";
77         case KEY_M:
78             return "M";
79         case KEY_N:
80             return "N";
81         case KEY_O:
82             return "O";
83         case KEY_P:
84             return "P";
85         case KEY_Q:
86             return "Q";
87         case KEY_R:
88             return "R";
89         case KEY_S:
90             return "S";
91         case KEY_T:
92             return "T";
93         case KEY_U:
94             return "U";
95         case KEY_V:
96             return "V";
97         case KEY_W:
98             return "W";
99         case KEY_X:
100             return "X";
101         case KEY_Y:
102             return "Y";
103         case KEY_Z:
104             return "Z";
105         case KEY_NUM0:
106             return "Num0";
107         case KEY_NUM1:
108             return "Num1";
109         case KEY_NUM2:
110             return "Num2";
111         case KEY_NUM3:
112             return "Num3";
113         case KEY_NUM4:
114             return "Num4";
115         case KEY_NUM5:
116             return "Num5";
117         case KEY_NUM6:
118             return "Num6";
119         case KEY_NUM7:
120             return "Num7";
121         case KEY_NUM8:
122             return "Num8";
123         case KEY_NUM9:
124             return "Num9";
125         case KEY_ESCAPE:
126             return "Escape";
127         case KEY_LCONTROL:
128             return "Left Control";
129         case KEY_LSHIFT:
130             return "Left Shift";
131         case KEY_LALT:
132             return "Left Alt";
133         case KEY_LSYSTEM:
134             return "Left System";
135         case KEY_RCONTROL:
136             return "Right Control";
137         case KEY_RSHIFT:
138             return "Right Shift";
139         case KEY_RALT:
140             return "Right Alt";
141         case KEY_RSYSTEM:
142             return "Right System";
143         case KEY_MENU:
144             return "Menu";
145         case KEY_LBRACKET:
146             return "Left Bracket";
147         case KEY_RBRACKET:
148             return "Right Bracket";
149         case KEY_SEMICOLON:
150             return "Semicolon";
151         case KEY_COMMA:
152             return "Comma";
153         case KEY_PERIOD:
154             return "Period";
155         case KEY_QUOTE:
156             return "Quote";
157         case KEY_SLASH:
158             return "Slash";
159         case KEY_BACKSLASH:
160             return "Backslash";
161         case KEY_TILDE:
162             return "Tilde";
163         case KEY_EQUAL:
164             return "Equal";
165         case KEY_DASH:
166             return "Dash";
167         case KEY_SPACE:
168             return "Space";
169         case KEY_RETURN:
170             return "Return";
171         case KEY_BACK:
172             return "Back";
173         case KEY_TAB:
174             return "Tab";
175         case KEY_PAGEUP:
176             return "Page Up";
177         case KEY_PAGEDOWN:
178             return "Page Down";
179         case KEY_END:
180             return "End";
181         case KEY_HOME:
182             return "Home";
183         case KEY_INSERT:
184             return "Insert";
185         case KEY_DELETE:
186             return "Delete";
187         case KEY_ADD:
188             return "Add";
189         case KEY_SUBTRACT:
190             return "Substract";
191         case KEY_MULTIPLY:
192             return "Multiply";
193         case KEY_DIVIDE:
194             return "Divide";
195         case KEY_LEFT:
196             return "Left";
197         case KEY_RIGHT:
198             return "Right";
199         case KEY_UP:
200             return "Up";
201         case KEY_DOWN:
202             return "Down";
203         case KEY_NUMPAD0:
204             return "Numpad 0";
205         case KEY_NUMPAD1:
206             return "Numpad 1";
207         case KEY_NUMPAD2:
208             return "Numpad 2";
209         case KEY_NUMPAD3:
210             return "Numpad 3";
211         case KEY_NUMPAD4:
212             return "Numpad 4";
213         case KEY_NUMPAD5:
214             return "Numpad 5";
215         case KEY_NUMPAD6:
216             return "Numpad 6";
217         case KEY_NUMPAD7:
218             return "Numpad 7";
219         case KEY_NUMPAD8:
220             return "Numpad 8";
221         case KEY_NUMPAD9:
222             return "Numpad 9";
223         case KEY_F1:
224             return "F1";
225         case KEY_F2:
226             return "F2";
227         case KEY_F3:
228             return "F3";
229         case KEY_F4:
230             return "F4";
231         case KEY_F5:
232             return "F5";
233         case KEY_F6:
234             return "F6";
235         case KEY_F7:
236             return "F7";
237         case KEY_F8:
238             return "F8";
239         case KEY_F9:
240             return "F9";
241         case KEY_F10:
242             return "F10";
243         case KEY_F11:
244             return "F11";
245         case KEY_F12:
246             return "F12";
247         case KEY_F13:
248             return "F13";
249         case KEY_F14:
250             return "F14";
251         case KEY_F15:
252             return "F15";
253         case KEY_PAUSE:
254             return "Pause";
255         default:
256             return "Unknown Key";
257     }
258 }
259 
KeyState(const Event::KeyEvent & event)260 static std::string KeyState(const Event::KeyEvent &event)
261 {
262     if (event.Shift || event.Control || event.Alt || event.System)
263     {
264         std::ostringstream buffer;
265         buffer << " [";
266 
267         if (event.Shift)
268         {
269             buffer << "Shift";
270         }
271         if (event.Control)
272         {
273             buffer << "Control";
274         }
275         if (event.Alt)
276         {
277             buffer << "Alt";
278         }
279         if (event.System)
280         {
281             buffer << "System";
282         }
283 
284         buffer << "]";
285         return buffer.str();
286     }
287     return "";
288 }
289 
PrintEvent(const Event & event)290 static void PrintEvent(const Event &event)
291 {
292     switch (event.Type)
293     {
294         case Event::EVENT_CLOSED:
295             std::cout << "Event: Window Closed" << std::endl;
296             break;
297         case Event::EVENT_MOVED:
298             std::cout << "Event: Window Moved (" << event.Move.X << ", " << event.Move.Y << ")"
299                       << std::endl;
300             break;
301         case Event::EVENT_RESIZED:
302             std::cout << "Event: Window Resized (" << event.Size.Width << ", " << event.Size.Height
303                       << ")" << std::endl;
304             break;
305         case Event::EVENT_LOST_FOCUS:
306             std::cout << "Event: Window Lost Focus" << std::endl;
307             break;
308         case Event::EVENT_GAINED_FOCUS:
309             std::cout << "Event: Window Gained Focus" << std::endl;
310             break;
311         case Event::EVENT_TEXT_ENTERED:
312             // TODO(cwallez) show the character
313             std::cout << "Event: Text Entered" << std::endl;
314             break;
315         case Event::EVENT_KEY_PRESSED:
316             std::cout << "Event: Key Pressed (" << KeyName(event.Key.Code) << KeyState(event.Key)
317                       << ")" << std::endl;
318             break;
319         case Event::EVENT_KEY_RELEASED:
320             std::cout << "Event: Key Released (" << KeyName(event.Key.Code) << KeyState(event.Key)
321                       << ")" << std::endl;
322             break;
323         case Event::EVENT_MOUSE_WHEEL_MOVED:
324             std::cout << "Event: Mouse Wheel (" << event.MouseWheel.Delta << ")" << std::endl;
325             break;
326         case Event::EVENT_MOUSE_BUTTON_PRESSED:
327             std::cout << "Event: Mouse Button Pressed " << MouseButtonName(event.MouseButton.Button)
328                       << " at (" << event.MouseButton.X << ", " << event.MouseButton.Y << ")"
329                       << std::endl;
330             break;
331         case Event::EVENT_MOUSE_BUTTON_RELEASED:
332             std::cout << "Event: Mouse Button Released "
333                       << MouseButtonName(event.MouseButton.Button) << " at (" << event.MouseButton.X
334                       << ", " << event.MouseButton.Y << ")" << std::endl;
335             break;
336         case Event::EVENT_MOUSE_MOVED:
337             std::cout << "Event: Mouse Moved (" << event.MouseMove.X << ", " << event.MouseMove.Y
338                       << ")" << std::endl;
339             break;
340         case Event::EVENT_MOUSE_ENTERED:
341             std::cout << "Event: Mouse Entered Window" << std::endl;
342             break;
343         case Event::EVENT_MOUSE_LEFT:
344             std::cout << "Event: Mouse Left Window" << std::endl;
345             break;
346         case Event::EVENT_TEST:
347             std::cout << "Event: Test" << std::endl;
348             break;
349         default:
350             UNREACHABLE();
351             break;
352     }
353 }
354 #endif
355 
OSWindow()356 OSWindow::OSWindow() : mX(0), mY(0), mWidth(0), mHeight(0), mValid(false), mIgnoreSizeEvents(false)
357 {}
358 
~OSWindow()359 OSWindow::~OSWindow() {}
360 
initialize(const std::string & name,int width,int height)361 bool OSWindow::initialize(const std::string &name, int width, int height)
362 {
363     mValid = initializeImpl(name, width, height);
364     return mValid;
365 }
366 
getX() const367 int OSWindow::getX() const
368 {
369     return mX;
370 }
371 
getY() const372 int OSWindow::getY() const
373 {
374     return mY;
375 }
376 
getWidth() const377 int OSWindow::getWidth() const
378 {
379     return mWidth;
380 }
381 
getHeight() const382 int OSWindow::getHeight() const
383 {
384     return mHeight;
385 }
386 
takeScreenshot(uint8_t * pixelData)387 bool OSWindow::takeScreenshot(uint8_t *pixelData)
388 {
389     return false;
390 }
391 
popEvent(Event * event)392 bool OSWindow::popEvent(Event *event)
393 {
394     if (mEvents.size() > 0 && event)
395     {
396         *event = mEvents.front();
397         mEvents.pop_front();
398         return true;
399     }
400     else
401     {
402         return false;
403     }
404 }
405 
pushEvent(Event event)406 void OSWindow::pushEvent(Event event)
407 {
408     switch (event.Type)
409     {
410         case Event::EVENT_MOVED:
411             mX = event.Move.X;
412             mY = event.Move.Y;
413             break;
414         case Event::EVENT_RESIZED:
415             mWidth  = event.Size.Width;
416             mHeight = event.Size.Height;
417             break;
418         default:
419             break;
420     }
421 
422     mEvents.push_back(event);
423 
424 #if DEBUG_EVENTS
425     PrintEvent(event);
426 #endif
427 }
428 
didTestEventFire()429 bool OSWindow::didTestEventFire()
430 {
431     Event topEvent;
432     while (popEvent(&topEvent))
433     {
434         if (topEvent.Type == Event::EVENT_TEST)
435         {
436             return true;
437         }
438     }
439 
440     return false;
441 }
442 
443 // static
Delete(OSWindow ** window)444 void OSWindow::Delete(OSWindow **window)
445 {
446     delete *window;
447     *window = nullptr;
448 }
449 
450 namespace angle
451 {
FindTestDataPath(const char * searchPath,char * dataPathOut,size_t maxDataPathOutLen)452 bool FindTestDataPath(const char *searchPath, char *dataPathOut, size_t maxDataPathOutLen)
453 {
454 #if defined(ANGLE_PLATFORM_ANDROID)
455     const std::string searchPaths[] = {
456         AndroidWindow::GetExternalStorageDirectory(),
457         AndroidWindow::GetExternalStorageDirectory() + "/third_party/angle"};
458 #else
459     const std::string searchPaths[] = {
460         GetExecutableDirectory(), GetExecutableDirectory() + "/../..", ".",
461         GetExecutableDirectory() + "/../../third_party/angle", "third_party/angle"};
462 #endif  // defined(ANGLE_PLATFORM_ANDROID)
463 
464     for (const std::string &path : searchPaths)
465     {
466         std::stringstream pathStream;
467         pathStream << path << "/" << searchPath;
468         std::string candidatePath = pathStream.str();
469 
470         if (candidatePath.size() + 1 >= maxDataPathOutLen)
471         {
472             ERR() << "FindTestDataPath: Path too long.";
473             return false;
474         }
475 
476         if (angle::IsDirectory(candidatePath.c_str()))
477         {
478             memcpy(dataPathOut, candidatePath.c_str(), candidatePath.size() + 1);
479             return true;
480         }
481 
482         std::ifstream inFile(candidatePath.c_str());
483         if (!inFile.fail())
484         {
485             memcpy(dataPathOut, candidatePath.c_str(), candidatePath.size() + 1);
486             return true;
487         }
488     }
489 
490     return false;
491 }
492 }  // namespace angle
493