498 lines
		
	
	
		
			12 KiB
		
	
	
	
		
			C++
		
	
	
	
			
		
		
	
	
			498 lines
		
	
	
		
			12 KiB
		
	
	
	
		
			C++
		
	
	
	
//
 | 
						|
// Copyright 2014 The ANGLE Project Authors. All rights reserved.
 | 
						|
// Use of this source code is governed by a BSD-style license that can be
 | 
						|
// found in the LICENSE file.
 | 
						|
//
 | 
						|
 | 
						|
#include "OSWindow.h"
 | 
						|
 | 
						|
#include <fstream>
 | 
						|
#include <iostream>
 | 
						|
#include <sstream>
 | 
						|
 | 
						|
#include "common/debug.h"
 | 
						|
#include "common/system_utils.h"
 | 
						|
 | 
						|
#if defined(ANGLE_PLATFORM_ANDROID)
 | 
						|
#    include "util/android/AndroidWindow.h"
 | 
						|
#endif  // defined(ANGLE_PLATFORM_ANDROID)
 | 
						|
 | 
						|
#ifndef DEBUG_EVENTS
 | 
						|
#    define DEBUG_EVENTS 0
 | 
						|
#endif
 | 
						|
 | 
						|
#if DEBUG_EVENTS
 | 
						|
