Ich versuche aus dem STDInput zu lesen, wobei ich den Inputbuffer auf Raw gesetzt habe, damit nicht enter gedrückt werden muss um die Eingabe zu lesen. Das funktioniert nur genau so lange ich Blockend lese. Nun habe ich den Spaß auch nicht Blockend versucht zu implementieren. Dies habe ich über zwei verschiedene Wege implementiert, einmal überprüfe ich ob Informationen im Puffer stehen mittels fpSelect, der andere Weg ist den Filedescriptor das Flag NonBlocking zu geben. Hier mein Code
Code: Alles auswählen
function ReadChar(Blocking: boolean = True): char;
var
oTIO, nTIO: Termios;
{$IfDef NonBlockingStdIn}
flags,
{$Else}
fdsin: tfdSet;
{$EndIf}
res: integer;
begin
res := 1;
Result := #0;
TCGetAttr(1, oTIO);
nTIO := oTIO;
CFMakeRaw(nTIO);
TCSetAttr(1, TCSANOW, nTIO);
if not Blocking then
begin
{$ifDef NonBlockingStdIn}
flags := FpFcntl(StdInputHandle, F_GetFl, 0);
FpFcntl(StdInputHandle, F_SetFl, flags or O_NONBLOCK);
{$Else}
fpFD_ZERO(fdsin);
fpFD_SET(StdInputHandle, fdsin);
res := fpSelect(StdInputHandle + 1, @fdsin, nil, nil, 0);
{$EndIf}
end;
if res > 0 then
res := FpRead(StdInputHandle, Result, 1);
{$ifDef NonBlockingStdIn}
if res = 0 then
Result := #0;
{$EndIf}
//restore settings
TCSetAttr(1, TCSANOW, oTIO);
{$ifDef NonBlockingStdIn}
if not Blocking then
FpFcntl(StdInputHandle, F_SetFl, flags);
{$EndIf}
end;
Über den Switch NonBlockingStdIn wird die entsprechende art der Non Blocking implementation ausgewählt.
Nun kommt ein sehr lustiges verhalten. Beide Arten funktionieren in so fern, dass die Funktion nicht blockierend ist und falls verfügbar einen Tastendruck liest, allerdings gibt es das kleine Problem, dass bei einem Tastendruck das Symbol der gedrückten Taste auf der Konsole ausgegeben wird. Dieses verhalten ist nicht wünschenswert und tritt Lustigerweise nicht auf wenn True als Parameter übergeben wird, also Blockierend gelesen wird.
Nun bin ich am verzweifeln, da ich mir dieses Phänomen absolut nicht erklären kann. Hat eventuell jemand eine Idee?