mirror of
https://github.com/gui-cs/Terminal.Gui.git
synced 2025-12-26 15:57:56 +01:00
Progress on the Windows driver
This commit is contained in:
@@ -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)
|
||||
|
||||
@@ -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 ();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user