March 21, 2011 Re: Get single keystroke? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Sean Eskapp | On 3/21/11, Sean Eskapp <eatingstaples@gmail.com> wrote: > What about on Linux? > I'm not sure. Both DMD and GDC can run the example on Windows. Perhaps they've got these functions implemented for Linux as well. But according to this: https://secure.wikimedia.org/wikipedia/en/wiki/Conio.h it seems these functions are usually only available for compilers targeting Windows. Have you tried compiling it on Linux, or does it fail to link? |
March 21, 2011 Re: Get single keystroke? | ||||
---|---|---|---|---|
| ||||
It looks like its not available on Linux, I've just tried with DMD. |
March 21, 2011 Re: Get single keystroke? | ||||
---|---|---|---|---|
| ||||
I believe I've found you a solution: import std.c.stdio; import std.c.linux.termios; extern(C) void cfmakeraw(termios *termios_p); void main() { termios ostate; /* saved tty state */ termios nstate; /* values for editor mode */ // Open stdin in raw mode /* Adjust output channel */ tcgetattr(1, &ostate); /* save old state */ tcgetattr(1, &nstate); /* get base of new state */ cfmakeraw(&nstate); tcsetattr(1, TCSADRAIN, &nstate); /* set mode */ // Read characters in raw mode writefln("The key hit is %s", cast(char)fgetc(stdin)); // Close tcsetattr(1, TCSADRAIN, &ostate); // return to original mode } I've tested this under Ubuntu and DMD 2.052 and it works. |
March 21, 2011 Re: Get single keystroke? | ||||
---|---|---|---|---|
| ||||
Woops forgot to add import std.stdio, here's a fixed version: import std.stdio : writefln; import std.c.stdio; import std.c.linux.termios; extern(C) void cfmakeraw(termios *termios_p); void main() { termios ostate; /* saved tty state */ termios nstate; /* values for editor mode */ // Open stdin in raw mode /* Adjust output channel */ tcgetattr(1, &ostate); /* save old state */ tcgetattr(1, &nstate); /* get base of new state */ cfmakeraw(&nstate); tcsetattr(1, TCSADRAIN, &nstate); /* set mode */ // Read characters in raw mode writefln("The key hit is %s", cast(char)fgetc(stdin)); // Close tcsetattr(1, TCSADRAIN, &ostate); // return to original mode } |
March 21, 2011 Re: Get single keystroke? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Andrej Mitrovic | == Quote from Andrej Mitrovic (andrej.mitrovich@gmail.com)'s article > I believe I've found you a solution: > import std.c.stdio; > import std.c.linux.termios; > extern(C) void cfmakeraw(termios *termios_p); > void main() { > termios ostate; /* saved tty state */ > termios nstate; /* values for editor mode */ > // Open stdin in raw mode > /* Adjust output channel */ > tcgetattr(1, &ostate); /* save old state */ > tcgetattr(1, &nstate); /* get base of new state */ > cfmakeraw(&nstate); > tcsetattr(1, TCSADRAIN, &nstate); /* set mode */ > // Read characters in raw mode > writefln("The key hit is %s", cast(char)fgetc(stdin)); > // Close > tcsetattr(1, TCSADRAIN, &ostate); // return to original mode > } > I've tested this under Ubuntu and DMD 2.052 and it works. Great, thanks! |
March 21, 2011 Re: Get single keystroke? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Andrej Mitrovic | On Mon, 21 Mar 2011 23:22:17 +0100, Andrej Mitrovic wrote: > Woops forgot to add import std.stdio, here's a fixed version: > > import std.stdio : writefln; > import std.c.stdio; > import std.c.linux.termios; > > extern(C) void cfmakeraw(termios *termios_p); > > void main() > { > termios ostate; /* saved tty state */ termios > nstate; /* values for editor mode */ > > // Open stdin in raw mode > /* Adjust output channel */ > tcgetattr(1, &ostate); /* save old state */ > tcgetattr(1, &nstate); /* get base of new > state */ cfmakeraw(&nstate); > tcsetattr(1, TCSADRAIN, &nstate); /* set mode */ > > // Read characters in raw mode > writefln("The key hit is %s", cast(char)fgetc(stdin)); > > // Close > tcsetattr(1, TCSADRAIN, &ostate); // return to original mode > } It looks like this can be dangerous, because the terminal can be left in an unusable state. Please read this: http://groups.google.com/group/comp.os.linux.development.apps/ browse_thread/thread/0667d16089e2b6fc |
March 21, 2011 Re: Get single keystroke? | ||||
---|---|---|---|---|
| ||||
Posted in reply to teo | On 3/21/11, teo <teo.ubuntu@yahoo.com> wrote:
> On Mon, 21 Mar 2011 23:22:17 +0100, Andrej Mitrovic wrote:
>
>> Woops forgot to add import std.stdio, here's a fixed version:
>>
>> import std.stdio : writefln;
>> import std.c.stdio;
>> import std.c.linux.termios;
>>
>> extern(C) void cfmakeraw(termios *termios_p);
>>
>> void main()
>> {
>> termios ostate; /* saved tty state */ termios
>> nstate; /* values for editor mode */
>>
>> // Open stdin in raw mode
>> /* Adjust output channel */
>> tcgetattr(1, &ostate); /* save old state */
>> tcgetattr(1, &nstate); /* get base of new
>> state */ cfmakeraw(&nstate);
>> tcsetattr(1, TCSADRAIN, &nstate); /* set mode */
>>
>> // Read characters in raw mode
>> writefln("The key hit is %s", cast(char)fgetc(stdin));
>>
>> // Close
>> tcsetattr(1, TCSADRAIN, &ostate); // return to original mode
>> }
>
> It looks like this can be dangerous, because the terminal can be left in an unusable state. Please read this: http://groups.google.com/group/comp.os.linux.development.apps/ browse_thread/thread/0667d16089e2b6fc
>
H mentions using tcgetattr to save old state and restoring it with tcsetattr. This is what this code does. Btw this code is not mine, Walter posted it and I just added the cfmakeraw prototype. So kudos goes to him.
|
March 22, 2011 Re: Get single keystroke? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Andrej Mitrovic | On 03/21/2011 03:37 PM, Andrej Mitrovic wrote: > On 3/21/11, teo<teo.ubuntu@yahoo.com> wrote: >> On Mon, 21 Mar 2011 23:22:17 +0100, Andrej Mitrovic wrote: >> >>> Woops forgot to add import std.stdio, here's a fixed version: >>> >>> import std.stdio : writefln; >>> import std.c.stdio; >>> import std.c.linux.termios; >>> >>> extern(C) void cfmakeraw(termios *termios_p); >>> >>> void main() >>> { >>> termios ostate; /* saved tty state */ termios >>> nstate; /* values for editor mode */ >>> >>> // Open stdin in raw mode >>> /* Adjust output channel */ >>> tcgetattr(1,&ostate); /* save old state */ >>> tcgetattr(1,&nstate); /* get base of new >>> state */ cfmakeraw(&nstate); >>> tcsetattr(1, TCSADRAIN,&nstate); /* set mode */ >>> >>> // Read characters in raw mode >>> writefln("The key hit is %s", cast(char)fgetc(stdin)); >>> >>> // Close >>> tcsetattr(1, TCSADRAIN,&ostate); // return to original mode >>> } >> >> It looks like this can be dangerous, because the terminal can be left in >> an unusable state. Please read this: >> http://groups.google.com/group/comp.os.linux.development.apps/ >> browse_thread/thread/0667d16089e2b6fc >> > > H mentions using tcgetattr to save old state and restoring it with > tcsetattr. This is what this code does. Btw this code is not mine, > Walter posted it and I just added the cfmakeraw prototype. So kudos > goes to him. Thanks for posting this. It can be improved by moving the last tcsetattr to an earlier scope(exit) statement: termios ostate; tcgetattr(1, &ostate); scope (exit) tcsetattr(1, TCSADRAIN, &ostate); Ali |
Copyright © 1999-2021 by the D Language Foundation