Posteado por: wozgeass | noviembre 16, 2009

C con Ncurses(segunda parte).


No solo se me permite poner texto, si no que tambien lo puedo hacer con estilo. No son muy elaborados como los que encontrariamos en una interfaz grafica, pero si le da enfasis al texto, lo hace entendido y a color lo que le quita lo aburrido a la terminal.

TEXTO CON ATRIBUTOS.

Existen varias funciones que nos permiten desplegar texto en la pantalla:

attrset();

attron();

attroff();

La funcion attrset( ) —> Establece los atributos al texto.

La funcion attron( ) y attroff( ) —> Especifica si los atributos del texto se inician o se paran respectivamente.

Hay un poco de confucion en cuanto a ¿que funcion usar attrset( ) o attron( )? para aplicar atributos de texto.

attrset(A_BOLD);

attron(A_BOLD);

Ambas funciones aplican el atributo “TEXTO EN NEGRITA” al texto mostrado. La diferencia radica en que attrset( ) quita todos los atributos previamente añadidos y attron( ) agrega el atributo a los ya existentes aplicandolos al texto.

ATRIBUTOS DE TEXTO.

Cuando iniciamos el modo ncurses, el texto de salida tiene por default el atributo ‘A_NORMAL’. Eso equivale a texto en color Blanco y fondo negro. Esto resultaba muy aburrido y tedioso.

Nombre de los atributos Lo que hace
A_ALTCHARSET Despliega el texto usando una como alternativa definida por la terminal
A_BLINK Un parpadeo en el texto
A_BOLD Despliega el texto en negrita y mas grueso
A_DIM Despliega el texto mas tenue
A_INVIS Despliega el texto escondido
A_REVERSE Despliega el texto con los atributos de forma inversa
A_UNDERLINE Despliega el texto subrayado
A_PROTECT Previene que el texto sea sobrescrito
A_HORIZONTAL
A_LOW
A_RIGHT
A_TOP

Estos atributos son usados con las funciones attrset( ), attron( ) y attroff( ) para manejar las apariencias del texto en la ventana, attron( ) y attroff( ) son usadas para establecer y quitar atributos individualmente, attrset( ) es usada para sobrescribir previamente atributos de texto y establecer uno nuevo para todo el texto.

Algunos atributos son definidos por la XSI(X/Open System Interface) pero no son implementados aun,  mas no encontre en ninguna version de Ncurses que existieran los atributos conocidos como “Highligted modes” A_HORIZONTAL, A_LOW, A_RIGHT, A_TOP Y A_VERTICAL, no estoy seguro de que signifiquen asi que no las tratare en este post…

ejemplo:

#include<ncurses.h>

int main(void)
{
initscr();
attron(A_BOLD);
addstr(“hola mundo!!\n”);
attron(A_BLINK);
addstr(“Me siento feliz de poder ponerle algo diferente el texto.\n”);
attroff(A_BOLD);
addstr(“Ncurses rulz!!\n”);
addstr(“Viva el software libre!!.\n”);
attrset(A_NORMAL);
addstr(“Otra cadena mas!\n”);
addstr(“Que interezante es este atributo.\n”);
refresh();
getch();
endwin();
return 0;
}

MULTIPLES ATRIBUTOS.

No tienes que usar en multiples ocaciones las funciones attron( ) o attroff( ) para aplicar o remover multiples atributos. La multiple aplicacion puede ser aplicada usando un  or ‘ | ‘ logico con cada atributo por separado, recuerda que para activarlos se usa la funcion attron( ) y para desactivarlos la funcion attroff( ).

attrset( A_BOLD | A_BLINK | A_UNDERLINE);

ejemplo:

#include <ncurses.h>
#define COUNT 5
int main(void){

char text[COUNT][15] = { “esto”, “me”, “parece”, “muy”, “entretenido” };
int a,b;
initscr();
for(a=0;a<COUNT;a++){
for(b=0;b<COUNT;b++){
if(b==a) attrset(A_BOLD | A_UNDERLINE);
printw(“%s”,text[b]);
if(b==a) attroff(A_BOLD | A_UNDERLINE);
addch(‘ ‘);
}
addstr(“\b\n”);
}
refresh();
getch();
endwin();
return 0;
}

Lo que nos da como salida lo siguiente:

esto me parece muy entretenido

esto me parece muy entretenido

esto me parece muy entretenido

esto me parece muy entretenido

esto me parece muy entretenido

¿PODEMOS TENER COLORES EN LA TERMINAL?

