www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Capturing keystrokes

reply "Chris" <wendlec tcd.ie> writes:
Just out of interest, is there a way of capturing keystrokes in 
D? E.g. if you have a CLI application that wants to capture 
Ctrl+... and the like, and possibly control the cursor.
Feb 07 2014
next sibling parent "Paul Freund" <freund.paul lvl3.org> writes:
On Friday, 7 February 2014 at 12:17:42 UTC, Chris wrote:
 Just out of interest, is there a way of capturing keystrokes in 
 D? E.g. if you have a CLI application that wants to capture 
 Ctrl+... and the like, and possibly control the cursor.

You can achieve this by interfacing operating system functions. If your target is windows you can take a look at my ScrollLocker project (https://github.com/PaulFreund/ScrollLocker). It is written in D and uses SetWindowsHookEx and WH_KEYBOARD_LL (low level keyboard hook) to capture key strokes (see helper/hooks.d). There should be similiar facilitys in other OS as well. It should also be possible to get certain combinations in the cmd/shell but I don't know how.
Feb 07 2014
prev sibling next sibling parent "Chris" <wendlec tcd.ie> writes:
On Friday, 7 February 2014 at 12:32:25 UTC, Paul Freund wrote:
 On Friday, 7 February 2014 at 12:17:42 UTC, Chris wrote:
 Just out of interest, is there a way of capturing keystrokes 
 in D? E.g. if you have a CLI application that wants to capture 
 Ctrl+... and the like, and possibly control the cursor.

You can achieve this by interfacing operating system functions. If your target is windows you can take a look at my ScrollLocker project (https://github.com/PaulFreund/ScrollLocker). It is written in D and uses SetWindowsHookEx and WH_KEYBOARD_LL (low level keyboard hook) to capture key strokes (see helper/hooks.d). There should be similiar facilitys in other OS as well. It should also be possible to get certain combinations in the cmd/shell but I don't know how.

Thanks for the link. It's a good starting point. I'm on Linux, so I'll have a look at the corresponding functions.
Feb 07 2014
prev sibling next sibling parent "Adam D. Ruppe" <destructionator gmail.com> writes:
On Friday, 7 February 2014 at 12:17:42 UTC, Chris wrote:
 Just out of interest, is there a way of capturing keystrokes in 
 D?

This isn't so much a D question as a C one - the operating system's C api will give a way, then you use those same functions in D. If you want input from your own terminal, my terminal.d might help. See the demo main here: https://github.com/adamdruppe/misc-stuff-including-D-programming-language-web-stuff/blob/master/terminal.d#L2007 It captures as much info as possible in real time, optionally including window resize events, mouse motion and clicks, and key presses. (Also key releases on Windows, but such information is /not/ available on Linux.) Ctrl+x keys are sent as as low ascii values. Ctrl+a is cast(char) 1. Ctrl+b is cast(char) 2. Ctrl+c is sent as cast(char) 3 (though note control+c is captured by the OS and sent as an interrupt signal instead - my lib can catch that too). and so on through Ctrl+z which is 26. You can get more information by doing a GUI program but then you'll have to do text output as gui too, so not as easy as cli. Of course, you could write a terminal emulator and have the best of both worlds... i've done it :) https://github.com/adamdruppe/terminal-emulator But I think terminal.d is what you want. Now, if you want to capture input from ANY window, not just your own, on Windows you can use the API to capture the keyboard, on X you can listen to events on the root window, and on Linux you can also read /dev/input to get raw keyboard events (if you like, I have a small lib that can help with this too). Note that reading /dev/input needs your program to be root.
Feb 07 2014
prev sibling next sibling parent "Chris" <wendlec tcd.ie> writes:
On Friday, 7 February 2014 at 15:40:06 UTC, Adam D. Ruppe wrote:
 On Friday, 7 February 2014 at 12:17:42 UTC, Chris wrote:
 Just out of interest, is there a way of capturing keystrokes 
 in D?

This isn't so much a D question as a C one - the operating system's C api will give a way, then you use those same functions in D. If you want input from your own terminal, my terminal.d might help. See the demo main here: https://github.com/adamdruppe/misc-stuff-including-D-programming-language-web-stuff/blob/master/terminal.d#L2007 It captures as much info as possible in real time, optionally including window resize events, mouse motion and clicks, and key presses. (Also key releases on Windows, but such information is /not/ available on Linux.) Ctrl+x keys are sent as as low ascii values. Ctrl+a is cast(char) 1. Ctrl+b is cast(char) 2. Ctrl+c is sent as cast(char) 3 (though note control+c is captured by the OS and sent as an interrupt signal instead - my lib can catch that too). and so on through Ctrl+z which is 26. You can get more information by doing a GUI program but then you'll have to do text output as gui too, so not as easy as cli. Of course, you could write a terminal emulator and have the best of both worlds... i've done it :) https://github.com/adamdruppe/terminal-emulator But I think terminal.d is what you want. Now, if you want to capture input from ANY window, not just your own, on Windows you can use the API to capture the keyboard, on X you can listen to events on the root window, and on Linux you can also read /dev/input to get raw keyboard events (if you like, I have a small lib that can help with this too). Note that reading /dev/input needs your program to be root.

I just had a look at terminal.d. Great stuff. It works, though it sometimes stops working and gives me this exception (after killing it with Ctrl+C): object.Exception terminal.d(814): write failed for some reason There is a syntax error on line 54; version = Demo should be version = Demo; I'll have a look at your other stuff too, it looks very interesting.
Feb 07 2014
prev sibling next sibling parent "Chris" <wendlec tcd.ie> writes:
On Friday, 7 February 2014 at 16:21:20 UTC, Chris wrote:
 On Friday, 7 February 2014 at 15:40:06 UTC, Adam D. Ruppe wrote:
 On Friday, 7 February 2014 at 12:17:42 UTC, Chris wrote:
 Just out of interest, is there a way of capturing keystrokes 
 in D?

This isn't so much a D question as a C one - the operating system's C api will give a way, then you use those same functions in D. If you want input from your own terminal, my terminal.d might help. See the demo main here: https://github.com/adamdruppe/misc-stuff-including-D-programming-language-web-stuff/blob/master/terminal.d#L2007 It captures as much info as possible in real time, optionally including window resize events, mouse motion and clicks, and key presses. (Also key releases on Windows, but such information is /not/ available on Linux.) Ctrl+x keys are sent as as low ascii values. Ctrl+a is cast(char) 1. Ctrl+b is cast(char) 2. Ctrl+c is sent as cast(char) 3 (though note control+c is captured by the OS and sent as an interrupt signal instead - my lib can catch that too). and so on through Ctrl+z which is 26. You can get more information by doing a GUI program but then you'll have to do text output as gui too, so not as easy as cli. Of course, you could write a terminal emulator and have the best of both worlds... i've done it :) https://github.com/adamdruppe/terminal-emulator But I think terminal.d is what you want. Now, if you want to capture input from ANY window, not just your own, on Windows you can use the API to capture the keyboard, on X you can listen to events on the root window, and on Linux you can also read /dev/input to get raw keyboard events (if you like, I have a small lib that can help with this too). Note that reading /dev/input needs your program to be root.

I just had a look at terminal.d. Great stuff. It works, though it sometimes stops working and gives me this exception (after killing it with Ctrl+C): object.Exception terminal.d(814): write failed for some reason There is a syntax error on line 54; version = Demo should be version = Demo; I'll have a look at your other stuff too, it looks very interesting.

It actually breaks when I press a modifier key like Ctrl.
Feb 07 2014
prev sibling next sibling parent "Adam D. Ruppe" <destructionator gmail.com> writes:
On Friday, 7 February 2014 at 16:58:48 UTC, Chris wrote:
 It actually breaks when I press a modifier key like Ctrl.

Ctrl alone or ctrl+ a key? Also which terminal emulator and any error message?
Feb 07 2014
prev sibling next sibling parent "Chris" <wendlec tcd.ie> writes:
On Friday, 7 February 2014 at 18:03:06 UTC, Adam D. Ruppe wrote:
 On Friday, 7 February 2014 at 16:58:48 UTC, Chris wrote:
 It actually breaks when I press a modifier key like Ctrl.

Ctrl alone or ctrl+ a key? Also which terminal emulator and any error message?

I used the xfce terminal. If I remember correctly, it would happen after just pressing Ctrl. It doesn't happen always but often enough. I'll check the details when I'm back at the machine I used.
Feb 09 2014
prev sibling next sibling parent 1100110 <0b1100110 gmail.com> writes:
On 2/7/14, 6:17, Chris wrote:
 Just out of interest, is there a way of capturing keystrokes in D? E.g.
 if you have a CLI application that wants to capture Ctrl+... and the
 like, and possibly control the cursor.

Check the Deimos github repo. (github.com/D-Programming-Deimos/ncurses I think) Ncurses bindings live in there. It can do everything you mention and more. If you decide to use it, let me know if you find any bugs.
Feb 09 2014
prev sibling next sibling parent "Chris" <wendlec tcd.ie> writes:
On Sunday, 9 February 2014 at 22:01:46 UTC, 1100110 wrote:
 On 2/7/14, 6:17, Chris wrote:
 Just out of interest, is there a way of capturing keystrokes 
 in D? E.g.
 if you have a CLI application that wants to capture Ctrl+... 
 and the
 like, and possibly control the cursor.

Check the Deimos github repo. (github.com/D-Programming-Deimos/ncurses I think) Ncurses bindings live in there. It can do everything you mention and more. If you decide to use it, let me know if you find any bugs.

Brilliant, thanks. It completely escaped me that ncurses was in the Deimos repo.
Feb 10 2014
prev sibling next sibling parent "Chris" <wendlec tcd.ie> writes:
On Friday, 7 February 2014 at 18:03:06 UTC, Adam D. Ruppe wrote:
 On Friday, 7 February 2014 at 16:58:48 UTC, Chris wrote:
 It actually breaks when I press a modifier key like Ctrl.

Ctrl alone or ctrl+ a key? Also which terminal emulator and any error message?

Adam The first time I stated ./terminal it worked fine (including Ctrl+) until I hit Ctrl+Shift. It went on strike right there. After restarting, anytime I click Ctrl it just hangs. After killing it I get the following error notification: object.Exception terminal.d(814): write failed for some reason ---------------- ./terminal(terminal.InputEvent[] terminal.RealTimeConsoleInput.readNextEvents()+0x5c) [0x467ff0] ./terminal(terminal.InputEvent terminal.RealTimeConsoleInput.nextEvent()+0x19f) [0x467d53] ./terminal(_Dmain+0x177) [0x469673] ./terminal(void rt.dmain2._d_run_main(int, char**, extern (C) int function(char[][])*).runAll().void __lambda1()+0x18) [0x481c24] ./terminal(void rt.dmain2._d_run_main(int, char**, extern (C) int function(char[][])*).tryExec(scope void delegate())+0x2a) [0x481b7e] ./terminal(void rt.dmain2._d_run_main(int, char**, extern (C) int function(char[][])*).runAll()+0x30) [0x481be4] ./terminal(void rt.dmain2._d_run_main(int, char**, extern (C) int function(char[][])*).tryExec(scope void delegate())+0x2a) [0x481b7e] ./terminal(_d_run_main+0x1a3) [0x481aff] ./terminal(main+0x17) [0x47cceb] /lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0xed) [0x7f4e040f976d] I used Xfce Terminal Emulator 0.4.8. on Ubuntu 12.04 (or .10?) LTS (with Xfce desktop)
Feb 10 2014
prev sibling next sibling parent "Dejan Lekic" <dejan.lekic gmail.com> writes:
 Brilliant, thanks. It completely escaped me that ncurses was in 
 the Deimos repo.

Note that NCurses needs ncurses library, while Adam's terminal introduces no dependency, and is pretty much usable on both POSIX and Windows environments.
Feb 10 2014
prev sibling next sibling parent "Chris" <wendlec tcd.ie> writes:
On Monday, 10 February 2014 at 14:32:44 UTC, Dejan Lekic wrote:
 Brilliant, thanks. It completely escaped me that ncurses was 
 in the Deimos repo.

Note that NCurses needs ncurses library, while Adam's terminal introduces no dependency, and is pretty much usable on both POSIX and Windows environments.

I know, but now I have the choice. Whatever suits better for the task at hand.
Feb 10 2014
prev sibling next sibling parent "Adam D. Ruppe" <destructionator gmail.com> writes:
On Monday, 10 February 2014 at 14:21:59 UTC, Chris wrote:
 The first time I stated ./terminal it worked fine (including 
 Ctrl+) until I hit Ctrl+Shift. It went on strike right there. 
 After restarting, anytime I click Ctrl it just hangs.

Weird, it must be sending a special escape sequence on it.... it works for me though on my 0.4.4 xfce terminal.... well, mostly works, I got the *terminal* to freeze up by opening and closing a few tabs, blargh. idk what the problem is though, I'd say give ncurses a try and if it works for you, that should be good.
Feb 10 2014
prev sibling parent "Chris" <wendlec tcd.ie> writes:
On Monday, 10 February 2014 at 23:23:41 UTC, Adam D. Ruppe wrote:
 On Monday, 10 February 2014 at 14:21:59 UTC, Chris wrote:
 The first time I stated ./terminal it worked fine (including 
 Ctrl+) until I hit Ctrl+Shift. It went on strike right there. 
 After restarting, anytime I click Ctrl it just hangs.

Weird, it must be sending a special escape sequence on it.... it works for me though on my 0.4.4 xfce terminal.... well, mostly works, I got the *terminal* to freeze up by opening and closing a few tabs, blargh. idk what the problem is though, I'd say give ncurses a try and if it works for you, that should be good.

Would be great, if this problem could be sorted out though. terminal.d seems to be pretty handy.
Feb 11 2014