ilyaigpetrov / ncurses-for-emscripten

ncurses 6.1 compiled by emscripten for usage in a browser. It is compiled, loaded, but doesn't work! You are wanted to make it work!
14 stars 5 forks source link

issues with hello.sh #1

Closed lunu-bounir closed 6 years ago

lunu-bounir commented 6 years ago
emcc ./hello.c \
  -I ./ncurses-6.1-llvm/test \
  -L ./ncurses-6.1-llvm/lib \
  -I ./ncurses-6.1-llvm/include \
  -lncurses_g \
  --preload-file  ./lib/terminfo@/home/web_user/.terminfo \
  -o hello.html \
  -s FORCE_FILESYSTEM=1 \
  -Ugetenv \
  --shell-file ./min-shell.html \
  -o out.html \
  -g4 \
  -s ASSERTIONS=2 \
  -s WASM=1 \
  -Werror \
  -s ALLOW_MEMORY_GROWTH=1 \
  --emrun

emrun --no_browser --port 8080 .

Hello

A few questions

  1. Why there are multiple outputs? -o out.html and -o hello.html
  2. If I have the -D"getenv(nam..., I'll get:
In file included from ./hello.c:3:
In file included from /emsdk_portable/sdk/system/include/libcxx/stdlib.h:94:
In file included from /emsdk_portable/sdk/system/include/compat/stdlib.h:14:
/emsdk_portable/sdk/system/include/libc/stdlib.h:51:7: error: expected identifier or '('
char *getenv (const char *);
      ^
<command line>:6:23: note: expanded from here
#define getenv(name) (char*) EM_ASM_INT ( {var envar = JSON.stringify(name);var ret=allocate(intArrayFromString(envar), 'i8', ALLOC_NORMAL);return ret ;},NULL)
                      ^
In file included from ./hello.c:3:

If I omit it, the hello.c compiles but I get Error opening terminal: "". in the browser console.

lunu-bounir commented 6 years ago

btw, I dont see lib/terminfo@/home/web_user/.terminfo file in your rp

ilyaigpetrov commented 6 years ago
  1. Why there are multiple outputs? -o out.html and -o hello.html

It's a mistake, delete one you don't like.

I dont see lib/terminfo@/home/web_user/.terminfo file in your rp

This line means lib/terminfo will be mounted under /home/web_user/.terminfo in BrowserFS.

  1. If I have the -D"getenv(nam..., I'll get:

