123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397 |
- /*
- * Copyright 2016 Google Inc.
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
- #include "include/gpu/vk/GrVkVulkan.h"
- #include "tools/sk_app/win/Window_win.h"
- #include <tchar.h>
- #include <windows.h>
- #include <windowsx.h>
- #include "src/core/SkUtils.h"
- #include "tools/ModifierKey.h"
- #include "tools/sk_app/WindowContext.h"
- #include "tools/sk_app/win/WindowContextFactory_win.h"
- #ifdef SK_VULKAN
- #include "tools/sk_app/VulkanWindowContext.h"
- #endif
- namespace sk_app {
- static int gWindowX = CW_USEDEFAULT;
- static int gWindowY = 0;
- static int gWindowWidth = CW_USEDEFAULT;
- static int gWindowHeight = 0;
- Window* Window::CreateNativeWindow(void* platformData) {
- HINSTANCE hInstance = (HINSTANCE)platformData;
- Window_win* window = new Window_win();
- if (!window->init(hInstance)) {
- delete window;
- return nullptr;
- }
- return window;
- }
- void Window_win::closeWindow() {
- RECT r;
- if (GetWindowRect(fHWnd, &r)) {
- gWindowX = r.left;
- gWindowY = r.top;
- gWindowWidth = r.right - r.left;
- gWindowHeight = r.bottom - r.top;
- }
- DestroyWindow(fHWnd);
- }
- Window_win::~Window_win() {
- this->closeWindow();
- }
- LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
- bool Window_win::init(HINSTANCE hInstance) {
- fHInstance = hInstance ? hInstance : GetModuleHandle(nullptr);
- // The main window class name
- static const TCHAR gSZWindowClass[] = _T("SkiaApp");
- static WNDCLASSEX wcex;
- static bool wcexInit = false;
- if (!wcexInit) {
- wcex.cbSize = sizeof(WNDCLASSEX);
- wcex.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
- wcex.lpfnWndProc = WndProc;
- wcex.cbClsExtra = 0;
- wcex.cbWndExtra = 0;
- wcex.hInstance = fHInstance;
- wcex.hIcon = LoadIcon(fHInstance, (LPCTSTR)IDI_WINLOGO);
- wcex.hCursor = LoadCursor(nullptr, IDC_ARROW);
- wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
- wcex.lpszMenuName = nullptr;
- wcex.lpszClassName = gSZWindowClass;
- wcex.hIconSm = LoadIcon(fHInstance, (LPCTSTR)IDI_WINLOGO);
- if (!RegisterClassEx(&wcex)) {
- return false;
- }
- wcexInit = true;
- }
- /*
- if (fullscreen)
- {
- DEVMODE dmScreenSettings;
- // If full screen set the screen to maximum size of the users desktop and 32bit.
- memset(&dmScreenSettings, 0, sizeof(dmScreenSettings));
- dmScreenSettings.dmSize = sizeof(dmScreenSettings);
- dmScreenSettings.dmPelsWidth = (unsigned long)width;
- dmScreenSettings.dmPelsHeight = (unsigned long)height;
- dmScreenSettings.dmBitsPerPel = 32;
- dmScreenSettings.dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT;
- // Change the display settings to full screen.
- ChangeDisplaySettings(&dmScreenSettings, CDS_FULLSCREEN);
- // Set the position of the window to the top left corner.
- posX = posY = 0;
- }
- */
- // gIsFullscreen = fullscreen;
- fHWnd = CreateWindow(gSZWindowClass, nullptr, WS_OVERLAPPEDWINDOW,
- gWindowX, gWindowY, gWindowWidth, gWindowHeight,
- nullptr, nullptr, fHInstance, nullptr);
- if (!fHWnd)
- {
- return false;
- }
- SetWindowLongPtr(fHWnd, GWLP_USERDATA, (LONG_PTR)this);
- RegisterTouchWindow(fHWnd, 0);
- return true;
- }
- static Window::Key get_key(WPARAM vk) {
- static const struct {
- WPARAM fVK;
- Window::Key fKey;
- } gPair[] = {
- { VK_BACK, Window::Key::kBack },
- { VK_CLEAR, Window::Key::kBack },
- { VK_RETURN, Window::Key::kOK },
- { VK_UP, Window::Key::kUp },
- { VK_DOWN, Window::Key::kDown },
- { VK_LEFT, Window::Key::kLeft },
- { VK_RIGHT, Window::Key::kRight },
- { VK_TAB, Window::Key::kTab },
- { VK_PRIOR, Window::Key::kPageUp },
- { VK_NEXT, Window::Key::kPageDown },
- { VK_HOME, Window::Key::kHome },
- { VK_END, Window::Key::kEnd },
- { VK_DELETE, Window::Key::kDelete },
- { VK_ESCAPE, Window::Key::kEscape },
- { VK_SHIFT, Window::Key::kShift },
- { VK_CONTROL, Window::Key::kCtrl },
- { VK_MENU, Window::Key::kOption },
- { 'A', Window::Key::kA },
- { 'C', Window::Key::kC },
- { 'V', Window::Key::kV },
- { 'X', Window::Key::kX },
- { 'Y', Window::Key::kY },
- { 'Z', Window::Key::kZ },
- };
- for (size_t i = 0; i < SK_ARRAY_COUNT(gPair); i++) {
- if (gPair[i].fVK == vk) {
- return gPair[i].fKey;
- }
- }
- return Window::Key::kNONE;
- }
- static ModifierKey get_modifiers(UINT message, WPARAM wParam, LPARAM lParam) {
- ModifierKey modifiers = ModifierKey::kNone;
- switch (message) {
- case WM_UNICHAR:
- case WM_CHAR:
- if (0 == (lParam & (1 << 30))) {
- modifiers |= ModifierKey::kFirstPress;
- }
- if (lParam & (1 << 29)) {
- modifiers |= ModifierKey::kOption;
- }
- break;
- case WM_KEYDOWN:
- case WM_SYSKEYDOWN:
- if (0 == (lParam & (1 << 30))) {
- modifiers |= ModifierKey::kFirstPress;
- }
- if (lParam & (1 << 29)) {
- modifiers |= ModifierKey::kOption;
- }
- break;
- case WM_KEYUP:
- case WM_SYSKEYUP:
- if (lParam & (1 << 29)) {
- modifiers |= ModifierKey::kOption;
- }
- break;
- case WM_LBUTTONDOWN:
- case WM_LBUTTONUP:
- case WM_MOUSEMOVE:
- case WM_MOUSEWHEEL:
- if (wParam & MK_CONTROL) {
- modifiers |= ModifierKey::kControl;
- }
- if (wParam & MK_SHIFT) {
- modifiers |= ModifierKey::kShift;
- }
- break;
- }
- return modifiers;
- }
- LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
- {
- PAINTSTRUCT ps;
- HDC hdc;
- Window_win* window = (Window_win*) GetWindowLongPtr(hWnd, GWLP_USERDATA);
- bool eventHandled = false;
- switch (message) {
- case WM_PAINT:
- hdc = BeginPaint(hWnd, &ps);
- window->onPaint();
- EndPaint(hWnd, &ps);
- eventHandled = true;
- break;
- case WM_CLOSE:
- PostQuitMessage(0);
- eventHandled = true;
- break;
- case WM_ACTIVATE:
- // disable/enable rendering here, depending on wParam != WA_INACTIVE
- break;
- case WM_SIZE:
- window->onResize(LOWORD(lParam), HIWORD(lParam));
- eventHandled = true;
- break;
- case WM_UNICHAR:
- eventHandled = window->onChar((SkUnichar)wParam,
- get_modifiers(message, wParam, lParam));
- break;
- case WM_CHAR: {
- const uint16_t* c = reinterpret_cast<uint16_t*>(&wParam);
- eventHandled = window->onChar(SkUTF16_NextUnichar(&c),
- get_modifiers(message, wParam, lParam));
- } break;
- case WM_KEYDOWN:
- case WM_SYSKEYDOWN:
- eventHandled = window->onKey(get_key(wParam), InputState::kDown,
- get_modifiers(message, wParam, lParam));
- break;
- case WM_KEYUP:
- case WM_SYSKEYUP:
- eventHandled = window->onKey(get_key(wParam), InputState::kUp,
- get_modifiers(message, wParam, lParam));
- break;
- case WM_LBUTTONDOWN:
- case WM_LBUTTONUP: {
- int xPos = GET_X_LPARAM(lParam);
- int yPos = GET_Y_LPARAM(lParam);
- //if (!gIsFullscreen)
- //{
- // RECT rc = { 0, 0, 640, 480 };
- // AdjustWindowRect(&rc, WS_OVERLAPPEDWINDOW, FALSE);
- // xPos -= rc.left;
- // yPos -= rc.top;
- //}
- InputState istate = ((wParam & MK_LBUTTON) != 0) ? InputState::kDown
- : InputState::kUp;
- eventHandled = window->onMouse(xPos, yPos, istate,
- get_modifiers(message, wParam, lParam));
- } break;
- case WM_MOUSEMOVE: {
- int xPos = GET_X_LPARAM(lParam);
- int yPos = GET_Y_LPARAM(lParam);
- //if (!gIsFullscreen)
- //{
- // RECT rc = { 0, 0, 640, 480 };
- // AdjustWindowRect(&rc, WS_OVERLAPPEDWINDOW, FALSE);
- // xPos -= rc.left;
- // yPos -= rc.top;
- //}
- eventHandled = window->onMouse(xPos, yPos, InputState::kMove,
- get_modifiers(message, wParam, lParam));
- } break;
- case WM_MOUSEWHEEL:
- eventHandled = window->onMouseWheel(GET_WHEEL_DELTA_WPARAM(wParam) > 0 ? +1.0f : -1.0f,
- get_modifiers(message, wParam, lParam));
- break;
- case WM_TOUCH: {
- uint16_t numInputs = LOWORD(wParam);
- std::unique_ptr<TOUCHINPUT[]> inputs(new TOUCHINPUT[numInputs]);
- if (GetTouchInputInfo((HTOUCHINPUT)lParam, numInputs, inputs.get(),
- sizeof(TOUCHINPUT))) {
- POINT topLeft = {0, 0};
- ClientToScreen(hWnd, &topLeft);
- for (uint16_t i = 0; i < numInputs; ++i) {
- TOUCHINPUT ti = inputs[i];
- InputState state;
- if (ti.dwFlags & TOUCHEVENTF_DOWN) {
- state = InputState::kDown;
- } else if (ti.dwFlags & TOUCHEVENTF_MOVE) {
- state = InputState::kMove;
- } else if (ti.dwFlags & TOUCHEVENTF_UP) {
- state = InputState::kUp;
- } else {
- continue;
- }
- // TOUCHINPUT coordinates are in 100ths of pixels
- // Adjust for that, and make them window relative
- LONG tx = (ti.x / 100) - topLeft.x;
- LONG ty = (ti.y / 100) - topLeft.y;
- eventHandled = window->onTouch(ti.dwID, state, tx, ty) || eventHandled;
- }
- }
- } break;
- default:
- return DefWindowProc(hWnd, message, wParam, lParam);
- }
- return eventHandled ? 0 : 1;
- }
- void Window_win::setTitle(const char* title) {
- SetWindowTextA(fHWnd, title);
- }
- void Window_win::show() {
- ShowWindow(fHWnd, SW_SHOW);
- }
- bool Window_win::attach(BackendType attachType) {
- fBackend = attachType;
- switch (attachType) {
- case kNativeGL_BackendType:
- fWindowContext = window_context_factory::NewGLForWin(fHWnd, fRequestedDisplayParams);
- break;
- #if SK_ANGLE
- case kANGLE_BackendType:
- fWindowContext = window_context_factory::NewANGLEForWin(fHWnd, fRequestedDisplayParams);
- break;
- #endif
- case kRaster_BackendType:
- fWindowContext = window_context_factory::NewRasterForWin(fHWnd,
- fRequestedDisplayParams);
- break;
- #ifdef SK_VULKAN
- case kVulkan_BackendType:
- fWindowContext = window_context_factory::NewVulkanForWin(fHWnd,
- fRequestedDisplayParams);
- break;
- #endif
- }
- this->onBackendCreated();
- return (SkToBool(fWindowContext));
- }
- void Window_win::onInval() {
- InvalidateRect(fHWnd, nullptr, false);
- }
- void Window_win::setRequestedDisplayParams(const DisplayParams& params, bool allowReattach) {
- // GL on Windows doesn't let us change MSAA after the window is created
- if (params.fMSAASampleCount != this->getRequestedDisplayParams().fMSAASampleCount
- && allowReattach) {
- // Need to change these early, so attach() creates the window context correctly
- fRequestedDisplayParams = params;
- delete fWindowContext;
- this->closeWindow();
- this->init(fHInstance);
- this->attach(fBackend);
- }
- INHERITED::setRequestedDisplayParams(params, allowReattach);
- }
- } // namespace sk_app
|