1 ////////////////////////////////////////////////////////////
2 //
3 // SFML - Simple and Fast Multimedia Library
4 // Copyright (C) 2007-2018 Laurent Gomila (laurent@sfml-dev.org)
5 //
6 // This software is provided 'as-is', without any express or implied warranty.
7 // In no event will the authors be held liable for any damages arising from the use of this software.
8 //
9 // Permission is granted to anyone to use this software for any purpose,
10 // including commercial applications, and to alter it and redistribute it freely,
11 // subject to the following restrictions:
12 //
13 // 1. The origin of this software must not be misrepresented;
14 // you must not claim that you wrote the original software.
15 // If you use this software in a product, an acknowledgment
16 // in the product documentation would be appreciated but is not required.
17 //
18 // 2. Altered source versions must be plainly marked as such,
19 // and must not be misrepresented as being the original software.
20 //
21 // 3. This notice may not be removed or altered from any source distribution.
22 //
23 ////////////////////////////////////////////////////////////
24
25 ////////////////////////////////////////////////////////////
26 // Headers
27 ////////////////////////////////////////////////////////////
28 #include <SFML/Window/Window.hpp> // important to be included first (conflict with None)
29 #include <SFML/Window/Unix/InputImpl.hpp>
30 #include <SFML/Window/Unix/Display.hpp>
31 #include <SFML/System/Err.hpp>
32 #include <X11/Xlib.h>
33 #include <X11/keysym.h>
34
35
36 namespace sf
37 {
38 namespace priv
39 {
40 ////////////////////////////////////////////////////////////
isKeyPressed(Keyboard::Key key)41 bool InputImpl::isKeyPressed(Keyboard::Key key)
42 {
43 // Get the corresponding X11 keysym
44 KeySym keysym = 0;
45 switch (key)
46 {
47 case Keyboard::LShift: keysym = XK_Shift_L; break;
48 case Keyboard::RShift: keysym = XK_Shift_R; break;
49 case Keyboard::LControl: keysym = XK_Control_L; break;
50 case Keyboard::RControl: keysym = XK_Control_R; break;
51 case Keyboard::LAlt: keysym = XK_Alt_L; break;
52 case Keyboard::RAlt: keysym = XK_Alt_R; break;
53 case Keyboard::LSystem: keysym = XK_Super_L; break;
54 case Keyboard::RSystem: keysym = XK_Super_R; break;
55 case Keyboard::Menu: keysym = XK_Menu; break;
56 case Keyboard::Escape: keysym = XK_Escape; break;
57 case Keyboard::Semicolon: keysym = XK_semicolon; break;
58 case Keyboard::Slash: keysym = XK_slash; break;
59 case Keyboard::Equal: keysym = XK_equal; break;
60 case Keyboard::Hyphen: keysym = XK_minus; break;
61 case Keyboard::LBracket: keysym = XK_bracketleft; break;
62 case Keyboard::RBracket: keysym = XK_bracketright; break;
63 case Keyboard::Comma: keysym = XK_comma; break;
64 case Keyboard::Period: keysym = XK_period; break;
65 case Keyboard::Quote: keysym = XK_apostrophe; break;
66 case Keyboard::Backslash: keysym = XK_backslash; break;
67 case Keyboard::Tilde: keysym = XK_grave; break;
68 case Keyboard::Space: keysym = XK_space; break;
69 case Keyboard::Enter: keysym = XK_Return; break;
70 case Keyboard::Backspace: keysym = XK_BackSpace; break;
71 case Keyboard::Tab: keysym = XK_Tab; break;
72 case Keyboard::PageUp: keysym = XK_Prior; break;
73 case Keyboard::PageDown: keysym = XK_Next; break;
74 case Keyboard::End: keysym = XK_End; break;
75 case Keyboard::Home: keysym = XK_Home; break;
76 case Keyboard::Insert: keysym = XK_Insert; break;
77 case Keyboard::Delete: keysym = XK_Delete; break;
78 case Keyboard::Add: keysym = XK_KP_Add; break;
79 case Keyboard::Subtract: keysym = XK_KP_Subtract; break;
80 case Keyboard::Multiply: keysym = XK_KP_Multiply; break;
81 case Keyboard::Divide: keysym = XK_KP_Divide; break;
82 case Keyboard::Pause: keysym = XK_Pause; break;
83 case Keyboard::F1: keysym = XK_F1; break;
84 case Keyboard::F2: keysym = XK_F2; break;
85 case Keyboard::F3: keysym = XK_F3; break;
86 case Keyboard::F4: keysym = XK_F4; break;
87 case Keyboard::F5: keysym = XK_F5; break;
88 case Keyboard::F6: keysym = XK_F6; break;
89 case Keyboard::F7: keysym = XK_F7; break;
90 case Keyboard::F8: keysym = XK_F8; break;
91 case Keyboard::F9: keysym = XK_F9; break;
92 case Keyboard::F10: keysym = XK_F10; break;
93 case Keyboard::F11: keysym = XK_F11; break;
94 case Keyboard::F12: keysym = XK_F12; break;
95 case Keyboard::F13: keysym = XK_F13; break;
96 case Keyboard::F14: keysym = XK_F14; break;
97 case Keyboard::F15: keysym = XK_F15; break;
98 case Keyboard::Left: keysym = XK_Left; break;
99 case Keyboard::Right: keysym = XK_Right; break;
100 case Keyboard::Up: keysym = XK_Up; break;
101 case Keyboard::Down: keysym = XK_Down; break;
102 case Keyboard::Numpad0: keysym = XK_KP_Insert; break;
103 case Keyboard::Numpad1: keysym = XK_KP_End; break;
104 case Keyboard::Numpad2: keysym = XK_KP_Down; break;
105 case Keyboard::Numpad3: keysym = XK_KP_Page_Down; break;
106 case Keyboard::Numpad4: keysym = XK_KP_Left; break;
107 case Keyboard::Numpad5: keysym = XK_KP_Begin; break;
108 case Keyboard::Numpad6: keysym = XK_KP_Right; break;
109 case Keyboard::Numpad7: keysym = XK_KP_Home; break;
110 case Keyboard::Numpad8: keysym = XK_KP_Up; break;
111 case Keyboard::Numpad9: keysym = XK_KP_Page_Up; break;
112 case Keyboard::A: keysym = XK_a; break;
113 case Keyboard::B: keysym = XK_b; break;
114 case Keyboard::C: keysym = XK_c; break;
115 case Keyboard::D: keysym = XK_d; break;
116 case Keyboard::E: keysym = XK_e; break;
117 case Keyboard::F: keysym = XK_f; break;
118 case Keyboard::G: keysym = XK_g; break;
119 case Keyboard::H: keysym = XK_h; break;
120 case Keyboard::I: keysym = XK_i; break;
121 case Keyboard::J: keysym = XK_j; break;
122 case Keyboard::K: keysym = XK_k; break;
123 case Keyboard::L: keysym = XK_l; break;
124 case Keyboard::M: keysym = XK_m; break;
125 case Keyboard::N: keysym = XK_n; break;
126 case Keyboard::O: keysym = XK_o; break;
127 case Keyboard::P: keysym = XK_p; break;
128 case Keyboard::Q: keysym = XK_q; break;
129 case Keyboard::R: keysym = XK_r; break;
130 case Keyboard::S: keysym = XK_s; break;
131 case Keyboard::T: keysym = XK_t; break;
132 case Keyboard::U: keysym = XK_u; break;
133 case Keyboard::V: keysym = XK_v; break;
134 case Keyboard::W: keysym = XK_w; break;
135 case Keyboard::X: keysym = XK_x; break;
136 case Keyboard::Y: keysym = XK_y; break;
137 case Keyboard::Z: keysym = XK_z; break;
138 case Keyboard::Num0: keysym = XK_0; break;
139 case Keyboard::Num1: keysym = XK_1; break;
140 case Keyboard::Num2: keysym = XK_2; break;
141 case Keyboard::Num3: keysym = XK_3; break;
142 case Keyboard::Num4: keysym = XK_4; break;
143 case Keyboard::Num5: keysym = XK_5; break;
144 case Keyboard::Num6: keysym = XK_6; break;
145 case Keyboard::Num7: keysym = XK_7; break;
146 case Keyboard::Num8: keysym = XK_8; break;
147 case Keyboard::Num9: keysym = XK_9; break;
148 default: keysym = 0; break;
149 }
150
151 // Sanity checks
152 if (key < 0 || key >= sf::Keyboard::KeyCount)
153 return false;
154
155 // Open a connection with the X server
156 Display* display = OpenDisplay();
157
158 // Convert to keycode
159 KeyCode keycode = XKeysymToKeycode(display, keysym);
160 if (keycode != 0)
161 {
162 // Get the whole keyboard state
163 char keys[32];
164 XQueryKeymap(display, keys);
165
166 // Close the connection with the X server
167 CloseDisplay(display);
168
169 // Check our keycode
170 return (keys[keycode / 8] & (1 << (keycode % 8))) != 0;
171 }
172 else
173 {
174 // Close the connection with the X server
175 CloseDisplay(display);
176
177 return false;
178 }
179 }
180
181
182 ////////////////////////////////////////////////////////////
setVirtualKeyboardVisible(bool)183 void InputImpl::setVirtualKeyboardVisible(bool /*visible*/)
184 {
185 // Not applicable
186 }
187
188
189 ////////////////////////////////////////////////////////////
isMouseButtonPressed(Mouse::Button button)190 bool InputImpl::isMouseButtonPressed(Mouse::Button button)
191 {
192 // Open a connection with the X server
193 Display* display = OpenDisplay();
194
195 // we don't care about these but they are required
196 ::Window root, child;
197 int wx, wy;
198 int gx, gy;
199
200 unsigned int buttons = 0;
201 XQueryPointer(display, DefaultRootWindow(display), &root, &child, &gx, &gy, &wx, &wy, &buttons);
202
203 // Close the connection with the X server
204 CloseDisplay(display);
205
206 switch (button)
207 {
208 case Mouse::Left: return buttons & Button1Mask;
209 case Mouse::Right: return buttons & Button3Mask;
210 case Mouse::Middle: return buttons & Button2Mask;
211 case Mouse::XButton1: return false; // not supported by X
212 case Mouse::XButton2: return false; // not supported by X
213 default: return false;
214 }
215
216 return false;
217 }
218
219
220 ////////////////////////////////////////////////////////////
getMousePosition()221 Vector2i InputImpl::getMousePosition()
222 {
223 // Open a connection with the X server
224 Display* display = OpenDisplay();
225
226 // we don't care about these but they are required
227 ::Window root, child;
228 int x, y;
229 unsigned int buttons;
230
231 int gx = 0;
232 int gy = 0;
233 XQueryPointer(display, DefaultRootWindow(display), &root, &child, &gx, &gy, &x, &y, &buttons);
234
235 // Close the connection with the X server
236 CloseDisplay(display);
237
238 return Vector2i(gx, gy);
239 }
240
241
242 ////////////////////////////////////////////////////////////
getMousePosition(const Window & relativeTo)243 Vector2i InputImpl::getMousePosition(const Window& relativeTo)
244 {
245 WindowHandle handle = relativeTo.getSystemHandle();
246 if (handle)
247 {
248 // Open a connection with the X server
249 Display* display = OpenDisplay();
250
251 // we don't care about these but they are required
252 ::Window root, child;
253 int gx, gy;
254 unsigned int buttons;
255
256 int x = 0;
257 int y = 0;
258 XQueryPointer(display, handle, &root, &child, &gx, &gy, &x, &y, &buttons);
259
260 // Close the connection with the X server
261 CloseDisplay(display);
262
263 return Vector2i(x, y);
264 }
265 else
266 {
267 return Vector2i();
268 }
269 }
270
271
272 ////////////////////////////////////////////////////////////
setMousePosition(const Vector2i & position)273 void InputImpl::setMousePosition(const Vector2i& position)
274 {
275 // Open a connection with the X server
276 Display* display = OpenDisplay();
277
278 XWarpPointer(display, None, DefaultRootWindow(display), 0, 0, 0, 0, position.x, position.y);
279 XFlush(display);
280
281 // Close the connection with the X server
282 CloseDisplay(display);
283 }
284
285
286 ////////////////////////////////////////////////////////////
setMousePosition(const Vector2i & position,const Window & relativeTo)287 void InputImpl::setMousePosition(const Vector2i& position, const Window& relativeTo)
288 {
289 // Open a connection with the X server
290 Display* display = OpenDisplay();
291
292 WindowHandle handle = relativeTo.getSystemHandle();
293 if (handle)
294 {
295 XWarpPointer(display, None, handle, 0, 0, 0, 0, position.x, position.y);
296 XFlush(display);
297 }
298
299 // Close the connection with the X server
300 CloseDisplay(display);
301 }
302
303
304 ////////////////////////////////////////////////////////////
isTouchDown(unsigned int)305 bool InputImpl::isTouchDown(unsigned int /*finger*/)
306 {
307 // Not applicable
308 return false;
309 }
310
311
312 ////////////////////////////////////////////////////////////
getTouchPosition(unsigned int)313 Vector2i InputImpl::getTouchPosition(unsigned int /*finger*/)
314 {
315 // Not applicable
316 return Vector2i();
317 }
318
319
320 ////////////////////////////////////////////////////////////
getTouchPosition(unsigned int,const Window &)321 Vector2i InputImpl::getTouchPosition(unsigned int /*finger*/, const Window& /*relativeTo*/)
322 {
323 // Not applicable
324 return Vector2i();
325 }
326
327 } // namespace priv
328
329 } // namespace sf
330