AnteriorPosterior

10.4. Acceso a pantalla en Linux: curses.h

  Curso: Fundamentos de programación en C, por Nacho Cabanes

10.4. Acceso a pantalla en Linux: curses.h

En Linux, hay una biblioteca llamada "curses", que es la que deberemos incluir si queremos usar algo más que el simple "printf": nos permitirá borrar la pantalla, escribir en unas ciertas coordenadas, cambiar colores o apariencias del texto, dibujar recuadros, etc.

Eso sí, el manejo es más complicado que en el caso de Turbo C: hay que tener en cuenta que en Linux (y en los Linux en general) podemos encontrarnos con que nuestro programa se use desde un terminal antiguo, que no permita colores, sino sólo negrita y subrayado, o que no actualice la pantalla continuamente, sino sólo en ciertos momentos. Es algo cada vez menos frecuente, pero si queremos que nuestro programa funciones siempre, deberemos llevar ciertas precauciones.

Por eso, el primer paso será activar el acceso a pantalla con “initscr” y terminar con “endwin”. Además, cuando queramos asegurarnos de que la información aparezca en pantalla, deberíamos usar “refresh”.

Como primeras órdenes, vamos a usar:

  • “clear” para borrar la pantalla.
  • “move” para desplazarnos a ciertas coordenadas.
  • “printw” para escribir en pantalla.

Con todo esto, un primer ejemplo sería:

/*---------------------------*/
/*  Ejemplo en C nº 90:      */
/*  C090.C                   */
/*                           */
/*  Pantalla con Curses (1)  */
/*                           */
/*  Curso de C,              */
/*    Nacho Cabanes          */
/*---------------------------*/
 
#include <curses.h>
 
int main() {
  initscr();
  clear();
  move(10,10);
  printw("hola");
  refresh();
  getch();
  endwin();
  return 0;  
}
 

Un detalle importante: a la hora de compilar hay que añadir la opción de que enlace la librería “ncurses”, bien desde las opciones de nuestro entorno de desarrollo (si usamos Ajuta, KDevelop o algún otro), o bien desde la línea de comandos:

cc ejemplo.c –lncurses –o ejemplo

(hay que recordar que se distinguen las mayúsculas de las minúsculas).

Podemos mejorarlo nuestro ejemplo un poco:

* En la inicialización, es frecuente que nos interese comprobar el teclado cada vez que se pulse una tecla, sin esperar a que se complete con Intro, y de asegurarse de eso se encarga la orden “cbreak”.
* También es frecuente que queramos que cuando se pulse una tecla, ésta no aparezca en pantalla. Eso lo hacemos con “noecho”.

Ya en el cuerpo del programa, también podemos seguir haciendo mejoras:

* Podemos desplazarnos a una cierta posición y escribir un texto, todo ello con la misma orden, si usamos “mvaddstr”.
* Podemos cambiar la apariencia del texto si le aplicamos ciertos atributos, usando la orden “attron”. Los atributos más habituales en un terminal Unix serían la negrita (A_BOLD) y el subrayado (A_UNDERLINE). Estos atributos se desactivarían con “attroff”.

Con todo esto, ahora tendríamos algo como

/*---------------------------*/
/*  Ejemplo en C nº 91:      */
/*  C091.C                   */
/*                           */
/*  Pantalla con Curses (2)  */
/*                           */
/*  Curso de C,              */
/*    Nacho Cabanes          */
/*---------------------------*/
 
#include <curses.h>
 
int main()
{
  initscr();              /* Inicialización */
  cbreak();               /* Sin esperar a Intro en el teclado */
  noecho();               /* Para que getch no escriba en pantalla */
  clear();                /* Borramos la pantalla */
  attron(A_BOLD);         /* Activamos la negrita (bold) */
  mvaddstr(2,10,"hola");  /* Escribimos en cierto sitio */
  attroff(A_BOLD);        /* Desactivamos la negrita */
  refresh(#40;);              /* Actualizamos la info en pantalla */
  getch();                /* Esperamos a que se pulse una tecla */
  endwin();               /* Se acabó */  
  return 0;
}
 

Finalmente, si queremos escribir en pantalla usando colores, tendremos que decir que queremos comenzar el modo de color con start_color(); durante la inicialización. Eso sí, antes deberíamos comprobar con has_colors() si nuestro terminal puede manejar colores (tenemos definida una constante FALSE para poder comprobarlo).

Entonces podríamos definir nuestros pares de color de fondo y de primer plano, con “init_pair”, así: init_pair(1, COLOR_CYAN, COLOR_BLACK); (nuestro par de colores 1 será texto azul claro sobre fondo negro).

Para usar estos colores, sería muy parecido a lo que ya conocemos: attron(COLOR_PAIR(1));

Y si queremos comprobar las teclas extendidas, haríamos keypad(stdscr, TRUE); durante la inicialización y en cuerpo del programa ya podríamos usar órdenes como

tecla = getch();
if (tecla == KEY_LEFT) ...

Vamos a ver un ejemplo que junte todo esto:

/*---------------------------*/
/*  Ejemplo en C nº 92:      */
/*  C092.C                   */
/*                           */
/*  Pantalla con Curses (3)  */
/*                           */
/*  Curso de C,              */
/*    Nacho Cabanes          */
/*---------------------------*/
 
#include <curses.h>
 
int main()
{
  int tecla;
 
  initscr();
  if(has_colors() == FALSE)
  { 
    endwin();
    printf("Su terminal no permite usar colores!\n");
    exit(1);
  }
  start_color();
  cbreak();
  noecho();
  keypad(stdscr, TRUE);
 
  clear();
  init_pair(1, COLOR_CYAN, COLOR_BLACK);
  attron(COLOR_PAIR(1));
  mvaddstr(2,10,"hola");
  attroff(COLOR_PAIR(1));
  refresh();
  tecla = getch();
  if (tecla == KEY_LEFT)
     printw("Has pulsado izquierda");
  getch();
  endwin();
  return 0;
}
 

Al igual que ocurría con Turbo C, esto no es todo lo que hay. También podemos crear ventanas, definir colores “a medida” a partir de su cantidad de rojo, verde y azul, podemos leer lo que hay en la pantalla, podemos manejar el ratón, e incluso tenemos rutinas para manejo de paneles y de formularios, pero todo ello queda fuera del cometido de este apartado, que es puramente introductorio.

Ejercicios propuestos:

  • Crea un menú para MsDos que muestre varias opciones en el centro de la pantalla, y el reloj en la parte superior derecha de la pantalla. Mientras el usuario no pulse una tecla, el reloj debe actualizarse continuamente.
  • Crea, tanto para MsDos como para Linux, un “protector de pantalla” que muestre tu nombre rebotando en los laterales de la pantalla. Deberá avanzar de posición cada segundo.

 

Actualizado el: 16-01-2015 00:06

AnteriorPosterior