Progress on the Windows driver

This commit is contained in:
Miguel de Icaza
2018-02-14 22:27:10 -05:00
parent 715c385d82
commit 4d1668549f
2 changed files with 124 additions and 27 deletions

View File

@@ -257,7 +257,7 @@ namespace Terminal.Gui {
/// </summary>
/// <param name="str">String.</param>
public abstract void AddStr (ustring str);
public abstract void PrepareToRun (MainLoop mainLoop, Action<KeyEvent> target, Action<MouseEvent> mouse);
public abstract void PrepareToRun (MainLoop mainLoop, Action<KeyEvent> keyHandler, Action<MouseEvent> mouseHandler);
/// <summary>
/// Updates the screen to reflect all the changes that have been done to the display buffer
@@ -996,8 +996,67 @@ namespace Terminal.Gui {
currentAttribute = c.value;
}
public override void PrepareToRun (MainLoop mainLoop, Action<KeyEvent> target, Action<MouseEvent> mouse)
Key MapKey (ConsoleKeyInfo keyInfo)
{
var key = keyInfo.Key;
if (key >= ConsoleKey.A && key <= ConsoleKey.Z){
var delta = key - ConsoleKey.A;
if (keyInfo.Modifiers == ConsoleModifiers.Control)
return (Key)((uint)Key.ControlA + delta);
if (keyInfo.Modifiers == ConsoleModifiers.Alt)
return (Key) (((uint)Key.AltMask) | ((uint)'A' + delta));
if (keyInfo.Modifiers == ConsoleModifiers.Shift)
return (Key)((uint)'A' + delta);
else
return (Key)((uint)'a' + delta);
}
if (key >= ConsoleKey.F1 && key <= ConsoleKey.F10) {
var delta = key - ConsoleKey.F1;
return (Key)(ConsoleKey.F1 + delta);
}
switch (keyInfo.Key){
case ConsoleKey.Tab:
return Key.ControlT;
case ConsoleKey.Escape:
return Key.Esc;
case ConsoleKey.Home:
return Key.Home;
case ConsoleKey.End:
return Key.End;
case ConsoleKey.LeftArrow:
return Key.CursorLeft;
case ConsoleKey.RightArrow:
return Key.CursorRight;
case ConsoleKey.UpArrow:
return Key.CursorUp;
case ConsoleKey.DownArrow:
return Key.CursorDown;
case ConsoleKey.PageUp:
return Key.PageUp;
case ConsoleKey.PageDown:
return Key.PageDown;
case ConsoleKey.Enter:
return Key.Enter;
case ConsoleKey.Spacebar:
return Key.Space;
case ConsoleKey.Backspace:
return Key.Backspace;
case ConsoleKey.Delete:
return Key.Delete;
}
return (Key)(0xffffffff);
}
public override void PrepareToRun (MainLoop mainLoop, Action<KeyEvent> keyHandler, Action<MouseEvent> mouseHandler)
{
mainLoop.WindowsKeyPressed = delegate (ConsoleKeyInfo consoleKey) {
var map = MapKey (consoleKey);
if (map == (Key) 0xffffffff)
return;
keyHandler (new KeyEvent (map));
};
}
public override void SetColors (ConsoleColor foreground, ConsoleColor background)

View File

@@ -28,6 +28,7 @@
using System.Collections.Generic;
using System;
using System.Runtime.InteropServices;
using System.Threading;
namespace Mono.Terminal {
@@ -36,6 +37,8 @@ namespace Mono.Terminal {
/// file descriptor, run timers and idle handlers.
/// </summary>
public class MainLoop {
static bool useUnix = true;
/// <summary>
/// Condition on which to wake up from file descriptor activity. These match the Linux/BSD poll definitions.
/// </summary>
@@ -168,13 +171,20 @@ namespace Mono.Terminal {
{
if (callback == null)
throw new ArgumentNullException ("callback");
if (!useUnix)
throw new Exception ("AddWatch is only supported for Unix");
var watch = new Watch () { Condition = condition, Callback = callback, File = fileDescriptor };
descriptorWatchers [fileDescriptor] = watch;
poll_dirty = true;
return watch;
}
/// <summary>
/// This event is raised when a key is pressed when using the Windows driver.
/// </summary>
public Action<ConsoleKeyInfo> WindowsKeyPressed;
/// <summary>
/// Removes an active watch from the mainloop.
/// </summary>
@@ -287,6 +297,18 @@ namespace Mono.Terminal {
Wakeup ();
}
AutoResetEvent keyReady = new AutoResetEvent (false);
AutoResetEvent waitForProbe = new AutoResetEvent (false);
ConsoleKeyInfo? windowsKeyResult = null;
void WindowsKeyReader ()
{
while (true) {
waitForProbe.WaitOne ();
var result = Console.ReadKey ();
keyReady.Set ();
}
}
/// <summary>
/// Determines whether there are pending events to be processed.
/// </summary>
@@ -298,22 +320,29 @@ namespace Mono.Terminal {
public bool EventsPending (bool wait = false)
{
long now = DateTime.UtcNow.Ticks;
int pollTimeout, n;
if (timeouts.Count > 0)
pollTimeout = (int) ((timeouts.Keys [0] - now) / TimeSpan.TicksPerMillisecond);
else
pollTimeout = -1;
if (!wait)
pollTimeout = 0;
UpdatePollMap ();
if (useUnix) {
int pollTimeout, n;
if (timeouts.Count > 0)
pollTimeout = (int)((timeouts.Keys [0] - now) / TimeSpan.TicksPerMillisecond);
else
pollTimeout = -1;
n = poll (pollmap, (uint) pollmap.Length, pollTimeout);
int ic;
lock (idleHandlers)
ic = idleHandlers.Count;
return n > 0 || timeouts.Count > 0 && ((timeouts.Keys [0] - DateTime.UtcNow.Ticks) < 0) || ic > 0;
if (!wait)
pollTimeout = 0;
UpdatePollMap ();
n = poll (pollmap, (uint)pollmap.Length, pollTimeout);
int ic;
lock (idleHandlers)
ic = idleHandlers.Count;
return n > 0 || timeouts.Count > 0 && ((timeouts.Keys [0] - DateTime.UtcNow.Ticks) < 0) || ic > 0;
} else {
windowsKeyResult = null;
waitForProbe.Set ();
keyReady.WaitOne ();
return false;
}
}
/// <summary>
@@ -329,18 +358,27 @@ namespace Mono.Terminal {
{
if (timeouts.Count > 0)
RunTimers ();
foreach (var p in pollmap){
Watch watch;
if (p.revents == 0)
continue;
if (useUnix) {
foreach (var p in pollmap) {
Watch watch;
if (!descriptorWatchers.TryGetValue (p.fd, out watch))
continue;
if (!watch.Callback (this))
descriptorWatchers.Remove (p.fd);
if (p.revents == 0)
continue;
if (!descriptorWatchers.TryGetValue (p.fd, out watch))
continue;
if (!watch.Callback (this))
descriptorWatchers.Remove (p.fd);
}
} else {
if (windowsKeyResult.HasValue) {
if (WindowsKeyPressed != null)
WindowsKeyPressed (windowsKeyResult.Value);
windowsKeyResult = null;
}
}
if (idleHandlers.Count > 0)
RunIdle ();
}