1 //
2 // Copyright (c) 2010-2018 Antmicro
3 // Copyright (c) 2011-2015 Realtime Embedded
4 //
5 // This file is licensed under the MIT License.
6 // Full license text is available in 'licenses/MIT.txt'.
7 //
8 using System;
9 using Xwt;
10 using Antmicro.Renode.Logging;
11 using Antmicro.Renode.Backends.Display.XInput;
12 using Antmicro.Renode.Extensions.Analyzers.Video.Handlers;
13 
14 namespace Antmicro.Renode.Extensions.Analyzers.Video.Events
15 {
16     internal class X11EventSource : IEventSource, IInputHandler
17     {
X11EventSource(FrameBufferDisplayWidget source)18         public X11EventSource(FrameBufferDisplayWidget source)
19         {
20             this.source = source;
21         }
22 
AttachHandler(IOHandler h)23         public void AttachHandler(IOHandler h)
24         {
25             handler = h;
26 
27             if(!XLibHelper.IsAvailable)
28             {
29                 MessageDialog.ShowError("libX11 library not found");
30                 return;
31             }
32 
33             int pid;
34             try
35             {
36                 pid = source.ParentWindow.Id;
37             }
38             catch(DllNotFoundException)
39             {
40                 MessageDialog.ShowError("gdk x11 library not found");
41                 return;
42             }
43 
44             XLibHelper.GrabCursorByWindow(pid);
45             XLibHelper.MoveCursorAbsolute(pid, (int)(source.ParentWindow.Size.Width / 2), (int)(source.ParentWindow.Size.Height / 2));
46 
47             XLibHelper.StartEventListenerLoop(this);
48         }
49 
DetachHandler()50         public void DetachHandler()
51         {
52             Stop = true;
53             XLibHelper.UngrabCursor();
54 
55             handler = null;
56         }
57 
ButtonPressed(int button)58         public void ButtonPressed(int button)
59         {
60             handler.ButtonPressed((PointerButton)button);
61         }
62 
ButtonReleased(int button)63         public void ButtonReleased(int button)
64         {
65             handler.ButtonReleased((PointerButton)button);
66         }
67 
KeyPressed(int keyCode)68         public void KeyPressed(int keyCode)
69         {
70             var key = X11ToKeyScanCodeConverter.Instance.GetScanCode(keyCode);
71             if(key != null)
72             {
73                 handler.KeyPressed(key.Value);
74                 return;
75             }
76 
77             Logger.LogAs(this, LogLevel.Warning, "Unhandled keycode: {0}", keyCode);
78         }
79 
KeyReleased(int keyCode)80         public void KeyReleased(int keyCode)
81         {
82             var key = X11ToKeyScanCodeConverter.Instance.GetScanCode(keyCode);
83             if(key != null)
84             {
85                 handler.KeyReleased(key.Value);
86                 return;
87             }
88 
89             Logger.LogAs(this, LogLevel.Warning, "Unhandled keycode: {0}", keyCode);
90         }
91 
MouseMoved(int x, int y, int dx, int dy)92         public void MouseMoved(int x, int y, int dx, int dy)
93         {
94             var image = source.Image;
95             if(image == null)
96             {
97                 return;
98             }
99 
100             if(lastX == null || lastY == null)
101             {
102                 lastX = x;
103                 lastY = y;
104                 return;
105             }
106 
107             dx = Math.Max(-20, dx);
108             dx = Math.Min(20, dx);
109 
110             dy = Math.Max(-20, dy);
111             dy = Math.Min(20, dy);
112 
113             var newx = (int)Math.Min(Math.Max(0, lastX.Value + dx), image.Width);
114             var newy = (int)Math.Min(Math.Max(0, lastY.Value + dy), image.Height);
115 
116             if(newx != lastX || newy != lastY)
117             {
118                 handler.MouseMoved(newx, newy, dx, dy);
119 
120                 lastX = newx;
121                 lastY = newy;
122             }
123         }
124 
125         public bool Stop { get; set; }
126 
127         public bool CursorFixed { get { return true; } }
128 
129         private FrameBufferDisplayWidget source;
130         private IOHandler handler;
131 
132         private int? lastX;
133         private int? lastY;
134 
135         public int X { get { return lastX ?? 0; } }
136         public int Y { get { return lastY ?? 0; } }
137 
138     }
139 }
140 
141