1*8975f5c5SAndroid Build Coastguard Worker //
2*8975f5c5SAndroid Build Coastguard Worker // Copyright 2015 The ANGLE Project Authors. All rights reserved.
3*8975f5c5SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
4*8975f5c5SAndroid Build Coastguard Worker // found in the LICENSE file.
5*8975f5c5SAndroid Build Coastguard Worker //
6*8975f5c5SAndroid Build Coastguard Worker
7*8975f5c5SAndroid Build Coastguard Worker // X11Window.cpp: Implementation of OSWindow for X11
8*8975f5c5SAndroid Build Coastguard Worker
9*8975f5c5SAndroid Build Coastguard Worker #include "util/linux/x11/X11Window.h"
10*8975f5c5SAndroid Build Coastguard Worker
11*8975f5c5SAndroid Build Coastguard Worker #include "common/debug.h"
12*8975f5c5SAndroid Build Coastguard Worker #include "util/Timer.h"
13*8975f5c5SAndroid Build Coastguard Worker #include "util/test_utils.h"
14*8975f5c5SAndroid Build Coastguard Worker
15*8975f5c5SAndroid Build Coastguard Worker #include <X11/Xlib.h>
16*8975f5c5SAndroid Build Coastguard Worker #include <X11/Xresource.h>
17*8975f5c5SAndroid Build Coastguard Worker #include <X11/Xutil.h>
18*8975f5c5SAndroid Build Coastguard Worker
19*8975f5c5SAndroid Build Coastguard Worker namespace
20*8975f5c5SAndroid Build Coastguard Worker {
21*8975f5c5SAndroid Build Coastguard Worker
WaitForMapNotify(Display * dpy,XEvent * event,XPointer window)22*8975f5c5SAndroid Build Coastguard Worker Bool WaitForMapNotify(Display *dpy, XEvent *event, XPointer window)
23*8975f5c5SAndroid Build Coastguard Worker {
24*8975f5c5SAndroid Build Coastguard Worker return event->type == MapNotify && event->xmap.window == reinterpret_cast<Window>(window);
25*8975f5c5SAndroid Build Coastguard Worker }
26*8975f5c5SAndroid Build Coastguard Worker
X11CodeToKey(Display * display,unsigned int scancode)27*8975f5c5SAndroid Build Coastguard Worker static Key X11CodeToKey(Display *display, unsigned int scancode)
28*8975f5c5SAndroid Build Coastguard Worker {
29*8975f5c5SAndroid Build Coastguard Worker int temp;
30*8975f5c5SAndroid Build Coastguard Worker KeySym *keySymbols;
31*8975f5c5SAndroid Build Coastguard Worker keySymbols = XGetKeyboardMapping(display, scancode, 1, &temp);
32*8975f5c5SAndroid Build Coastguard Worker
33*8975f5c5SAndroid Build Coastguard Worker KeySym keySymbol = keySymbols[0];
34*8975f5c5SAndroid Build Coastguard Worker XFree(keySymbols);
35*8975f5c5SAndroid Build Coastguard Worker
36*8975f5c5SAndroid Build Coastguard Worker switch (keySymbol)
37*8975f5c5SAndroid Build Coastguard Worker {
38*8975f5c5SAndroid Build Coastguard Worker case XK_Shift_L:
39*8975f5c5SAndroid Build Coastguard Worker return KEY_LSHIFT;
40*8975f5c5SAndroid Build Coastguard Worker case XK_Shift_R:
41*8975f5c5SAndroid Build Coastguard Worker return KEY_RSHIFT;
42*8975f5c5SAndroid Build Coastguard Worker case XK_Alt_L:
43*8975f5c5SAndroid Build Coastguard Worker return KEY_LALT;
44*8975f5c5SAndroid Build Coastguard Worker case XK_Alt_R:
45*8975f5c5SAndroid Build Coastguard Worker return KEY_RALT;
46*8975f5c5SAndroid Build Coastguard Worker case XK_Control_L:
47*8975f5c5SAndroid Build Coastguard Worker return KEY_LCONTROL;
48*8975f5c5SAndroid Build Coastguard Worker case XK_Control_R:
49*8975f5c5SAndroid Build Coastguard Worker return KEY_RCONTROL;
50*8975f5c5SAndroid Build Coastguard Worker case XK_Super_L:
51*8975f5c5SAndroid Build Coastguard Worker return KEY_LSYSTEM;
52*8975f5c5SAndroid Build Coastguard Worker case XK_Super_R:
53*8975f5c5SAndroid Build Coastguard Worker return KEY_RSYSTEM;
54*8975f5c5SAndroid Build Coastguard Worker case XK_Menu:
55*8975f5c5SAndroid Build Coastguard Worker return KEY_MENU;
56*8975f5c5SAndroid Build Coastguard Worker
57*8975f5c5SAndroid Build Coastguard Worker case XK_semicolon:
58*8975f5c5SAndroid Build Coastguard Worker return KEY_SEMICOLON;
59*8975f5c5SAndroid Build Coastguard Worker case XK_slash:
60*8975f5c5SAndroid Build Coastguard Worker return KEY_SLASH;
61*8975f5c5SAndroid Build Coastguard Worker case XK_equal:
62*8975f5c5SAndroid Build Coastguard Worker return KEY_EQUAL;
63*8975f5c5SAndroid Build Coastguard Worker case XK_minus:
64*8975f5c5SAndroid Build Coastguard Worker return KEY_DASH;
65*8975f5c5SAndroid Build Coastguard Worker case XK_bracketleft:
66*8975f5c5SAndroid Build Coastguard Worker return KEY_LBRACKET;
67*8975f5c5SAndroid Build Coastguard Worker case XK_bracketright:
68*8975f5c5SAndroid Build Coastguard Worker return KEY_RBRACKET;
69*8975f5c5SAndroid Build Coastguard Worker case XK_comma:
70*8975f5c5SAndroid Build Coastguard Worker return KEY_COMMA;
71*8975f5c5SAndroid Build Coastguard Worker case XK_period:
72*8975f5c5SAndroid Build Coastguard Worker return KEY_PERIOD;
73*8975f5c5SAndroid Build Coastguard Worker case XK_backslash:
74*8975f5c5SAndroid Build Coastguard Worker return KEY_BACKSLASH;
75*8975f5c5SAndroid Build Coastguard Worker case XK_asciitilde:
76*8975f5c5SAndroid Build Coastguard Worker return KEY_TILDE;
77*8975f5c5SAndroid Build Coastguard Worker case XK_Escape:
78*8975f5c5SAndroid Build Coastguard Worker return KEY_ESCAPE;
79*8975f5c5SAndroid Build Coastguard Worker case XK_space:
80*8975f5c5SAndroid Build Coastguard Worker return KEY_SPACE;
81*8975f5c5SAndroid Build Coastguard Worker case XK_Return:
82*8975f5c5SAndroid Build Coastguard Worker return KEY_RETURN;
83*8975f5c5SAndroid Build Coastguard Worker case XK_BackSpace:
84*8975f5c5SAndroid Build Coastguard Worker return KEY_BACK;
85*8975f5c5SAndroid Build Coastguard Worker case XK_Tab:
86*8975f5c5SAndroid Build Coastguard Worker return KEY_TAB;
87*8975f5c5SAndroid Build Coastguard Worker case XK_Page_Up:
88*8975f5c5SAndroid Build Coastguard Worker return KEY_PAGEUP;
89*8975f5c5SAndroid Build Coastguard Worker case XK_Page_Down:
90*8975f5c5SAndroid Build Coastguard Worker return KEY_PAGEDOWN;
91*8975f5c5SAndroid Build Coastguard Worker case XK_End:
92*8975f5c5SAndroid Build Coastguard Worker return KEY_END;
93*8975f5c5SAndroid Build Coastguard Worker case XK_Home:
94*8975f5c5SAndroid Build Coastguard Worker return KEY_HOME;
95*8975f5c5SAndroid Build Coastguard Worker case XK_Insert:
96*8975f5c5SAndroid Build Coastguard Worker return KEY_INSERT;
97*8975f5c5SAndroid Build Coastguard Worker case XK_Delete:
98*8975f5c5SAndroid Build Coastguard Worker return KEY_DELETE;
99*8975f5c5SAndroid Build Coastguard Worker case XK_KP_Add:
100*8975f5c5SAndroid Build Coastguard Worker return KEY_ADD;
101*8975f5c5SAndroid Build Coastguard Worker case XK_KP_Subtract:
102*8975f5c5SAndroid Build Coastguard Worker return KEY_SUBTRACT;
103*8975f5c5SAndroid Build Coastguard Worker case XK_KP_Multiply:
104*8975f5c5SAndroid Build Coastguard Worker return KEY_MULTIPLY;
105*8975f5c5SAndroid Build Coastguard Worker case XK_KP_Divide:
106*8975f5c5SAndroid Build Coastguard Worker return KEY_DIVIDE;
107*8975f5c5SAndroid Build Coastguard Worker case XK_Pause:
108*8975f5c5SAndroid Build Coastguard Worker return KEY_PAUSE;
109*8975f5c5SAndroid Build Coastguard Worker
110*8975f5c5SAndroid Build Coastguard Worker case XK_F1:
111*8975f5c5SAndroid Build Coastguard Worker return KEY_F1;
112*8975f5c5SAndroid Build Coastguard Worker case XK_F2:
113*8975f5c5SAndroid Build Coastguard Worker return KEY_F2;
114*8975f5c5SAndroid Build Coastguard Worker case XK_F3:
115*8975f5c5SAndroid Build Coastguard Worker return KEY_F3;
116*8975f5c5SAndroid Build Coastguard Worker case XK_F4:
117*8975f5c5SAndroid Build Coastguard Worker return KEY_F4;
118*8975f5c5SAndroid Build Coastguard Worker case XK_F5:
119*8975f5c5SAndroid Build Coastguard Worker return KEY_F5;
120*8975f5c5SAndroid Build Coastguard Worker case XK_F6:
121*8975f5c5SAndroid Build Coastguard Worker return KEY_F6;
122*8975f5c5SAndroid Build Coastguard Worker case XK_F7:
123*8975f5c5SAndroid Build Coastguard Worker return KEY_F7;
124*8975f5c5SAndroid Build Coastguard Worker case XK_F8:
125*8975f5c5SAndroid Build Coastguard Worker return KEY_F8;
126*8975f5c5SAndroid Build Coastguard Worker case XK_F9:
127*8975f5c5SAndroid Build Coastguard Worker return KEY_F9;
128*8975f5c5SAndroid Build Coastguard Worker case XK_F10:
129*8975f5c5SAndroid Build Coastguard Worker return KEY_F10;
130*8975f5c5SAndroid Build Coastguard Worker case XK_F11:
131*8975f5c5SAndroid Build Coastguard Worker return KEY_F11;
132*8975f5c5SAndroid Build Coastguard Worker case XK_F12:
133*8975f5c5SAndroid Build Coastguard Worker return KEY_F12;
134*8975f5c5SAndroid Build Coastguard Worker case XK_F13:
135*8975f5c5SAndroid Build Coastguard Worker return KEY_F13;
136*8975f5c5SAndroid Build Coastguard Worker case XK_F14:
137*8975f5c5SAndroid Build Coastguard Worker return KEY_F14;
138*8975f5c5SAndroid Build Coastguard Worker case XK_F15:
139*8975f5c5SAndroid Build Coastguard Worker return KEY_F15;
140*8975f5c5SAndroid Build Coastguard Worker
141*8975f5c5SAndroid Build Coastguard Worker case XK_Left:
142*8975f5c5SAndroid Build Coastguard Worker return KEY_LEFT;
143*8975f5c5SAndroid Build Coastguard Worker case XK_Right:
144*8975f5c5SAndroid Build Coastguard Worker return KEY_RIGHT;
145*8975f5c5SAndroid Build Coastguard Worker case XK_Down:
146*8975f5c5SAndroid Build Coastguard Worker return KEY_DOWN;
147*8975f5c5SAndroid Build Coastguard Worker case XK_Up:
148*8975f5c5SAndroid Build Coastguard Worker return KEY_UP;
149*8975f5c5SAndroid Build Coastguard Worker
150*8975f5c5SAndroid Build Coastguard Worker case XK_KP_Insert:
151*8975f5c5SAndroid Build Coastguard Worker return KEY_NUMPAD0;
152*8975f5c5SAndroid Build Coastguard Worker case XK_KP_End:
153*8975f5c5SAndroid Build Coastguard Worker return KEY_NUMPAD1;
154*8975f5c5SAndroid Build Coastguard Worker case XK_KP_Down:
155*8975f5c5SAndroid Build Coastguard Worker return KEY_NUMPAD2;
156*8975f5c5SAndroid Build Coastguard Worker case XK_KP_Page_Down:
157*8975f5c5SAndroid Build Coastguard Worker return KEY_NUMPAD3;
158*8975f5c5SAndroid Build Coastguard Worker case XK_KP_Left:
159*8975f5c5SAndroid Build Coastguard Worker return KEY_NUMPAD4;
160*8975f5c5SAndroid Build Coastguard Worker case XK_KP_5:
161*8975f5c5SAndroid Build Coastguard Worker return KEY_NUMPAD5;
162*8975f5c5SAndroid Build Coastguard Worker case XK_KP_Right:
163*8975f5c5SAndroid Build Coastguard Worker return KEY_NUMPAD6;
164*8975f5c5SAndroid Build Coastguard Worker case XK_KP_Home:
165*8975f5c5SAndroid Build Coastguard Worker return KEY_NUMPAD7;
166*8975f5c5SAndroid Build Coastguard Worker case XK_KP_Up:
167*8975f5c5SAndroid Build Coastguard Worker return KEY_NUMPAD8;
168*8975f5c5SAndroid Build Coastguard Worker case XK_KP_Page_Up:
169*8975f5c5SAndroid Build Coastguard Worker return KEY_NUMPAD9;
170*8975f5c5SAndroid Build Coastguard Worker
171*8975f5c5SAndroid Build Coastguard Worker case XK_a:
172*8975f5c5SAndroid Build Coastguard Worker return KEY_A;
173*8975f5c5SAndroid Build Coastguard Worker case XK_b:
174*8975f5c5SAndroid Build Coastguard Worker return KEY_B;
175*8975f5c5SAndroid Build Coastguard Worker case XK_c:
176*8975f5c5SAndroid Build Coastguard Worker return KEY_C;
177*8975f5c5SAndroid Build Coastguard Worker case XK_d:
178*8975f5c5SAndroid Build Coastguard Worker return KEY_D;
179*8975f5c5SAndroid Build Coastguard Worker case XK_e:
180*8975f5c5SAndroid Build Coastguard Worker return KEY_E;
181*8975f5c5SAndroid Build Coastguard Worker case XK_f:
182*8975f5c5SAndroid Build Coastguard Worker return KEY_F;
183*8975f5c5SAndroid Build Coastguard Worker case XK_g:
184*8975f5c5SAndroid Build Coastguard Worker return KEY_G;
185*8975f5c5SAndroid Build Coastguard Worker case XK_h:
186*8975f5c5SAndroid Build Coastguard Worker return KEY_H;
187*8975f5c5SAndroid Build Coastguard Worker case XK_i:
188*8975f5c5SAndroid Build Coastguard Worker return KEY_I;
189*8975f5c5SAndroid Build Coastguard Worker case XK_j:
190*8975f5c5SAndroid Build Coastguard Worker return KEY_J;
191*8975f5c5SAndroid Build Coastguard Worker case XK_k:
192*8975f5c5SAndroid Build Coastguard Worker return KEY_K;
193*8975f5c5SAndroid Build Coastguard Worker case XK_l:
194*8975f5c5SAndroid Build Coastguard Worker return KEY_L;
195*8975f5c5SAndroid Build Coastguard Worker case XK_m:
196*8975f5c5SAndroid Build Coastguard Worker return KEY_M;
197*8975f5c5SAndroid Build Coastguard Worker case XK_n:
198*8975f5c5SAndroid Build Coastguard Worker return KEY_N;
199*8975f5c5SAndroid Build Coastguard Worker case XK_o:
200*8975f5c5SAndroid Build Coastguard Worker return KEY_O;
201*8975f5c5SAndroid Build Coastguard Worker case XK_p:
202*8975f5c5SAndroid Build Coastguard Worker return KEY_P;
203*8975f5c5SAndroid Build Coastguard Worker case XK_q:
204*8975f5c5SAndroid Build Coastguard Worker return KEY_Q;
205*8975f5c5SAndroid Build Coastguard Worker case XK_r:
206*8975f5c5SAndroid Build Coastguard Worker return KEY_R;
207*8975f5c5SAndroid Build Coastguard Worker case XK_s:
208*8975f5c5SAndroid Build Coastguard Worker return KEY_S;
209*8975f5c5SAndroid Build Coastguard Worker case XK_t:
210*8975f5c5SAndroid Build Coastguard Worker return KEY_T;
211*8975f5c5SAndroid Build Coastguard Worker case XK_u:
212*8975f5c5SAndroid Build Coastguard Worker return KEY_U;
213*8975f5c5SAndroid Build Coastguard Worker case XK_v:
214*8975f5c5SAndroid Build Coastguard Worker return KEY_V;
215*8975f5c5SAndroid Build Coastguard Worker case XK_w:
216*8975f5c5SAndroid Build Coastguard Worker return KEY_W;
217*8975f5c5SAndroid Build Coastguard Worker case XK_x:
218*8975f5c5SAndroid Build Coastguard Worker return KEY_X;
219*8975f5c5SAndroid Build Coastguard Worker case XK_y:
220*8975f5c5SAndroid Build Coastguard Worker return KEY_Y;
221*8975f5c5SAndroid Build Coastguard Worker case XK_z:
222*8975f5c5SAndroid Build Coastguard Worker return KEY_Z;
223*8975f5c5SAndroid Build Coastguard Worker
224*8975f5c5SAndroid Build Coastguard Worker case XK_1:
225*8975f5c5SAndroid Build Coastguard Worker return KEY_NUM1;
226*8975f5c5SAndroid Build Coastguard Worker case XK_2:
227*8975f5c5SAndroid Build Coastguard Worker return KEY_NUM2;
228*8975f5c5SAndroid Build Coastguard Worker case XK_3:
229*8975f5c5SAndroid Build Coastguard Worker return KEY_NUM3;
230*8975f5c5SAndroid Build Coastguard Worker case XK_4:
231*8975f5c5SAndroid Build Coastguard Worker return KEY_NUM4;
232*8975f5c5SAndroid Build Coastguard Worker case XK_5:
233*8975f5c5SAndroid Build Coastguard Worker return KEY_NUM5;
234*8975f5c5SAndroid Build Coastguard Worker case XK_6:
235*8975f5c5SAndroid Build Coastguard Worker return KEY_NUM6;
236*8975f5c5SAndroid Build Coastguard Worker case XK_7:
237*8975f5c5SAndroid Build Coastguard Worker return KEY_NUM7;
238*8975f5c5SAndroid Build Coastguard Worker case XK_8:
239*8975f5c5SAndroid Build Coastguard Worker return KEY_NUM8;
240*8975f5c5SAndroid Build Coastguard Worker case XK_9:
241*8975f5c5SAndroid Build Coastguard Worker return KEY_NUM9;
242*8975f5c5SAndroid Build Coastguard Worker case XK_0:
243*8975f5c5SAndroid Build Coastguard Worker return KEY_NUM0;
244*8975f5c5SAndroid Build Coastguard Worker }
245*8975f5c5SAndroid Build Coastguard Worker
246*8975f5c5SAndroid Build Coastguard Worker return Key(0);
247*8975f5c5SAndroid Build Coastguard Worker }
248*8975f5c5SAndroid Build Coastguard Worker
AddX11KeyStateToEvent(Event * event,unsigned int state)249*8975f5c5SAndroid Build Coastguard Worker static void AddX11KeyStateToEvent(Event *event, unsigned int state)
250*8975f5c5SAndroid Build Coastguard Worker {
251*8975f5c5SAndroid Build Coastguard Worker event->Key.Shift = state & ShiftMask;
252*8975f5c5SAndroid Build Coastguard Worker event->Key.Control = state & ControlMask;
253*8975f5c5SAndroid Build Coastguard Worker event->Key.Alt = state & Mod1Mask;
254*8975f5c5SAndroid Build Coastguard Worker event->Key.System = state & Mod4Mask;
255*8975f5c5SAndroid Build Coastguard Worker }
256*8975f5c5SAndroid Build Coastguard Worker
setWindowSizeHints(Display * display,Window window,int width,int height)257*8975f5c5SAndroid Build Coastguard Worker void setWindowSizeHints(Display *display, Window window, int width, int height)
258*8975f5c5SAndroid Build Coastguard Worker {
259*8975f5c5SAndroid Build Coastguard Worker // Set PMinSize and PMaxSize on XSizeHints so windows larger than the screen do not get adjusted
260*8975f5c5SAndroid Build Coastguard Worker // to screen size
261*8975f5c5SAndroid Build Coastguard Worker XSizeHints *sizeHints = XAllocSizeHints();
262*8975f5c5SAndroid Build Coastguard Worker sizeHints->flags = PMinSize | PMaxSize;
263*8975f5c5SAndroid Build Coastguard Worker sizeHints->min_width = width;
264*8975f5c5SAndroid Build Coastguard Worker sizeHints->min_height = height;
265*8975f5c5SAndroid Build Coastguard Worker sizeHints->max_width = width;
266*8975f5c5SAndroid Build Coastguard Worker sizeHints->max_height = height;
267*8975f5c5SAndroid Build Coastguard Worker
268*8975f5c5SAndroid Build Coastguard Worker XSetWMNormalHints(display, window, sizeHints);
269*8975f5c5SAndroid Build Coastguard Worker
270*8975f5c5SAndroid Build Coastguard Worker XFree(sizeHints);
271*8975f5c5SAndroid Build Coastguard Worker }
272*8975f5c5SAndroid Build Coastguard Worker
273*8975f5c5SAndroid Build Coastguard Worker } // namespace
274*8975f5c5SAndroid Build Coastguard Worker
275*8975f5c5SAndroid Build Coastguard Worker class ANGLE_UTIL_EXPORT X11Window : public OSWindow
276*8975f5c5SAndroid Build Coastguard Worker {
277*8975f5c5SAndroid Build Coastguard Worker public:
278*8975f5c5SAndroid Build Coastguard Worker X11Window();
279*8975f5c5SAndroid Build Coastguard Worker X11Window(int visualId);
280*8975f5c5SAndroid Build Coastguard Worker ~X11Window() override;
281*8975f5c5SAndroid Build Coastguard Worker
282*8975f5c5SAndroid Build Coastguard Worker void disableErrorMessageDialog() override;
283*8975f5c5SAndroid Build Coastguard Worker void destroy() override;
284*8975f5c5SAndroid Build Coastguard Worker
285*8975f5c5SAndroid Build Coastguard Worker void resetNativeWindow() override;
286*8975f5c5SAndroid Build Coastguard Worker EGLNativeWindowType getNativeWindow() const override;
287*8975f5c5SAndroid Build Coastguard Worker void *getPlatformExtension() override;
288*8975f5c5SAndroid Build Coastguard Worker EGLNativeDisplayType getNativeDisplay() const override;
289*8975f5c5SAndroid Build Coastguard Worker
290*8975f5c5SAndroid Build Coastguard Worker void messageLoop() override;
291*8975f5c5SAndroid Build Coastguard Worker
292*8975f5c5SAndroid Build Coastguard Worker void setMousePosition(int x, int y) override;
293*8975f5c5SAndroid Build Coastguard Worker bool setOrientation(int width, int height) override;
294*8975f5c5SAndroid Build Coastguard Worker bool setPosition(int x, int y) override;
295*8975f5c5SAndroid Build Coastguard Worker bool resize(int width, int height) override;
296*8975f5c5SAndroid Build Coastguard Worker void setVisible(bool isVisible) override;
297*8975f5c5SAndroid Build Coastguard Worker
298*8975f5c5SAndroid Build Coastguard Worker void signalTestEvent() override;
299*8975f5c5SAndroid Build Coastguard Worker
300*8975f5c5SAndroid Build Coastguard Worker private:
301*8975f5c5SAndroid Build Coastguard Worker bool initializeImpl(const std::string &name, int width, int height) override;
302*8975f5c5SAndroid Build Coastguard Worker void processEvent(const XEvent &event);
303*8975f5c5SAndroid Build Coastguard Worker
304*8975f5c5SAndroid Build Coastguard Worker Atom WM_DELETE_WINDOW;
305*8975f5c5SAndroid Build Coastguard Worker Atom WM_PROTOCOLS;
306*8975f5c5SAndroid Build Coastguard Worker Atom TEST_EVENT;
307*8975f5c5SAndroid Build Coastguard Worker
308*8975f5c5SAndroid Build Coastguard Worker Display *mDisplay;
309*8975f5c5SAndroid Build Coastguard Worker Window mWindow;
310*8975f5c5SAndroid Build Coastguard Worker int mRequestedVisualId;
311*8975f5c5SAndroid Build Coastguard Worker bool mVisible;
312*8975f5c5SAndroid Build Coastguard Worker bool mConfigured = false;
313*8975f5c5SAndroid Build Coastguard Worker bool mDestroyed = false;
314*8975f5c5SAndroid Build Coastguard Worker };
315*8975f5c5SAndroid Build Coastguard Worker
X11Window()316*8975f5c5SAndroid Build Coastguard Worker X11Window::X11Window()
317*8975f5c5SAndroid Build Coastguard Worker : WM_DELETE_WINDOW(None),
318*8975f5c5SAndroid Build Coastguard Worker WM_PROTOCOLS(None),
319*8975f5c5SAndroid Build Coastguard Worker TEST_EVENT(None),
320*8975f5c5SAndroid Build Coastguard Worker mDisplay(nullptr),
321*8975f5c5SAndroid Build Coastguard Worker mWindow(0),
322*8975f5c5SAndroid Build Coastguard Worker mRequestedVisualId(-1),
323*8975f5c5SAndroid Build Coastguard Worker mVisible(false)
324*8975f5c5SAndroid Build Coastguard Worker {}
325*8975f5c5SAndroid Build Coastguard Worker
X11Window(int visualId)326*8975f5c5SAndroid Build Coastguard Worker X11Window::X11Window(int visualId)
327*8975f5c5SAndroid Build Coastguard Worker : WM_DELETE_WINDOW(None),
328*8975f5c5SAndroid Build Coastguard Worker WM_PROTOCOLS(None),
329*8975f5c5SAndroid Build Coastguard Worker TEST_EVENT(None),
330*8975f5c5SAndroid Build Coastguard Worker mDisplay(nullptr),
331*8975f5c5SAndroid Build Coastguard Worker mWindow(0),
332*8975f5c5SAndroid Build Coastguard Worker mRequestedVisualId(visualId),
333*8975f5c5SAndroid Build Coastguard Worker mVisible(false)
334*8975f5c5SAndroid Build Coastguard Worker {}
335*8975f5c5SAndroid Build Coastguard Worker
~X11Window()336*8975f5c5SAndroid Build Coastguard Worker X11Window::~X11Window()
337*8975f5c5SAndroid Build Coastguard Worker {
338*8975f5c5SAndroid Build Coastguard Worker destroy();
339*8975f5c5SAndroid Build Coastguard Worker }
340*8975f5c5SAndroid Build Coastguard Worker
initializeImpl(const std::string & name,int width,int height)341*8975f5c5SAndroid Build Coastguard Worker bool X11Window::initializeImpl(const std::string &name, int width, int height)
342*8975f5c5SAndroid Build Coastguard Worker {
343*8975f5c5SAndroid Build Coastguard Worker destroy();
344*8975f5c5SAndroid Build Coastguard Worker
345*8975f5c5SAndroid Build Coastguard Worker mDisplay = XOpenDisplay(nullptr);
346*8975f5c5SAndroid Build Coastguard Worker if (!mDisplay)
347*8975f5c5SAndroid Build Coastguard Worker {
348*8975f5c5SAndroid Build Coastguard Worker return false;
349*8975f5c5SAndroid Build Coastguard Worker }
350*8975f5c5SAndroid Build Coastguard Worker
351*8975f5c5SAndroid Build Coastguard Worker {
352*8975f5c5SAndroid Build Coastguard Worker int screen = DefaultScreen(mDisplay);
353*8975f5c5SAndroid Build Coastguard Worker Window root = RootWindow(mDisplay, screen);
354*8975f5c5SAndroid Build Coastguard Worker
355*8975f5c5SAndroid Build Coastguard Worker Visual *visual;
356*8975f5c5SAndroid Build Coastguard Worker if (mRequestedVisualId == -1)
357*8975f5c5SAndroid Build Coastguard Worker {
358*8975f5c5SAndroid Build Coastguard Worker visual = DefaultVisual(mDisplay, screen);
359*8975f5c5SAndroid Build Coastguard Worker }
360*8975f5c5SAndroid Build Coastguard Worker else
361*8975f5c5SAndroid Build Coastguard Worker {
362*8975f5c5SAndroid Build Coastguard Worker XVisualInfo visualTemplate;
363*8975f5c5SAndroid Build Coastguard Worker visualTemplate.visualid = mRequestedVisualId;
364*8975f5c5SAndroid Build Coastguard Worker
365*8975f5c5SAndroid Build Coastguard Worker int numVisuals = 0;
366*8975f5c5SAndroid Build Coastguard Worker XVisualInfo *visuals =
367*8975f5c5SAndroid Build Coastguard Worker XGetVisualInfo(mDisplay, VisualIDMask, &visualTemplate, &numVisuals);
368*8975f5c5SAndroid Build Coastguard Worker if (numVisuals <= 0)
369*8975f5c5SAndroid Build Coastguard Worker {
370*8975f5c5SAndroid Build Coastguard Worker return false;
371*8975f5c5SAndroid Build Coastguard Worker }
372*8975f5c5SAndroid Build Coastguard Worker ASSERT(numVisuals == 1);
373*8975f5c5SAndroid Build Coastguard Worker
374*8975f5c5SAndroid Build Coastguard Worker visual = visuals[0].visual;
375*8975f5c5SAndroid Build Coastguard Worker XFree(visuals);
376*8975f5c5SAndroid Build Coastguard Worker }
377*8975f5c5SAndroid Build Coastguard Worker
378*8975f5c5SAndroid Build Coastguard Worker int depth = DefaultDepth(mDisplay, screen);
379*8975f5c5SAndroid Build Coastguard Worker Colormap colormap = XCreateColormap(mDisplay, root, visual, AllocNone);
380*8975f5c5SAndroid Build Coastguard Worker
381*8975f5c5SAndroid Build Coastguard Worker XSetWindowAttributes attributes;
382*8975f5c5SAndroid Build Coastguard Worker unsigned long attributeMask = CWBorderPixel | CWColormap | CWEventMask;
383*8975f5c5SAndroid Build Coastguard Worker
384*8975f5c5SAndroid Build Coastguard Worker attributes.event_mask = StructureNotifyMask | PointerMotionMask | ButtonPressMask |
385*8975f5c5SAndroid Build Coastguard Worker ButtonReleaseMask | FocusChangeMask | EnterWindowMask |
386*8975f5c5SAndroid Build Coastguard Worker LeaveWindowMask | KeyPressMask | KeyReleaseMask;
387*8975f5c5SAndroid Build Coastguard Worker attributes.border_pixel = 0;
388*8975f5c5SAndroid Build Coastguard Worker attributes.colormap = colormap;
389*8975f5c5SAndroid Build Coastguard Worker
390*8975f5c5SAndroid Build Coastguard Worker mWindow = XCreateWindow(mDisplay, root, 0, 0, width, height, 0, depth, InputOutput, visual,
391*8975f5c5SAndroid Build Coastguard Worker attributeMask, &attributes);
392*8975f5c5SAndroid Build Coastguard Worker XFreeColormap(mDisplay, colormap);
393*8975f5c5SAndroid Build Coastguard Worker }
394*8975f5c5SAndroid Build Coastguard Worker
395*8975f5c5SAndroid Build Coastguard Worker if (!mWindow)
396*8975f5c5SAndroid Build Coastguard Worker {
397*8975f5c5SAndroid Build Coastguard Worker destroy();
398*8975f5c5SAndroid Build Coastguard Worker return false;
399*8975f5c5SAndroid Build Coastguard Worker }
400*8975f5c5SAndroid Build Coastguard Worker
401*8975f5c5SAndroid Build Coastguard Worker // Tell the window manager to notify us when the user wants to close the
402*8975f5c5SAndroid Build Coastguard Worker // window so we can do it ourselves.
403*8975f5c5SAndroid Build Coastguard Worker WM_DELETE_WINDOW = XInternAtom(mDisplay, "WM_DELETE_WINDOW", False);
404*8975f5c5SAndroid Build Coastguard Worker WM_PROTOCOLS = XInternAtom(mDisplay, "WM_PROTOCOLS", False);
405*8975f5c5SAndroid Build Coastguard Worker if (WM_DELETE_WINDOW == None || WM_PROTOCOLS == None)
406*8975f5c5SAndroid Build Coastguard Worker {
407*8975f5c5SAndroid Build Coastguard Worker destroy();
408*8975f5c5SAndroid Build Coastguard Worker return false;
409*8975f5c5SAndroid Build Coastguard Worker }
410*8975f5c5SAndroid Build Coastguard Worker
411*8975f5c5SAndroid Build Coastguard Worker if (XSetWMProtocols(mDisplay, mWindow, &WM_DELETE_WINDOW, 1) == 0)
412*8975f5c5SAndroid Build Coastguard Worker {
413*8975f5c5SAndroid Build Coastguard Worker destroy();
414*8975f5c5SAndroid Build Coastguard Worker return false;
415*8975f5c5SAndroid Build Coastguard Worker }
416*8975f5c5SAndroid Build Coastguard Worker
417*8975f5c5SAndroid Build Coastguard Worker // Create an atom to identify our test event
418*8975f5c5SAndroid Build Coastguard Worker TEST_EVENT = XInternAtom(mDisplay, "ANGLE_TEST_EVENT", False);
419*8975f5c5SAndroid Build Coastguard Worker if (TEST_EVENT == None)
420*8975f5c5SAndroid Build Coastguard Worker {
421*8975f5c5SAndroid Build Coastguard Worker destroy();
422*8975f5c5SAndroid Build Coastguard Worker return false;
423*8975f5c5SAndroid Build Coastguard Worker }
424*8975f5c5SAndroid Build Coastguard Worker
425*8975f5c5SAndroid Build Coastguard Worker setWindowSizeHints(mDisplay, mWindow, width, height);
426*8975f5c5SAndroid Build Coastguard Worker
427*8975f5c5SAndroid Build Coastguard Worker XFlush(mDisplay);
428*8975f5c5SAndroid Build Coastguard Worker
429*8975f5c5SAndroid Build Coastguard Worker mX = 0;
430*8975f5c5SAndroid Build Coastguard Worker mY = 0;
431*8975f5c5SAndroid Build Coastguard Worker mWidth = width;
432*8975f5c5SAndroid Build Coastguard Worker mHeight = height;
433*8975f5c5SAndroid Build Coastguard Worker
434*8975f5c5SAndroid Build Coastguard Worker return true;
435*8975f5c5SAndroid Build Coastguard Worker }
436*8975f5c5SAndroid Build Coastguard Worker
disableErrorMessageDialog()437*8975f5c5SAndroid Build Coastguard Worker void X11Window::disableErrorMessageDialog() {}
438*8975f5c5SAndroid Build Coastguard Worker
destroy()439*8975f5c5SAndroid Build Coastguard Worker void X11Window::destroy()
440*8975f5c5SAndroid Build Coastguard Worker {
441*8975f5c5SAndroid Build Coastguard Worker if (mWindow)
442*8975f5c5SAndroid Build Coastguard Worker {
443*8975f5c5SAndroid Build Coastguard Worker XDestroyWindow(mDisplay, mWindow);
444*8975f5c5SAndroid Build Coastguard Worker XFlush(mDisplay);
445*8975f5c5SAndroid Build Coastguard Worker // There appears to be a race condition where XDestroyWindow+XCreateWindow ignores
446*8975f5c5SAndroid Build Coastguard Worker // the new size (the same window normally gets reused but this only happens sometimes on
447*8975f5c5SAndroid Build Coastguard Worker // some X11 versions). Wait until we get the destroy notification.
448*8975f5c5SAndroid Build Coastguard Worker mWindow = 0; // Set before messageLoop() to avoid a race in processEvent().
449*8975f5c5SAndroid Build Coastguard Worker while (!mDestroyed)
450*8975f5c5SAndroid Build Coastguard Worker {
451*8975f5c5SAndroid Build Coastguard Worker messageLoop();
452*8975f5c5SAndroid Build Coastguard Worker angle::Sleep(10);
453*8975f5c5SAndroid Build Coastguard Worker }
454*8975f5c5SAndroid Build Coastguard Worker }
455*8975f5c5SAndroid Build Coastguard Worker if (mDisplay)
456*8975f5c5SAndroid Build Coastguard Worker {
457*8975f5c5SAndroid Build Coastguard Worker XCloseDisplay(mDisplay);
458*8975f5c5SAndroid Build Coastguard Worker mDisplay = nullptr;
459*8975f5c5SAndroid Build Coastguard Worker }
460*8975f5c5SAndroid Build Coastguard Worker WM_DELETE_WINDOW = None;
461*8975f5c5SAndroid Build Coastguard Worker WM_PROTOCOLS = None;
462*8975f5c5SAndroid Build Coastguard Worker }
463*8975f5c5SAndroid Build Coastguard Worker
resetNativeWindow()464*8975f5c5SAndroid Build Coastguard Worker void X11Window::resetNativeWindow() {}
465*8975f5c5SAndroid Build Coastguard Worker
getNativeWindow() const466*8975f5c5SAndroid Build Coastguard Worker EGLNativeWindowType X11Window::getNativeWindow() const
467*8975f5c5SAndroid Build Coastguard Worker {
468*8975f5c5SAndroid Build Coastguard Worker return mWindow;
469*8975f5c5SAndroid Build Coastguard Worker }
470*8975f5c5SAndroid Build Coastguard Worker
getPlatformExtension()471*8975f5c5SAndroid Build Coastguard Worker void *X11Window::getPlatformExtension()
472*8975f5c5SAndroid Build Coastguard Worker {
473*8975f5c5SAndroid Build Coastguard Worker // X11 native window for eglCreateSurfacePlatformEXT is Window*
474*8975f5c5SAndroid Build Coastguard Worker return &mWindow;
475*8975f5c5SAndroid Build Coastguard Worker }
476*8975f5c5SAndroid Build Coastguard Worker
getNativeDisplay() const477*8975f5c5SAndroid Build Coastguard Worker EGLNativeDisplayType X11Window::getNativeDisplay() const
478*8975f5c5SAndroid Build Coastguard Worker {
479*8975f5c5SAndroid Build Coastguard Worker return reinterpret_cast<EGLNativeDisplayType>(mDisplay);
480*8975f5c5SAndroid Build Coastguard Worker }
481*8975f5c5SAndroid Build Coastguard Worker
messageLoop()482*8975f5c5SAndroid Build Coastguard Worker void X11Window::messageLoop()
483*8975f5c5SAndroid Build Coastguard Worker {
484*8975f5c5SAndroid Build Coastguard Worker int eventCount = XPending(mDisplay);
485*8975f5c5SAndroid Build Coastguard Worker while (eventCount--)
486*8975f5c5SAndroid Build Coastguard Worker {
487*8975f5c5SAndroid Build Coastguard Worker XEvent event;
488*8975f5c5SAndroid Build Coastguard Worker XNextEvent(mDisplay, &event);
489*8975f5c5SAndroid Build Coastguard Worker processEvent(event);
490*8975f5c5SAndroid Build Coastguard Worker }
491*8975f5c5SAndroid Build Coastguard Worker }
492*8975f5c5SAndroid Build Coastguard Worker
setMousePosition(int x,int y)493*8975f5c5SAndroid Build Coastguard Worker void X11Window::setMousePosition(int x, int y)
494*8975f5c5SAndroid Build Coastguard Worker {
495*8975f5c5SAndroid Build Coastguard Worker XWarpPointer(mDisplay, None, mWindow, 0, 0, 0, 0, x, y);
496*8975f5c5SAndroid Build Coastguard Worker }
497*8975f5c5SAndroid Build Coastguard Worker
setOrientation(int width,int height)498*8975f5c5SAndroid Build Coastguard Worker bool X11Window::setOrientation(int width, int height)
499*8975f5c5SAndroid Build Coastguard Worker {
500*8975f5c5SAndroid Build Coastguard Worker UNIMPLEMENTED();
501*8975f5c5SAndroid Build Coastguard Worker return false;
502*8975f5c5SAndroid Build Coastguard Worker }
503*8975f5c5SAndroid Build Coastguard Worker
setPosition(int x,int y)504*8975f5c5SAndroid Build Coastguard Worker bool X11Window::setPosition(int x, int y)
505*8975f5c5SAndroid Build Coastguard Worker {
506*8975f5c5SAndroid Build Coastguard Worker XMoveWindow(mDisplay, mWindow, x, y);
507*8975f5c5SAndroid Build Coastguard Worker XFlush(mDisplay);
508*8975f5c5SAndroid Build Coastguard Worker return true;
509*8975f5c5SAndroid Build Coastguard Worker }
510*8975f5c5SAndroid Build Coastguard Worker
resize(int width,int height)511*8975f5c5SAndroid Build Coastguard Worker bool X11Window::resize(int width, int height)
512*8975f5c5SAndroid Build Coastguard Worker {
513*8975f5c5SAndroid Build Coastguard Worker setWindowSizeHints(mDisplay, mWindow, width, height);
514*8975f5c5SAndroid Build Coastguard Worker XResizeWindow(mDisplay, mWindow, width, height);
515*8975f5c5SAndroid Build Coastguard Worker
516*8975f5c5SAndroid Build Coastguard Worker XFlush(mDisplay);
517*8975f5c5SAndroid Build Coastguard Worker
518*8975f5c5SAndroid Build Coastguard Worker Timer timer;
519*8975f5c5SAndroid Build Coastguard Worker timer.start();
520*8975f5c5SAndroid Build Coastguard Worker
521*8975f5c5SAndroid Build Coastguard Worker // Wait until the window has actually been resized so that the code calling resize
522*8975f5c5SAndroid Build Coastguard Worker // can assume the window has been resized.
523*8975f5c5SAndroid Build Coastguard Worker const double kResizeWaitDelay = 0.2;
524*8975f5c5SAndroid Build Coastguard Worker while ((mHeight != height || mWidth != width) &&
525*8975f5c5SAndroid Build Coastguard Worker timer.getElapsedWallClockTime() < kResizeWaitDelay)
526*8975f5c5SAndroid Build Coastguard Worker {
527*8975f5c5SAndroid Build Coastguard Worker messageLoop();
528*8975f5c5SAndroid Build Coastguard Worker angle::Sleep(10);
529*8975f5c5SAndroid Build Coastguard Worker }
530*8975f5c5SAndroid Build Coastguard Worker
531*8975f5c5SAndroid Build Coastguard Worker return true;
532*8975f5c5SAndroid Build Coastguard Worker }
533*8975f5c5SAndroid Build Coastguard Worker
setVisible(bool isVisible)534*8975f5c5SAndroid Build Coastguard Worker void X11Window::setVisible(bool isVisible)
535*8975f5c5SAndroid Build Coastguard Worker {
536*8975f5c5SAndroid Build Coastguard Worker if (mVisible == isVisible)
537*8975f5c5SAndroid Build Coastguard Worker {
538*8975f5c5SAndroid Build Coastguard Worker return;
539*8975f5c5SAndroid Build Coastguard Worker }
540*8975f5c5SAndroid Build Coastguard Worker
541*8975f5c5SAndroid Build Coastguard Worker if (isVisible)
542*8975f5c5SAndroid Build Coastguard Worker {
543*8975f5c5SAndroid Build Coastguard Worker XMapWindow(mDisplay, mWindow);
544*8975f5c5SAndroid Build Coastguard Worker
545*8975f5c5SAndroid Build Coastguard Worker // Wait until we get an event saying this window is mapped so that the
546*8975f5c5SAndroid Build Coastguard Worker // code calling setVisible can assume the window is visible.
547*8975f5c5SAndroid Build Coastguard Worker // This is important when creating a framebuffer as the framebuffer content
548*8975f5c5SAndroid Build Coastguard Worker // is undefined when the window is not visible.
549*8975f5c5SAndroid Build Coastguard Worker XEvent placeholderEvent;
550*8975f5c5SAndroid Build Coastguard Worker XIfEvent(mDisplay, &placeholderEvent, WaitForMapNotify,
551*8975f5c5SAndroid Build Coastguard Worker reinterpret_cast<XPointer>(mWindow));
552*8975f5c5SAndroid Build Coastguard Worker }
553*8975f5c5SAndroid Build Coastguard Worker else
554*8975f5c5SAndroid Build Coastguard Worker {
555*8975f5c5SAndroid Build Coastguard Worker XUnmapWindow(mDisplay, mWindow);
556*8975f5c5SAndroid Build Coastguard Worker XFlush(mDisplay);
557*8975f5c5SAndroid Build Coastguard Worker }
558*8975f5c5SAndroid Build Coastguard Worker
559*8975f5c5SAndroid Build Coastguard Worker // Block until we get ConfigureNotify to set up fully before returning.
560*8975f5c5SAndroid Build Coastguard Worker mConfigured = false;
561*8975f5c5SAndroid Build Coastguard Worker while (!mConfigured)
562*8975f5c5SAndroid Build Coastguard Worker {
563*8975f5c5SAndroid Build Coastguard Worker messageLoop();
564*8975f5c5SAndroid Build Coastguard Worker angle::Sleep(10);
565*8975f5c5SAndroid Build Coastguard Worker }
566*8975f5c5SAndroid Build Coastguard Worker
567*8975f5c5SAndroid Build Coastguard Worker mVisible = isVisible;
568*8975f5c5SAndroid Build Coastguard Worker }
569*8975f5c5SAndroid Build Coastguard Worker
signalTestEvent()570*8975f5c5SAndroid Build Coastguard Worker void X11Window::signalTestEvent()
571*8975f5c5SAndroid Build Coastguard Worker {
572*8975f5c5SAndroid Build Coastguard Worker XEvent event;
573*8975f5c5SAndroid Build Coastguard Worker event.type = ClientMessage;
574*8975f5c5SAndroid Build Coastguard Worker event.xclient.message_type = TEST_EVENT;
575*8975f5c5SAndroid Build Coastguard Worker // Format needs to be valid or a BadValue is generated
576*8975f5c5SAndroid Build Coastguard Worker event.xclient.format = 32;
577*8975f5c5SAndroid Build Coastguard Worker
578*8975f5c5SAndroid Build Coastguard Worker // Hijack StructureNotifyMask as we know we will be listening for it.
579*8975f5c5SAndroid Build Coastguard Worker XSendEvent(mDisplay, mWindow, False, StructureNotifyMask, &event);
580*8975f5c5SAndroid Build Coastguard Worker
581*8975f5c5SAndroid Build Coastguard Worker // For test events, the tests want to check that it really did arrive, and they don't wait
582*8975f5c5SAndroid Build Coastguard Worker // long. XSync here makes sure the event is sent by the time the messageLoop() is called.
583*8975f5c5SAndroid Build Coastguard Worker XSync(mDisplay, false);
584*8975f5c5SAndroid Build Coastguard Worker }
585*8975f5c5SAndroid Build Coastguard Worker
processEvent(const XEvent & xEvent)586*8975f5c5SAndroid Build Coastguard Worker void X11Window::processEvent(const XEvent &xEvent)
587*8975f5c5SAndroid Build Coastguard Worker {
588*8975f5c5SAndroid Build Coastguard Worker // TODO(cwallez) text events
589*8975f5c5SAndroid Build Coastguard Worker switch (xEvent.type)
590*8975f5c5SAndroid Build Coastguard Worker {
591*8975f5c5SAndroid Build Coastguard Worker case ButtonPress:
592*8975f5c5SAndroid Build Coastguard Worker {
593*8975f5c5SAndroid Build Coastguard Worker Event event;
594*8975f5c5SAndroid Build Coastguard Worker MouseButton button = MOUSEBUTTON_UNKNOWN;
595*8975f5c5SAndroid Build Coastguard Worker int wheelY = 0;
596*8975f5c5SAndroid Build Coastguard Worker
597*8975f5c5SAndroid Build Coastguard Worker // The mouse wheel updates are sent via button events.
598*8975f5c5SAndroid Build Coastguard Worker switch (xEvent.xbutton.button)
599*8975f5c5SAndroid Build Coastguard Worker {
600*8975f5c5SAndroid Build Coastguard Worker case Button4:
601*8975f5c5SAndroid Build Coastguard Worker wheelY = 1;
602*8975f5c5SAndroid Build Coastguard Worker break;
603*8975f5c5SAndroid Build Coastguard Worker case Button5:
604*8975f5c5SAndroid Build Coastguard Worker wheelY = -1;
605*8975f5c5SAndroid Build Coastguard Worker break;
606*8975f5c5SAndroid Build Coastguard Worker case 6:
607*8975f5c5SAndroid Build Coastguard Worker break;
608*8975f5c5SAndroid Build Coastguard Worker case 7:
609*8975f5c5SAndroid Build Coastguard Worker break;
610*8975f5c5SAndroid Build Coastguard Worker
611*8975f5c5SAndroid Build Coastguard Worker case Button1:
612*8975f5c5SAndroid Build Coastguard Worker button = MOUSEBUTTON_LEFT;
613*8975f5c5SAndroid Build Coastguard Worker break;
614*8975f5c5SAndroid Build Coastguard Worker case Button2:
615*8975f5c5SAndroid Build Coastguard Worker button = MOUSEBUTTON_MIDDLE;
616*8975f5c5SAndroid Build Coastguard Worker break;
617*8975f5c5SAndroid Build Coastguard Worker case Button3:
618*8975f5c5SAndroid Build Coastguard Worker button = MOUSEBUTTON_RIGHT;
619*8975f5c5SAndroid Build Coastguard Worker break;
620*8975f5c5SAndroid Build Coastguard Worker case 8:
621*8975f5c5SAndroid Build Coastguard Worker button = MOUSEBUTTON_BUTTON4;
622*8975f5c5SAndroid Build Coastguard Worker break;
623*8975f5c5SAndroid Build Coastguard Worker case 9:
624*8975f5c5SAndroid Build Coastguard Worker button = MOUSEBUTTON_BUTTON5;
625*8975f5c5SAndroid Build Coastguard Worker break;
626*8975f5c5SAndroid Build Coastguard Worker
627*8975f5c5SAndroid Build Coastguard Worker default:
628*8975f5c5SAndroid Build Coastguard Worker break;
629*8975f5c5SAndroid Build Coastguard Worker }
630*8975f5c5SAndroid Build Coastguard Worker
631*8975f5c5SAndroid Build Coastguard Worker if (wheelY != 0)
632*8975f5c5SAndroid Build Coastguard Worker {
633*8975f5c5SAndroid Build Coastguard Worker event.Type = Event::EVENT_MOUSE_WHEEL_MOVED;
634*8975f5c5SAndroid Build Coastguard Worker event.MouseWheel.Delta = wheelY;
635*8975f5c5SAndroid Build Coastguard Worker pushEvent(event);
636*8975f5c5SAndroid Build Coastguard Worker }
637*8975f5c5SAndroid Build Coastguard Worker
638*8975f5c5SAndroid Build Coastguard Worker if (button != MOUSEBUTTON_UNKNOWN)
639*8975f5c5SAndroid Build Coastguard Worker {
640*8975f5c5SAndroid Build Coastguard Worker event.Type = Event::EVENT_MOUSE_BUTTON_RELEASED;
641*8975f5c5SAndroid Build Coastguard Worker event.MouseButton.Button = button;
642*8975f5c5SAndroid Build Coastguard Worker event.MouseButton.X = xEvent.xbutton.x;
643*8975f5c5SAndroid Build Coastguard Worker event.MouseButton.Y = xEvent.xbutton.y;
644*8975f5c5SAndroid Build Coastguard Worker pushEvent(event);
645*8975f5c5SAndroid Build Coastguard Worker }
646*8975f5c5SAndroid Build Coastguard Worker }
647*8975f5c5SAndroid Build Coastguard Worker break;
648*8975f5c5SAndroid Build Coastguard Worker
649*8975f5c5SAndroid Build Coastguard Worker case ButtonRelease:
650*8975f5c5SAndroid Build Coastguard Worker {
651*8975f5c5SAndroid Build Coastguard Worker Event event;
652*8975f5c5SAndroid Build Coastguard Worker MouseButton button = MOUSEBUTTON_UNKNOWN;
653*8975f5c5SAndroid Build Coastguard Worker
654*8975f5c5SAndroid Build Coastguard Worker switch (xEvent.xbutton.button)
655*8975f5c5SAndroid Build Coastguard Worker {
656*8975f5c5SAndroid Build Coastguard Worker case Button1:
657*8975f5c5SAndroid Build Coastguard Worker button = MOUSEBUTTON_LEFT;
658*8975f5c5SAndroid Build Coastguard Worker break;
659*8975f5c5SAndroid Build Coastguard Worker case Button2:
660*8975f5c5SAndroid Build Coastguard Worker button = MOUSEBUTTON_MIDDLE;
661*8975f5c5SAndroid Build Coastguard Worker break;
662*8975f5c5SAndroid Build Coastguard Worker case Button3:
663*8975f5c5SAndroid Build Coastguard Worker button = MOUSEBUTTON_RIGHT;
664*8975f5c5SAndroid Build Coastguard Worker break;
665*8975f5c5SAndroid Build Coastguard Worker case 8:
666*8975f5c5SAndroid Build Coastguard Worker button = MOUSEBUTTON_BUTTON4;
667*8975f5c5SAndroid Build Coastguard Worker break;
668*8975f5c5SAndroid Build Coastguard Worker case 9:
669*8975f5c5SAndroid Build Coastguard Worker button = MOUSEBUTTON_BUTTON5;
670*8975f5c5SAndroid Build Coastguard Worker break;
671*8975f5c5SAndroid Build Coastguard Worker
672*8975f5c5SAndroid Build Coastguard Worker default:
673*8975f5c5SAndroid Build Coastguard Worker break;
674*8975f5c5SAndroid Build Coastguard Worker }
675*8975f5c5SAndroid Build Coastguard Worker
676*8975f5c5SAndroid Build Coastguard Worker if (button != MOUSEBUTTON_UNKNOWN)
677*8975f5c5SAndroid Build Coastguard Worker {
678*8975f5c5SAndroid Build Coastguard Worker event.Type = Event::EVENT_MOUSE_BUTTON_RELEASED;
679*8975f5c5SAndroid Build Coastguard Worker event.MouseButton.Button = button;
680*8975f5c5SAndroid Build Coastguard Worker event.MouseButton.X = xEvent.xbutton.x;
681*8975f5c5SAndroid Build Coastguard Worker event.MouseButton.Y = xEvent.xbutton.y;
682*8975f5c5SAndroid Build Coastguard Worker pushEvent(event);
683*8975f5c5SAndroid Build Coastguard Worker }
684*8975f5c5SAndroid Build Coastguard Worker }
685*8975f5c5SAndroid Build Coastguard Worker break;
686*8975f5c5SAndroid Build Coastguard Worker
687*8975f5c5SAndroid Build Coastguard Worker case KeyPress:
688*8975f5c5SAndroid Build Coastguard Worker {
689*8975f5c5SAndroid Build Coastguard Worker Event event;
690*8975f5c5SAndroid Build Coastguard Worker event.Type = Event::EVENT_KEY_PRESSED;
691*8975f5c5SAndroid Build Coastguard Worker event.Key.Code = X11CodeToKey(mDisplay, xEvent.xkey.keycode);
692*8975f5c5SAndroid Build Coastguard Worker AddX11KeyStateToEvent(&event, xEvent.xkey.state);
693*8975f5c5SAndroid Build Coastguard Worker pushEvent(event);
694*8975f5c5SAndroid Build Coastguard Worker }
695*8975f5c5SAndroid Build Coastguard Worker break;
696*8975f5c5SAndroid Build Coastguard Worker
697*8975f5c5SAndroid Build Coastguard Worker case KeyRelease:
698*8975f5c5SAndroid Build Coastguard Worker {
699*8975f5c5SAndroid Build Coastguard Worker Event event;
700*8975f5c5SAndroid Build Coastguard Worker event.Type = Event::EVENT_KEY_RELEASED;
701*8975f5c5SAndroid Build Coastguard Worker event.Key.Code = X11CodeToKey(mDisplay, xEvent.xkey.keycode);
702*8975f5c5SAndroid Build Coastguard Worker AddX11KeyStateToEvent(&event, xEvent.xkey.state);
703*8975f5c5SAndroid Build Coastguard Worker pushEvent(event);
704*8975f5c5SAndroid Build Coastguard Worker }
705*8975f5c5SAndroid Build Coastguard Worker break;
706*8975f5c5SAndroid Build Coastguard Worker
707*8975f5c5SAndroid Build Coastguard Worker case EnterNotify:
708*8975f5c5SAndroid Build Coastguard Worker {
709*8975f5c5SAndroid Build Coastguard Worker Event event;
710*8975f5c5SAndroid Build Coastguard Worker event.Type = Event::EVENT_MOUSE_ENTERED;
711*8975f5c5SAndroid Build Coastguard Worker pushEvent(event);
712*8975f5c5SAndroid Build Coastguard Worker }
713*8975f5c5SAndroid Build Coastguard Worker break;
714*8975f5c5SAndroid Build Coastguard Worker
715*8975f5c5SAndroid Build Coastguard Worker case LeaveNotify:
716*8975f5c5SAndroid Build Coastguard Worker {
717*8975f5c5SAndroid Build Coastguard Worker Event event;
718*8975f5c5SAndroid Build Coastguard Worker event.Type = Event::EVENT_MOUSE_LEFT;
719*8975f5c5SAndroid Build Coastguard Worker pushEvent(event);
720*8975f5c5SAndroid Build Coastguard Worker }
721*8975f5c5SAndroid Build Coastguard Worker break;
722*8975f5c5SAndroid Build Coastguard Worker
723*8975f5c5SAndroid Build Coastguard Worker case MotionNotify:
724*8975f5c5SAndroid Build Coastguard Worker {
725*8975f5c5SAndroid Build Coastguard Worker Event event;
726*8975f5c5SAndroid Build Coastguard Worker event.Type = Event::EVENT_MOUSE_MOVED;
727*8975f5c5SAndroid Build Coastguard Worker event.MouseMove.X = xEvent.xmotion.x;
728*8975f5c5SAndroid Build Coastguard Worker event.MouseMove.Y = xEvent.xmotion.y;
729*8975f5c5SAndroid Build Coastguard Worker pushEvent(event);
730*8975f5c5SAndroid Build Coastguard Worker }
731*8975f5c5SAndroid Build Coastguard Worker break;
732*8975f5c5SAndroid Build Coastguard Worker
733*8975f5c5SAndroid Build Coastguard Worker case ConfigureNotify:
734*8975f5c5SAndroid Build Coastguard Worker {
735*8975f5c5SAndroid Build Coastguard Worker mConfigured = true;
736*8975f5c5SAndroid Build Coastguard Worker if (mWindow == 0)
737*8975f5c5SAndroid Build Coastguard Worker {
738*8975f5c5SAndroid Build Coastguard Worker break;
739*8975f5c5SAndroid Build Coastguard Worker }
740*8975f5c5SAndroid Build Coastguard Worker if (xEvent.xconfigure.width != mWidth || xEvent.xconfigure.height != mHeight)
741*8975f5c5SAndroid Build Coastguard Worker {
742*8975f5c5SAndroid Build Coastguard Worker Event event;
743*8975f5c5SAndroid Build Coastguard Worker event.Type = Event::EVENT_RESIZED;
744*8975f5c5SAndroid Build Coastguard Worker event.Size.Width = xEvent.xconfigure.width;
745*8975f5c5SAndroid Build Coastguard Worker event.Size.Height = xEvent.xconfigure.height;
746*8975f5c5SAndroid Build Coastguard Worker pushEvent(event);
747*8975f5c5SAndroid Build Coastguard Worker }
748*8975f5c5SAndroid Build Coastguard Worker if (xEvent.xconfigure.x != mX || xEvent.xconfigure.y != mY)
749*8975f5c5SAndroid Build Coastguard Worker {
750*8975f5c5SAndroid Build Coastguard Worker // Sometimes, the window manager reparents our window (for example
751*8975f5c5SAndroid Build Coastguard Worker // when resizing) then the X and Y coordinates will be with respect to
752*8975f5c5SAndroid Build Coastguard Worker // the new parent and not what the user wants to know. Use
753*8975f5c5SAndroid Build Coastguard Worker // XTranslateCoordinates to get the coordinates on the screen.
754*8975f5c5SAndroid Build Coastguard Worker int screen = DefaultScreen(mDisplay);
755*8975f5c5SAndroid Build Coastguard Worker Window root = RootWindow(mDisplay, screen);
756*8975f5c5SAndroid Build Coastguard Worker
757*8975f5c5SAndroid Build Coastguard Worker int x, y;
758*8975f5c5SAndroid Build Coastguard Worker Window child;
759*8975f5c5SAndroid Build Coastguard Worker XTranslateCoordinates(mDisplay, mWindow, root, 0, 0, &x, &y, &child);
760*8975f5c5SAndroid Build Coastguard Worker
761*8975f5c5SAndroid Build Coastguard Worker if (x != mX || y != mY)
762*8975f5c5SAndroid Build Coastguard Worker {
763*8975f5c5SAndroid Build Coastguard Worker Event event;
764*8975f5c5SAndroid Build Coastguard Worker event.Type = Event::EVENT_MOVED;
765*8975f5c5SAndroid Build Coastguard Worker event.Move.X = x;
766*8975f5c5SAndroid Build Coastguard Worker event.Move.Y = y;
767*8975f5c5SAndroid Build Coastguard Worker pushEvent(event);
768*8975f5c5SAndroid Build Coastguard Worker }
769*8975f5c5SAndroid Build Coastguard Worker }
770*8975f5c5SAndroid Build Coastguard Worker }
771*8975f5c5SAndroid Build Coastguard Worker break;
772*8975f5c5SAndroid Build Coastguard Worker
773*8975f5c5SAndroid Build Coastguard Worker case FocusIn:
774*8975f5c5SAndroid Build Coastguard Worker if (xEvent.xfocus.mode == NotifyNormal || xEvent.xfocus.mode == NotifyWhileGrabbed)
775*8975f5c5SAndroid Build Coastguard Worker {
776*8975f5c5SAndroid Build Coastguard Worker Event event;
777*8975f5c5SAndroid Build Coastguard Worker event.Type = Event::EVENT_GAINED_FOCUS;
778*8975f5c5SAndroid Build Coastguard Worker pushEvent(event);
779*8975f5c5SAndroid Build Coastguard Worker }
780*8975f5c5SAndroid Build Coastguard Worker break;
781*8975f5c5SAndroid Build Coastguard Worker
782*8975f5c5SAndroid Build Coastguard Worker case FocusOut:
783*8975f5c5SAndroid Build Coastguard Worker if (xEvent.xfocus.mode == NotifyNormal || xEvent.xfocus.mode == NotifyWhileGrabbed)
784*8975f5c5SAndroid Build Coastguard Worker {
785*8975f5c5SAndroid Build Coastguard Worker Event event;
786*8975f5c5SAndroid Build Coastguard Worker event.Type = Event::EVENT_LOST_FOCUS;
787*8975f5c5SAndroid Build Coastguard Worker pushEvent(event);
788*8975f5c5SAndroid Build Coastguard Worker }
789*8975f5c5SAndroid Build Coastguard Worker break;
790*8975f5c5SAndroid Build Coastguard Worker
791*8975f5c5SAndroid Build Coastguard Worker case DestroyNotify:
792*8975f5c5SAndroid Build Coastguard Worker // Note: we already received WM_DELETE_WINDOW
793*8975f5c5SAndroid Build Coastguard Worker mDestroyed = true;
794*8975f5c5SAndroid Build Coastguard Worker break;
795*8975f5c5SAndroid Build Coastguard Worker
796*8975f5c5SAndroid Build Coastguard Worker case ClientMessage:
797*8975f5c5SAndroid Build Coastguard Worker if (xEvent.xclient.message_type == WM_PROTOCOLS &&
798*8975f5c5SAndroid Build Coastguard Worker static_cast<Atom>(xEvent.xclient.data.l[0]) == WM_DELETE_WINDOW)
799*8975f5c5SAndroid Build Coastguard Worker {
800*8975f5c5SAndroid Build Coastguard Worker Event event;
801*8975f5c5SAndroid Build Coastguard Worker event.Type = Event::EVENT_CLOSED;
802*8975f5c5SAndroid Build Coastguard Worker pushEvent(event);
803*8975f5c5SAndroid Build Coastguard Worker }
804*8975f5c5SAndroid Build Coastguard Worker else if (xEvent.xclient.message_type == TEST_EVENT)
805*8975f5c5SAndroid Build Coastguard Worker {
806*8975f5c5SAndroid Build Coastguard Worker Event event;
807*8975f5c5SAndroid Build Coastguard Worker event.Type = Event::EVENT_TEST;
808*8975f5c5SAndroid Build Coastguard Worker pushEvent(event);
809*8975f5c5SAndroid Build Coastguard Worker }
810*8975f5c5SAndroid Build Coastguard Worker break;
811*8975f5c5SAndroid Build Coastguard Worker }
812*8975f5c5SAndroid Build Coastguard Worker }
813*8975f5c5SAndroid Build Coastguard Worker
CreateX11Window()814*8975f5c5SAndroid Build Coastguard Worker OSWindow *CreateX11Window()
815*8975f5c5SAndroid Build Coastguard Worker {
816*8975f5c5SAndroid Build Coastguard Worker return new X11Window();
817*8975f5c5SAndroid Build Coastguard Worker }
818*8975f5c5SAndroid Build Coastguard Worker
CreateX11WindowWithVisualId(int visualId)819*8975f5c5SAndroid Build Coastguard Worker OSWindow *CreateX11WindowWithVisualId(int visualId)
820*8975f5c5SAndroid Build Coastguard Worker {
821*8975f5c5SAndroid Build Coastguard Worker return new X11Window(visualId);
822*8975f5c5SAndroid Build Coastguard Worker }
823*8975f5c5SAndroid Build Coastguard Worker
IsX11WindowAvailable()824*8975f5c5SAndroid Build Coastguard Worker bool IsX11WindowAvailable()
825*8975f5c5SAndroid Build Coastguard Worker {
826*8975f5c5SAndroid Build Coastguard Worker Display *display = XOpenDisplay(nullptr);
827*8975f5c5SAndroid Build Coastguard Worker if (!display)
828*8975f5c5SAndroid Build Coastguard Worker {
829*8975f5c5SAndroid Build Coastguard Worker return false;
830*8975f5c5SAndroid Build Coastguard Worker }
831*8975f5c5SAndroid Build Coastguard Worker XCloseDisplay(display);
832*8975f5c5SAndroid Build Coastguard Worker return true;
833*8975f5c5SAndroid Build Coastguard Worker }
834