conio.h for Linux

For those of you who like to make command-line RPGs in C using conio.h, but disappointed because conio.h library is not available in Linux. Your wait is over!
I have included a modern GNU/Linux implementation of the old MS-DOS conio.h library. Included functions are getch, getche, kbhit, gotoxy, and clrscr.

Header:

/*
 *	terminal_io.h
 *	Author: Jakash3
 *	Date: 22 Dec 2011
 *	Some conio.h functions for GNU/Linux
 */
#ifndef TERMINAL_IO
#define TERMINAL_IO

#include <stdio.h>
#include <unistd.h>
#include <termios.h>
#include <sys/select.h>

// Turns terminal line buffering on or off
void terminal_lnbuf(int yn);

// Turns terminal keyboard echo on or off
void terminal_echo(int yn);

// Get next immediate character input (no echo)
int getch();

// Get next immediate character input (with echo)
int getche();

// Check if a key has been pressed at terminal
int kbhit();

// Set cursor position
void gotoxy(int x, int y);

// Clear terminal screen and set cursor to top left
void clrscr();

#endif

Source:

#include "terminal_io.h"

void terminal_lnbuf(int yn) {
   struct termios oldt, newt;
   tcgetattr(0, &oldt);
   newt = oldt;
   if (!yn) newt.c_lflag &= ~ICANON;
   else newt.c_lflag |= ICANON;
   tcsetattr(0, TCSANOW, &newt);
}

void terminal_echo(int yn) {
   struct termios oldt, newt;
   tcgetattr(0, &oldt);
   newt = oldt;
   if (!yn) newt.c_lflag &= ~ECHO;
   else newt.c_lflag |= ECHO;
   tcsetattr(0, TCSANOW, &newt);
}

void gotoxy(int x, int y) { printf("\x1B[%d;%df", y, x); }

void clrscr() { printf("\x1B[2J\x1B[0;0f"); }

int getch() {
   register int ch;
   terminal_lnbuf(0);
   terminal_echo(0);
   ch = getchar();
   terminal_lnbuf(1);
   terminal_echo(1);
   return ch;
}

int getche() {
   register int ch;
   terminal_lnbuf(0);
   ch = getchar();
   terminal_lnbuf(1);
   return ch;
}

int kbhit() {
   register int ret;
   fd_set fds;
   terminal_lnbuf(0);
   terminal_echo(0);
   struct timeval tv;
   tv.tv_sec = 0;
   tv.tv_usec = 0;
   FD_ZERO(&fds);
   FD_SET(0, &fds);
   select(1, &fds, 0, 0, &tv);
   ret = FD_ISSET(0, &fds);
   terminal_lnbuf(1);
   terminal_echo(1);
   return ret;
}

7 thoughts on “conio.h for Linux

  1. I don’t test your code.
    But , I hope this solution will give us some help.
    I thinking about people how give and share the chance to have a good life and be honest with themselves and others.
    I love your blog and honestly I would come back with issues about coprocessor assembler level, MMX and others.
    It may seem primitive but it will help create an appropriate portfolio for you.
    Redards.

    • The most simplistic example is simulating the “Press any key…” effect. Where the user doesn’t have to press Enter, but ANY key since line buffering is turned off. Normally, all input must be followed by a new line character before the program reads it, these functions allow you to stat characters entered to the console in real time.

  2. This is an excellent example. However, I am using Ubuntu 10.04 and Eclipse with a USB keyboard and the ICANON flag does not eliminate the need to press . I have done additional research and found that the VTIME feature works but in the end, I always have to press to read the buffered input characters regardless if I use getchar() or read(STDIN_FILENO, &ch, 1) to acquire the data. Any suggestions?

  3. Sorry about the missing text. I did not know I could not bracket the word “enter” with the greater than and less than characters.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: