mirror of https://github.com/adamdruppe/arsd.git
dynamic load of xlib
This commit is contained in:
parent
ae17d5a497
commit
0755efc96d
7
dub.json
7
dub.json
|
@ -42,14 +42,12 @@
|
||||||
"configurations": [
|
"configurations": [
|
||||||
{
|
{
|
||||||
"name": "normal",
|
"name": "normal",
|
||||||
"libs-posix": ["X11", "Xext", "GL", "GLU"],
|
"libs-windows": ["gdi32"]
|
||||||
"libs-windows": ["gdi32", "opengl32", "glu32"]
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "without-opengl",
|
"name": "without-opengl",
|
||||||
"versions": ["without_opengl"],
|
"versions": ["without_opengl"],
|
||||||
"libs-windows": ["gdi32"],
|
"libs-windows": ["gdi32"]
|
||||||
"libs-posix": ["X11", "Xext"]
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "cocoa",
|
"name": "cocoa",
|
||||||
|
@ -308,6 +306,7 @@
|
||||||
"name": "terminal",
|
"name": "terminal",
|
||||||
"description": "Cross-platform Terminal I/O with color, mouse support, real time input, etc.",
|
"description": "Cross-platform Terminal I/O with color, mouse support, real time input, etc.",
|
||||||
"targetType": "library",
|
"targetType": "library",
|
||||||
|
"libs-windows": ["user32"],
|
||||||
"sourceFiles": ["terminal.d"],
|
"sourceFiles": ["terminal.d"],
|
||||||
"importPaths": ["."],
|
"importPaths": ["."],
|
||||||
"dflags": ["-mv=arsd.terminal=terminal.d"],
|
"dflags": ["-mv=arsd.terminal=terminal.d"],
|
||||||
|
|
30
nanovega.d
30
nanovega.d
|
@ -2706,7 +2706,7 @@ public nothrow @trusted @nogc:
|
||||||
|
|
||||||
/// Inverts this matrix.
|
/// Inverts this matrix.
|
||||||
/// If inverted matrix cannot be calculated, `this.valid` fill be `false`.
|
/// If inverted matrix cannot be calculated, `this.valid` fill be `false`.
|
||||||
ref NVGMatrix invert () {
|
ref NVGMatrix invert () return {
|
||||||
float[6] inv = void;
|
float[6] inv = void;
|
||||||
immutable double det = cast(double)mat.ptr[0]*mat.ptr[3]-cast(double)mat.ptr[2]*mat.ptr[1];
|
immutable double det = cast(double)mat.ptr[0]*mat.ptr[3]-cast(double)mat.ptr[2]*mat.ptr[1];
|
||||||
if (det > -1e-6 && det < 1e-6) {
|
if (det > -1e-6 && det < 1e-6) {
|
||||||
|
@ -2725,40 +2725,40 @@ public nothrow @trusted @nogc:
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Sets this matrix to identity matrix.
|
/// Sets this matrix to identity matrix.
|
||||||
ref NVGMatrix identity () { version(aliced) pragma(inline, true); mat[] = IdentityMat[]; return this; }
|
ref NVGMatrix identity () return { version(aliced) pragma(inline, true); mat[] = IdentityMat[]; return this; }
|
||||||
|
|
||||||
/// Translate this matrix.
|
/// Translate this matrix.
|
||||||
ref NVGMatrix translate (in float tx, in float ty) {
|
ref NVGMatrix translate (in float tx, in float ty) return {
|
||||||
version(aliced) pragma(inline, true);
|
version(aliced) pragma(inline, true);
|
||||||
return this.mul(Translated(tx, ty));
|
return this.mul(Translated(tx, ty));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Scale this matrix.
|
/// Scale this matrix.
|
||||||
ref NVGMatrix scale (in float sx, in float sy) {
|
ref NVGMatrix scale (in float sx, in float sy) return {
|
||||||
version(aliced) pragma(inline, true);
|
version(aliced) pragma(inline, true);
|
||||||
return this.mul(Scaled(sx, sy));
|
return this.mul(Scaled(sx, sy));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Rotate this matrix.
|
/// Rotate this matrix.
|
||||||
ref NVGMatrix rotate (in float a) {
|
ref NVGMatrix rotate (in float a) return {
|
||||||
version(aliced) pragma(inline, true);
|
version(aliced) pragma(inline, true);
|
||||||
return this.mul(Rotated(a));
|
return this.mul(Rotated(a));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Skew this matrix by X axis.
|
/// Skew this matrix by X axis.
|
||||||
ref NVGMatrix skewX (in float a) {
|
ref NVGMatrix skewX (in float a) return {
|
||||||
version(aliced) pragma(inline, true);
|
version(aliced) pragma(inline, true);
|
||||||
return this.mul(SkewedX(a));
|
return this.mul(SkewedX(a));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Skew this matrix by Y axis.
|
/// Skew this matrix by Y axis.
|
||||||
ref NVGMatrix skewY (in float a) {
|
ref NVGMatrix skewY (in float a) return {
|
||||||
version(aliced) pragma(inline, true);
|
version(aliced) pragma(inline, true);
|
||||||
return this.mul(SkewedY(a));
|
return this.mul(SkewedY(a));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Skew this matrix by both axes.
|
/// Skew this matrix by both axes.
|
||||||
ref NVGMatrix skewY (in float ax, in float ay) {
|
ref NVGMatrix skewY (in float ax, in float ay) return {
|
||||||
version(aliced) pragma(inline, true);
|
version(aliced) pragma(inline, true);
|
||||||
return this.mul(SkewedXY(ax, ay));
|
return this.mul(SkewedXY(ax, ay));
|
||||||
}
|
}
|
||||||
|
@ -2826,15 +2826,15 @@ public nothrow @trusted @nogc:
|
||||||
float tx () const { pragma(inline, true); return mat.ptr[4]; } /// Returns x translation of this matrix.
|
float tx () const { pragma(inline, true); return mat.ptr[4]; } /// Returns x translation of this matrix.
|
||||||
float ty () const { pragma(inline, true); return mat.ptr[5]; } /// Returns y translation of this matrix.
|
float ty () const { pragma(inline, true); return mat.ptr[5]; } /// Returns y translation of this matrix.
|
||||||
|
|
||||||
ref NVGMatrix scaleX (in float v) { pragma(inline, true); return scaleRotateTransform(v, scaleY, rotation, tx, ty); } /// Sets x scaling of this matrix.
|
ref NVGMatrix scaleX (in float v) return { pragma(inline, true); return scaleRotateTransform(v, scaleY, rotation, tx, ty); } /// Sets x scaling of this matrix.
|
||||||
ref NVGMatrix scaleY (in float v) { pragma(inline, true); return scaleRotateTransform(scaleX, v, rotation, tx, ty); } /// Sets y scaling of this matrix.
|
ref NVGMatrix scaleY (in float v) return { pragma(inline, true); return scaleRotateTransform(scaleX, v, rotation, tx, ty); } /// Sets y scaling of this matrix.
|
||||||
ref NVGMatrix rotation (in float v) { pragma(inline, true); return scaleRotateTransform(scaleX, scaleY, v, tx, ty); } /// Sets rotation of this matrix.
|
ref NVGMatrix rotation (in float v) return { pragma(inline, true); return scaleRotateTransform(scaleX, scaleY, v, tx, ty); } /// Sets rotation of this matrix.
|
||||||
ref NVGMatrix tx (in float v) { pragma(inline, true); mat.ptr[4] = v; return this; } /// Sets x translation of this matrix.
|
ref NVGMatrix tx (in float v) return { pragma(inline, true); mat.ptr[4] = v; return this; } /// Sets x translation of this matrix.
|
||||||
ref NVGMatrix ty (in float v) { pragma(inline, true); mat.ptr[5] = v; return this; } /// Sets y translation of this matrix.
|
ref NVGMatrix ty (in float v) return { pragma(inline, true); mat.ptr[5] = v; return this; } /// Sets y translation of this matrix.
|
||||||
|
|
||||||
/// Utility function to be used in `setXXX()`.
|
/// Utility function to be used in `setXXX()`.
|
||||||
/// This is the same as doing: `mat.identity.rotate(a).scale(xs, ys).translate(tx, ty)`, only faster
|
/// This is the same as doing: `mat.identity.rotate(a).scale(xs, ys).translate(tx, ty)`, only faster
|
||||||
ref NVGMatrix scaleRotateTransform (in float xscale, in float yscale, in float a, in float tx, in float ty) {
|
ref NVGMatrix scaleRotateTransform (in float xscale, in float yscale, in float a, in float tx, in float ty) return {
|
||||||
immutable float cs = nvg__cosf(a), sn = nvg__sinf(a);
|
immutable float cs = nvg__cosf(a), sn = nvg__sinf(a);
|
||||||
mat.ptr[0] = xscale*cs; mat.ptr[1] = yscale*sn;
|
mat.ptr[0] = xscale*cs; mat.ptr[1] = yscale*sn;
|
||||||
mat.ptr[2] = xscale*-sn; mat.ptr[3] = yscale*cs;
|
mat.ptr[2] = xscale*-sn; mat.ptr[3] = yscale*cs;
|
||||||
|
@ -2843,7 +2843,7 @@ public nothrow @trusted @nogc:
|
||||||
}
|
}
|
||||||
|
|
||||||
/// This is the same as doing: `mat.identity.rotate(a).translate(tx, ty)`, only faster
|
/// This is the same as doing: `mat.identity.rotate(a).translate(tx, ty)`, only faster
|
||||||
ref NVGMatrix rotateTransform (in float a, in float tx, in float ty) {
|
ref NVGMatrix rotateTransform (in float a, in float tx, in float ty) return {
|
||||||
immutable float cs = nvg__cosf(a), sn = nvg__sinf(a);
|
immutable float cs = nvg__cosf(a), sn = nvg__sinf(a);
|
||||||
mat.ptr[0] = cs; mat.ptr[1] = sn;
|
mat.ptr[0] = cs; mat.ptr[1] = sn;
|
||||||
mat.ptr[2] = -sn; mat.ptr[3] = cs;
|
mat.ptr[2] = -sn; mat.ptr[3] = cs;
|
||||||
|
|
4
script.d
4
script.d
|
@ -1,6 +1,8 @@
|
||||||
/*
|
/*
|
||||||
|
|
||||||
FIXME: i kinda do want a catch type filter.
|
FIXME: i kinda do want a catch type filter e.g. catch(Exception f)
|
||||||
|
|
||||||
|
FIXME: I also kinda want implicit construction of structs at times.
|
||||||
|
|
||||||
REPL plan:
|
REPL plan:
|
||||||
easy movement to/from a real editor
|
easy movement to/from a real editor
|
||||||
|
|
1075
simpledisplay.d
1075
simpledisplay.d
File diff suppressed because it is too large
Load Diff
268
terminal.d
268
terminal.d
|
@ -168,7 +168,9 @@ __gshared void delegate() nothrow @nogc sigIntExtension;
|
||||||
|
|
||||||
version(TerminalDirectToEmulator) {
|
version(TerminalDirectToEmulator) {
|
||||||
version=WithEncapsulatedSignals;
|
version=WithEncapsulatedSignals;
|
||||||
} else version(Posix) {
|
}
|
||||||
|
|
||||||
|
version(Posix) {
|
||||||
enum SIGWINCH = 28;
|
enum SIGWINCH = 28;
|
||||||
__gshared bool windowSizeChanged = false;
|
__gshared bool windowSizeChanged = false;
|
||||||
__gshared bool interrupted = false; /// you might periodically check this in a long operation and abort if it is set. Remember it is volatile. It is also sent through the input event loop via RealTimeConsoleInput
|
__gshared bool interrupted = false; /// you might periodically check this in a long operation and abort if it is set. Remember it is volatile. It is also sent through the input event loop via RealTimeConsoleInput
|
||||||
|
@ -236,6 +238,8 @@ version(Win32Console) {
|
||||||
enum GREEN_BIT = 2;
|
enum GREEN_BIT = 2;
|
||||||
enum BLUE_BIT = 1;
|
enum BLUE_BIT = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pragma(lib, "user32");
|
||||||
}
|
}
|
||||||
|
|
||||||
version(Posix) {
|
version(Posix) {
|
||||||
|
@ -735,6 +739,7 @@ struct Terminal {
|
||||||
string[string] termcap;
|
string[string] termcap;
|
||||||
void readTermcap(string t = null) {
|
void readTermcap(string t = null) {
|
||||||
version(TerminalDirectToEmulator)
|
version(TerminalDirectToEmulator)
|
||||||
|
if(usingDirectEmulator)
|
||||||
t = "xterm";
|
t = "xterm";
|
||||||
import std.process;
|
import std.process;
|
||||||
import std.string;
|
import std.string;
|
||||||
|
@ -1054,9 +1059,10 @@ struct Terminal {
|
||||||
bool hasDefaultDarkBackground() {
|
bool hasDefaultDarkBackground() {
|
||||||
version(Win32Console) {
|
version(Win32Console) {
|
||||||
return !(defaultBackgroundColor & 0xf);
|
return !(defaultBackgroundColor & 0xf);
|
||||||
} else version(TerminalDirectToEmulator) {
|
|
||||||
return integratedTerminalEmulatorConfiguration.defaultBackground.g < 100;
|
|
||||||
} else {
|
} else {
|
||||||
|
version(TerminalDirectToEmulator)
|
||||||
|
if(usingDirectEmulator)
|
||||||
|
return integratedTerminalEmulatorConfiguration.defaultBackground.g < 100;
|
||||||
// FIXME: there is probably a better way to do this
|
// FIXME: there is probably a better way to do this
|
||||||
// but like idk how reliable it is.
|
// but like idk how reliable it is.
|
||||||
if(terminalInFamily("linux"))
|
if(terminalInFamily("linux"))
|
||||||
|
@ -1082,6 +1088,8 @@ struct Terminal {
|
||||||
this.t = t;
|
this.t = t;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool usingDirectEmulator;
|
||||||
}
|
}
|
||||||
|
|
||||||
version(TerminalDirectToEmulator)
|
version(TerminalDirectToEmulator)
|
||||||
|
@ -1096,6 +1104,32 @@ struct Terminal {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
import arsd.simpledisplay;
|
||||||
|
static if(UsingSimpledisplayX11) {
|
||||||
|
try {
|
||||||
|
if(arsd.simpledisplay.librariesSuccessfullyLoaded) {
|
||||||
|
XDisplayConnection.get();
|
||||||
|
this.usingDirectEmulator = true;
|
||||||
|
} else if(!integratedTerminalEmulatorConfiguration.fallbackToDegradedTerminal) {
|
||||||
|
throw new Exception("Unable to load X libraries to create custom terminal.");
|
||||||
|
}
|
||||||
|
} catch(Exception e) {
|
||||||
|
if(!integratedTerminalEmulatorConfiguration.fallbackToDegradedTerminal)
|
||||||
|
throw e;
|
||||||
|
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
this.usingDirectEmulator = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!usingDirectEmulator) {
|
||||||
|
version(Posix)
|
||||||
|
posixInitialize(type, 0, 1, null);
|
||||||
|
else
|
||||||
|
throw new Exception("Total wtf - are you on a windows system without a gui?!?");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
tcaps = uint.max; // all capabilities
|
tcaps = uint.max; // all capabilities
|
||||||
import core.thread;
|
import core.thread;
|
||||||
|
|
||||||
|
@ -1159,6 +1193,11 @@ struct Terminal {
|
||||||
* ditto on getSizeOverride. That's there so you can do something instead of ioctl.
|
* ditto on getSizeOverride. That's there so you can do something instead of ioctl.
|
||||||
*/
|
*/
|
||||||
this(ConsoleOutputType type, int fdIn = 0, int fdOut = 1, int[] delegate() getSizeOverride = null) {
|
this(ConsoleOutputType type, int fdIn = 0, int fdOut = 1, int[] delegate() getSizeOverride = null) {
|
||||||
|
posixInitialize(type, fdIn, fdOut, getSizeOverride);
|
||||||
|
}
|
||||||
|
|
||||||
|
version(Posix)
|
||||||
|
private void posixInitialize(ConsoleOutputType type, int fdIn = 0, int fdOut = 1, int[] delegate() getSizeOverride = null) {
|
||||||
this.fdIn = fdIn;
|
this.fdIn = fdIn;
|
||||||
this.fdOut = fdOut;
|
this.fdOut = fdOut;
|
||||||
this.getSizeOverride = getSizeOverride;
|
this.getSizeOverride = getSizeOverride;
|
||||||
|
@ -1199,7 +1238,7 @@ struct Terminal {
|
||||||
return Terminal(ConsoleOutputType.cellular);
|
return Terminal(ConsoleOutputType.cellular);
|
||||||
}
|
}
|
||||||
|
|
||||||
version(Win32Console) {
|
version(Windows) {
|
||||||
HANDLE hConsole;
|
HANDLE hConsole;
|
||||||
CONSOLE_SCREEN_BUFFER_INFO originalSbi;
|
CONSOLE_SCREEN_BUFFER_INFO originalSbi;
|
||||||
}
|
}
|
||||||
|
@ -1283,12 +1322,18 @@ struct Terminal {
|
||||||
doTermcap("te");
|
doTermcap("te");
|
||||||
}
|
}
|
||||||
version(TerminalDirectToEmulator) {
|
version(TerminalDirectToEmulator) {
|
||||||
writeln("\n\n<exited>");
|
if(usingDirectEmulator) {
|
||||||
setTitle(tew.terminalEmulator.currentTitle ~ " <exited>");
|
writeln("\n\n<exited>");
|
||||||
tew.term = null;
|
setTitle(tew.terminalEmulator.currentTitle ~ " <exited>");
|
||||||
|
tew.term = null;
|
||||||
|
|
||||||
if(integratedTerminalEmulatorConfiguration.closeOnExit)
|
if(integratedTerminalEmulatorConfiguration.closeOnExit)
|
||||||
tew.parentWindow.close();
|
tew.parentWindow.close();
|
||||||
|
} else {
|
||||||
|
if(terminalInFamily("xterm", "rxvt", "screen", "tmux")) {
|
||||||
|
writeStringRaw("\033[23;0t"); // restore window title from the stack
|
||||||
|
}
|
||||||
|
}
|
||||||
} else
|
} else
|
||||||
if(terminalInFamily("xterm", "rxvt", "screen", "tmux")) {
|
if(terminalInFamily("xterm", "rxvt", "screen", "tmux")) {
|
||||||
writeStringRaw("\033[23;0t"); // restore window title from the stack
|
writeStringRaw("\033[23;0t"); // restore window title from the stack
|
||||||
|
@ -1371,7 +1416,10 @@ struct Terminal {
|
||||||
// fallback to 16 color for term that i know don't take it well
|
// fallback to 16 color for term that i know don't take it well
|
||||||
import std.process;
|
import std.process;
|
||||||
import std.string;
|
import std.string;
|
||||||
version(TerminalDirectToEmulator) {} else
|
version(TerminalDirectToEmulator)
|
||||||
|
if(usingDirectEmulator)
|
||||||
|
goto skip_approximation;
|
||||||
|
|
||||||
if(environment.get("TERM") == "rxvt" || environment.get("TERM") == "linux") {
|
if(environment.get("TERM") == "rxvt" || environment.get("TERM") == "linux") {
|
||||||
// not likely supported, use 16 color fallback
|
// not likely supported, use 16 color fallback
|
||||||
auto setTof = approximate16Color(foreground);
|
auto setTof = approximate16Color(foreground);
|
||||||
|
@ -1386,6 +1434,8 @@ struct Terminal {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
skip_approximation:
|
||||||
|
|
||||||
// otherwise, assume it is probably supported and give it a try
|
// otherwise, assume it is probably supported and give it a try
|
||||||
writeStringRaw(format("\033[38;5;%dm\033[48;5;%dm",
|
writeStringRaw(format("\033[38;5;%dm\033[48;5;%dm",
|
||||||
colorToXTermPaletteIndex(foreground),
|
colorToXTermPaletteIndex(foreground),
|
||||||
|
@ -1698,9 +1748,19 @@ struct Terminal {
|
||||||
return;
|
return;
|
||||||
|
|
||||||
version(TerminalDirectToEmulator) {
|
version(TerminalDirectToEmulator) {
|
||||||
tew.sendRawInput(cast(ubyte[]) writeBuffer);
|
if(usingDirectEmulator) {
|
||||||
writeBuffer = null;
|
tew.sendRawInput(cast(ubyte[]) writeBuffer);
|
||||||
} else version(Posix) {
|
writeBuffer = null;
|
||||||
|
} else {
|
||||||
|
interiorFlush();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
interiorFlush();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void interiorFlush() {
|
||||||
|
version(Posix) {
|
||||||
if(_writeDelegate !is null) {
|
if(_writeDelegate !is null) {
|
||||||
_writeDelegate(writeBuffer);
|
_writeDelegate(writeBuffer);
|
||||||
} else {
|
} else {
|
||||||
|
@ -1730,8 +1790,17 @@ struct Terminal {
|
||||||
|
|
||||||
int[] getSize() {
|
int[] getSize() {
|
||||||
version(TerminalDirectToEmulator) {
|
version(TerminalDirectToEmulator) {
|
||||||
return [tew.terminalEmulator.width, tew.terminalEmulator.height];
|
if(usingDirectEmulator)
|
||||||
} else version(Windows) {
|
return [tew.terminalEmulator.width, tew.terminalEmulator.height];
|
||||||
|
else
|
||||||
|
return getSizeInternal();
|
||||||
|
} else {
|
||||||
|
return getSizeInternal();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private int[] getSizeInternal() {
|
||||||
|
version(Windows) {
|
||||||
CONSOLE_SCREEN_BUFFER_INFO info;
|
CONSOLE_SCREEN_BUFFER_INFO info;
|
||||||
GetConsoleScreenBufferInfo( hConsole, &info );
|
GetConsoleScreenBufferInfo( hConsole, &info );
|
||||||
|
|
||||||
|
@ -2100,7 +2169,7 @@ struct RealTimeConsoleInput {
|
||||||
// so this hack is just to give some room for that to happen without destroying the rest of the world
|
// so this hack is just to give some room for that to happen without destroying the rest of the world
|
||||||
}
|
}
|
||||||
|
|
||||||
version(Win32Console) {
|
version(Windows) {
|
||||||
private DWORD oldInput;
|
private DWORD oldInput;
|
||||||
private DWORD oldOutput;
|
private DWORD oldOutput;
|
||||||
HANDLE inputHandle;
|
HANDLE inputHandle;
|
||||||
|
@ -2115,9 +2184,13 @@ struct RealTimeConsoleInput {
|
||||||
this.flags = flags;
|
this.flags = flags;
|
||||||
this.terminal = terminal;
|
this.terminal = terminal;
|
||||||
|
|
||||||
version(Win32Console) {
|
version(Windows) {
|
||||||
inputHandle = GetStdHandle(STD_INPUT_HANDLE);
|
inputHandle = GetStdHandle(STD_INPUT_HANDLE);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
version(Win32Console) {
|
||||||
|
|
||||||
GetConsoleMode(inputHandle, &oldInput);
|
GetConsoleMode(inputHandle, &oldInput);
|
||||||
|
|
||||||
DWORD mode = 0;
|
DWORD mode = 0;
|
||||||
|
@ -2145,54 +2218,12 @@ struct RealTimeConsoleInput {
|
||||||
}
|
}
|
||||||
|
|
||||||
version(TerminalDirectToEmulator) {
|
version(TerminalDirectToEmulator) {
|
||||||
terminal.tew.terminalEmulator.echo = (flags & ConsoleInputFlags.echo) ? true : false;
|
if(terminal.usingDirectEmulator)
|
||||||
|
terminal.tew.terminalEmulator.echo = (flags & ConsoleInputFlags.echo) ? true : false;
|
||||||
|
else version(Posix)
|
||||||
|
posixInit();
|
||||||
} else version(Posix) {
|
} else version(Posix) {
|
||||||
this.fdIn = terminal.fdIn;
|
posixInit();
|
||||||
this.fdOut = terminal.fdOut;
|
|
||||||
|
|
||||||
if(fdIn != -1) {
|
|
||||||
tcgetattr(fdIn, &old);
|
|
||||||
auto n = old;
|
|
||||||
|
|
||||||
auto f = ICANON;
|
|
||||||
if(!(flags & ConsoleInputFlags.echo))
|
|
||||||
f |= ECHO;
|
|
||||||
|
|
||||||
// \033Z or \033[c
|
|
||||||
|
|
||||||
n.c_lflag &= ~f;
|
|
||||||
tcsetattr(fdIn, TCSANOW, &n);
|
|
||||||
}
|
|
||||||
|
|
||||||
// some weird bug breaks this, https://github.com/robik/ConsoleD/issues/3
|
|
||||||
//destructor ~= { tcsetattr(fdIn, TCSANOW, &old); };
|
|
||||||
|
|
||||||
if(flags & ConsoleInputFlags.size) {
|
|
||||||
import core.sys.posix.signal;
|
|
||||||
sigaction_t n;
|
|
||||||
n.sa_handler = &sizeSignalHandler;
|
|
||||||
n.sa_mask = cast(sigset_t) 0;
|
|
||||||
n.sa_flags = 0;
|
|
||||||
sigaction(SIGWINCH, &n, &oldSigWinch);
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
import core.sys.posix.signal;
|
|
||||||
sigaction_t n;
|
|
||||||
n.sa_handler = &interruptSignalHandler;
|
|
||||||
n.sa_mask = cast(sigset_t) 0;
|
|
||||||
n.sa_flags = 0;
|
|
||||||
sigaction(SIGINT, &n, &oldSigIntr);
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
import core.sys.posix.signal;
|
|
||||||
sigaction_t n;
|
|
||||||
n.sa_handler = &hangupSignalHandler;
|
|
||||||
n.sa_mask = cast(sigset_t) 0;
|
|
||||||
n.sa_flags = 0;
|
|
||||||
sigaction(SIGHUP, &n, &oldHupIntr);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if(UseVtSequences) {
|
if(UseVtSequences) {
|
||||||
|
@ -2259,6 +2290,56 @@ struct RealTimeConsoleInput {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
version(Posix)
|
||||||
|
private void posixInit() {
|
||||||
|
this.fdIn = terminal.fdIn;
|
||||||
|
this.fdOut = terminal.fdOut;
|
||||||
|
|
||||||
|
if(fdIn != -1) {
|
||||||
|
tcgetattr(fdIn, &old);
|
||||||
|
auto n = old;
|
||||||
|
|
||||||
|
auto f = ICANON;
|
||||||
|
if(!(flags & ConsoleInputFlags.echo))
|
||||||
|
f |= ECHO;
|
||||||
|
|
||||||
|
// \033Z or \033[c
|
||||||
|
|
||||||
|
n.c_lflag &= ~f;
|
||||||
|
tcsetattr(fdIn, TCSANOW, &n);
|
||||||
|
}
|
||||||
|
|
||||||
|
// some weird bug breaks this, https://github.com/robik/ConsoleD/issues/3
|
||||||
|
//destructor ~= { tcsetattr(fdIn, TCSANOW, &old); };
|
||||||
|
|
||||||
|
if(flags & ConsoleInputFlags.size) {
|
||||||
|
import core.sys.posix.signal;
|
||||||
|
sigaction_t n;
|
||||||
|
n.sa_handler = &sizeSignalHandler;
|
||||||
|
n.sa_mask = cast(sigset_t) 0;
|
||||||
|
n.sa_flags = 0;
|
||||||
|
sigaction(SIGWINCH, &n, &oldSigWinch);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
import core.sys.posix.signal;
|
||||||
|
sigaction_t n;
|
||||||
|
n.sa_handler = &interruptSignalHandler;
|
||||||
|
n.sa_mask = cast(sigset_t) 0;
|
||||||
|
n.sa_flags = 0;
|
||||||
|
sigaction(SIGINT, &n, &oldSigIntr);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
import core.sys.posix.signal;
|
||||||
|
sigaction_t n;
|
||||||
|
n.sa_handler = &hangupSignalHandler;
|
||||||
|
n.sa_mask = cast(sigset_t) 0;
|
||||||
|
n.sa_flags = 0;
|
||||||
|
sigaction(SIGHUP, &n, &oldHupIntr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void fdReadyReader() {
|
void fdReadyReader() {
|
||||||
auto queue = readNextEvents();
|
auto queue = readNextEvents();
|
||||||
foreach(event; queue)
|
foreach(event; queue)
|
||||||
|
@ -2318,13 +2399,15 @@ struct RealTimeConsoleInput {
|
||||||
|
|
||||||
// the delegate thing doesn't actually work for this... for some reason
|
// the delegate thing doesn't actually work for this... for some reason
|
||||||
|
|
||||||
version(TerminalDirectToEmulator) { } else
|
version(TerminalDirectToEmulator) {
|
||||||
version(Posix)
|
if(terminal && terminal.usingDirectEmulator)
|
||||||
|
goto skip_extra;
|
||||||
|
}
|
||||||
|
|
||||||
|
version(Posix) {
|
||||||
if(fdIn != -1)
|
if(fdIn != -1)
|
||||||
tcsetattr(fdIn, TCSANOW, &old);
|
tcsetattr(fdIn, TCSANOW, &old);
|
||||||
|
|
||||||
version(TerminalDirectToEmulator) { } else
|
|
||||||
version(Posix) {
|
|
||||||
if(flags & ConsoleInputFlags.size) {
|
if(flags & ConsoleInputFlags.size) {
|
||||||
// restoration
|
// restoration
|
||||||
sigaction(SIGWINCH, &oldSigWinch, null);
|
sigaction(SIGWINCH, &oldSigWinch, null);
|
||||||
|
@ -2333,6 +2416,8 @@ struct RealTimeConsoleInput {
|
||||||
sigaction(SIGHUP, &oldHupIntr, null);
|
sigaction(SIGHUP, &oldHupIntr, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
skip_extra:
|
||||||
|
|
||||||
// we're just undoing everything the constructor did, in reverse order, same criteria
|
// we're just undoing everything the constructor did, in reverse order, same criteria
|
||||||
foreach_reverse(d; destructor)
|
foreach_reverse(d; destructor)
|
||||||
d();
|
d();
|
||||||
|
@ -2375,6 +2460,9 @@ struct RealTimeConsoleInput {
|
||||||
|
|
||||||
bool timedCheckForInput_bypassingBuffer(int milliseconds) {
|
bool timedCheckForInput_bypassingBuffer(int milliseconds) {
|
||||||
version(TerminalDirectToEmulator) {
|
version(TerminalDirectToEmulator) {
|
||||||
|
if(!terminal.usingDirectEmulator)
|
||||||
|
return timedCheckForInput_bypassingBuffer_impl(milliseconds);
|
||||||
|
|
||||||
import core.time;
|
import core.time;
|
||||||
if(terminal.tew.terminalEmulator.pendingForApplication.length)
|
if(terminal.tew.terminalEmulator.pendingForApplication.length)
|
||||||
return true;
|
return true;
|
||||||
|
@ -2385,7 +2473,12 @@ struct RealTimeConsoleInput {
|
||||||
return terminal.tew.terminalEmulator.pendingForApplication.length || terminal.interrupted || terminal.windowSizeChanged || terminal.hangedUp;
|
return terminal.tew.terminalEmulator.pendingForApplication.length || terminal.interrupted || terminal.windowSizeChanged || terminal.hangedUp;
|
||||||
else
|
else
|
||||||
return false;
|
return false;
|
||||||
} else version(Win32Console) {
|
} else
|
||||||
|
return timedCheckForInput_bypassingBuffer_impl(milliseconds);
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool timedCheckForInput_bypassingBuffer_impl(int milliseconds) {
|
||||||
|
version(Windows) {
|
||||||
auto response = WaitForSingleObject(inputHandle, milliseconds);
|
auto response = WaitForSingleObject(inputHandle, milliseconds);
|
||||||
if(response == 0)
|
if(response == 0)
|
||||||
return true; // the object is ready
|
return true; // the object is ready
|
||||||
|
@ -2458,6 +2551,8 @@ struct RealTimeConsoleInput {
|
||||||
//int inputBufferPosition;
|
//int inputBufferPosition;
|
||||||
int nextRaw(bool interruptable = false) {
|
int nextRaw(bool interruptable = false) {
|
||||||
version(TerminalDirectToEmulator) {
|
version(TerminalDirectToEmulator) {
|
||||||
|
if(!terminal.usingDirectEmulator)
|
||||||
|
return nextRaw_impl(interruptable);
|
||||||
moar:
|
moar:
|
||||||
//if(interruptable && inputQueue.length)
|
//if(interruptable && inputQueue.length)
|
||||||
//return -1;
|
//return -1;
|
||||||
|
@ -2474,7 +2569,11 @@ struct RealTimeConsoleInput {
|
||||||
terminal.tew.terminalEmulator.pendingForApplication = terminal.tew.terminalEmulator.pendingForApplication[1 .. $];
|
terminal.tew.terminalEmulator.pendingForApplication = terminal.tew.terminalEmulator.pendingForApplication[1 .. $];
|
||||||
return a;
|
return a;
|
||||||
}
|
}
|
||||||
} else version(Posix) {
|
} else
|
||||||
|
return nextRaw_impl(interruptable);
|
||||||
|
}
|
||||||
|
private int nextRaw_impl(bool interruptable = false) {
|
||||||
|
version(Posix) {
|
||||||
if(fdIn == -1)
|
if(fdIn == -1)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
@ -4640,14 +4739,20 @@ class LineGetter {
|
||||||
|
|
||||||
// then get the current cursor position to start fresh
|
// then get the current cursor position to start fresh
|
||||||
version(TerminalDirectToEmulator) {
|
version(TerminalDirectToEmulator) {
|
||||||
|
if(!terminal.usingDirectEmulator)
|
||||||
|
return updateCursorPosition_impl();
|
||||||
startOfLineX = terminal.tew.terminalEmulator.cursorX;
|
startOfLineX = terminal.tew.terminalEmulator.cursorX;
|
||||||
startOfLineY = terminal.tew.terminalEmulator.cursorY;
|
startOfLineY = terminal.tew.terminalEmulator.cursorY;
|
||||||
} else version(Win32Console) {
|
} else
|
||||||
|
updateCursorPosition_impl();
|
||||||
|
}
|
||||||
|
private void updateCursorPosition_impl() {
|
||||||
|
version(Win32Console) {
|
||||||
CONSOLE_SCREEN_BUFFER_INFO info;
|
CONSOLE_SCREEN_BUFFER_INFO info;
|
||||||
GetConsoleScreenBufferInfo(terminal.hConsole, &info);
|
GetConsoleScreenBufferInfo(terminal.hConsole, &info);
|
||||||
startOfLineX = info.dwCursorPosition.X;
|
startOfLineX = info.dwCursorPosition.X;
|
||||||
startOfLineY = info.dwCursorPosition.Y;
|
startOfLineY = info.dwCursorPosition.Y;
|
||||||
} else {
|
} else version(Posix) {
|
||||||
// request current cursor position
|
// request current cursor position
|
||||||
|
|
||||||
// we have to turn off cooked mode to get this answer, otherwise it will all
|
// we have to turn off cooked mode to get this answer, otherwise it will all
|
||||||
|
@ -5968,6 +6073,25 @@ version(TerminalDirectToEmulator) {
|
||||||
Added March 29, 2020. Included in release v7.1.0.
|
Added March 29, 2020. Included in release v7.1.0.
|
||||||
+/
|
+/
|
||||||
void delegate(TerminalEmulatorWindow) menuExtensionsConstructor;
|
void delegate(TerminalEmulatorWindow) menuExtensionsConstructor;
|
||||||
|
|
||||||
|
/++
|
||||||
|
Set this to true if you want [Terminal] to fallback to the user's
|
||||||
|
existing native terminal in the event that creating the custom terminal
|
||||||
|
is impossible for whatever reason.
|
||||||
|
|
||||||
|
If your application must have all advanced features, set this to `false`.
|
||||||
|
Otherwise, be sure you handle the absence of advanced features in your
|
||||||
|
application by checking methods like [Terminal.inlineImagesSupported],
|
||||||
|
etc., and only use things you can gracefully degrade without.
|
||||||
|
|
||||||
|
If this is set to false, `Terminal`'s constructor will throw if the gui fails
|
||||||
|
instead of carrying on with the stdout terminal (if possible).
|
||||||
|
|
||||||
|
History:
|
||||||
|
Added June 28, 2020. Included in release v8.1.0.
|
||||||
|
|
||||||
|
+/
|
||||||
|
bool fallbackToDegradedTerminal = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/+
|
/+
|
||||||
|
|
|
@ -821,7 +821,7 @@ class TerminalEmulator {
|
||||||
hasNonCharacterData = false;
|
hasNonCharacterData = false;
|
||||||
chStore = c;
|
chStore = c;
|
||||||
}
|
}
|
||||||
ref TextAttributes attributes() {
|
ref TextAttributes attributes() return {
|
||||||
assert(!hasNonCharacterData);
|
assert(!hasNonCharacterData);
|
||||||
return attributesStore;
|
return attributesStore;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue