Recent

Author Topic: Yet Another [kbReleased] question - help needed  (Read 8901 times)

Darie

  • New Member
  • *
  • Posts: 31
Yet Another [kbReleased] question - help needed
« on: April 01, 2024, 02:48:39 pm »
Since the kbReleased event is not implemented in the keyboard unit, is there another way to read the released state of a key in terminal?

Which would be the most simple way to do-it?

I know this can be done in SDL, SFML, MONO etc. but I would prefer not to go that far.
Thank you.
« Last Edit: April 02, 2024, 09:27:10 pm by Darie »
The sphere of knowledge is in continuous expansion. So is the contact of it's points with the unknown --Blaise Pascal

cdbc

  • Hero Member
  • *****
  • Posts: 1085
    • http://www.cdbc.dk
Re: Yet Another [kbReleased] question - help needed
« Reply #1 on: April 01, 2024, 03:04:20 pm »
Hi
In *nix, you could have a look in unit termio and maybe get lucky  :D
Regards Benny
If it ain't broke, don't fix it ;)
PCLinuxOS(rolling release) 64bit -> KDE5 -> FPC 3.2.2 -> Lazarus 2.2.6 up until Jan 2024 from then on it's: KDE5/QT5 -> FPC 3.3.1 -> Lazarus 3.0

Darie

  • New Member
  • *
  • Posts: 31
Re: Yet Another [kbReleased] question - help needed
« Reply #2 on: April 01, 2024, 07:33:08 pm »
Hi @cdbc,

Thanks for the suggestion. Using termio, actually, one needs to implement a mechanism to simulate a key release based on a specific delay. This would catch some events, other it will not. Something similar is implemented in the PTC super-tetris example.

[RANT]
Anyway, I am F*KiN stunned and outraged that for such a simple and natural thing one must now go to such lengths as installing a sh*tload of frameworks, counting in the tenths, hundreds or even more megs, only to have access to an event. From the "mov ah, 0x00 int 0x16 mov ah, 0x01 int 0x16" that's a truck load of garbage for such a thing. WTF??? >:(

And don't get me wrong, I understand all the security imperatives and approaches but in this case, more than one TEAM-of-DEVS specific to an OS or another have p*ssed on their shoes.

FFS, all I want is to be able to cross-platform read a key_released event in a terminal app!
[/RANT]

Phew...
EDIT: This, after not being able to make a simple beep in the console... Seems some things are not going in the right direction.
« Last Edit: April 01, 2024, 07:46:31 pm by Darie »
The sphere of knowledge is in continuous expansion. So is the contact of it's points with the unknown --Blaise Pascal

Darie

  • New Member
  • *
  • Posts: 31
Re: Yet Another [kbReleased] question - help needed
« Reply #3 on: April 01, 2024, 08:41:16 pm »
Trying to answer my own question:

After more reading
https://stackoverflow.com/questions/1409216/receiving-key-press-and-key-release-events-in-linux-terminal-applications
https://www.linuxjournal.com/article/1080
https://asm.sourceforge.net/articles/rawkb.html
And more reading
https://superuser.com/questions/248517/show-keys-pressed-in-linux
https://stackoverflow.com/questions/58360050/detecting-keyboard-key-press-and-release-on-linux

And, finally, some quality reading Why Is It so Hard to Detect Keyup Event on Linux? (Thanks, Robert!)
Quote
This article is dedicated to discussing why it's so hard to detect the 'key up' or 'key release' event in a Linux terminal environment without relying on X server. Several techniques and code examples will be shown that are capable of detecting the keyup event on Linux (with and without an X server), but all techniques presented here have significant limitations due to historical reasons that will be discussed.  These limitations will be discussed in terms of implementation details of the Linux console, terminal emulators, X server, and SSH based environments.

The solution that presents itself is to spawn a second thread to wrap the key polling and implement there methods for KeyUp & KeyDown based on virtual events timed on arbitrary millisecond delays. Nvm, this would not work for n-key roll-over. Since on the 2nd key press the 1st one is not read anymore.

Here's the termio test program:
Code: Pascal  [Select][+][-]
  1. PROGRAM
  2.   nKeyRollOverTest_TERMIO;
  3.  
  4. USES
  5.   BaseUnix, Termio;
  6.  
  7. VAR
  8.   oldTermios, newTermios: Termios;
  9.   key: char;
  10.   bytesRead: ssize_t;
  11.  
  12. BEGIN
  13.   tcGetAttr(StdInputHandle, oldTermios);
  14.   newTermios := oldTermios;
  15.   cfMakeRaw(newTermios);
  16.   tcSetAttr(StdInputHandle, TCSANOW, newTermios);
  17.  
  18.   repeat
  19.     bytesRead := fpRead(StdInputHandle, @key, 1);
  20.     if not ( bytesRead = 0 ) then write(key, ' ');
  21.   until key = 'q';
  22.  
  23.   tcSetAttr(StdInputHandle, TCSANOW, oldTermios);
  24. END.

Same problem in PTC:
Code: Pascal  [Select][+][-]
  1. PROGRAM
  2.   nKeyRollOverTest_PTC;
  3. USES
  4.   ptc;
  5. VAR
  6.   console: IPTCConsole;
  7.   format: IPTCFormat;
  8.   key: IPTCKeyEvent;
  9. BEGIN
  10.   console := TPTCConsoleFactory.CreateNew;
  11.   format := TPTCFormatFactory.CreateNew(32, $00FF0000, $0000FF00, $000000FF);
  12.   console.open('Keyboard example', 1,1 , format);
  13.  
  14.   repeat
  15.     while console.KeyPressed do begin
  16.       console.ReadKey(key);
  17.       write(key.code, ' ');
  18.       if key.code = PTCKEY_ESCAPE then halt;
  19.     end;
  20.   until False;
  21.  
  22.   console.close;
  23. END.
« Last Edit: April 01, 2024, 10:40:32 pm by Darie »
The sphere of knowledge is in continuous expansion. So is the contact of it's points with the unknown --Blaise Pascal

Darie

  • New Member
  • *
  • Posts: 31
Re: Yet Another [kbReleased] question - help needed
« Reply #4 on: April 02, 2024, 04:57:43 pm »
Here is an overkill workaround for those who must have acces to a key_released event in terminal, based on SDL2:

Code: Pascal  [Select][+][-]
  1. USES
  2.   SDL2;
  3. VAR
  4.   quit: boolean = false;
  5.   win: PSDL_Window;
  6.   evt: TSDL_Event;
  7. BEGIN
  8.   if sdl_init(SDL_INIT_VIDEO) < 0 then HALT;
  9.   win := sdl_createWindow('hidden', 1,1 , 1,1 , SDL_WINDOW_BORDERLESS
  10.               or SDL_WINDOW_ALWAYS_ON_TOP or SDL_WINDOW_SKIP_TASKBAR);
  11.   if win = nil then halt;
  12.   repeat
  13.     sdl_raiseWindow(win); //win
  14.     sdl_setWindowInputFocus(win); //nix
  15.     while sdl_pollEvent(@evt) = 1 do case evt.type_ of
  16.       SDL_KEYUP: write(sdl_getKeyName(evt.key.keysym.sym));
  17.       SDL_KEYDOWN: if evt.key.keysym.sym = SDLK_ESCAPE then quit := true;
  18.     end;
  19.     sdl_delay(50);
  20.   until quit;
  21.   sdl_destroyWindow(win);
  22.   sdl_quit;
  23. END.

As I was saying, although I understand the legacy and the new imperatives, I do not think that such functionality should be missing from a high-level programming language. Given that until now the things have been in a certain way it does not mean than one should stop improving upon. We have a helicopter on Mars but we cannot handle key_released in terminal. I mean... c'mon!

Surely, this (lack of key_released) and the lack of beep are OS implementation issues. But behind these lacking features are dev-teams decisions. And coming front (or hiding behind) by saying "we have / the team has decided...", or "legacy", does not make things right and some times it just hides mediocrity or the failure of taking a better decision. As a developer I know that interacting mostly with a machine all day long may dull one's sensibility towards such aspects. Nevertheless, that does not make things right.

Thanks, and I hope this helps.
« Last Edit: April 04, 2024, 09:20:59 am by Darie »
The sphere of knowledge is in continuous expansion. So is the contact of it's points with the unknown --Blaise Pascal

 

TinyPortal © 2005-2018