Claro que podemos manejar colores, una pregunta mejor seria: ¿Sera facil manejarlo?, Afortunadamente la libreria Ncurses viene con varias herramientas que me ayudan para determinar que tipo de terminales soportan manejo de colores y cuales.

has_colors( );

La funcion has_colors( ) retorna un TRUE logico, si la terminal es capaz de desplegar texto de color, Falso si es de lo contrario. Ambas estan definidas en la libreria ncurses.h.

Despues de determinar si la terminal tiene color, puedes iniciar el modo a color con la funcion:

start_color( );

La funcion start_color( ) Retorna OK(Esta definida en la libreria ncurses.h) si la funcion de color fue correctamente iniciada o ERR(Esta definida en la libreria ncurses.h) en caso contrario. Despues de llamar a la funcion start_color( ) podremos usar atributos en el texto y sobra de fondo.

Ejemplo.

#include<ncurses.h>

#include<stdlib.h>

void bomb(char *msg);

int main(){

initscr();

//Probamos si la terminal soporta el uso de colores

if(!has_colors()){

bomb(“No esta soportado”);

}

//Si la terminal soporta colores.

printw(“Inicio correctamente\n”);

printw(“felicidades tu terminal si lo soporta\n”);

printw(“Ncurses soporta %d colores\n”, COLORS);

printw(“y %d combinaciones de color\n”, COLOR_PAIRS);

refresh();

getch();

endwin();

return 0;

}

void bomb(char *msg){

endwin();

puts(msg);

exit(1);

}

NOTA: El uso de COLORS y COLOR_PAIRS, estas constantes son establecidas cuando llamamos la funcion start_color().

COLOR Y COLOR_PAIRS.

Las constantes COLORS y COLOR_PAIRS devuelve cuantos colores y cuantas combinaciones puede desplegarce en pantalla(en primer plano y en el fondo).  El valor de COLORS devuelve basicamente cuantos colores puede manejar la terminal. La PC normal tiene 8 colores disponibles, estos son los 8 colores estandar usados en una PC desde el primer adaptador grafico en 1981 PC IBM.

NCURSES NUMBER PC-BIOS PC NAME NCURSES NOMBRE
0 0 negro COLOR_BLACK
1 4 rojo COLOR_RED
2 2 verde COLOR_GREEN
3 6 cafe COLOR_YELLOW
4 1 azul COLOR_BLUE
5 5 magenta COLOR_MAGENTA
6 3 cyan COLOR_CYAN
7 7 blanco COLOR_WHITE

Es importante recordar que el valor COLORS solo devuelve cuantos colores estan disponibles, color_pairs() solo hace una simple combinacion de texto y color de fondo. Cada combinacion se le asigna un numero para el valor de COLOR_PAIRS.

init_pair(1, COLOR_YELLOW, COLOR_RED); //Asignamos el valor de 1 a COLOR_PAIRS, letras amarillas y fondo rojo

El siguiente paso es aplicar los atributos de color al texto. Esto lo hacemos usando las funciones attrset() o attron():

attrset(COLOR_PAIR(1));

attron(COLOR_PAIR(1));

Como COLOR_PAIR(1), ya lo tenemos definido con el texto de color amarillo y fondo de color rojo, ahora para aplicar atributos de color en el color de letras y fondo debemos volver a usar la funcion init_pair( ) que redefinira el color de letras y el de fondo.

init_pair(2, COLOR_WHITE, COLOR_BLUE);

attrset (COLOR_PAIR(2));

¿CUANTOS COLORES SOPORTA LA TERMINAL?

Mientras Ncurses tiene disponible 8 colores en las terminales hay un par de colores extra de donde escojer. El secreto es aplicar el atributo texto en negritas(A_BOLD), este afecta solo a las letras.

ejemplo.

attrset(COLOR_PAIR(1) | A_BOLD);

#include <ncurses.h>
#include <stdlib.h>
void bomb(int r);
int main(void){
initscr();
start_color();
init_pair(1,COLOR_BLACK,COLOR_RED);
init_pair(2,COLOR_BLUE,COLOR_BLACK);
attrset(COLOR_PAIR(1));
addstr(“My name is Mr. Black!\n”);
attrset(COLOR_PAIR(2));
addstr(“My name is Mr. Blue!\n”);
attrset(COLOR_PAIR(1));
addstr(“How do you do?\n”);
attrset(COLOR_PAIR(2));
addstr(“How do I do “);
attron(A_BOLD);
addstr(“what”);
attroff(A_BOLD);
addch(‘?’);
refresh();
getch();
endwin();
return 0;
}

