mirror of https://github.com/buggins/dlangide.git
terminal device
This commit is contained in:
parent
3ca6e5ea6e
commit
045acfd73d
|
@ -346,6 +346,7 @@ struct TerminalContent {
|
||||||
class TerminalWidget : WidgetGroup, OnScrollHandler {
|
class TerminalWidget : WidgetGroup, OnScrollHandler {
|
||||||
protected ScrollBar _verticalScrollBar;
|
protected ScrollBar _verticalScrollBar;
|
||||||
protected TerminalContent _content;
|
protected TerminalContent _content;
|
||||||
|
protected TerminalDevice _device;
|
||||||
this() {
|
this() {
|
||||||
this(null);
|
this(null);
|
||||||
}
|
}
|
||||||
|
@ -357,7 +358,29 @@ class TerminalWidget : WidgetGroup, OnScrollHandler {
|
||||||
_verticalScrollBar.minValue = 0;
|
_verticalScrollBar.minValue = 0;
|
||||||
_verticalScrollBar.scrollEvent = this;
|
_verticalScrollBar.scrollEvent = this;
|
||||||
addChild(_verticalScrollBar);
|
addChild(_verticalScrollBar);
|
||||||
|
_device = new TerminalDevice();
|
||||||
|
TerminalWidget _this = this;
|
||||||
|
if (_device.create()) {
|
||||||
|
_device.onBytesRead = delegate (char[] data) {
|
||||||
|
import dlangui.platforms.common.platform;
|
||||||
|
Window w = window;
|
||||||
|
if (w) {
|
||||||
|
//w.exe
|
||||||
|
w.executeInUiThread(delegate() {
|
||||||
|
if (w.isChild(_this))
|
||||||
|
write(cast(string)data);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
~this() {
|
||||||
|
if (_device)
|
||||||
|
destroy(_device);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// returns terminal/tty device (or named pipe for windows) name
|
||||||
|
@property string deviceName() { return _device ? _device.name : null; }
|
||||||
|
|
||||||
void scrollTo(int y) {
|
void scrollTo(int y) {
|
||||||
_content.scrollTo(y);
|
_content.scrollTo(y);
|
||||||
|
@ -657,16 +680,22 @@ class TerminalWidget : WidgetGroup, OnScrollHandler {
|
||||||
|
|
||||||
import core.thread;
|
import core.thread;
|
||||||
|
|
||||||
|
interface TerminalInputHandler {
|
||||||
|
void onBytesReceived(char[] data);
|
||||||
|
}
|
||||||
|
|
||||||
class TerminalDevice : Thread {
|
class TerminalDevice : Thread {
|
||||||
|
Signal!TerminalInputHandler onBytesRead;
|
||||||
version (Windows) {
|
version (Windows) {
|
||||||
import win32.windows;
|
import win32.windows;
|
||||||
HANDLE hpipe;
|
HANDLE hpipe;
|
||||||
} else {
|
} else {
|
||||||
int masterfd;
|
int masterfd;
|
||||||
}
|
}
|
||||||
string name;
|
@property string deviceName() { return _name; }
|
||||||
bool closed;
|
private string _name;
|
||||||
bool connected;
|
private bool started;
|
||||||
|
private bool closed;
|
||||||
|
|
||||||
this() {
|
this() {
|
||||||
super(&threadProc);
|
super(&threadProc);
|
||||||
|
@ -676,6 +705,39 @@ class TerminalDevice : Thread {
|
||||||
}
|
}
|
||||||
|
|
||||||
void threadProc() {
|
void threadProc() {
|
||||||
|
started = true;
|
||||||
|
Log.d("TerminalDevice threadProc() enter");
|
||||||
|
version(Windows) {
|
||||||
|
while (!closed) {
|
||||||
|
Log.d("Waiting for TerminalDevice client");
|
||||||
|
if (ConnectNamedPipe(hpipe, null)) {
|
||||||
|
// accept client
|
||||||
|
Log.d("TerminalDevice client connected");
|
||||||
|
char[4096] buf;
|
||||||
|
for (;;) {
|
||||||
|
if (closed)
|
||||||
|
break;
|
||||||
|
DWORD bytesRead = 0;
|
||||||
|
// read data from client
|
||||||
|
if (ReadFile(hpipe, &buf, buf.length, &bytesRead, null)) {
|
||||||
|
if (closed)
|
||||||
|
break;
|
||||||
|
if (bytesRead && onBytesRead.assigned) {
|
||||||
|
onBytesRead(buf[0 .. bytesRead].dup);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Log.d("TerminalDevice client disconnecting");
|
||||||
|
// disconnect client
|
||||||
|
DisconnectNamedPipe(hpipe);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// posix
|
||||||
|
}
|
||||||
|
Log.d("TerminalDevice threadProc() exit");
|
||||||
}
|
}
|
||||||
|
|
||||||
bool write(string msg) {
|
bool write(string msg) {
|
||||||
|
@ -700,7 +762,28 @@ class TerminalDevice : Thread {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
void close() {
|
void close() {
|
||||||
|
if (closed)
|
||||||
|
return;
|
||||||
|
closed = true;
|
||||||
|
if (!started)
|
||||||
|
return;
|
||||||
version (Windows) {
|
version (Windows) {
|
||||||
|
import std.string;
|
||||||
|
// ping terminal to handle closed flag
|
||||||
|
HANDLE h = CreateFileA(
|
||||||
|
_name.toStringz, // pipe name
|
||||||
|
GENERIC_READ | // read and write access
|
||||||
|
GENERIC_WRITE,
|
||||||
|
0, // no sharing
|
||||||
|
null, // default security attributes
|
||||||
|
OPEN_EXISTING, // opens existing pipe
|
||||||
|
0, // default attributes
|
||||||
|
null);
|
||||||
|
if (h != INVALID_HANDLE_VALUE) {
|
||||||
|
DWORD bytesWritten = 0;
|
||||||
|
WriteFile(h, "stop".ptr, 4, &bytesWritten, null);
|
||||||
|
CloseHandle(h);
|
||||||
|
}
|
||||||
if (hpipe && hpipe != INVALID_HANDLE_VALUE) {
|
if (hpipe && hpipe != INVALID_HANDLE_VALUE) {
|
||||||
CloseHandle(hpipe);
|
CloseHandle(hpipe);
|
||||||
hpipe = null;
|
hpipe = null;
|
||||||
|
@ -712,15 +795,15 @@ class TerminalDevice : Thread {
|
||||||
masterfd = 0;
|
masterfd = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
name = null;
|
join(false);
|
||||||
closed = true;
|
_name = null;
|
||||||
}
|
}
|
||||||
bool create() {
|
bool create() {
|
||||||
import std.string;
|
import std.string;
|
||||||
version (Windows) {
|
version (Windows) {
|
||||||
import std.uuid;
|
import std.uuid;
|
||||||
name = "\\\\.\\pipe\\dlangide-terminal-" ~ randomUUID().toString;
|
_name = "\\\\.\\pipe\\dlangide-terminal-" ~ randomUUID().toString;
|
||||||
hpipe = CreateNamedPipeA(cast(const(char)*)name.toStringz,
|
hpipe = CreateNamedPipeA(cast(const(char)*)_name.toStringz,
|
||||||
PIPE_ACCESS_DUPLEX,
|
PIPE_ACCESS_DUPLEX,
|
||||||
cast(uint)PIPE_TYPE_BYTE,
|
cast(uint)PIPE_TYPE_BYTE,
|
||||||
1,
|
1,
|
||||||
|
@ -758,9 +841,9 @@ class TerminalDevice : Thread {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
name = fromStringz(s).dup;
|
_name = fromStringz(s).dup;
|
||||||
}
|
}
|
||||||
Log.i("ptty device created: ", name);
|
Log.i("ptty device created: ", _name);
|
||||||
start();
|
start();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue