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