piyush-balwani
piyush-balwani

Reputation: 544

getch not working without initscr

I gone through the Documentation of NCURSES. I am not getting that if I use getch without initscr then why this program is not working. Is there any other approach to get arrow keys input without clearing screen (that initscr do).

#include <ncurses.h>
#include <unistd.h>
int main()
{
    int ch;
    //initscr();
    //raw();
    //keypad(stdscr, TRUE);
    //noecho();

    while(1)
    {
        ch = getch();
        switch(ch)
        {
            case KEY_UP: 
                printw("\nUp Arrow");
                break;
            case KEY_DOWN: 
                printw("\nDown Arrow");
                break;
            case KEY_LEFT: 
                printw("\nLeft Arrow");
                break;
            case KEY_RIGHT: 
                printw("\nRight Arrow");
                break;
        }

        if(ch == KEY_UP)
            break;
    }
    //endwin();
}

Upvotes: 4

Views: 1986

Answers (3)

Arnaud Ali&#232;s
Arnaud Ali&#232;s

Reputation: 1092

I have a solution without ncurses

You can use simple-getch like this:

t_key keys[] = {
  {"[A", K_UP},
  {"[B", K_DOWN},
  {"[D", K_LEFT},
  {"[C", K_RIGHT},
  {NULL, K_UNK},
};

int key;

ch_init();
while ((key = ch_get(keys)) != K_BACK)
  {
    printf("%d\n", key);
  }
ch_end();

keys array is a list of escape sequences which will be used, (when you type an arrow key in a terminal, it will write an escape key followed by multiples characters to define the key.)

This sequences may/will change between terminals, you should use termcap to properly set this sequences.

Upvotes: 0

Amrith Krishna
Amrith Krishna

Reputation: 2851

Alternatively you may use change the terminal attribute through tcsetattr in termios. If you cycle between the canonical mode (requires new line for the process to begin) and non-canonocal mode (Keypress is more than enough).

The following program works as follows - THe process waits for user input. If up arrow key is pressed, it prints 'Arrow key pressed' and exits. If something else is pressed, it waits for the user to press Enter and then prints the user inpu. Exits after the inut is printed.

#include <termios.h>
#include <unistd.h>
#include <fcntl.h>
#include <stdio.h>
int main()
{
  struct termios oldt, newt;
  char ch, command[20];
  int oldf;

  tcgetattr(STDIN_FILENO, &oldt);
  newt = oldt;
  newt.c_lflag &= ~(ICANON | ECHO);
  tcsetattr(STDIN_FILENO, TCSANOW, &newt);
  oldf = fcntl(STDIN_FILENO, F_GETFL, 0);
  fcntl(STDIN_FILENO, F_SETFL, oldf | O_NONBLOCK);

  while(1)
  {
    ch = getchar();
    if (ch == '\033')
    { printf("Arrow key\n"); ch=-1; break;}
    else if(ch == -1) // by default the function returns -1, as it is non blocking
    {
      continue;
    }
    else
    {
      break;
    }

  }
  tcsetattr(STDIN_FILENO, TCSANOW, &oldt);
  fcntl(STDIN_FILENO, F_SETFL, oldf);
  if(ch != EOF)
  {
    ungetc(ch,stdin);ith
    putchar(ch);
    scanf("%s",command);
    printf("\n%s\n",command);

    return 1;
  }

  return 0;
}

Upvotes: 2

Thomas Dickey
Thomas Dickey

Reputation: 54583

getch is the same as wgetch(stdscr). It assumes that the screen has been initialized. ncurses (any curses implementation) has to do a couple of things to make wgetch usable:

  • read the terminal description
  • initialize the terminal I/O modes
  • allocate a screen to draw on.

The last is because wgetch does a wrefresh on the window for which it was called, before doing a read.

You could use newterm with filter to avoid clearing the screen, and doing line-oriented input. The filter program in ncurses-examples demonstrates how to do this.

Upvotes: 2

Related Questions