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

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: Fix line lengths Created 4 years, 6 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
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 static double now_ms() { return SkTime::GetNSecs() * 1e-6; }
22
23 namespace sk_app {
24
25 SkTDynamicHash<Window_unix,::Window> Window_unix::gWindowMap;
26
27 Window* Window::CreateNativeWindow(void* platformData) {
28 Display* display = (Display*)platformData;
29
30 Window_unix* window = new Window_unix();
31 if (!window->init(display)) {
32 delete window;
33 return nullptr;
34 }
35
36 return window;
37 }
38
39 bool Window_unix::init(Display* display) {
40 fDisplay = display;
41
42 fWidth = 1280;
43 fHeight = 960;
44 fHWnd = XCreateSimpleWindow(display, DefaultRootWindow(display), 0, 0, fWidt h, fHeight,
45 0, BlackPixel(display, DefaultScreen(display)),
46 BlackPixel(display, DefaultScreen(display)));
47
48 if (!fHWnd) {
49 return false;
50 }
51
52 // choose the events we care about
53 XSelectInput(display, fHWnd,
54 ExposureMask | StructureNotifyMask | KeyPressMask | KeyReleaseM ask |
55 PointerMotionMask | ButtonPressMask | ButtonReleaseMask);
56
57 // set up to catch window delete message
58 fWmDeleteMessage = XInternAtom(display, "WM_DELETE_WINDOW", False);
59 XSetWMProtocols(display, fHWnd, &fWmDeleteMessage, 1);
60
61 // add to hashtable of windows
62 gWindowMap.add(this);
63
64 // init event variables
65 fResizeTimer = -200.0;
66 fExposeCount = 0;
67
68 return true;
69 }
70
71 static Window::Key get_key(KeySym keysym) {
72 static const struct {
73 KeySym fXK;
74 Window::Key fKey;
75 } gPair[] = {
76 { XK_BackSpace, Window::Key::kBack },
77 { XK_Clear, Window::Key::kBack },
78 { XK_Return, Window::Key::kOK },
79 { XK_Up, Window::Key::kUp },
80 { XK_Down, Window::Key::kDown },
81 { XK_Left, Window::Key::kLeft },
82 { XK_Right, Window::Key::kRight }
83 };
84 for (size_t i = 0; i < SK_ARRAY_COUNT(gPair); i++) {
85 if (gPair[i].fXK == keysym) {
86 return gPair[i].fKey;
87 }
88 }
89 return Window::Key::kNONE;
90 }
91
92 static uint32_t get_modifiers(const XEvent& event) {
93 static const struct {
94 unsigned fXMask;
95 unsigned fSkMask;
96 } gModifiers[] = {
97 { ShiftMask, Window::kShift_ModifierKey },
98 { ControlMask, Window::kControl_ModifierKey },
99 { Mod1Mask, Window::kOption_ModifierKey },
100 };
101
102 auto modifiers = 0;
103 for (size_t i = 0; i < SK_ARRAY_COUNT(gModifiers); ++i) {
104 if (event.xkey.state & gModifiers[i].fXMask) {
105 modifiers |= gModifiers[i].fSkMask;
106 }
107 }
108 return modifiers;
109 }
110
111 bool Window_unix::handleEvent(const XEvent& event) {
112 switch (event.type) {
113 case ClientMessage:
114 if ((Atom)event.xclient.data.l[0] == fWmDeleteMessage &&
115 gWindowMap.count() == 1) {
116 return true;
117 }
118 break;
119
120 case Expose:
121 if (event.xexpose.count == 0 && (now_ms() - fResizeTimer) > 200.0) {
122 this->onPaint();
123 fResizeTimer = -200.0;
124 }
125 if (event.xexpose.send_event) {
126 --fExposeCount;
127 }
128 break;
129
130 case ConfigureNotify:
131 if ((int)fWidth != event.xconfigurerequest.width ||
132 (int)fHeight != event.xconfigurerequest.height) {
133 this->onResize(event.xconfigurerequest.width, event.xconfigurere quest.height);
134 fWidth = event.xconfigurerequest.width;
135 fHeight = event.xconfigurerequest.height;
136 }
137 if (fResizeTimer < 0.0) {
138 fResizeTimer = now_ms();
139 }
140 break;
141
142 case ButtonPress:
143 if (event.xbutton.button == Button1) {
144 this->onMouse(event.xbutton.x, event.xbutton.y,
145 Window::kDown_InputState, get_modifiers(event));
146 }
147 break;
148
149 case ButtonRelease:
150 if (event.xbutton.button == Button1) {
151 this->onMouse(event.xbutton.x, event.xbutton.y,
152 Window::kUp_InputState, get_modifiers(event));
153 }
154 break;
155
156 case MotionNotify:
157 // only track if left button is down
158 if (event.xmotion.state & Button1Mask) {
159 this->onMouse(event.xmotion.x, event.xmotion.y,
160 Window::kMove_InputState, get_modifiers(event));
161 }
162 break;
163
164 case KeyPress: {
165 int shiftLevel = (event.xkey.state & ShiftMask) ? 1 : 0;
166 KeySym keysym = XkbKeycodeToKeysym(fDisplay, event.xkey.keycode,
167 0, shiftLevel);
168 if (keysym == XK_Escape) {
169 return true;
170 }
171 Window::Key key = get_key(keysym);
172 if (key != Window::Key::kNONE) {
173 (void) this->onKey(key, Window::kDown_InputState,
174 get_modifiers(event));
175 } else {
176 long uni = keysym2ucs(keysym);
177 if (uni != -1) {
178 (void) this->onChar((SkUnichar) uni,
179 get_modifiers(event));
180 }
181 }
182 } break;
183
184 case KeyRelease: {
185 int shiftLevel = (event.xkey.state & ShiftMask) ? 1 : 0;
186 KeySym keysym = XkbKeycodeToKeysym(fDisplay, event.xkey.keycode,
187 0, shiftLevel);
188 Window::Key key = get_key(keysym);
189 (void) this->onKey(key, Window::kUp_InputState,
190 get_modifiers(event));
191 } break;
192
193
194 default:
195 break;
196 }
197
198 return false;
199 }
200
201 void Window_unix::setTitle(const char* title) {
202 XTextProperty textproperty;
203 XStringListToTextProperty(const_cast<char**>(&title), 1, &textproperty);
204 XSetWMName(fDisplay, fHWnd, &textproperty);
205 }
206
207 void Window_unix::show() {
208 XMapWindow(fDisplay, fHWnd);
209 }
210
211 bool Window_unix::attach(BackendType attachType, const DisplayParams& params) {
212 ContextPlatformData_unix platformData;
213 platformData.fDisplay = fDisplay;
214 platformData.fHWnd = fHWnd;
215 XWindowAttributes attribs;
216 XGetWindowAttributes(fDisplay, fHWnd, &attribs);
217 platformData.fVisualID = XVisualIDFromVisual(attribs.visual);
218 switch (attachType) {
219 case kVulkan_BackendType:
220 default:
221 fWindowContext = VulkanWindowContext::Create((void*)&platformData, p arams);
222 break;
223 }
224
225 return (SkToBool(fWindowContext));
226 }
227
228 void Window_unix::inval() {
229 XEvent event;
230 event.type = Expose;
231 event.xexpose.send_event = True;
232 event.xexpose.display = fDisplay;
233 event.xexpose.window = fHWnd;
234 event.xexpose.x = 0;
235 event.xexpose.y = 0;
236 event.xexpose.width = fWidth;
237 event.xexpose.height = fHeight;
238 event.xexpose.count = fExposeCount;
239
240 // Tracking an expose count keeps us from having bursty renders
241 XSendEvent(fDisplay, fHWnd, False, 0, &event);
242 ++fExposeCount;
243 }
244
245 } // namespace sk_app
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698