Non blocking Input read funktioniert nicht raw.

Antworten
Warf
Beiträge: 1908
Registriert: Di 23. Sep 2014, 17:46
OS, Lazarus, FPC: Win10 | Linux
CPU-Target: x86_64

Non blocking Input read funktioniert nicht raw.

Beitrag von Warf »

Hey ho leute, ich habe aktuell ein kleines Problem, sowohl unter Linux als auch unter OSX.
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?

Mathias
Beiträge: 6164
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunk)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: Non blocking Input read funktioniert nicht raw.

Beitrag von Mathias »

Versteht ich es richtig, du willst selbst ein ReadKey schreiben ?
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

Warf
Beiträge: 1908
Registriert: Di 23. Sep 2014, 17:46
OS, Lazarus, FPC: Win10 | Linux
CPU-Target: x86_64

Re: Non blocking Input read funktioniert nicht raw.

Beitrag von Warf »

Mathias hat geschrieben:Versteht ich es richtig, du willst selbst ein ReadKey schreiben ?


Jein, die Funktionalität von Readkey habe ich bereits, ich will das ganze nun noch nicht Blockierend realisieren, also dass der Buffer nur ausgelesen wird wenn was drin steht, und nicht so lange gewartet wird bis was drin steht. Das funktioniert zwar auch, allerdings wird dann der Bufferinhalt auf die Konsole geprintet, was ich nicht haben will. Nicht blockierend (also wie Readkey) funktioniert es wunderbar

Mathias
Beiträge: 6164
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunk)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: Non blocking Input read funktioniert nicht raw.

Beitrag von Mathias »

Keypressed ?

Liefert true wen etwas im Buffer ist.
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

Antworten