www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - obtaining keyboard scan codes

reply Andrew Edwards <ridimz_at yahoo.dot.com> writes:
The C function getch() provides a means to access most control 
characters from the keyboard, but how do I go about obtaining the ones 
it does not cover?

Specifically these:

enum {
   KEY_HOME    =  ##,
   KEY_UP      =  ##,
   KEY_PGUP    =  ##,
   KEY_LEFT    =  ##,
   KEY_CENTER  =  ##,
   KEY_RIGHT   =  ##,
   KEY_END     =  ##,
   KEY_DOWN    =  ##,
   KEY_PGDN    =  ##,
   KEY_INSERT  =  ##,
   KEY_DELETE  =  ##,
   KEY_F1      =  ##,
   KEY_F2      =  ##,
   KEY_F3      =  ##,
   KEY_F4      =  ##,
   KEY_F5      =  ##,
   KEY_F7      =  ##,
   KEY_F8      =  ##,
   KEY_F9      =  ##,
   ...
}

Thanks,
Andrew
Jul 06 2004
next sibling parent reply "Pablo Aguilar" <paguilarg hotmail.com> writes:
You have to call getch() twice, the first call returns a value of 0, while
the second returns the scan code for the key (scan code, not character code
since the keys you're looking for have no character code)

so you end up having something like a nested switch statement and you can't
do:

c = getch();
if( c == 0 )
 c = getch();

and then switch, because the scan codes are valid character codes (for
instance, I think F1's scan code gives you a ';' scan code)

So, this is how it used to be in C, I'm assuming it still works the same in
D
Hope it helps

 The C function getch() provides a means to access most control
 characters from the keyboard, but how do I go about obtaining the ones
 it does not cover?

 Specifically these:

 enum {
    KEY_HOME    =  ##,
    KEY_UP      =  ##,
    KEY_PGUP    =  ##,
    KEY_LEFT    =  ##,
    KEY_CENTER  =  ##,
    KEY_RIGHT   =  ##,
    KEY_END     =  ##,
    KEY_DOWN    =  ##,
    KEY_PGDN    =  ##,
    KEY_INSERT  =  ##,
    KEY_DELETE  =  ##,
    KEY_F1      =  ##,
    KEY_F2      =  ##,
    KEY_F3      =  ##,
    KEY_F4      =  ##,
    KEY_F5      =  ##,
    KEY_F7      =  ##,
    KEY_F8      =  ##,
    KEY_F9      =  ##,
    ...
 }

 Thanks,
 Andrew

Jul 06 2004
parent "Carlos Santander B." <carlos8294 msn.com> writes:
"Pablo Aguilar" <paguilarg hotmail.com> escribió en el mensaje
news:ccfirl$1ttr$1 digitaldaemon.com
| You have to call getch() twice, the first call returns a value of 0, while
| the second returns the scan code for the key (scan code, not character
code
| since the keys you're looking for have no character code)
|
| so you end up having something like a nested switch statement and you
can't
| do:
|
| c = getch();
| if( c == 0 )
|  c = getch();
|
| and then switch, because the scan codes are valid character codes (for
| instance, I think F1's scan code gives you a ';' scan code)
|
| So, this is how it used to be in C, I'm assuming it still works the same
in
| D
| Hope it helps
|

Essentially right, but I just don't think that works on Linux (just in
case).

-----------------------
Carlos Santander Bernal
Jul 06 2004
prev sibling next sibling parent "Walter" <newshound digitalmars.com> writes:
You can look at the source to microEmacs, which does this. See
www.digitalmars.com
Jul 06 2004
prev sibling next sibling parent reply Arcane Jill <Arcane_member pathlink.com> writes:
In article <ccff0l$1os5$1 digitaldaemon.com>, Andrew Edwards says...
The C function getch() provides a means to access most control 
characters from the keyboard,

A brief interjection about technical jargon here. If a keystroke generates an ASCII control code (a single character code in the range 0x00 to 1x1F inclusive), then it CAN be detected by getch(). For historical reasons, certain keystrokes do generate ASCII control codes (characters in the range 0x00 to 0x1F). However, not all keys can be guaranteed to do this. Many, such as the cursor keys, for example, send "control sequences" to a console (and that's assuming a command-line app which HAS a console). The problem is not that you can't detect control codes, it's that many keys don't generation them. More often than not, pressing a key will generate some VT102 and ECMA-48/ISO 6429/ANSI X3.64 terminal control /sequence/. And of course, the whole process is ENTIRELY platform dependent. In short, getch() cannot be guaranteed to return a single character from each key. but how do I go about obtaining the ones
it does not cover?

Specifically these:

enum {
   KEY_HOME    =  ##,
   KEY_UP      =  ##,
   KEY_PGUP    =  ##,
   KEY_LEFT    =  ##,
   KEY_CENTER  =  ##,
   KEY_RIGHT   =  ##,
   KEY_END     =  ##,
   KEY_DOWN    =  ##,
   KEY_PGDN    =  ##,
   KEY_INSERT  =  ##,
   KEY_DELETE  =  ##,
   KEY_F1      =  ##,
   KEY_F2      =  ##,
   KEY_F3      =  ##,
   KEY_F4      =  ##,
   KEY_F5      =  ##,
   KEY_F7      =  ##,
   KEY_F8      =  ##,
   KEY_F9      =  ##,
   ...
}

Thanks,
Andrew

First off, this is not a D question. You have exactly the same problem in any language. The answer, however, is that there is NO WAY to achieve this in a platform-independent way. For a start, not all keyboards actually HAVE the above keys. For another thing, not all keystrokes send single bytes. Some send multiple bytes. For a third thing, a "scan code" (the term used in your subject title) is not EVEN the same thing as what I assume you intended by the phrase "control character" in your opening paragraph. A scan code is a hardware number (which will ALSO differ from keyboard to keyboard, and from operating system to operating system). The bytes emitted up through the event queue (what you called "control characters") are a software concept. For example, SHIFT and A will have two separate scan codes, but the single character 'A' will be percieved by getch(). In theory, of course, any key COULD be programmed to act like a shift key. And for a fourth thing, not all computers even have keyboards! Sorry if this reply is a bit of a downer, but you have at least identified an important area where D-in-the-future might need to go. It occurs to me that a std module to address exactly this area might be a very good thing. Such a module could define an enum (at LEAST sixteen bits wide, but let's make it 32 to be safe) containing an enumerated value for every possible key on every known keyboard in the world (including Chinese and Russian keyboards, and maybe even including those mad extra keys you get these days like "LAUNCH WEB BROWSER"?). Such a module could provide a getch()-like function. But it's time to drop the old way of thinking that each valid key combination must generate exactly one ASCII character. D doesn't even /use/ ASCII, except as a subset of Unicode, and - in Unicode - the meaning of characters 0x00 to 0x1F is undefined (apart for whitespace and linebreak properties). Those ancient "control codes" to which you refer hark back to the days of punched paper tape, when if you hit control-H on your keyboard, a physical bell would ring on the teletype. We're way past that paradigm now, so expecting it to still work just like it used to is asking too much. There are just too many keys on a keyboard for that to be feasable, these days (and that's ignoring things like Input Method Editors, and so on). It's not a D problem, it's a problem inherent in all computer languages. But maybe, if someone has time (and I don't), it could be D that provides the comprehensive solution. We are already providing that solution with OUTPUT (Unicode). Maybe we could provide a similar solution for INPUT. Just my thoughts. My apologies to Andrew for being completely unhelpful. Arcane Jill
Jul 07 2004
next sibling parent "Bent Rasmussen" <exo bent-rasmussen.info> writes:
 It's not a D problem, it's a problem inherent in all computer languages.

 maybe, if someone has time (and I don't), it could be D that provides the
 comprehensive solution. We are already providing that solution with OUTPUT
 (Unicode). Maybe we could provide a similar solution for INPUT.

Sounds like a great idea.
 Just my thoughts. My apologies to Andrew for being completely unhelpful.

 Arcane Jill

Jul 07 2004
prev sibling next sibling parent reply "Walter" <newshound digitalmars.com> writes:
"Arcane Jill" <Arcane_member pathlink.com> wrote in message
news:ccg8g9$2sqb$1 digitaldaemon.com...
 It's not a D problem, it's a problem inherent in all computer languages.

 maybe, if someone has time (and I don't), it could be D that provides the
 comprehensive solution. We are already providing that solution with OUTPUT
 (Unicode). Maybe we could provide a similar solution for INPUT.

I've been through this exact problem with multiple machines. For DOS, Windows, and Linux, the solutions are in the microEmacs source downloadable from the front page www.digitalmars.com.
Jul 07 2004
next sibling parent Andrew <Andrew_member pathlink.com> writes:
In article <cchajm$1c8n$1 digitaldaemon.com>, Walter says...
"Arcane Jill" <Arcane_member pathlink.com> wrote in message
news:ccg8g9$2sqb$1 digitaldaemon.com...
 It's not a D problem, it's a problem inherent in all computer languages.

 maybe, if someone has time (and I don't), it could be D that provides the
 comprehensive solution. We are already providing that solution with OUTPUT
 (Unicode). Maybe we could provide a similar solution for INPUT.

I've been through this exact problem with multiple machines. For DOS, Windows, and Linux, the solutions are in the microEmacs source downloadable from the front page www.digitalmars.com.

Which I will be looking at as soon as I get off work! Thanks, Andrew
Jul 07 2004
prev sibling parent Anderw <Anderw_member pathlink.com> writes:
In article <cchajm$1c8n$1 digitaldaemon.com>, Walter says...
"Arcane Jill" <Arcane_member pathlink.com> wrote in message
news:ccg8g9$2sqb$1 digitaldaemon.com...
 It's not a D problem, it's a problem inherent in all computer languages.

 maybe, if someone has time (and I don't), it could be D that provides the
 comprehensive solution. We are already providing that solution with OUTPUT
 (Unicode). Maybe we could provide a similar solution for INPUT.

I've been through this exact problem with multiple machines. For DOS, Windows, and Linux, the solutions are in the microEmacs source downloadable from the front page www.digitalmars.com.

Thanks! I'll check it out as soon as I get a chance.
Jul 07 2004
prev sibling parent reply Andrew <Andrew_member pathlink.com> writes:
In article <ccg8g9$2sqb$1 digitaldaemon.com>, Arcane Jill says...
In article <ccff0l$1os5$1 digitaldaemon.com>, Andrew Edwards says...
The C function getch() provides a means to access most control 
characters from the keyboard,

A brief interjection about technical jargon here. If a keystroke generates an ASCII control code (a single character code in the range 0x00 to 1x1F inclusive), then it CAN be detected by getch(). For historical reasons, certain keystrokes do generate ASCII control codes (characters in the range 0x00 to 0x1F). However, not all keys can be guaranteed to do this. Many, such as the cursor keys, for example, send "control sequences" to a console (and that's assuming a command-line app which HAS a console). The problem is not that you can't detect control codes, it's that many keys don't generation them. More often than not, pressing a key will generate some VT102 and ECMA-48/ISO 6429/ANSI X3.64 terminal control /sequence/. And of course, the whole process is ENTIRELY platform dependent. In short, getch() cannot be guaranteed to return a single character from each key.

Which is exactly why I requested this information! I'd like to implement a UNICODE version for D.
but how do I go about obtaining the ones 
it does not cover?

Specifically these:

enum {
   KEY_HOME    =  ##,
   KEY_UP      =  ##,
   KEY_PGUP    =  ##,
   KEY_LEFT    =  ##,
   KEY_CENTER  =  ##,
   KEY_RIGHT   =  ##,
   KEY_END     =  ##,
   KEY_DOWN    =  ##,
   KEY_PGDN    =  ##,
   KEY_INSERT  =  ##,
   KEY_DELETE  =  ##,
   KEY_F1      =  ##,
   KEY_F2      =  ##,
   KEY_F3      =  ##,
   KEY_F4      =  ##,
   KEY_F5      =  ##,
   KEY_F7      =  ##,
   KEY_F8      =  ##,
   KEY_F9      =  ##,
   ...
}

Thanks,
Andrew

First off, this is not a D question. You have exactly the same problem in any language. The answer, however, is that there is NO WAY to achieve this in a platform-independent way. For a start, not all keyboards actually HAVE the above keys. For another thing, not all keystrokes send single bytes. Some send multiple bytes. For a third thing, a "scan code" (the term used in your subject title) is not EVEN the same thing as what I assume you intended by the phrase "control character" in your opening paragraph. A scan code is a hardware number (which will ALSO differ from keyboard to keyboard, and from operating system to operating system). The bytes emitted up through the event queue (what you called "control characters") are a software concept. For example, SHIFT and A will have two separate scan codes, but the single character 'A' will be percieved by getch(). In theory, of course, any key COULD be programmed to act like a shift key. And for a fourth thing, not all computers even have keyboards! Sorry if this reply is a bit of a downer, but you have at least identified an important area where D-in-the-future might need to go. It occurs to me that a std module to address exactly this area might be a very good thing. Such a module could define an enum (at LEAST sixteen bits wide, but let's make it 32 to be safe) containing an enumerated value for every possible key on every known keyboard in the world (including Chinese and Russian keyboards, and maybe even including those mad extra keys you get these days like "LAUNCH WEB BROWSER"?). Such a module could provide a getch()-like function. But it's time to drop the old way of thinking that each valid key combination must generate exactly one ASCII character. D doesn't even /use/ ASCII, except as a subset of Unicode, and - in Unicode - the meaning of characters 0x00 to 0x1F is undefined (apart for whitespace and linebreak properties). Those ancient "control codes" to which you refer hark back to the days of punched paper tape, when if you hit control-H on your keyboard, a physical bell would ring on the teletype. We're way past that paradigm now, so expecting it to still work just like it used to is asking too much. There are just too many keys on a keyboard for that to be feasable, these days (and that's ignoring things like Input Method Editors, and so on). It's not a D problem, it's a problem inherent in all computer languages. But maybe, if someone has time (and I don't), it could be D that provides the comprehensive solution. We are already providing that solution with OUTPUT (Unicode). Maybe we could provide a similar solution for INPUT. Just my thoughts. My apologies to Andrew for being completely unhelpful. Arcane Jill

Jul 07 2004
parent reply Arcane Jill <Arcane_member pathlink.com> writes:
In article <cche3t$1h6i$1 digitaldaemon.com>, Andrew says...

In short, getch() cannot be guaranteed to return a single character from each
key.

Which is exactly why I requested this information! I'd like to implement a UNICODE version for D.

Oh Cool! Be the one. Just remember though that Unicode only defines characters, not keys. So, returning (say) a Russian letter from a Russian keyboard would fit nicely within your paradigm, but if the user presses CURSOR-LEFT or F10 or NUMERIC-KEYPAD-PLUS, there will actually be /no/ Unicode character defined to represent these keys. You can't use unassigned codepoints, because what is unassigned in Unicode today won't necessarily be unassigned in Unicode tomorrow. You can't use private use characters because that might conflict with someone's private mapping. So I'd suggest inventing your own standard. And I'd suggest you make use of numerical values greater than 0x110000 for keys which don't map to a character (to avoid conflicting with Unicode. Just remember to document that the return value is a dchar. Good luck, and I'll be really looking forward to what you come up with. Arcane Jill
Jul 07 2004
parent Andrew Edwards <ridimz_at yahoo.dot.com> writes:
Arcane Jill wrote:

 In article <cche3t$1h6i$1 digitaldaemon.com>, Andrew says...
 
 
In short, getch() cannot be guaranteed to return a single character from each
key.

Which is exactly why I requested this information! I'd like to implement a UNICODE version for D.

Oh Cool! Be the one.

I can only promise that I will give it my best shot... Unfortunately I'm a very slow learner. Me being here should in no way suggest that I'm an educated or experienced programmer. As a matter of fact my experience is seriously lacking, and my education stems mostly lurking around this newsgroup for a little over. I'm simply here because I am steadfast in my desire to learn how to program.
 Just remember though that Unicode only defines characters, not keys. So,
 returning (say) a Russian letter from a Russian keyboard would fit nicely
within
 your paradigm, but if the user presses CURSOR-LEFT or F10 or
 NUMERIC-KEYPAD-PLUS, there will actually be /no/ Unicode character defined to
 represent these keys.

Got it! I download the Unicode 4.0 manual and am in the process of reading. I'll also be relying heavily on Walter's microEmacs for inspiration.
 You can't use unassigned codepoints, because what is unassigned in Unicode
today
 won't necessarily be unassigned in Unicode tomorrow.
 
 You can't use private use characters because that might conflict with someone's
 private mapping.
 
 So I'd suggest inventing your own standard. And I'd suggest you make use of
 numerical values greater than 0x110000 for keys which don't map to a character
 (to avoid conflicting with Unicode. Just remember to document that the return
 value is a dchar.
 
 Good luck, and I'll be really looking forward to what you come up with.

Thanks for the encouragement...
 Arcane Jill
 
 

Jul 07 2004
prev sibling parent reply Charlie <Charlie_member pathlink.com> writes:
On win32 there used to be a GetAsynchKeyState but i cant seem to find it on msdn
anywhere :S.

Charlie

In article <ccff0l$1os5$1 digitaldaemon.com>, Andrew Edwards says...
The C function getch() provides a means to access most control 
characters from the keyboard, but how do I go about obtaining the ones 
it does not cover?

Specifically these:

enum {
   KEY_HOME    =  ##,
   KEY_UP      =  ##,
   KEY_PGUP    =  ##,
   KEY_LEFT    =  ##,
   KEY_CENTER  =  ##,
   KEY_RIGHT   =  ##,
   KEY_END     =  ##,
   KEY_DOWN    =  ##,
   KEY_PGDN    =  ##,
   KEY_INSERT  =  ##,
   KEY_DELETE  =  ##,
   KEY_F1      =  ##,
   KEY_F2      =  ##,
   KEY_F3      =  ##,
   KEY_F4      =  ##,
   KEY_F5      =  ##,
   KEY_F7      =  ##,
   KEY_F8      =  ##,
   KEY_F9      =  ##,
   ...
}

Thanks,
Andrew

Jul 07 2004
parent "Vathix" <vathixSpamFix dprogramming.com> writes:
"Charlie" <Charlie_member pathlink.com> wrote in message
news:cch82r$18t8$1 digitaldaemon.com...
 On win32 there used to be a GetAsynchKeyState but i cant seem to find it

 anywhere :S.

 Charlie

GetAsyncKeyState http://msdn.microsoft.com/library/en-us/winui/winui/windowsuserinterface/use rinput/keyboardinput/keyboardinputreference/keyboardinputfunctions/getasynck eystate.asp
Jul 07 2004