| Index: tools/viewer/sk_app/mac/Window_mac.cpp
|
| diff --git a/tools/viewer/sk_app/mac/Window_mac.cpp b/tools/viewer/sk_app/mac/Window_mac.cpp
|
| index b1ab5c9fe78f186e57c6c803657a782fc2faa402..4aad93c5e382bd2d4b75405ed6dc01e5035728b0 100644
|
| --- a/tools/viewer/sk_app/mac/Window_mac.cpp
|
| +++ b/tools/viewer/sk_app/mac/Window_mac.cpp
|
| @@ -5,8 +5,6 @@
|
| * found in the LICENSE file.
|
| */
|
|
|
| -//#include <tchar.h>
|
| -
|
| #include "SkUtils.h"
|
| #include "Timer.h"
|
| #include "WindowContextFactory_mac.h"
|
| @@ -14,243 +12,200 @@
|
|
|
| namespace sk_app {
|
|
|
| -Window* Window::CreateNativeWindow(void* platformData) {
|
| -#if 0
|
| - // TODO: platform-specific window creation
|
| - Display* display = (Display*)platformData;
|
| +SkTDynamicHash<Window_mac, Uint32> Window_mac::gWindowMap;
|
|
|
| +Window* Window::CreateNativeWindow(void*) {
|
| Window_mac* window = new Window_mac();
|
| - if (!window->initWindow(display, nullptr)) {
|
| + if (!window->initWindow(nullptr)) {
|
| delete window;
|
| return nullptr;
|
| }
|
|
|
| return window;
|
| -#else
|
| - return nullptr;
|
| -#endif
|
| }
|
| -
|
| -#if 0
|
| - // TODO: Implement Mac window code
|
| -
|
| -const long kEventMask = ExposureMask | StructureNotifyMask |
|
| - KeyPressMask | KeyReleaseMask |
|
| - PointerMotionMask | ButtonPressMask | ButtonReleaseMask;
|
|
|
| -bool Window_mac::initWindow(Display* display, const DisplayParams* params) {
|
| +bool Window_mac::initWindow(const DisplayParams* params) {
|
| if (params && params->fMSAASampleCount != fMSAASampleCount) {
|
| this->closeWindow();
|
| }
|
| // we already have a window
|
| - if (fDisplay) {
|
| + if (fWindow) {
|
| return true;
|
| }
|
| - fDisplay = display;
|
|
|
| fWidth = 1280;
|
| fHeight = 960;
|
|
|
| - // Attempt to create a window that supports GL
|
| - GLint att[] = {
|
| - GLX_RGBA,
|
| - GLX_DEPTH_SIZE, 24,
|
| - GLX_DOUBLEBUFFER,
|
| - GLX_STENCIL_SIZE, 8,
|
| - None
|
| - };
|
| - SkASSERT(nullptr == fVisualInfo);
|
| - if (params && params->fMSAASampleCount > 0) {
|
| - static const GLint kAttCount = SK_ARRAY_COUNT(att);
|
| - GLint msaaAtt[kAttCount + 4];
|
| - memcpy(msaaAtt, att, sizeof(att));
|
| - SkASSERT(None == msaaAtt[kAttCount - 1]);
|
| - msaaAtt[kAttCount - 1] = GLX_SAMPLE_BUFFERS_ARB;
|
| - msaaAtt[kAttCount + 0] = 1;
|
| - msaaAtt[kAttCount + 1] = GLX_SAMPLES_ARB;
|
| - msaaAtt[kAttCount + 2] = params->fMSAASampleCount;
|
| - msaaAtt[kAttCount + 3] = None;
|
| - fVisualInfo = glXChooseVisual(display, DefaultScreen(display), msaaAtt);
|
| - fMSAASampleCount = params->fMSAASampleCount;
|
| - }
|
| - if (nullptr == fVisualInfo) {
|
| - fVisualInfo = glXChooseVisual(display, DefaultScreen(display), att);
|
| - fMSAASampleCount = 0;
|
| - }
|
| + SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
|
| + SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 0);
|
| + SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);
|
| +
|
| + SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8);
|
| + SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8);
|
| + SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8);
|
| + SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
|
| + SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 0);
|
| + SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 8);
|
| +
|
| + SDL_GL_SetAttribute(SDL_GL_ACCELERATED_VISUAL, 1);
|
|
|
| - if (fVisualInfo) {
|
| - Colormap colorMap = XCreateColormap(display,
|
| - RootWindow(display, fVisualInfo->screen),
|
| - fVisualInfo->visual,
|
| - AllocNone);
|
| - XSetWindowAttributes swa;
|
| - swa.colormap = colorMap;
|
| - swa.event_mask = kEventMask;
|
| - fWindow = XCreateWindow(display,
|
| - RootWindow(display, fVisualInfo->screen),
|
| - 0, 0, // x, y
|
| - fWidth, fHeight,
|
| - 0, // border width
|
| - fVisualInfo->depth,
|
| - InputOutput,
|
| - fVisualInfo->visual,
|
| - CWEventMask | CWColormap,
|
| - &swa);
|
| + if (params && params->fMSAASampleCount > 0) {
|
| + SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 1);
|
| + SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, params->fMSAASampleCount);
|
| } else {
|
| - // Create a simple window instead. We will not be able to show GL
|
| - fWindow = XCreateSimpleWindow(display,
|
| - DefaultRootWindow(display),
|
| - 0, 0, // x, y
|
| - fWidth, fHeight,
|
| - 0, // border width
|
| - 0, // border value
|
| - 0); // background value
|
| - XSelectInput(display, fWindow, kEventMask);
|
| + SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 0);
|
| }
|
| + // TODO: handle other display params
|
| +
|
| + uint32_t windowFlags = SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE;
|
| + fWindow = SDL_CreateWindow("SDL Window", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED,
|
| + fWidth, fHeight, windowFlags);
|
|
|
| if (!fWindow) {
|
| return false;
|
| }
|
|
|
| - // set up to catch window delete message
|
| - fWmDeleteMessage = XInternAtom(display, "WM_DELETE_WINDOW", False);
|
| - XSetWMProtocols(display, fWindow, &fWmDeleteMessage, 1);
|
| -
|
| // add to hashtable of windows
|
| + fWindowID = SDL_GetWindowID(fWindow);
|
| gWindowMap.add(this);
|
|
|
| - // init event variables
|
| - fPendingPaint = false;
|
| - fPendingResize = false;
|
| -
|
| return true;
|
| }
|
|
|
| void Window_mac::closeWindow() {
|
| - if (fDisplay) {
|
| - this->detach();
|
| - SkASSERT(fGC);
|
| - XFreeGC(fDisplay, fGC);
|
| - fGC = nullptr;
|
| - gWindowMap.remove(fWindow);
|
| - XDestroyWindow(fDisplay, fWindow);
|
| - fWindow = 0;
|
| - fVisualInfo = nullptr;
|
| - fDisplay = nullptr;
|
| - fMSAASampleCount = 0;
|
| + if (fWindow) {
|
| + gWindowMap.remove(fWindowID);
|
| + SDL_DestroyWindow(fWindow);
|
| + fWindowID = 0;
|
| + fWindow = nullptr;
|
| }
|
| }
|
|
|
| -static Window::Key get_key(KeySym keysym) {
|
| +static Window::Key get_key(const SDL_Keysym& keysym) {
|
| static const struct {
|
| - KeySym fXK;
|
| + SDL_Keycode fSDLK;
|
| Window::Key fKey;
|
| } gPair[] = {
|
| - { XK_BackSpace, Window::Key::kBack },
|
| - { XK_Clear, Window::Key::kBack },
|
| - { XK_Return, Window::Key::kOK },
|
| - { XK_Up, Window::Key::kUp },
|
| - { XK_Down, Window::Key::kDown },
|
| - { XK_Left, Window::Key::kLeft },
|
| - { XK_Right, Window::Key::kRight }
|
| + { SDLK_BACKSPACE, Window::Key::kBack },
|
| + { SDLK_CLEAR, Window::Key::kBack },
|
| + { SDLK_RETURN, Window::Key::kOK },
|
| + { SDLK_UP, Window::Key::kUp },
|
| + { SDLK_DOWN, Window::Key::kDown },
|
| + { SDLK_LEFT, Window::Key::kLeft },
|
| + { SDLK_RIGHT, Window::Key::kRight }
|
| };
|
| for (size_t i = 0; i < SK_ARRAY_COUNT(gPair); i++) {
|
| - if (gPair[i].fXK == keysym) {
|
| + if (gPair[i].fSDLK == keysym.sym) {
|
| return gPair[i].fKey;
|
| }
|
| }
|
| return Window::Key::kNONE;
|
| }
|
|
|
| -static uint32_t get_modifiers(const XEvent& event) {
|
| +static uint32_t get_modifiers(const SDL_Event& event) {
|
| static const struct {
|
| - unsigned fXMask;
|
| + unsigned fSDLMask;
|
| unsigned fSkMask;
|
| } gModifiers[] = {
|
| - { ShiftMask, Window::kShift_ModifierKey },
|
| - { ControlMask, Window::kControl_ModifierKey },
|
| - { Mod1Mask, Window::kOption_ModifierKey },
|
| + { KMOD_SHIFT, Window::kShift_ModifierKey },
|
| + { KMOD_CTRL, Window::kControl_ModifierKey },
|
| + { KMOD_ALT, Window::kOption_ModifierKey },
|
| };
|
|
|
| auto modifiers = 0;
|
| - for (size_t i = 0; i < SK_ARRAY_COUNT(gModifiers); ++i) {
|
| - if (event.xkey.state & gModifiers[i].fXMask) {
|
| - modifiers |= gModifiers[i].fSkMask;
|
| +
|
| + switch (event.type) {
|
| + case SDL_KEYDOWN:
|
| + // fall through
|
| + case SDL_KEYUP: {
|
| + for (size_t i = 0; i < SK_ARRAY_COUNT(gModifiers); ++i) {
|
| + if (event.key.keysym.mod & gModifiers[i].fSDLMask) {
|
| + modifiers |= gModifiers[i].fSkMask;
|
| + }
|
| + }
|
| + if (0 == event.key.repeat) {
|
| + modifiers |= Window::kFirstPress_ModifierKey;
|
| + }
|
| + break;
|
| + }
|
| +
|
| + default: {
|
| + SDL_Keymod mod = SDL_GetModState();
|
| + for (size_t i = 0; i < SK_ARRAY_COUNT(gModifiers); ++i) {
|
| + if (mod & gModifiers[i].fSDLMask) {
|
| + modifiers |= gModifiers[i].fSkMask;
|
| + }
|
| + }
|
| + break;
|
| }
|
| }
|
| return modifiers;
|
| }
|
|
|
| -bool Window_mac::handleEvent(const XEvent& event) {
|
| - switch (event.type) {
|
| - case MapNotify:
|
| - if (!fGC) {
|
| - fGC = XCreateGC(fDisplay, fWindow, 0, nullptr);
|
| - }
|
| - break;
|
| +bool Window_mac::HandleWindowEvent(const SDL_Event& event) {
|
| + Window_mac* win = gWindowMap.find(event.window.windowID);
|
| + if (win && win->handleEvent(event)) {
|
| + return true;
|
| + }
|
|
|
| - case ClientMessage:
|
| - if ((Atom)event.xclient.data.l[0] == fWmDeleteMessage &&
|
| - gWindowMap.count() == 1) {
|
| - return true;
|
| + return false;
|
| +}
|
| +
|
| +bool Window_mac::handleEvent(const SDL_Event& event) {
|
| + switch (event.type) {
|
| + case SDL_WINDOWEVENT:
|
| + if (SDL_WINDOWEVENT_EXPOSED == event.window.event) {
|
| + this->onPaint();
|
| + } else if (SDL_WINDOWEVENT_RESIZED == event.window.event) {
|
| + this->onResize(event.window.data1, event.window.data2);
|
| }
|
| break;
|
|
|
| - case ButtonPress:
|
| - if (event.xbutton.button == Button1) {
|
| - this->onMouse(event.xbutton.x, event.xbutton.y,
|
| + case SDL_MOUSEBUTTONDOWN:
|
| + if (event.button.button == SDL_BUTTON_LEFT) {
|
| + this->onMouse(event.button.x, event.button.y,
|
| Window::kDown_InputState, get_modifiers(event));
|
| }
|
| break;
|
|
|
| - case ButtonRelease:
|
| - if (event.xbutton.button == Button1) {
|
| - this->onMouse(event.xbutton.x, event.xbutton.y,
|
| + case SDL_MOUSEBUTTONUP:
|
| + if (event.button.button == SDL_BUTTON_LEFT) {
|
| + this->onMouse(event.button.x, event.button.y,
|
| Window::kUp_InputState, get_modifiers(event));
|
| }
|
| break;
|
|
|
| - case MotionNotify:
|
| + case SDL_MOUSEMOTION:
|
| // only track if left button is down
|
| - if (event.xmotion.state & Button1Mask) {
|
| - this->onMouse(event.xmotion.x, event.xmotion.y,
|
| + if (event.motion.state & SDL_BUTTON_LMASK) {
|
| + this->onMouse(event.motion.x, event.motion.y,
|
| Window::kMove_InputState, get_modifiers(event));
|
| }
|
| break;
|
|
|
| - case KeyPress: {
|
| - int shiftLevel = (event.xkey.state & ShiftMask) ? 1 : 0;
|
| - KeySym keysym = XkbKeycodeToKeysym(fDisplay, event.xkey.keycode,
|
| - 0, shiftLevel);
|
| - if (keysym == XK_Escape) {
|
| + case SDL_KEYDOWN: {
|
| + if (event.key.keysym.sym == SDLK_ESCAPE) {
|
| return true;
|
| }
|
| - Window::Key key = get_key(keysym);
|
| + Window::Key key = get_key(event.key.keysym);
|
| if (key != Window::Key::kNONE) {
|
| - (void) this->onKey(key, Window::kDown_InputState,
|
| + (void) this->onKey(key, Window::kDown_InputState,
|
| get_modifiers(event));
|
| } else {
|
| - long uni = keysym2ucs(keysym);
|
| - if (uni != -1) {
|
| - (void) this->onChar((SkUnichar) uni,
|
| - get_modifiers(event));
|
| - }
|
| + (void) this->onChar((SkUnichar) event.key.keysym.sym,
|
| + get_modifiers(event));
|
| }
|
| } break;
|
|
|
| - case KeyRelease: {
|
| - int shiftLevel = (event.xkey.state & ShiftMask) ? 1 : 0;
|
| - KeySym keysym = XkbKeycodeToKeysym(fDisplay, event.xkey.keycode,
|
| - 0, shiftLevel);
|
| - Window::Key key = get_key(keysym);
|
| - (void) this->onKey(key, Window::kUp_InputState,
|
| - get_modifiers(event));
|
| + case SDL_KEYUP: {
|
| + Window::Key key = get_key(event.key.keysym);
|
| + if (key != Window::Key::kNONE) {
|
| + (void) this->onKey(key, Window::kUp_InputState,
|
| + get_modifiers(event));
|
| + }
|
| } break;
|
| -
|
|
|
| default:
|
| - // these events should be handled in the main event loop
|
| - SkASSERT(event.type != Expose && event.type != ConfigureNotify);
|
| break;
|
| }
|
|
|
| @@ -258,29 +213,19 @@ bool Window_mac::handleEvent(const XEvent& event) {
|
| }
|
|
|
| void Window_mac::setTitle(const char* title) {
|
| - XTextProperty textproperty;
|
| - XStringListToTextProperty(const_cast<char**>(&title), 1, &textproperty);
|
| - XSetWMName(fDisplay, fWindow, &textproperty);
|
| + SDL_SetWindowTitle(fWindow, title);
|
| }
|
|
|
| void Window_mac::show() {
|
| - XMapWindow(fDisplay, fWindow);
|
| + SDL_ShowWindow(fWindow);
|
| }
|
|
|
| bool Window_mac::attach(BackendType attachType, const DisplayParams& params) {
|
| - this->initWindow(fDisplay, ¶ms);
|
| + this->initWindow(¶ms);
|
|
|
| - MacWindowInfo info;
|
| -#if 0
|
| - // Init Mac window info here
|
| - info.foo = foo;
|
| -#endif
|
| + window_context_factory::MacWindowInfo info;
|
| + info.fWindow = fWindow;
|
| switch (attachType) {
|
| -#ifdef SK_VULKAN
|
| - case kVulkan_BackendType:
|
| - fWindowContext = NewVulkanForMac(info, params);
|
| - break;
|
| -#endif
|
| case kNativeGL_BackendType:
|
| default:
|
| fWindowContext = NewGLForMac(info, params);
|
| @@ -291,19 +236,11 @@ bool Window_mac::attach(BackendType attachType, const DisplayParams& params) {
|
| }
|
|
|
| void Window_mac::onInval() {
|
| - XEvent event;
|
| - event.type = Expose;
|
| - event.xexpose.send_event = True;
|
| - event.xexpose.display = fDisplay;
|
| - event.xexpose.window = fWindow;
|
| - event.xexpose.x = 0;
|
| - event.xexpose.y = 0;
|
| - event.xexpose.width = fWidth;
|
| - event.xexpose.height = fHeight;
|
| - event.xexpose.count = 0;
|
| -
|
| - XSendEvent(fDisplay, fWindow, False, 0, &event);
|
| + SDL_Event sdlevent;
|
| + sdlevent.type = SDL_WINDOWEVENT;
|
| + sdlevent.window.windowID = fWindowID;
|
| + sdlevent.window.event = SDL_WINDOWEVENT_EXPOSED;
|
| + SDL_PushEvent(&sdlevent);
|
| }
|
| -#endif
|
| -
|
| +
|
| } // namespace sk_app
|
|
|