jueves, diciembre 04, 2008

La Libreria Ncurses

Hola a tod@s!! Ya se que hacia bastante tiempo que no escribia nada para el sistema del pinguino, de modo que ahi va una entrada sobre la libreria Ncurses ^^

El caso es que esta libreria ya es algo antigua, aunque yo la he descubierto hace poco. Se trata de una libreria de consola para el compilador de lenguaje C ( en Linux por lo general es Gcc).

En fin, a continuacion os dejo una explicacion mas detallada de mano de la web de Bulma ; )

<< Las ncurses son unas librerías que ayudan a la programación en modo texto para Linux. Es decir, movimientos de cursores, colores, recoger teclas (sin tener que esperar el "Intro") y un largo etcétera. Lo que hacia conio.h en otros sistemas.

También hay gente que a veces tiene problemas con printf y scanf/fgets, debido a buffers intermedios de Linux. Con las ncurses ya no habrá este problema.

En el escrito en cuestión veremos como empezar a programar con ncurses de forma práctica.

Muchos habíamos usado la librería conio.h con el BorlandC o otros compiladores. En Linux existe una librería que intenta "emularla", llamada uConio pero no es estándard de Unix ni hay paquete para Debian, etc.

En lugar de usar la librería uConio, podemos usar las ncurses. Estas pueden ser usadas desde una forma muy simple hasta para hacer auténticas maravillas. En este artículo veremos una introducción práctica para empezar a usarlas.

Existe bastante documentación por Internet, pero suele ser demasiado profunda al acercarnos por primera vez a la programación usando esas librerías. Incluso, en muchas ocasiones no necesitamos muchas de las funcionalidades que nos ofrecen.

Para compilar programas que usen las ncurses en Debian tendremos que instalar el paquete libncurses5-dev. Seguramente lo tendremos instalado ya que también se necesita para compilar el Kernel.
En otras distribuciones necesitaremos instalar un paquete de nombre parecido.

Un programa de ncurses tendrá dos cosas significativas:

* Tendrá este include: #include
* Se compilará de una forma parecida a gcc -lncurses fichero.c

El tipico programa de 'Hola Mundo' seria el siguiente:
#include 
int main()
{
initscr();
printw("Hola Bulma!!!");
refresh();
getch();
endwin();
return 0;
}

initscr: es para entrar en modo ncurses
printw: es para imprimir en la "ventana"*. Es importante usar printw, scanfw, etc. y no usar printf, scanf, ya que tendríamos resultados no deseados.
refresh: aquí es donde realmente se refresca la pantalla. Podemos hacer varios printw y al final un solo refresh para actualizar la pantalla. Si no hacemos el refresh quizás no saldrá impreso por pantalla.
getch: espera una sola pulsación de una tecla. Nos devuelve el código ASCII de la tecla pulsada como un entero. Fijaros que no espera el "Enter" final de línea
endwin: terminamos el modo de ncurses. Si no lo hacemos, nos quedará el terminal medio desconfigurado. Para solucionarlo podríamos hacer reset desde la misma consola.

Recordar una vez más de compilar con gcc -lncurses programa.c

(*)En ncurses podemos gestionar ventanas, escribir en ellas de forma independiente, generar scrolls, etc.. Para hacer una ventana usaríamos la función newwin, para eliminarla delwin, y un largo etcétera (man newwin). En este escrito, no crearemos ventanas, por tanto todo el terminal en sí será considerado una ventana.

Para pedir cosas a un usuario con ncurses haríamos:

#include
int main ()

{

char cadena[128];
initscr();

printw("Dime tu nombre\n");
scanw("%s",cadena);
printw("Te llamas: %s\n",cadena);

refresh();
getch();
endwin();
return(0);
}

La sintaxis del scanw es la misma que la del scanf tradicional.

Si no quisiéramos que lo que escribe el usuario saliera por pantalla (sin echo):

printw("Escribe la contraseña: ");
noecho();
scanw("%s",cadena);
echo();
printw("La contraseña es: %s\n",cadena);

Fácil, ¿no?
"Limpiar" la pantalla
Para "limpiar" la pantalla podemos hacer, sencillamente:

erase();

Moviendonos por la pantalla
Si nos queremos posicionar en un sitio de la pantalla usaremos la función move:

move (10,2);
printw("Escribe la contraseña: ");

¡Ojo! que es move(int y, int x); (fila, columna). Los que habíamos usado la conio.h era gotoxy(int x, int y) (va al revés).

Igualmente podríamos haber usado:

mvprintw(10,2,"Escribe la contraseña: ");

Poniendo colores en la pantalla
Si quisiéramos hacer un printw con colores:

if (has_colors())
{

start_color();

init_pair(1,COLOR_RED,COLOR_YELLOW);
attron(COLOR_PAIR(1));
printw("Escribe la contraseña: ");
attroff(COLOR_PAIR(1));
}

has_colors: devuelve 0 o 1 si el terminal tiene soporte para colores o no.
start_color: inicia el modo de colores. Si no lo hacemos no veremos los colores.
init_pair: asociamos el "par" 1 el color rojo para el texto y el amarillo para el fondo (los colores disponibles con BLACK, RED, GREEN, YELLOW, BLUE, MAGENTA, CYAN, WHITE).
attron: y ponemos los colores de forma activa. También podríamos hacer:

attron(COLOR_PAIR(1) | A_UNDERLINE);

Y así lo tendríamos subrallado. Tenemos disponibles A_NORMAL,A_BLINK, A_BOLD, etc. (man attron para ver más opciones)

Es más, si queremos se pueden personalizar los colores en sí mediante la función init_color (man init_color).

Enlaces

* El ncurses Programming HOWTO
* Un FAQ de ncurses
* Otro manual de ncurses
* Escribir Programas con ncurses (en castellano)
* man ncurses
* El man de cada función de ncurses (muy bien detallados)

Queda mucho para hacer con esas librerías. Por ejemplo toda la gestión de ventanas, crearlas, modificarlas, imprimir dentro; menús, submenús; usar el mouse, etc.

Eso sólo ha sido una manera de introducirnos en la programación de ncurses, a partir de aquí podemos hacer si lo queremos muchas otras cosas.

Comentar que hay un port para Perl de las ncurses (paquete libcurses-perl) y, también desde Perl, una manera rápida de hacer ventanas y formularios usando las libcurses (paquete libcurses-widgets-perl) >>

En fin, espero que os haya gustado esta entrada, y sobretodo a los que teneis la aficion de programar. Nos vemos muy pronto con otra interesante entrada ; )

Fuente: http://www.bulma.net/body.phtml?nIdNoticia=2004