dennisw@tekigm2.MEN.TEK.COM (Dennis G Ward) (07/31/90)
I've got a truly great program underway, but I can't stand to let the user break out of it with Ctrl-C or Ctrl-Break, and I need keyboard input. What's the trick(s)? -- Dennis Ward dennisw@tekigm2.MEN.TEK.COM C1-820 (206)253-5428
nmouawad@water.waterloo.edu (Naji Mouawad) (07/31/90)
In article <9627@tekigm2.MEN.TEK.COM> dennisw@tekigm2.MEN.TEK.COM (Dennis G Ward) writes: >I've got a truly great program underway, but I can't stand to let the >user break out of it with Ctrl-C or Ctrl-Break, and I need keyboard >input. What's the trick(s)? >-- >Dennis Ward dennisw@tekigm2.MEN.TEK.COM C1-820 (206)253-5428 The best method I know of, is to trap interrupt 09h. Write a little routine that does the following: -checks if the scan code of a key corresponds to the break key or the key with letter 'C'. The scan code, in case you don't know is the number that the keyboard processor sends, each time a key is pressed. These are listed in several books. -If that's not the case, jump to the adress of the interrupt 9h. -if it is, check the state of the Ctrl key (bit number 4 I think of byte 0:40H, again you can find this info in Peter Norton's book or the Programmer's Solver etc.) If Ctrl is down, ignore the key and exist, if it's up pass it onto the old interrupt 09h. Prefix interrupt 09 with this routine. That is set the address of interrupt 09h to the Segment:offset of your routine. In C and Pascal there are various ways of replacing an interrupt. You can also take a look at any resident utility in PC Mag. They do it all the time. Maybe C or Pascal has a simple function to do so, I don't remember. Good Luck. -- ---------------+------------------------------------------- | Naji Mouawad | nmouawad@water.uwaterloo.edu | | University |-------------------------------------------| | Of Waterloo | "Thanks God, we cannot prove He Exists." |
fs-info@sbsvax.cs.uni-sb.de (c/o Peter Gaal) (07/31/90)
In article <1990Jul31.023745.1116@water.waterloo.edu>, nmouawad@water.waterloo.edu (Naji Mouawad) writes: > In article <9627@tekigm2.MEN.TEK.COM> dennisw@tekigm2.MEN.TEK.COM (Dennis G > Ward) writes: > > >input. What's the trick(s)? > >-- > >Dennis Ward dennisw@tekigm2.MEN.TEK.COM C1-820 (206)253-5428 > > The best method I know of, is to trap interrupt 09h. Write a little routine > that does the following: > ["little" deleted] Hmm, with your suggestion, you have to do scancode processing yourself, but why shouldn't MSDOS do the work for you ? The following should work: Choose a global flag variable, say c_break Replace INT09h with the following (meta)code: call original int09h look if c_break is true if yes, get the next "keystroke" (getch() in C is ok here!), this overreads the break scancode reset the c_break flag if you want, set some other flag to signal c_break was hit else do nothing and complete When the original int09h runs and detects ctrl-break or ctrl-C was pressed, it calls one of the DOS ctrl-break handlers (int19h or int24h, but please do not beat me if that's wrong, I have no doc handy...) which normally set a DOS internal flag which causes DOS to terminate your program on thenext int21h. So the only thing which remains to do is to replace these two ctrl-break interrupts with your own handler, simply setting the c_break flag inspected by your own keyboard handler. It is important NOT to call the original ctrl-break handlers from your own, because otherwise DOS would show up with a nasty "^C" string later. I hope I go it half right... Bye Patrick
feit@cs.odu.edu (Mark A. Feit) (08/01/90)
In article <5717@sbsvax.cs.uni-sb.de> fs-info@sbsvax.cs.uni-sb.de (c/o Peter Gaal) writes: In article <1990Jul31.023745.1116@water.waterloo.edu>, nmouawad@water.waterloo.edu (Naji Mouawad) writes: > In article <9627@tekigm2.MEN.TEK.COM> dennisw@tekigm2.MEN.TEK.COM (Dennis G > Ward) writes: > > >input. What's the trick(s)? > >-- > >Dennis Ward dennisw@tekigm2.MEN.TEK.COM C1-820 (206)253-5428 > > The best method I know of, is to trap interrupt 09h. Write a little routine > that does the following: > ["little" deleted] Hmm, with your suggestion, you have to do scancode processing yourself, but why shouldn't MSDOS do the work for you ? [Pseudocode Obliterated... MS-DOS doesn't work for me. Ptui!] A quick solution in C that lets the runtime library do the dirty work: -------------8<-----Trim Here------------------ BOOL break_flag = FALSE; void ctrl_break( void ) { break_flag = TRUE; /* Do as little as possible in here... DOS gets in a strange state during interrupts and doesn't take kindly to I/O being done.*/ signal( SIGINT, ctrl_break ); } void ctrl_break_handler( void ) /* Or whatever you need... */ { signal( SIGINT, SIG_IGN ); /* Shut ^Break off completely... Don't want recursive calls. */ printf( "\n\nWHAM! Ctrl-Break!\n\n" ); break_flag = FALSE; /* Do your own thing in here */ signal( SIGINT, ctrl_break ); /* Reset things */ } main( int argc, char **argv ) { signal( SIGINT, ctrl_break ); for ( ; ; ) { /* forever */ /* Your code here */ if ( break_flag ) handle_ctrl_break(); } } -------------8<-----Trim Here------------------ A couple of suggestions: 1. Implement the code to check on break_flag inside of something that gets run very often. For example, I have a routine that gets called over and over while the system is waiting for a key. This also means that you can finish up critical operations and _then_ check for a break. 2. If you want to get rid of that nasty ^C on the screen, the only way I can find is to freopen() stdout to NUL. There's no other way as far as I can see without horking the keyboard interrupt (messy) or modifying your BIOS (out of the question). If you're using some screen I/O package, odds are it uses its own direct reads and writes and stdout just sits idle anyway. - Mark ................................... ................................... : Mark A. Feit : feit@cs.odu.edu : : Old Dominion University CS Dept. : feit@xanth.UUCP : : Norfolk, Virginia, U.S.A., Earth : "So where's my lunch, anyway?" : ................................... ................................... Y :)8 G-G-G-D-E-C -- - Mark ................................... ................................... : Mark A. Feit : feit@cs.odu.edu : : Old Dominion University CS Dept. : feit@xanth.UUCP : : Norfolk, Virginia, U.S.A., Earth : "So where's my lunch, anyway?" : ................................... ................................... Y :)8 G-G-G-D-E-C
alex@bilver.UUCP (Alex Matulich) (08/04/90)
In article <9627@tekigm2.MEN.TEK.COM> dennisw@tekigm2.MEN.TEK.COM (Dennis G Ward) writes: >I've got a truly great program underway, but I can't stand to let the >user break out of it with Ctrl-C or Ctrl-Break, and I need keyboard >input. What's the trick(s)? The most PORTABLE way to do it (and it works well too) is to use the signal() function in the standard library, like so: --------------------------------------- #include <signal.h> void ctrlctrap(i) int i; { signal(SIGINT, ctrlctrap); /* make sure next ctrl-break comes back here */ } void main() { signal(SIGINT, ctrlctrap); /* activate ctrl-c/ctrl-break trap handler */ etc.... -------------------------------------- Every time ctrl-c or ctrl break is pressed, the funtion ctrlctrap() will be invoked, and will reset the pointer for the next ctrl-c to call ctrlctrap() again. This has worked on every ANSI compiler I have tried it on (Lattice, Microsoft, unix compilers, etc.) -- /// Alex Matulich /// Unicorn Research Corp, 4621 N Landmark Dr, Orlando, FL 32817 \\\/// alex@bilver.UUCP ...uunet!tarpit!bilver!alex \XX/ From BitNet try: IN%"bilver!alex@uunet.uu.net"