static const char *MouseButtonName(MouseButton button)
 | 
						|
{
 | 
						|
    switch (button)
 | 
						|
    {
 | 
						|
        case MOUSEBUTTON_UNKNOWN:
 | 
						|
            return "Unknown";
 | 
						|
        case MOUSEBUTTON_LEFT:
 | 
						|
            return "Left";
 | 
						|
        case MOUSEBUTTON_RIGHT:
 | 
						|
            return "Right";
 | 
						|
        case MOUSEBUTTON_MIDDLE:
 | 
						|
            return "Middle";
 | 
						|
        case MOUSEBUTTON_BUTTON4:
 | 
						|
            return "Button4";
 | 
						|
        case MOUSEBUTTON_BUTTON5:
 | 
						|
            return "Button5";
 | 
						|
        default:
 | 
						|
            UNREACHABLE();
 | 
						|
            return nullptr;
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
static const char *KeyName(Key key)
 | 
						|
{
 | 
						|
    switch (key)
 | 
						|
    {
 | 
						|
        case KEY_UNKNOWN:
 | 
						|
            return "Unknown";
 | 
						|
        case KEY_A:
 | 
						|
            return "A";
 | 
						|
        case KEY_B:
 | 
						|
            return "B";
 | 
						|
        case KEY_C:
 | 
						|
            return "C";
 | 
						|
        case KEY_D:
 | 
						|
            return "D";
 | 
						|
        case KEY_E:
 | 
						|
            return "E";
 | 
						|
        case KEY_F:
 | 
						|
            return "F";
 | 
						|
        case KEY_G:
 | 
						|
            return "G";
 | 
						|
        case KEY_H:
 | 
						|
            return "H";
 | 
						|
        case KEY_I:
 | 
						|
            return "I";
 | 
						|
        case KEY_J:
 | 
						|
            return "J";
 | 
						|
        case KEY_K:
 | 
						|
            return "K";
 | 
						|
        case KEY_L:
 | 
						|
            return "L";
 | 
						|
        case KEY_M:
 | 
						|
            return "M";
 | 
						|
        case KEY_N:
 | 
						|
            return "N";
 | 
						|
        case KEY_O:
 | 
						|
            return "O";
 | 
						|
        case KEY_P:
 | 
						|
            return "P";
 | 
						|
        case KEY_Q:
 | 
						|
            return "Q";
 | 
						|
        case KEY_R:
 | 
						|
            return "R";
 | 
						|
        case KEY_S:
 | 
						|
            return "S";
 | 
						|
        case KEY_T:
 | 
						|
            return "T";
 | 
						|
        case KEY_U:
 | 
						|
            return "U";
 | 
						|
        case KEY_V:
 | 
						|
            return "V";
 | 
						|
        case KEY_W:
 | 
						|
            return "W";
 | 
						|
        case KEY_X:
 | 
						|
            return "X";
 | 
						|
        case KEY_Y:
 | 
						|
            return "Y";
 | 
						|
        case KEY_Z:
 | 
						|
            return "Z";
 | 
						|
        case KEY_NUM0:
 | 
						|
            return "Num0";
 | 
						|
        case KEY_NUM1:
 | 
						|
            return "Num1";
 | 
						|
        case KEY_NUM2:
 | 
						|
            return "Num2";
 | 
						|
        case KEY_NUM3:
 | 
						|
            return "Num3";
 | 
						|
        case KEY_NUM4:
 | 
						|
            return "Num4";
 | 
						|
        case KEY_NUM5:
 | 
						|
            return "Num5";
 | 
						|
        case KEY_NUM6:
 | 
						|
            return "Num6";
 | 
						|
        case KEY_NUM7:
 | 
						|
            return "Num7";
 | 
						|
        case KEY_NUM8:
 | 
						|
            return "Num8";
 | 
						|
        case KEY_NUM9:
 | 
						|
            return "Num9";
 | 
						|
        case KEY_ESCAPE:
 | 
						|
            return "Escape";
 | 
						|
        case KEY_LCONTROL:
 | 
						|
            return "Left Control";
 | 
						|
        case KEY_LSHIFT:
 | 
						|
            return "Left Shift";
 | 
						|
        case KEY_LALT:
 | 
						|
            return "Left Alt";
 | 
						|
        case KEY_LSYSTEM:
 | 
						|
            return "Left System";
 | 
						|
        case KEY_RCONTROL:
 | 
						|
            return "Right Control";
 | 
						|
        case KEY_RSHIFT:
 | 
						|
            return "Right Shift";
 | 
						|
        case KEY_RALT:
 | 
						|
            return "Right Alt";
 | 
						|
        case KEY_RSYSTEM:
 | 
						|
            return "Right System";
 | 
						|
        case KEY_MENU:
 | 
						|
            return "Menu";
 | 
						|
        case KEY_LBRACKET:
 | 
						|
            return "Left Bracket";
 | 
						|
        case KEY_RBRACKET:
 | 
						|
            return "Right Bracket";
 | 
						|
        case KEY_SEMICOLON:
 | 
						|
            return "Semicolon";
 | 
						|
        case KEY_COMMA:
 | 
						|
            return "Comma";
 | 
						|
        case KEY_PERIOD:
 | 
						|
            return "Period";
 | 
						|
        case KEY_QUOTE:
 | 
						|
            return "Quote";
 | 
						|
        case KEY_SLASH:
 | 
						|
            return "Slash";
 | 
						|
        case KEY_BACKSLASH:
 | 
						|
            return "Backslash";
 | 
						|
        case KEY_TILDE:
 | 
						|
            return "Tilde";
 | 
						|
        case KEY_EQUAL:
 | 
						|
            return "Equal";
 | 
						|
        case KEY_DASH:
 | 
						|
            return "Dash";
 | 
						|
        case KEY_SPACE:
 | 
						|
            return "Space";
 | 
						|
        case KEY_RETURN:
 | 
						|
            return "Return";
 | 
						|
        case KEY_BACK:
 | 
						|
            return "Back";
 | 
						|
        case KEY_TAB:
 | 
						|
            return "Tab";
 | 
						|
        case KEY_PAGEUP:
 | 
						|
            return "Page Up";
 | 
						|
        case KEY_PAGEDOWN:
 | 
						|
            return "Page Down";
 | 
						|
        case KEY_END:
 | 
						|
            return "End";
 | 
						|
        case KEY_HOME:
 | 
						|
            return "Home";
 | 
						|
        case KEY_INSERT:
 | 
						|
            return "Insert";
 | 
						|
        case KEY_DELETE:
 | 
						|
            return "Delete";
 | 
						|
        case KEY_ADD:
 | 
						|
            return "Add";
 | 
						|
        case KEY_SUBTRACT:
 | 
						|
            return "Substract";
 | 
						|
        case KEY_MULTIPLY:
 | 
						|
            return "Multiply";
 | 
						|
        case KEY_DIVIDE:
 | 
						|
            return "Divide";
 | 
						|
        case KEY_LEFT:
 | 
						|
            return "Left";
 | 
						|
        case KEY_RIGHT:
 | 
						|
            return "Right";
 | 
						|
        case KEY_UP:
 | 
						|
            return "Up";
 | 
						|
        case KEY_DOWN:
 | 
						|
            return "Down";
 | 
						|
        case KEY_NUMPAD0:
 | 
						|
            return "Numpad 0";
 | 
						|
        case KEY_NUMPAD1:
 | 
						|
            return "Numpad 1";
 | 
						|
        case KEY_NUMPAD2:
 | 
						|
            return "Numpad 2";
 | 
						|
        case KEY_NUMPAD3:
 | 
						|
            return "Numpad 3";
 | 
						|
        case KEY_NUMPAD4:
 | 
						|
            return "Numpad 4";
 | 
						|
        case KEY_NUMPAD5:
 | 
						|
            return "Numpad 5";
 | 
						|
        case KEY_NUMPAD6:
 | 
						|
            return "Numpad 6";
 | 
						|
        case KEY_NUMPAD7:
 | 
						|
            return "Numpad 7";
 | 
						|
        case KEY_NUMPAD8:
 | 
						|
            return "Numpad 8";
 | 
						|
        case KEY_NUMPAD9:
 | 
						|
            return "Numpad 9";
 | 
						|
        case KEY_F1:
 | 
						|
            return "F1";
 | 
						|
        case KEY_F2:
 | 
						|
            return "F2";
 | 
						|
        case KEY_F3:
 | 
						|
            return "F3";
 | 
						|
        case KEY_F4:
 | 
						|
            return "F4";
 | 
						|
        case KEY_F5:
 | 
						|
            return "F5";
 | 
						|
        case KEY_F6:
 | 
						|
            return "F6";
 | 
						|
        case KEY_F7:
 | 
						|
            return "F7";
 | 
						|
        case KEY_F8:
 | 
						|
            return "F8";
 | 
						|
        case KEY_F9:
 | 
						|
            return "F9";
 | 
						|
        case KEY_F10:
 | 
						|
            return "F10";
 | 
						|
        case KEY_F11:
 | 
						|
            return "F11";
 | 
						|
        case KEY_F12:
 | 
						|
            return "F12";
 | 
						|
        case KEY_F13:
 | 
						|
            return "F13";
 | 
						|
        case KEY_F14:
 | 
						|
            return "F14";
 | 
						|
        case KEY_F15:
 | 
						|
            return "F15";
 | 
						|
        case KEY_PAUSE:
 | 
						|
            return "Pause";
 | 
						|
        default:
 | 
						|
            return "Unknown Key";
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
static std::string KeyState(const Event::KeyEvent &event)
 | 
						|
{
 | 
						|
    if (event.Shift || event.Control || event.Alt || event.System)
 | 
						|
    {
 | 
						|
        std::ostringstream buffer;
 | 
						|
        buffer << " [";
 | 
						|
 | 
						|
        if (event.Shift)
 | 
						|
        {
 | 
						|
            buffer << "Shift";
 | 
						|
        }
 | 
						|
        if (event.Control)
 | 
						|
        {
 | 
						|
            buffer << "Control";
 | 
						|
        }
 | 
						|
        if (event.Alt)
 | 
						|
        {
 | 
						|
            buffer << "Alt";
 | 
						|
        }
 | 
						|
        if (event.System)
 | 
						|
        {
 | 
						|
            buffer << "System";
 | 
						|
        }
 | 
						|
 | 
						|
        buffer << "]";
 | 
						|
        return buffer.str();
 | 
						|
    }
 | 
						|
    return "";
 | 
						|
}
 | 
						|
 | 
						|
static void PrintEvent(const Event &event)
 | 
						|
{
 | 
						|
    switch (event.Type)
 | 
						|
    {
 | 
						|
        case Event::EVENT_CLOSED:
 | 
						|
            std::cout << "Event: Window Closed" << std::endl;
 | 
						|
            break;
 | 
						|
        case Event::EVENT_MOVED:
 | 
						|
            std::cout << "Event: Window Moved (" << event.Move.X << ", " << event.Move.Y << ")"
 | 
						|
                      << std::endl;
 | 
						|
            break;
 | 
						|
        case Event::EVENT_RESIZED:
 | 
						|
            std::cout << "Event: Window Resized (" << event.Size.Width << ", " << event.Size.Height
 | 
						|
                      << ")" << std::endl;
 | 
						|
            break;
 | 
						|
        case Event::EVENT_LOST_FOCUS:
 | 
						|
            std::cout << "Event: Window Lost Focus" << std::endl;
 | 
						|
            break;
 | 
						|
        case Event::EVENT_GAINED_FOCUS:
 | 
						|
            std::cout << "Event: Window Gained Focus" << std::endl;
 | 
						|
            break;
 | 
						|
        case Event::EVENT_TEXT_ENTERED:
 | 
						|
            // TODO(cwallez) show the character
 | 
						|
            std::cout << "Event: Text Entered" << std::endl;
 | 
						|
            break;
 | 
						|
        case Event::EVENT_KEY_PRESSED:
 | 
						|
            std::cout << "Event: Key Pressed (" << KeyName(event.Key.Code) << KeyState(event.Key)
 | 
						|
                      << ")" << std::endl;
 | 
						|
            break;
 | 
						|
        case Event::EVENT_KEY_RELEASED:
 | 
						|
            std::cout << "Event: Key Released (" << KeyName(event.Key.Code) << KeyState(event.Key)
 | 
						|
                      << ")" << std::endl;
 | 
						|
            break;
 | 
						|
        case Event::EVENT_MOUSE_WHEEL_MOVED:
 | 
						|
            std::cout << "Event: Mouse Wheel (" << event.MouseWheel.Delta << ")" << std::endl;
 | 
						|
            break;
 | 
						|
        case Event::EVENT_MOUSE_BUTTON_PRESSED:
 | 
						|
            std::cout << "Event: Mouse Button Pressed " << MouseButtonName(event.MouseButton.Button)
 | 
						|
                      << " at (" << event.MouseButton.X << ", " << event.MouseButton.Y << ")"
 | 
						|
                      << std::endl;
 | 
						|
            break;
 | 
						|
        case Event::EVENT_MOUSE_BUTTON_RELEASED:
 | 
						|
            std::cout << "Event: Mouse Button Released "
 | 
						|
                      << MouseButtonName(event.MouseButton.Button) << " at (" << event.MouseButton.X
 | 
						|
                      << ", " << event.MouseButton.Y << ")" << std::endl;
 | 
						|
            break;
 | 
						|
        case Event::EVENT_MOUSE_MOVED:
 | 
						|
            std::cout << "Event: Mouse Moved (" << event.MouseMove.X << ", " << event.MouseMove.Y
 | 
						|
                      << ")" << std::endl;
 | 
						|
            break;
 | 
						|
        case Event::EVENT_MOUSE_ENTERED:
 | 
						|
            std::cout << "Event: Mouse Entered Window" << std::endl;
 | 
						|
            break;
 | 
						|
        case Event::EVENT_MOUSE_LEFT:
 | 
						|
            std::cout << "Event: Mouse Left Window" << std::endl;
 | 
						|
            break;
 | 
						|
        case Event::EVENT_TEST:
 | 
						|
            std::cout << "Event: Test" << std::endl;
 | 
						|
            break;
 | 
						|
        default:
 | 
						|
            UNREACHABLE();
 | 
						|
            break;
 | 
						|
    }
 | 
						|
}
 | 
						|
#endif
 | 
						|
 | 
						|
OSWindow::OSWindow() : mX(0), mY(0), mWidth(0), mHeight(0), mValid(false), mIgnoreSizeEvents(false)
 | 
						|
{}
 | 
						|
 | 
						|
OSWindow::~OSWindow() {}
 | 
						|
 | 
						|
bool OSWindow::initialize(const std::string &name, int width, int height)
 | 
						|
{
 | 
						|
    mValid = initializeImpl(name, width, height);
 | 
						|
    return mValid;
 | 
						|
}
 | 
						|
 | 
						|
int OSWindow::getX() const
 | 
						|
{
 | 
						|
    return mX;
 | 
						|
}
 | 
						|
 | 
						|
int OSWindow::getY() const
 | 
						|
{
 | 
						|
    return mY;
 | 
						|
}
 | 
						|
 | 
						|
int OSWindow::getWidth() const
 | 
						|
{
 | 
						|
    return mWidth;
 | 
						|
}
 | 
						|
 | 
						|
int OSWindow::getHeight() const
 | 
						|
{
 | 
						|
    return mHeight;
 | 
						|
}
 | 
						|
 | 
						|
bool OSWindow::takeScreenshot(uint8_t *pixelData)
 | 
						|
{
 | 
						|
    return false;
 | 
						|
}
 | 
						|
 | 
						|
void *OSWindow::getPlatformExtension()
 | 
						|
{
 | 
						|
    return reinterpret_cast<void *>(getNativeWindow());
 | 
						|
}
 | 
						|
 | 
						|
bool OSWindow::popEvent(Event *event)
 | 
						|
{
 | 
						|
    if (mEvents.size() > 0 && event)
 | 
						|
    {
 | 
						|
        *event = mEvents.front();
 | 
						|
        mEvents.pop_front();
 | 
						|
        return true;
 | 
						|
    }
 | 
						|
    else
 | 
						|
    {
 | 
						|
        return false;
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
void OSWindow::pushEvent(Event event)
 | 
						|
{
 | 
						|
    switch (event.Type)
 | 
						|
    {
 | 
						|
        case Event::EVENT_MOVED:
 | 
						|
            mX = event.Move.X;
 | 
						|
            mY = event.Move.Y;
 | 
						|
            break;
 | 
						|
        case Event::EVENT_RESIZED:
 | 
						|
            mWidth  = event.Size.Width;
 | 
						|
            mHeight = event.Size.Height;
 | 
						|
            break;
 | 
						|
        default:
 | 
						|
            break;
 | 
						|
    }
 | 
						|
 | 
						|
    mEvents.push_back(event);
 | 
						|
 | 
						|
#if DEBUG_EVENTS
 | 
						|
    PrintEvent(event);
 | 
						|
#endif
 | 
						|
}
 | 
						|
 | 
						|
bool OSWindow::didTestEventFire()
 | 
						|
{
 | 
						|
    Event topEvent;
 | 
						|
    while (popEvent(&topEvent))
 | 
						|
    {
 | 
						|
        if (topEvent.Type == Event::EVENT_TEST)
 | 
						|
        {
 | 
						|
            return true;
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    return false;
 | 
						|
}
 | 
						|
 | 
						|
// static
 | 
						|
void OSWindow::Delete(OSWindow **window)
 | 
						|
{
 | 
						|
    delete *window;
 | 
						|
    *window = nullptr;
 | 
						|
}
 | 
						|
 | 
						|
namespace angle
 | 
						|
{
 | 
						|
bool FindTestDataPath(const char *searchPath, char *dataPathOut, size_t maxDataPathOutLen)
 | 
						|
{
 | 
						|
#if defined(ANGLE_PLATFORM_ANDROID)
 | 
						|
    const std::string searchPaths[] = {
 | 
						|
        AndroidWindow::GetExternalStorageDirectory(),
 | 
						|
        AndroidWindow::GetExternalStorageDirectory() + "/third_party/angle"};
 | 
						|
#else
 | 
						|
    const std::string searchPaths[] = {
 | 
						|
        GetExecutableDirectory(), GetExecutableDirectory() + "/../..", ".",
 | 
						|
        GetExecutableDirectory() + "/../../third_party/angle", "third_party/angle"};
 | 
						|
#endif  // defined(ANGLE_PLATFORM_ANDROID)
 | 
						|
 | 
						|
    for (const std::string &path : searchPaths)
 | 
						|
    {
 | 
						|
        std::stringstream pathStream;
 | 
						|
        pathStream << path << "/" << searchPath;
 | 
						|
        std::string candidatePath = pathStream.str();
 | 
						|
 | 
						|
        if (candidatePath.size() + 1 >= maxDataPathOutLen)
 | 
						|
        {
 | 
						|
            ERR() << "FindTestDataPath: Path too long.";
 | 
						|
            return false;
 | 
						|
        }
 | 
						|
 | 
						|
        if (angle::IsDirectory(candidatePath.c_str()))
 | 
						|
        {
 | 
						|
            memcpy(dataPathOut, candidatePath.c_str(), candidatePath.size() + 1);
 | 
						|
            return true;
 | 
						|
        }
 | 
						|
 | 
						|
        std::ifstream inFile(candidatePath.c_str());
 | 
						|
        if (!inFile.fail())
 | 
						|
        {
 | 
						|
            memcpy(dataPathOut, candidatePath.c_str(), candidatePath.size() + 1);
 | 
						|
            return true;
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    return false;
 | 
						|
}
 | 
						|
}  // namespace angle
 |