In /emsdk_portable/sdk/system/include/libc/stdlib.h:51:7 try commenting out char *getenv (const char *); (will be // char *getenv (const char *);).

ilyaigpetrov commented 6 years ago

Let me know if you have any other problem, glad to see other people treading this path.

ilyaigpetrov commented 6 years ago

If you don't know for some reason, this compiled library won't work in a browser without pty implementation for a browser which I couldn't find anywhere. I made some notice about "work needed" in the README.md. Sorry, if I'm too late.

lunu-bounir commented 6 years ago

Thanks for the reply. Even after commenting the stdlib.h:51:7, I still get a weird string for the terminal

Error opening terminal: @ʮ
ilyaigpetrov commented 6 years ago

You may get more debug output by sending FS.readFile('./trace', {encoding: 'utf8'}) in the console of hello.html. But I guess -D"getenv(nam... doesn't work for some reason. You may vote for changing getenv behavior of emscripten here.

lunu-bounir commented 6 years ago

So I hardcoded the name like this and it seems to be working

-D"getenv(name)=(char*) EM_ASM_INT ( {var jsString = 'xterm'; var lengthBytes = lengthBytesUTF8(jsString)+1; var stringOnWasmHeap = _malloc(lengthBytes); stringToUTF8(jsString, stringOnWasmHeap, lengthBytes+1); return stringOnWasmHeap;},NULL)

Here is the output of the debugger

TRACING NCURSES version 6.1.20180127 (tracelevel=0x1fff)
called {initscr()
+ called {new_prescr()
_nc_alloc_screen_sp 0x50e460
+ return }0x50e460
+ called {newterm(0x50e460, "xterm", 0x607c,0x5ffc)
+ + called {setupterm("xterm",1,0xdb5c)
your terminal name is xterm
+ + + called {_nc_first_db
duplicate /usr/share/terminfo
not found /usr/share/terminfo
+ + + return }
_nc_next_db 1 /home/web_user/.terminfo
+ + + called {_nc_read_tic_entry(file=0xdc20, path=/home/web_user/.terminfo, name=��)
cannot open terminfo /home/web_user/.terminfo/�/�� (errno=2)
+ + + return }code 0
+ + + called {del_curterm(0, 0x50ec40)
_nc_free_termtype((null))
+ + + return }0
+ + return }-1
+ return }0
ilyaigpetrov commented 6 years ago

Maybe if you could write the right implementation for getenv(name) which just doesn't always return xterm but works for other env vars as well. Then it could work one step further I think. I totally don't understand how to write such functions.

lunu-bounir commented 6 years ago

okay thanks! I'll try more later.

lunu-bounir commented 6 years ago

If you don't know for some reason, this compiled library won't work in a browser without pty implementation for a browser

So if I fix the getenv issue what would be the problem. I tested the xterm.js library and it can write to the terminal just fine; e.g.: term.write('Hello from \x1B[1;3;31mxterm.js\x1B[0m $ ')

ilyaigpetrov commented 6 years ago

Ncurses program writes to STDOUT some string which should be handled by PTY (slave) and only after that sent to xterm (PTY master). Without PTY slave I get this result: https://github.com/kripken/emscripten/issues/6766#issuecomment-402068383 I'm not confident about how it should work, my picture of things may be wrong.

ilyaigpetrov commented 6 years ago

Here are more discussions about it:

ilyaigpetrov commented 6 years ago

While learning about PTY slave/master you may find this article useful: http://rachid.koucha.free.fr/tech_corner/pty_pdip.html

lunu-bounir commented 6 years ago

Without PTY slave I get this result

Mine is screen shot

ilyaigpetrov commented 6 years ago
  1. How about hello.c, could you get it working without garbage in the terminal? How have you done it?
  2. You may find more examples to play here.
lunu-bounir commented 6 years ago

1.

It works but with errors in the console;

screen shot screen shot

lunu-bounir commented 6 years ago

You may find more examples to play here.

I looked at some of them. But since most of them require user input like with getch we need to first write a wrapper for the user input

ilyaigpetrov commented 6 years ago

Please, share your setup. Actually I want to look at how you glue Module.print to term.write (should be in min-shell.html). You may upload it to a GH repo, gist, pastebin, but GH repo would be the best because I will be able to see more files.

lunu-bounir commented 6 years ago

Here you go! example.zip

Just run example.sh

ilyaigpetrov commented 6 years ago

I got rid of --emrun and mini-shell.html, switched to your example.html and it worked. Thank you.

But since most of them require user input like with getch we need to first write a wrapper for the user input

I think if you compile with --emrun and -o out.html then getch will work as window.prompt() in a browser. I've managed to get it work once, so I know.

ilyaigpetrov commented 6 years ago

I've added ./getch2.sh, it works via window.prompt, you may try to redefine it in min-shell.html. Also I added ./worm2.sh which compiles, but doesn't pass some assertion in a browser.

lunu-bounir commented 6 years ago

just a quick question; have you tried to compile https://pdcurses.sourceforge.io/ instead. It is a lot smaller equivalent.

ilyaigpetrov commented 6 years ago

I think I have seen pdcurses already ported to emscripten with a game ported with it. I don't switch to PDCurses because:

lunu-bounir commented 6 years ago

just a quick update. In the incoming version of emscripten there is a TTY object with put_char, get_char and flush JS functions. We need to somehow register our xterm.js or termlib.js with this TTY object.

ilyaigpetrov commented 6 years ago

Could I give me a link to that incoming version source files? P.S. I gave you a wrong link to vote for adding reentrance to emscripten, here is the right link: https://github.com/kripken/emscripten/issues/6778

lunu-bounir commented 6 years ago

https://github.com/kripken/emscripten/tree/incoming

ilyaigpetrov commented 5 years ago

Hey, @lunu-bounir, could you, please, fork this project if you need it because I am not going to maintain it anymore and thinking to delete its repo.

lunu-bounir commented 5 years ago

Thanks for the heads up. Done! :)