Search code examples
cioterminalstdininstant-messaging

How to keep STDIN at bottom the terminal in C


I am writing a simple instant messaging client in c. It's currently working well, however if a user is typing and receives a message while typing, the message displays AFTER the text, then the user continues on the line below. It would look like this:

USER: I am trying to ty...FRIEND: Hello

pe a message. <--- (the end of the users message)

My idea is:

Somehow force the current data from stdin and load it into a buffer, then use a \r before printing FRIEND: to erase what is on the line, then print from the buffer. Does anyone have any concrete examples of how to accomplish this task?

The final result should be

FRIEND: Hello

USER: I am trying to type a message

The user started typing the message, received a message, the stdin line was shifted downwards, then the user completed their message.

Note: I am running GNOME Terminal 3.6.2 on the newest version of Linux Mint


Solution

  • The usual way to do this is using ncurses (any flavor of curses would work), accepting the input in one window and writing the result to another. Here is a short example:

    #include <curses.h>
    
    int
    main(void)
    {
        bool done = FALSE;
        WINDOW *input, *output;
        char buffer[1024];
    
        initscr();
        cbreak();
        echo();
        input = newwin(1, COLS, LINES - 1, 0);
        output = newwin(LINES - 1, COLS, 0, 0);
        wmove(output, LINES - 2, 0);    /* start at the bottom */
        scrollok(output, TRUE);
        while (!done) {
        mvwprintw(input, 0, 0, "> ");
        if (wgetnstr(input, buffer, COLS - 4) != OK) {
            break;
        }
        werase(input);
        waddch(output, '\n');   /* result from wgetnstr has no newline */
        waddstr(output, buffer);
        wrefresh(output);
        done = (*buffer == 4);  /* quit on control-D */
        }
        endwin();
        return 0;
    }
    

    If you want to learn about VT100 control codes (as distinct from ECMA-48), vt100.net has manuals for some terminals.

    Regarding the link VT100 control codes: that is a source of misinformation, as noted in the ncurses FAQ How do I get color with VT100?