Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(7)

Side by Side Diff: tools/viewer/sk_app/unix/Window_unix.cpp

Issue 1999213002: Add Xlib support to viewer (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Remove viewer hack Created 4 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « tools/viewer/sk_app/unix/Window_unix.h ('k') | tools/viewer/sk_app/unix/main_unix.cpp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 /*
2 * Copyright 2016 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
8 //#include <tchar.h>
9
10 #include "SkUtils.h"
11 #include "Timer.h"
12 #include "../VulkanWindowContext.h"
13 #include "Window_unix.h"
14
15 extern "C" {
16 #include "keysym2ucs.h"
17 }
18 #include <X11/Xutil.h>
19 #include <X11/XKBlib.h>
20
21 namespace sk_app {
22
23 SkTDynamicHash<Window_unix, XWindow> Window_unix::gWindowMap;
24
25 Window* Window::CreateNativeWindow(void* platformData) {
26 Display* display = (Display*)platformData;
27
28 Window_unix* window = new Window_unix();
29 if (!window->init(display)) {
30 delete window;
31 return nullptr;
32 }
33
34 return window;
35 }
36
37 bool Window_unix::init(Display* display) {
38 fDisplay = display;
39
40 fWidth = 1280;
41 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
46 if (!fHWnd) {
47 return false;
48 }
49
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
56 fWmDeleteMessage = XInternAtom(display, "WM_DELETE_WINDOW", False);
57 XSetWMProtocols(display, fHWnd, &fWmDeleteMessage, 1);
58
59 // add to hashtable of windows
60 gWindowMap.add(this);
61
62 // init event variables
63 fPendingPaint = false;
64 fPendingResize = false;
65
66 return true;
67 }
68
69 static Window::Key get_key(KeySym keysym) {
70 static const struct {
71 KeySym fXK;
72 Window::Key fKey;
73 } gPair[] = {
74 { XK_BackSpace, Window::Key::kBack },
75 { XK_Clear, Window::Key::kBack },
76 { XK_Return, Window::Key::kOK },
77 { XK_Up, Window::Key::kUp },
78 { XK_Down, Window::Key::kDown },
79 { XK_Left, Window::Key::kLeft },
80 { XK_Right, Window::Key::kRight }
81 };
82 for (size_t i = 0; i < SK_ARRAY_COUNT(gPair); i++) {
83 if (gPair[i].fXK == keysym) {
84 return gPair[i].fKey;
85 }
86 }
87 return Window::Key::kNONE;
88 }
89
90 static uint32_t get_modifiers(const XEvent& event) {
91 static const struct {
92 unsigned fXMask;
93 unsigned fSkMask;
94 } gModifiers[] = {
95 { ShiftMask, Window::kShift_ModifierKey },
96 { ControlMask, Window::kControl_ModifierKey },
97 { Mod1Mask, Window::kOption_ModifierKey },
98 };
99
100 auto modifiers = 0;
101 for (size_t i = 0; i < SK_ARRAY_COUNT(gModifiers); ++i) {
102 if (event.xkey.state & gModifiers[i].fXMask) {
103 modifiers |= gModifiers[i].fSkMask;
104 }
105 }
106 return modifiers;
107 }
108
109 bool Window_unix::handleEvent(const XEvent& event) {
110 switch (event.type) {
111 case ClientMessage:
112 if ((Atom)event.xclient.data.l[0] == fWmDeleteMessage &&
113 gWindowMap.count() == 1) {
114 return true;
115 }
116 break;
117
118 case ButtonPress:
119 if (event.xbutton.button == Button1) {
120 this->onMouse(event.xbutton.x, event.xbutton.y,
121 Window::kDown_InputState, get_modifiers(event));
122 }
123 break;
124
125 case ButtonRelease:
126 if (event.xbutton.button == Button1) {
127 this->onMouse(event.xbutton.x, event.xbutton.y,
128 Window::kUp_InputState, get_modifiers(event));
129 }
130 break;
131
132 case MotionNotify:
133 // only track if left button is down
134 if (event.xmotion.state & Button1Mask) {
135 this->onMouse(event.xmotion.x, event.xmotion.y,
136 Window::kMove_InputState, get_modifiers(event));
137 }
138 break;
139
140 case KeyPress: {
141 int shiftLevel = (event.xkey.state & ShiftMask) ? 1 : 0;
142 KeySym keysym = XkbKeycodeToKeysym(fDisplay, event.xkey.keycode,
143 0, shiftLevel);
144 if (keysym == XK_Escape) {
145 return true;
146 }
147 Window::Key key = get_key(keysym);
148 if (key != Window::Key::kNONE) {
149 (void) this->onKey(key, Window::kDown_InputState,
150 get_modifiers(event));
151 } else {
152 long uni = keysym2ucs(keysym);
153 if (uni != -1) {
154 (void) this->onChar((SkUnichar) uni,
155 get_modifiers(event));
156 }
157 }
158 } break;
159
160 case KeyRelease: {
161 int shiftLevel = (event.xkey.state & ShiftMask) ? 1 : 0;
162 KeySym keysym = XkbKeycodeToKeysym(fDisplay, event.xkey.keycode,
163 0, shiftLevel);
164 Window::Key key = get_key(keysym);
165 (void) this->onKey(key, Window::kUp_InputState,
166 get_modifiers(event));
167 } break;
168
169
170 default:
171 // these events should be handled in the main event loop
172 SkASSERT(event.type != Expose && event.type != ConfigureNotify);
173 break;
174 }
175
176 return false;
177 }
178
179 void Window_unix::setTitle(const char* title) {
180 XTextProperty textproperty;
181 XStringListToTextProperty(const_cast<char**>(&title), 1, &textproperty);
182 XSetWMName(fDisplay, fHWnd, &textproperty);
183 }
184
185 void Window_unix::show() {
186 XMapWindow(fDisplay, fHWnd);
187 }
188
189 bool Window_unix::attach(BackendType attachType, const DisplayParams& params) {
190 ContextPlatformData_unix platformData;
191 platformData.fDisplay = fDisplay;
192 platformData.fHWnd = fHWnd;
193 XWindowAttributes attribs;
194 XGetWindowAttributes(fDisplay, fHWnd, &attribs);
195 platformData.fVisualID = XVisualIDFromVisual(attribs.visual);
196 switch (attachType) {
197 case kVulkan_BackendType:
198 default:
199 fWindowContext = VulkanWindowContext::Create((void*)&platformData, p arams);
200 break;
201 }
202
203 return (SkToBool(fWindowContext));
204 }
205
206 void Window_unix::onInval() {
207 XEvent event;
208 event.type = Expose;
209 event.xexpose.send_event = True;
210 event.xexpose.display = fDisplay;
211 event.xexpose.window = fHWnd;
212 event.xexpose.x = 0;
213 event.xexpose.y = 0;
214 event.xexpose.width = fWidth;
215 event.xexpose.height = fHeight;
216 event.xexpose.count = 0;
217
218 XSendEvent(fDisplay, fHWnd, False, 0, &event);
219 }
220
221 } // namespace sk_app
OLDNEW
« no previous file with comments | « tools/viewer/sk_app/unix/Window_unix.h ('k') | tools/viewer/sk_app/unix/main_unix.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698