| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright 2016 Google Inc. | 2 * Copyright 2016 Google Inc. |
| 3 * | 3 * |
| 4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
| 5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
| 6 */ | 6 */ |
| 7 | 7 |
| 8 //#include <tchar.h> | 8 //#include <tchar.h> |
| 9 | 9 |
| 10 #include "SkUtils.h" | 10 #include "SkUtils.h" |
| 11 #include "Timer.h" | 11 #include "Timer.h" |
| 12 #include "../GLWindowContext.h" |
| 12 #include "../VulkanWindowContext.h" | 13 #include "../VulkanWindowContext.h" |
| 13 #include "Window_unix.h" | 14 #include "Window_unix.h" |
| 14 | 15 |
| 15 extern "C" { | 16 extern "C" { |
| 16 #include "keysym2ucs.h" | 17 #include "keysym2ucs.h" |
| 17 } | 18 } |
| 18 #include <X11/Xutil.h> | 19 #include <X11/Xutil.h> |
| 19 #include <X11/XKBlib.h> | 20 #include <X11/XKBlib.h> |
| 20 | 21 |
| 21 namespace sk_app { | 22 namespace sk_app { |
| 22 | 23 |
| 23 SkTDynamicHash<Window_unix, XWindow> Window_unix::gWindowMap; | 24 SkTDynamicHash<Window_unix, XWindow> Window_unix::gWindowMap; |
| 24 | 25 |
| 25 Window* Window::CreateNativeWindow(void* platformData) { | 26 Window* Window::CreateNativeWindow(void* platformData) { |
| 26 Display* display = (Display*)platformData; | 27 Display* display = (Display*)platformData; |
| 27 | 28 |
| 28 Window_unix* window = new Window_unix(); | 29 Window_unix* window = new Window_unix(); |
| 29 if (!window->init(display)) { | 30 if (!window->initWindow(display, nullptr)) { |
| 30 delete window; | 31 delete window; |
| 31 return nullptr; | 32 return nullptr; |
| 32 } | 33 } |
| 33 | 34 |
| 34 return window; | 35 return window; |
| 35 } | 36 } |
| 36 | 37 |
| 37 bool Window_unix::init(Display* display) { | 38 const long kEventMask = ExposureMask | StructureNotifyMask | |
| 39 KeyPressMask | KeyReleaseMask | |
| 40 PointerMotionMask | ButtonPressMask | ButtonReleaseMask; |
| 41 |
| 42 bool Window_unix::initWindow(Display* display, const DisplayParams* params) { |
| 43 if (params && params->fMSAASampleCount != fMSAASampleCount) { |
| 44 this->closeWindow(); |
| 45 } |
| 46 // we already have a window |
| 47 if (fDisplay) { |
| 48 return true; |
| 49 } |
| 38 fDisplay = display; | 50 fDisplay = display; |
| 39 | 51 |
| 40 fWidth = 1280; | 52 fWidth = 1280; |
| 41 fHeight = 960; | 53 fHeight = 960; |
| 42 fHWnd = XCreateSimpleWindow(display, DefaultRootWindow(display), 0, 0, fWidt
h, fHeight, | |
| 43 0, BlackPixel(display, DefaultScreen(display)), | |
| 44 BlackPixel(display, DefaultScreen(display))); | |
| 45 | 54 |
| 46 if (!fHWnd) { | 55 // Attempt to create a window that supports GL |
| 56 GLint att[] = { |
| 57 GLX_RGBA, |
| 58 GLX_DEPTH_SIZE, 24, |
| 59 GLX_DOUBLEBUFFER, |
| 60 GLX_STENCIL_SIZE, 8, |
| 61 None |
| 62 }; |
| 63 SkASSERT(nullptr == fVisualInfo); |
| 64 if (params && params->fMSAASampleCount > 0) { |
| 65 static const GLint kAttCount = SK_ARRAY_COUNT(att); |
| 66 GLint msaaAtt[kAttCount + 4]; |
| 67 memcpy(msaaAtt, att, sizeof(att)); |
| 68 SkASSERT(None == msaaAtt[kAttCount - 1]); |
| 69 msaaAtt[kAttCount - 1] = GLX_SAMPLE_BUFFERS_ARB; |
| 70 msaaAtt[kAttCount + 0] = 1; |
| 71 msaaAtt[kAttCount + 1] = GLX_SAMPLES_ARB; |
| 72 msaaAtt[kAttCount + 2] = params->fMSAASampleCount; |
| 73 msaaAtt[kAttCount + 3] = None; |
| 74 fVisualInfo = glXChooseVisual(display, DefaultScreen(display), msaaAtt); |
| 75 fMSAASampleCount = params->fMSAASampleCount; |
| 76 } |
| 77 if (nullptr == fVisualInfo) { |
| 78 fVisualInfo = glXChooseVisual(display, DefaultScreen(display), att); |
| 79 fMSAASampleCount = 0; |
| 80 } |
| 81 |
| 82 if (fVisualInfo) { |
| 83 Colormap colorMap = XCreateColormap(display, |
| 84 RootWindow(display, fVisualInfo->scr
een), |
| 85 fVisualInfo->visual, |
| 86 AllocNone); |
| 87 XSetWindowAttributes swa; |
| 88 swa.colormap = colorMap; |
| 89 swa.event_mask = kEventMask; |
| 90 fWindow = XCreateWindow(display, |
| 91 RootWindow(display, fVisualInfo->screen), |
| 92 0, 0, // x, y |
| 93 fWidth, fHeight, |
| 94 0, // border width |
| 95 fVisualInfo->depth, |
| 96 InputOutput, |
| 97 fVisualInfo->visual, |
| 98 CWEventMask | CWColormap, |
| 99 &swa); |
| 100 } else { |
| 101 // Create a simple window instead. We will not be able to show GL |
| 102 fWindow = XCreateSimpleWindow(display, |
| 103 DefaultRootWindow(display), |
| 104 0, 0, // x, y |
| 105 fWidth, fHeight, |
| 106 0, // border width |
| 107 0, // border value |
| 108 0); // background value |
| 109 XSelectInput(display, fWindow, kEventMask); |
| 110 } |
| 111 |
| 112 if (!fWindow) { |
| 47 return false; | 113 return false; |
| 48 } | 114 } |
| 49 | 115 |
| 50 // choose the events we care about | |
| 51 XSelectInput(display, fHWnd, | |
| 52 ExposureMask | StructureNotifyMask | KeyPressMask | KeyReleaseM
ask | | |
| 53 PointerMotionMask | ButtonPressMask | ButtonReleaseMask); | |
| 54 | |
| 55 // set up to catch window delete message | 116 // set up to catch window delete message |
| 56 fWmDeleteMessage = XInternAtom(display, "WM_DELETE_WINDOW", False); | 117 fWmDeleteMessage = XInternAtom(display, "WM_DELETE_WINDOW", False); |
| 57 XSetWMProtocols(display, fHWnd, &fWmDeleteMessage, 1); | 118 XSetWMProtocols(display, fWindow, &fWmDeleteMessage, 1); |
| 58 | 119 |
| 59 // add to hashtable of windows | 120 // add to hashtable of windows |
| 60 gWindowMap.add(this); | 121 gWindowMap.add(this); |
| 61 | 122 |
| 62 // init event variables | 123 // init event variables |
| 63 fPendingPaint = false; | 124 fPendingPaint = false; |
| 64 fPendingResize = false; | 125 fPendingResize = false; |
| 65 | 126 |
| 66 return true; | 127 return true; |
| 67 } | 128 } |
| 68 | 129 |
| 130 void Window_unix::closeWindow() { |
| 131 if (fDisplay) { |
| 132 this->detach(); |
| 133 SkASSERT(fGC); |
| 134 XFreeGC(fDisplay, fGC); |
| 135 fGC = nullptr; |
| 136 gWindowMap.remove(fWindow); |
| 137 XDestroyWindow(fDisplay, fWindow); |
| 138 fWindow = 0; |
| 139 fVisualInfo = nullptr; |
| 140 fDisplay = nullptr; |
| 141 fMSAASampleCount = 0; |
| 142 } |
| 143 } |
| 144 |
| 69 static Window::Key get_key(KeySym keysym) { | 145 static Window::Key get_key(KeySym keysym) { |
| 70 static const struct { | 146 static const struct { |
| 71 KeySym fXK; | 147 KeySym fXK; |
| 72 Window::Key fKey; | 148 Window::Key fKey; |
| 73 } gPair[] = { | 149 } gPair[] = { |
| 74 { XK_BackSpace, Window::Key::kBack }, | 150 { XK_BackSpace, Window::Key::kBack }, |
| 75 { XK_Clear, Window::Key::kBack }, | 151 { XK_Clear, Window::Key::kBack }, |
| 76 { XK_Return, Window::Key::kOK }, | 152 { XK_Return, Window::Key::kOK }, |
| 77 { XK_Up, Window::Key::kUp }, | 153 { XK_Up, Window::Key::kUp }, |
| 78 { XK_Down, Window::Key::kDown }, | 154 { XK_Down, Window::Key::kDown }, |
| (...skipping 22 matching lines...) Expand all Loading... |
| 101 for (size_t i = 0; i < SK_ARRAY_COUNT(gModifiers); ++i) { | 177 for (size_t i = 0; i < SK_ARRAY_COUNT(gModifiers); ++i) { |
| 102 if (event.xkey.state & gModifiers[i].fXMask) { | 178 if (event.xkey.state & gModifiers[i].fXMask) { |
| 103 modifiers |= gModifiers[i].fSkMask; | 179 modifiers |= gModifiers[i].fSkMask; |
| 104 } | 180 } |
| 105 } | 181 } |
| 106 return modifiers; | 182 return modifiers; |
| 107 } | 183 } |
| 108 | 184 |
| 109 bool Window_unix::handleEvent(const XEvent& event) { | 185 bool Window_unix::handleEvent(const XEvent& event) { |
| 110 switch (event.type) { | 186 switch (event.type) { |
| 187 case MapNotify: |
| 188 if (!fGC) { |
| 189 fGC = XCreateGC(fDisplay, fWindow, 0, nullptr); |
| 190 } |
| 191 break; |
| 192 |
| 111 case ClientMessage: | 193 case ClientMessage: |
| 112 if ((Atom)event.xclient.data.l[0] == fWmDeleteMessage && | 194 if ((Atom)event.xclient.data.l[0] == fWmDeleteMessage && |
| 113 gWindowMap.count() == 1) { | 195 gWindowMap.count() == 1) { |
| 114 return true; | 196 return true; |
| 115 } | 197 } |
| 116 break; | 198 break; |
| 117 | 199 |
| 118 case ButtonPress: | 200 case ButtonPress: |
| 119 if (event.xbutton.button == Button1) { | 201 if (event.xbutton.button == Button1) { |
| 120 this->onMouse(event.xbutton.x, event.xbutton.y, | 202 this->onMouse(event.xbutton.x, event.xbutton.y, |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 172 SkASSERT(event.type != Expose && event.type != ConfigureNotify); | 254 SkASSERT(event.type != Expose && event.type != ConfigureNotify); |
| 173 break; | 255 break; |
| 174 } | 256 } |
| 175 | 257 |
| 176 return false; | 258 return false; |
| 177 } | 259 } |
| 178 | 260 |
| 179 void Window_unix::setTitle(const char* title) { | 261 void Window_unix::setTitle(const char* title) { |
| 180 XTextProperty textproperty; | 262 XTextProperty textproperty; |
| 181 XStringListToTextProperty(const_cast<char**>(&title), 1, &textproperty); | 263 XStringListToTextProperty(const_cast<char**>(&title), 1, &textproperty); |
| 182 XSetWMName(fDisplay, fHWnd, &textproperty); | 264 XSetWMName(fDisplay, fWindow, &textproperty); |
| 183 } | 265 } |
| 184 | 266 |
| 185 void Window_unix::show() { | 267 void Window_unix::show() { |
| 186 XMapWindow(fDisplay, fHWnd); | 268 XMapWindow(fDisplay, fWindow); |
| 187 } | 269 } |
| 188 | 270 |
| 189 bool Window_unix::attach(BackendType attachType, const DisplayParams& params) { | 271 bool Window_unix::attach(BackendType attachType, const DisplayParams& params) { |
| 272 this->initWindow(fDisplay, ¶ms); |
| 273 |
| 190 ContextPlatformData_unix platformData; | 274 ContextPlatformData_unix platformData; |
| 191 platformData.fDisplay = fDisplay; | 275 platformData.fDisplay = fDisplay; |
| 192 platformData.fHWnd = fHWnd; | 276 platformData.fWindow = fWindow; |
| 193 XWindowAttributes attribs; | 277 platformData.fVisualInfo = fVisualInfo; |
| 194 XGetWindowAttributes(fDisplay, fHWnd, &attribs); | |
| 195 platformData.fVisualID = XVisualIDFromVisual(attribs.visual); | |
| 196 switch (attachType) { | 278 switch (attachType) { |
| 197 case kVulkan_BackendType: | 279 case kVulkan_BackendType: |
| 280 fWindowContext = VulkanWindowContext::Create((void*)&platformData, p
arams); |
| 281 break; |
| 282 |
| 283 case kNativeGL_BackendType: |
| 198 default: | 284 default: |
| 199 fWindowContext = VulkanWindowContext::Create((void*)&platformData, p
arams); | 285 fWindowContext = GLWindowContext::Create((void*)&platformData, param
s); |
| 200 break; | 286 break; |
| 201 } | 287 } |
| 202 | 288 |
| 203 return (SkToBool(fWindowContext)); | 289 return (SkToBool(fWindowContext)); |
| 204 } | 290 } |
| 205 | 291 |
| 206 void Window_unix::onInval() { | 292 void Window_unix::onInval() { |
| 207 XEvent event; | 293 XEvent event; |
| 208 event.type = Expose; | 294 event.type = Expose; |
| 209 event.xexpose.send_event = True; | 295 event.xexpose.send_event = True; |
| 210 event.xexpose.display = fDisplay; | 296 event.xexpose.display = fDisplay; |
| 211 event.xexpose.window = fHWnd; | 297 event.xexpose.window = fWindow; |
| 212 event.xexpose.x = 0; | 298 event.xexpose.x = 0; |
| 213 event.xexpose.y = 0; | 299 event.xexpose.y = 0; |
| 214 event.xexpose.width = fWidth; | 300 event.xexpose.width = fWidth; |
| 215 event.xexpose.height = fHeight; | 301 event.xexpose.height = fHeight; |
| 216 event.xexpose.count = 0; | 302 event.xexpose.count = 0; |
| 217 | 303 |
| 218 XSendEvent(fDisplay, fHWnd, False, 0, &event); | 304 XSendEvent(fDisplay, fWindow, False, 0, &event); |
| 219 } | 305 } |
| 220 | 306 |
| 221 } // namespace sk_app | 307 } // namespace sk_app |
| OLD | NEW |