Ademas podemos definir nuestros propios colores de texto, definir un color de texto Rosa y usarlo si quieres. Esto lo hacemos con la funcion init_color(). El problema es que no esta soportada en todas las terminales, pero podemos confirmar si tienemos soporte con la funcion can_change_color() que regresa un TRUE o False logico dependiendo si es soportada o no.

ejemplo.

if(!can_change_color())

printf(“No tienes soporte”);

Pero si tienes soporte, con la funcion init_color( )  crearemos nuestro propio atributo de color.

init_color(COLOR , r, g, b);

Los valores pasados a init_color() son solo enteros cortos. Donde COLOR representa el numero del nuevo color, luego viene los valores para red (r), green (g), blue (b) que tiene el rango de 0 a 1000 que representa la intensidad de un color en particular.

init_color(1, 255, 255, 255);

#include<ncurses.h>
#include<stdlib.h>
#define NEW_COLOR 1
#define RED 1000
#define GREEN 750
#define BLUE 750
int main(){
initscr();
start_color();
if(!can_change_color()){
printw(“No esta soportada por la terminal:\n”);
getch();
endwin();
exit(-1);
}
else{
init_color(NEW_COLOR,RED,GREEN,BLUE);
init_pair(1,NEW_COLOR,COLOR_BLACK);
attrset(COLOR_PAIR(1));
printw(“Este es un color %d\n”,NEW_COLOR);
refresh();
getch();
}
endwin();
return 0;
}

La funcion init_color( ) es usada en la linea 15 para crear un nuevo color ROSA mezclando 1000 puntos de color rojo con 750 de color azul y verde, luego el color nuevo es usado por la funcion init_pair() y puesto en pantalla por la funcion printw(). En la terminal que no se pudo ponder el nuevo atributo de color nos muestra un color de texto rojo.

PONIENDO COLOR A TODA LA VENTANA.

Ademas de poder colorear el texto, es posible aplicar los mismos atributos a la ventana, la funcion que establece los atributos de fondo para la pantalla estandar es:

bkgd();

COLOR EN LA PANTALLA DE FONDO.

Para establecer el color de fondo, debes hacer tes cosas dos de las cuales ya debes saber:

  1. Determinar si la terminal soporta el manejo de colores con la funcion has_color( ) .
  2. Hacer la combinacion de texto con el color de fondo usando la funcion init_pair( ).
  3. Lo ultimo por hacer es usar la funcion bkgd( ) para que se vea nuestra pantall a color.

#include <ncurses.h>
int main(void){
initscr();
start_color();
init_pair(1,COLOR_WHITE,COLOR_BLUE);
bkgd(COLOR_PAIR(1));
printw(“Probando color!”);
refresh();
getch();
endwin();
return 0;
}

Lo que hace el siguiente programa es poner una pantalla de color azul y color blanco al texto. Todo el texto aparecera con los atributos aplicados automaticamente.

Ademas podemos poner caracteres como un atributo en el fondo de la pantalla estandar.

bkgd(‘.’);

Para combinar un caracter a un atributo para el fondo de la pantalla usando un ó logico (‘|’):

bkgd(COLOR_PAIR(1) | ‘.’);

#include<ncurses.h>
main(){
initscr();
start_color();
init_pair(1, COLOR_BLUE, COLOR_WHITE);
init_pair(2, COLOR_MAGENTA, COLOR_BLUE);
bkgd(COLOR_PAIR(1) | ‘*’);
refresh();
sleep(4);
bkgd(COLOR_PAIR(2) | ‘.’);
refresh();
getch();
endwin();
return 0;
}

Para cerrar este post me gustaria agregar la funcion beep() que simplemente hace un pitido en la terminal obteniendo la atencion de los usuarios. La funcion flash() es un nuevo pitido tambien diseñado para obtener la atencion de los usuarios, aunque no esta soportada en todas la terminales.

#include<ncurses.h>
main(){
initscr();
start_color();
init_pair(1, COLOR_BLUE, COLOR_WHITE);
bkgd(COLOR_PAIR(1));
addstr(“Pon atencion al pito de la terminal!!”);
refresh();
beep();
sleep(2);
addstr(“Otro pitido mas moderno!!”);
refresh();
flash();
sleep(2);
endwin();
}

wozgeass:  push eax, 1

int 80h

EOF!!!

hasta el proximo post…

Anuncios

Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s

Categorías

A %d blogueros les gusta esto: