How to set Console to Raw mode?

Just starting out? Need help? Post your questions and find answers here.
ron.dunn
New User
New User
Posts: 1
Joined: Mon May 16, 2022 9:04 am

How to set Console to Raw mode?

Post by ron.dunn »

First lines of PureBasic :)

I'm trying to write a console program that reads from STDIN.

The following code requires an ENTER key after each input. I need to set the terminal to raw mode to get each character as it is typed.

How do I do this?

I don't want to use Inkey() because it appears to get keyboard scan codes rather than the characters sent to STDIN by the terminal program. I need the STDIN stream to get the result of an output sequence like ESC[6n which will return the current cursor position in a form like ESC[<row>;<col>R; and other sequences such as mouse events.

You'll see that this small example does echo the cursor position as I expect, but the program doesn't continue past ReadConsoleData() until I press ENTER, which is not usable in my scenario.

Code: Select all

OpenConsole()

Print (Chr(27) + "[6n")

*keybuf = AllocateMemory (128)

Repeat
    Delay(10)

    keycount = ReadConsoleData (*keybuf,128)
    PrintN ("Cnt: " + Str(keycount))
    If keycount > 1
        s$ = PeekS (*keybuf,keycount,#PB_Ascii)
        PrintN ("Len: " + Str(Len(s$)))
        PrintN ("Key: " + s$)
        PrintN ("Esc: " + EscapeString(s$))
        PrintN ("")
        EndIf
    
    Until Left(s$,1) = "q"
Axolotl
Enthusiast
Enthusiast
Posts: 432
Joined: Wed Dec 31, 2008 3:36 pm

Re: How to set Console to Raw mode?

Post by Axolotl »

Hello and welcome to PB forum.

That ís exactly the way I started....
Here are some console input codes to start with.
Maybe this is helpful

Code: Select all

Enumeration     ; Special Keys for GetKey, WaitKey, ...
  #skF1 = 368
  #skF2
  #skF3
  #skF4
  #skF5
  #skF6
  #skF7
  #skF8
  #skF9
  #skF10
  #skF11
  #skF12
EndEnumeration

;; Easy Read Keyboard Procedures 
;;------------------------------------------------------------------------------
Procedure.w ReadKey()
  Protected KeyPressed$, Result.w
  
  KeyPressed$ = Inkey()
  If KeyPressed$ <> ""
    Result = Asc(KeyPressed$)
  ElseIf RawKey()
    Result = RawKey() + $100    ; my idea of dealing with extended key codes like F1, .... 
  Else
    Delay(20) ; don't eat the entire cpu performance  :) 
    Result = 0
  EndIf
  ProcedureReturn Result
EndProcedure 

Procedure.w GetKey()
  Protected Result.w
  Repeat
    Result = ReadKey()
  Until Result <> 0  
Debug "GetKey() Result = " + RSet(Str(Result), 3) + "  $" + RSet(Hex(Result), 3, "0")  
  ProcedureReturn Result
EndProcedure 

Procedure.w GetTimeKey(WaitTime.l, DefValue.w)
  Protected Result.w, EndTime.l
  
  If WaitTime > 0 
    EndTime = AddDate(Date(), #PB_Date_Second, WaitTime)  
  EndIf 
  Repeat
    Result = ReadKey()
    If WaitTime > 0 And Date() > EndTime 
      Result = DefValue
      Break   ; DefValue könnte auch 0 sein, !!!
    EndIf
  Until Result <> 0 
Debug "GetTimeKey()  Result = " + RSet(Str(Result), 3) + "  $" + RSet(Hex(Result), 3, "0")    
  ProcedureReturn Result
EndProcedure 

Procedure.w GetTimeKeyText(Text.s, WaitTime.l, DefValue.w)
  Protected txt.s, back.s
  Protected n.l, i.l, CntLen.w
  Protected Result.w, StartTime.l, Now.l, OldTime.l, CountDown.l
  
  CountDown = WaitTime  
  CntLen = Len(Str(CountDown))
  If Text
    n = FindString(Text, "@t@", 1)
    If n > 0   ;; show countdown...
      Print(Left(Text, n-1))
      txt = Right(Text, Len(Text)-n-2)
      Print(RSet(Str(CountDown), CntLen))
      Print(txt)
      back = "" : For i = 1 To CntLen+Len(Txt) : back + Chr(8) : Next i
    Else
      Print(Text)
    EndIf  
  EndIf

  StartTime = Date()  ;; save start time 
  OldTime = StartTime
  Repeat
    Result = ReadKey()    ;; any keys pressed?

    If n > 0   ;; show countdown...
      Now = Date()          ;; whats the time?
      If Now <> OldTime
        Print(back)
        CountDown-1
        OldTime = Now       
        Print(RSet(Str(CountDown), CntLen))
        Print(txt)
      EndIf 
    EndIf 

    If WaitTime > 0 And CountDown <= 0
      Result = DefValue
      Break   ;; DefValue könnte auch 0 sein, !!!
    EndIf
  Until Result <> 0 
    
Debug "GetTimeKey()  Result = " + RSet(Str(Result), 3) + "  $" + RSet(Hex(Result), 3, "0")  
  
  ProcedureReturn Result
EndProcedure 


Procedure.s KeyValue(AKey.w)
  Protected Key.s
  
  If AKey >= 32 And AKey <= 127
    Key = Chr(AKey)
  ElseIf AKey >= 368 And AKey <= 379
    Key = "{F" + Str(AKey-367) + "}"  
  Else
    Key = Str(AKey)
  EndIf 
  ProcedureReturn Key
EndProcedure 

Procedure TestKeys()
  Protected Key.w
  
  PrintN(" "+Chr(2)+" TestKey mode: ")
  PrintN("")
  PrintN("    Press ESC (Value: 27, $1B) to quit.")
  PrintN("")
  Repeat
    Print(" Press Key: ?" + Chr(8))
    Key = GetKey()
    Print(Chr(8)+Chr(8))
    Print(" = " + RSet(Str(Key), 3))
    Print(",  $" + RSet(Hex(Key), 3, "0"))  
    If Key >= 32 And Key <= 127
      Print(",  Ch = '" + Chr(Key) + "'")   
    ElseIf Key >= 368 And Key <= 379
      Print(",  Ch = {F" + Str(Key-367)+"}")  
    EndIf 
    PrintN("")  
  Until Key = 27 
  PrintN("");
EndProcedure 
OpenConsole() 
TestKeys() 
Mostly running PureBasic <latest stable version and current alpha/beta> (x64) on Windows 11 Home
Olli
Addict
Addict
Posts: 1071
Joined: Wed May 27, 2020 12:26 pm

Re: How to set Console to Raw mode?

Post by Olli »

https://www.purebasic.com/documentation ... index.html

Remark:

Code: Select all

WriteConsoleData(Ascii(Chr(27) + "[6n"), 4)
You just have to free the buffers created with the function Ascii() :

Code: Select all

OpenConsole()

*b = Ascii(Chr(27) + "[6n")
WriteConsoleData(*b, MemorySize(*b) )
FreeMemory(*b)

*b = AllocateMemory(65536)
Size = ReadConsoleData(*b, 65536)
PrintN(PeekS(*b, Size, #PB_Ascii) )
FreeMemory(*b)

Input()
CloseConsole()
Axolotl
Enthusiast
Enthusiast
Posts: 432
Joined: Wed Dec 31, 2008 3:36 pm

Re: How to set Console to Raw mode?

Post by Axolotl »

too bad, i would have hoped for some kind of reaction. :o
Mostly running PureBasic <latest stable version and current alpha/beta> (x64) on Windows 11 Home
Post Reply