Ncurses y PHP I

Hallá por el 2005 hice un curso de administración de linux y dimos un poco por encima lo que es Ncurses.

Ncurses es la implementación libre de Curses que es una librería que provee de funcionalidades para pintado de pantalla, manejo de teclado y ratón para terminales en modo texto independientemente del tipo de terminal. Esto es que hay terminales que son a color o solo a dos colores, con diferentes tamaños en número de columnas y filas, en juego de caracteres, y también en funcionalidades de ratón, teclado. Ncurses maneja todo eso por nosotros.


Formulario de instalación de Linux (wikipedia)

Ncurses está desarrollado en C pero existen interfaces para acceder a sus funciones desde otros lenguajes como Python, Perl, JavaScript, PHP y muchos otros.

Yo trabajo con PHP que es un lenguaje principalmente para el desarrollo web y me pareció interesante poder usarlo para hacer algo que no sea web y me acordé de esta librería así que pensé que seria interesante investigar sobre ello y ver que podemos hacer con PHP y Ncurses.

En las listas de comandos que daré a continuación asumo que Ubuntu esta recién instalado y que hay que instalar todas las dependencias desde cero. También que estamos como super usuario.

Instalando Ncurses en PHP5.6

El motivo es porque la extensión Ncurses no se portó a PHP7 pero hay una forma de instalarlo que explicaré después.

La extensión ncurses para php no está disponible en APT sino en PECL así que tenemos que instalar eso primero.

apt-get update
apt-get -y install software-properties-common
add-apt-repository ppa:ondrej/php
apt-get update
apt-get -y install php5.6-dev php5.6-xml libncurses5-dev libncursesw5-dev
pecl install ncurses
echo "extension=ncurses.so" > /etc/php/5.6/cli/conf.d/20-ncurses.ini

Ahora podemos comprobar que esta instalado con el siguiente comando:

php -m | grep ncurses

Instalando Ncurses en PHP.7

En PHP7 el proceso tiene mas pasos porque en vez de intentar instalar ncurses con PECL como en el punto 6 ya que daría error, vamos a descargarlo y a aplicar un parche a mano.

apt-get update
apt-get -y install wget php-dev libncursesw5-dev libncurses5-dev php-pear
cd /root
pecl download ncurses
mkdir /root/ncurses
cd /root/ncurses
tar -xvzf /root/ncurses-1.0.2.tgz
wget "https://bugs.php.net/patch-display.php?bug_id=71299&amps;patch=ncurses-php7-support-again.patch&amps;revision=1474549490&amps;download=1" -O ncurses.patch
mv ncurses-1.0.2 ncurses-php5
patch --strip=0 --verbose --ignore-whitespace <ncurses.patch
cd ncurses-php5
phpize
./configure
make
make install
cat &lt;&lt;'EndOfHereDoc' &rt;/etc/php/7.2/mods-available/ncurses.ini
; configuration for php ncurses module
; priority=20
extension=ncurses.so
EndOfHereDoc
ln --symbolic /etc/php/7.2/mods-available/ncurses.ini /etc/php/7.2/cli/conf.d/20-ncurses.ini
php -m | grep ncurses

Código de ejemplo:

Aquí pongo un script en PHP que pinta un cuadro en medio de la pantalla con la frase hola mundo.

#!/usr/bin/env php
<?php
/*
 * Forzamos esta variable de entorno a "linux" porque en algunos terminales
 * los bordes que vamos a usar para pintar la el cuadro de dialogo no se
 * ven bien en Putty y en color sinó es con este valor.
 */
putenv('TERM=linux');

//Iniciamos ncurses.
$ncurses_session = ncurses_init();

//Guardamos la configuración que había antes de correr este script.
ncurses_savetty();

//Comprobamos si el terminal tiene color.
if (ncurses_has_colors()) {
    ncurses_start_color();
	//Creamos una combinación de color de tinta y papel.
    ncurses_init_pair(
		1,						//índice
		NCURSES_COLOR_YELLOW,	//Color de tinta
		NCURSES_COLOR_BLUE		//Color de papel
	);
	//Establecemos el color por defecto.
    ncurses_color_set(1);
}
/**
 * Creamos un "ventana" con los valores 0.
 * Esto crea una "ventana" del tamaño de la pantalla.
 * La ventana es un concepto que yá se explicará.
 */
$ventana_principal = ncurses_newwin(
	0, //filas
	0, //columnas
	0, //x
	0  //y
);

//Usamos la ventana para capurar el tamaño en filas y columnas por referencia.
ncurses_getmaxyx($ventana_principal, $filas, $columnas);

//Creamos otra ventana más pequeña para pintar en ella.
$mi_ventana = ncurses_newwin(
	5,	//filas
	15,	//columnas
	($filas - 5) / 2,		//y
	($columnas - 15) / 2	//x
);

//Establecemos el mismo color que creamos arriba para esta ventana.
ncurses_wcolor_set($mi_ventana, 1);

/*
 * Este bucle es para pintar el fondo de nuestra ventana
 * pintaremos 5 lineas de espacios de fondo azul
 */
for($y = 0; $y < 5; $y++){
	//Ponemos el cursor en la fila correspondiente.
	ncurses_wmove($mi_ventana, $y, 0);
	//Pintamos una línea horizontal de espacios de 15 carácteres.
	ncurses_whline(
		$mi_ventana,	//Manejador de nuestra ventana.
		ord(' '),		//Carácter que vamos a pintar. Tiene que convertirse a código ASCII.
		15
	);
}

//Ahora pintamos un texto dentro de nuestra ventana.
ncurses_mvwaddstr(
	$mi_ventana,	//Manejador de nuestra ventana.
	2,				//y, relativo al interior de la ventana.
	3,				//x, relativo al interior de la ventana.
	'Hola mundo'	//texto
);

//Ahora pintamos un borde al rededor.
ncurses_wborder(
	$mi_ventana,	//Manejador de nuestra ventana.
	0, //caracter para pintar línea izquierdo, 0 =│, ord('|') para otro
	0, //caracter para pintar línea derecho, 0 =│, ord('|') para otro
	0, //caracter para pintar línea superior, 0 = ─, ord('-') para otro
	0, //caracter para pintar línea inferior, 0 = ─, ord('-') para otro
	0, //caracter para pintar esquina superior izquierda 0 = ┌, ord('+') para otro
	0, //caracter para pintar esquina superior derecha 0 = ┐, ord('+') para otro
	0, //caracter para pintar esquina inferior izquierda 0 = └, ord('+') para otro
	0  //caracter para pintar esquina inferior derecha 0 = ┘, ord('+') para otro
); // border it

//Dibujamos lo que hemos hecho arriba con la ventana en la pantalla.
ncurses_wrefresh($mi_ventana);

//reestablecemos la configuración que había antes de correr el script
ncurses_resetty();
//cerramos ncurses
ncurses_end();

Cópia y pega este script en el fichero test.php y ejecútalo con el siguiente comando:

php test.php

El resultado debería ser así:

Asi es como luce en Putty

Espero que lo encuentren interesante.

Comentarios

Entradas populares