Hi,
In my current program I try to read a character from the input prompt:
(set 'tmp (read-char 0))
This works, however, I need to press the <enter>-key in order to continue the program. So, if I send a message to the console like "Do you want to continue (Y/N)", and the user presses "Y", he also have to press <enter> after that to continue.
Actually I want *just* to press "Y" after which program continues. How can I do that in newLisp?
Peter
Norman has an example on his site how to use the ncurses library to do this:
http://www.nodep.nl/downloads/newlisp/ncurses.lsp
On Win32 MinGW has a getch(), which you could import somehow.
Whe you are done writing the newMACS editor, let us know :)
Lutz
here is a solution for making a library with MinGW on Win32.
The 'C' file:
/* getchar.c - library getchar.dll to get character from keyboard */
#include <stdio.h>
#include <conio.h>
int GetChar(void)
{
return(getch());
}
The 'getchar.def' file:
LIBRARY getchar.dll
EXPORTS
GetChar @1 GetChar
The 'Makefile':
# makefile for getchar.dll for MinGW compiler
#
OBJS = getchar.o
CFLAGS = -Wall -pedantic -c -O3 -DMINGW
CC = c:/MinGW/bin/gcc
STRIP = c:/MinGW/bin/strip
WRAP = c:/MinGW/bin/dllwrap
VERSION = 0.0.2
default: $(OBJS)
$(WRAP) *.o --enable-stdcall-fixup --def getchar.def -o getchar.dll -lws2_32
$(STRIP) getchar.dll
.c.o:
$(CC) $(CFLAGS) $<
$(OBJS): getchar.c getchar.def Makefile
The just do:
(import "getchar.dll" "GetChar")
(GetChar)
Lutz
Hmm... I thought of that (e.g. importing a C-function), but it is not possible within newLisp itself?
(Actually, I am not creating an editor but I was trying to create the smallest interpreter on earth using newLisp... really!)
I have not found a way to do this on Linux/UNIX using standard 'libc' calls (not curses !). If someone can show me how, I will put a keyboard function in the next release.
Lutz
Isn't "int getchar(void)" part of the STDIO library? I can't remember; I will look into it tonight.
Looking into my old personal sources I found this:
int kb_hit(void)
{
#ifdef WIN32
char c;
while(!kbhit()){}; //wait for user to press a key
return(int)getch();
#else // Should work for most Unices
struct termios term, oterm;
int fd = 0;
int c = 0;
/* get the terminal settings */
tcgetattr(fd, &oterm);
/* get a copy of the settings, which we modify */
memcpy(&term, &oterm, sizeof(term));
/* put the terminal in non-canonical mode, any
reads timeout after 0.1 seconds or when a
single character is read */
term.c_lflag = term.c_lflag & (!ICANON);
term.c_cc[VMIN] = 0;
term.c_cc[VTIME] = 1;
tcsetattr(fd, TCSANOW, &term);
/* get input - timeout after 0.1 seconds or
when one character is read. If timed out
getchar() returns -1, otherwise it returns
the character */
c=getchar();
/* reset the terminal to original state */
tcsetattr(fd, TCSANOW, &oterm);
/* return character */
return c;
#endif
}
This code I ripped from a webpage which does not exist anymore... I have adjusted it a little bit to fit my needs at the time, but I think it is suitable for a generic GETCHAR, also on most unices. I have tested it only with Linux.
>>> Isn't "int getchar(void)" part of the STDIO library?
Yes it is, but it sits in the functions until you hit <enter>, just like (read-char 0) does. 'C' getchar() is really a macro around the 'C' read(int handle ...) function newLISP is using.
Lutz
Thanks for 'C' code, I will experiment with this.
Lutz
One addition: I see I have included <termios.h> to get this code working... I hope Solaris has this header file.
Have it working on Linux/Solaris/MinGW/CYGWIN/Win32-Borland, but cannot get it to work on BSD. Anybody out there who can help with BSD (I tried on freeBSD 4.7) ???
This is what I have so far on UNIX:
struct termios term, oterm;
int c = 0;
tcgetattr(0, &oterm);
memcpy(&term, &oterm, sizeof(term));
/* put the terminal in non-canonical mode, any
reads timeout after 0.1 seconds or when a
single character is read */
term.c_lflag &= ~(ICANON | ECHO);
term.c_cc[VMIN] = 0;
term.c_cc[VTIME] = 1;
tcsetattr(0, TCSANOW, &term);
while((c=getchar()) == -1);
/* reset the terminal to original state */
tcsetattr(0, TCSANOW, &oterm);
Lutz
I just tested the code on OpenBSD 3.4 and it seems to work fine. Unfortunately I can not have a FreeBSD machine available...