8½, el Sistema gráfico de Ventanas de Plan 9

Rob Pike

rob@plan9.bell-labs.com

ABSTRACT

El sistema de Ventanas de Plan 9, 8½, es un programa de modesto tamaño y nuevo diseño. Proporciona servicios de I/O en formato texto y gráficos en mapas de bits para programas cliente, locales y remotos, con el objeto de ofrecer un servicio multiplexado de archivo para tales clientes. Sirve los tradicionales archivos de UNIX como /dev/tty así como aquellos más inusuales que proveen acceso al ratón y a la pantalla tal cual. Las operaciones de gráficos de mapas de bits son proporcionadas sirviendo un archivo llamado /dev/bitblt que interpreta los mensajes del cliente para proporcionar una trama de operaciones. El archivo de servicio que 8½ ofrece a sus clientes es idéntico al que usa para su propia implementación, así que fundamentalmente no es más que un multiplexador. Esta arquitectura tiene algunas simetrías de compensación y pueden ser implementadas de manera compacta.

Introducción

En 1989 construí un sistema de ventanas de juguete en tan sólo algunos cientos de líneas de código fuente usando un lenguaje familiar y una arquitectura inusual que envolviese procesos concurrentes [Pike89]. Aunque ese sistema fue rudimentariamente mejorable, demostró que los sistemas de ventanas no son complicados de una forma inherente. Al año siguiente, para el nuevo sistema distribuido Plan 9 [Pike92], apliqué algunas de de las lecciones de ese proyecto de juguete para escribir, en C, un sistema de ventanas de calidad de producción llamado 8½. 8½ proporciona, en blanco y negro, escala de grises, o pantallas a color, los servicios requeridos de un sistema de ventana moderno, incluyendo programabilidad y soporte para gráficos remotos. El sistema entero, incluyendo el programa que por defecto corre en la ventana — el equivalente de xterm [Far89] con ‘cortar y pegar’ entre ventanas — está bien bajo 90 kilobytes de texto en un procesador Motorola 68020, siendo como la mitad del tamaño del kernel del sistema operativo que lo soporta y la décima parte del tamaño del servidor X [Sche86] sin xterm.

Qué hace a 8½ tan compacto? Mucho de lo salvado proviene sobre todo de simplificar: 8½ tiene una pequeña superposicionalidad gráfica, una interfaz de programación sencilla, y una simple, fija interfaz de usuario. 8½ también toma algunas decisiones por autorización — ratón de tres botones, solapación de ventanas, programa de terminal interno y gestor de ventanas, etc. — más que intentar satisfacer todos los gustos. Aunque compacto, 8½ no es ascético. Proporciona lo fundamental y bastantes extras para hacerlo más cómodo de usar. El ingrediente más importante para su mínimo tamaño, sin embargo, es sobretodo su diseño como un servidor de archivos. Esta estructura podría ser aplicable a los sistemas de ventana en los tradicionales sistemas operativos de tipo UNIX.

El pequeño tamaño de 8½ no refleja una funcionalidad restringida: 8½ provee un servicio ásperamente equivalente al X window system. Los clientes de 8½ podrían, por supuesto, ser tan complejos como se desee, aunque la tendencia a imitar el diseño de 8½ y la pulcra interfaz de programación viene a significar que no están próximos a las hinchadas aplicaciones de X.

Modelo de Usuario

8½ conecta la única pantalla, ratón, y teclado del terminal (en terminología de Plan 9) o workstation (en terminología comercial) dentro de un array de terminales virtuales independientes que podrían ser terminales de texto con soporte de shell y la usual suite de herramientas o aplicaciones gráficas que requiriesen de todos los recursos de la pantalla de mapa de bits y el ratón. El texto es representado en UTF, una codificación de la Unicode Standard [Pike93]. La interfaz de programación entera se proporciona a través de la lectura y escritura de archivos en /dev.

Primeramente por razones de historia y familiaridad, el modelo general y la apariencia de 8½ son similares a los de mux [Pike88]. El botón derecho tiene un pequeño menú para controlar la creación de ventanas, destrucción, y emplazamiento. Cuando se crea una ventana, arranca la shell por defecto, rc [Duff90], con el estándard de entrada y salida direccionado a la ventana y accesible a través del archivo /dev/cons (‘console’), análogo al /dev/tty de UNIX. El cambio de nombres representa una ruptura con el pasado: Plan 9 no proporciona un modelo de terminales de estilo teletipo. 8½ proporciona el único camino para la mayoría de los usuarios que acceden a Plan 9.

Las aplicaciones gráficas, como los programas normales, pueden correr tecleando sus nombres en la shell que se ejecuta en una ventana. Esto corre la aplicación en la misma ventana; para correr la aplicación en una ventana nueva podría usarse un programa externo, window, descrito más abajo. Para las aplicaciones gráficas, el modelo de terminal virtual es algo extendido para dejar a los programas manejar a su gusto las operaciones gráficas, acceder al ratón, e interactuar con funciones relacionadas con la lectura y escritura de archivos mediante sugestivos nombres como /dev/mouse y /dev/window pre-ventana multiplexada como /dev/cons. La implementación y la semántica de estos archivos, descrita más abajo, es central para la estructura de 8½.

El programa por defecto que se ejecuta en una ventana es familiar para los usuarios de terminales Blit [Pike83]. Es muy similar al de mux [Pike88], proporcionando edición basada en el ratón de entrada y salida de texto, la viabilidad para el desplazamiento de pantalla [scroll] para ver salidas anteriores, y demás. Tiene también una nueva característica, accionada pulsando ESC, que otorga al usuario el control cuando los caracteres tecleados pueden ser leidos por la shell o una aplicacion, en vez de (por ejemplo) después de cada nueva línea. Esta característica hace que la ventana del programa se utilice directamente para muchas ediciones de texto, tareas tales como redactar correos email antes de enviarlos.

Plan 9 y 8½

Plan 9 es un sistema distribuido que proporciona soporte para aplicaciones tipo UNIX en un entorno construido a partir de distintos CPUservers [servidores centrales], fileservers [servidores de archivos],y terminales conectados por varias redes [Pike90]. Los terminales son comparables a modestas estaciones de trabajo [ workstations] que, una vez conectadas a un fileserver sobre una red de ancho de banda medio como Ethernet, son máquinas autosuficientes ejecutando un sistema operativo completo. A diferencia de las workstations cuyo papel, sin embargo, es el de proporcionar sólo una interfaz de usuario multiplexada comparable al resto del sistema: ejecutan el sistema de ventana y soportan tareas interactivas simples tales como la edición de texto. Para nosotros se suele mentir en alguna parte respecto de las workstations y los terminales X en cuanto a diseño, coste, manejo, y función. (Los terminales pueden ser usados para computación en términos generales, pero en la práctica los usuarios de Plan 9 hacen sus tareas en los CPUservers.) El software de terminal de Plan 9, incluyendo 8½, fue desarrollado en una máquina basada en el procesador 68020 de Motorola llamada Gnot y se ha portado a NeXTstation, MIPS Magnum 3000, SGI Indigos, y Sun SPARCstations—todas las pequeñas workstations que usamos como terminales—como también a PCs.

Las computaciones más grandes tales como la compilación, procesado de textos, o cálculo científico se realizan en los CPUservers, que están conectados a los fileservers mediante redes de amplio ancho de banda. Para trabajo interactivo, estas operaciones pueden acceder al terminal que las envió instantáneamente. El terminal y el CPUserver estando usados por un usuario en particular son conectados al mismo fileserver, aunque sobre redes diferentes; Plan 9 proporciona una vista del fileserver que es independiente de la localización en la red.

Los componentes de Plan 9 son conectados por un protoclo común basado en los archivos compartidos. Todos los recursos en la red son implementados como servidores de archivo; los programas que deseen acceder a ellos se conectan sobre la red y se comunican usando un archivo ordinario de operaciones. Un aspecto inusual de Plan 9 es que el espacio de nombres de un proceso, el grupo de archivos a los que puede accederse por su nombre, (por ejemplo por una llamada al sistema open ) no es global para todos los procesos en una máquina; distintos procesos pueden tener distintos espacios de nombres. El sistema proporciona métodos mediante los cuales los procesos pueden cambiar su espacio de nombres, tal como se habilita para mount un servicio sobre un directorio existente, que hace visibles los archivos de ese servicio en el directorio. (Es una operación diferente de la de su homónimo en UNIX.) Múltiples servicios se pueden montar sobre el mismo directorio, dejando los archivos de múltiples servicios para ser accedidos en el mismo directorio. Las opciones para la llamada al sistema mount controlan el orden de búsqueda de archivos semejante a un directorio de unión.

El ejemplo más obvio de una red de recursos es un fileserver, Donde residen permanentemente los archivos. Hay un número de servicios inusuales, sin embargo, cuyo diseño en un entorno diferente no estaría claramente basado en archivos. Se han descrito muchos en otras partes [Pike92]; algunos ejemplos son la representación de procesos por depuración, como los archivos de procesos de Killian para la 8ª Edición [Kill84], y la implementación de los pares nombre/valor de los exec del entorno UNIX como archivos. Los procesos de usuario pueden también implementar un archivo de servicio y habilitarlo para los clientes de la red, como las ‘mounted streams’ en la 9ª Edición [Pres90]. un ejemplo típico es un programa que interpreta un archivo de sistema externamente definido como el de un CD-ROM o un sistema UNIX estándard y habilita el contenido a programas de Plan 9. Este diseño se utiliza para todas las aplicaciones distribuidas en Plan 9, incluyendo 8½.

8½ sirve un grupo de archivos en el directorio convencional /dev con nombres como cons, mouse, y screen. Los clientes de 8½ se comunican con el sistema de ventana leyendo y escribiendo esos archivos. Por ejemplo, un programa cliente, como puede ser la shell, puede imprimir texto leyendo su salida estándard, que es automáticamente conectada a /dev/cons, o podría abrir y escribir ese archivo explícitamente. Sin embargo, a diferencia de los archivos servidos por un fileserver tradicional, la instancia de /dev/cons proporcionada en cada ventana por 8½ es un archivo distinto; el pre-proceso del espacio de nombres de Plan 9 deja a 8½ proporcionar un único /dev/cons para cada cliente. Este mecanismo se ilustra mejor en la creación de un nuevo cliente de 8½.

Cuando arranca 8½, crea un conducto full-duplex como medio de comunicación para los mensajes que implementa el fichero de servicio que proporcionará. Una finalidad será compartida por todos los clientes; la otra es sostenida por 8½ para aceptar peticiones de I/O. Cuando un usuario abre una nueva ventana usando el ratón, 8½ posiciona en memoria las estructuras de datos de la ventana y bifurca un proceso hijo. El espacio de nombres del hijo, inicialmente compartido con el padre, se duplica entonces así que los cambios que haga el hijo en su espacio de nombres no afectará a su progenitor. El hijo entonces procede a finalizar su conducto de comunicación, cfd, para el directorio /dev mediante una ejecución de la llamada de sistema: mount

mount(cfd, "/dev", MBEFORE, buf)

Esta llamada accede al servicio asociado al descriptor de archivo cfd — el cliente al final del conducto — al comienzo de /dev de modo que los archivos en el nuevo servicio tengan prioridad sobre los archivos existentes en el directorio. Esto crea los nuevos archivos cons, mouse, y demás, disponibles en /dev en una ruta que oculta cualquier archivo con el mismo nombre que haya ya en ese lugar. El argumento buf es una cadena de caracteres (null en este caso), descrita después.

El proceso cliente cierra entonces los descriptores de archivo 0, 1, y 2 y abre /dev/cons repetidamente para conectar los estándares de entrada, salida, y archivos de error de la ventana /dev/cons. Hace entonces un exec llamada al sistema para empezar a ejecutar la shell en la ventana. Esta secuencia entera, completa con el manejo de rror, es de 33 líneas de C.

La vista de estos eventos desde el final del conducto de 8½ es una secuencia mensajes de protocolo de archivo del nuevo cliente generado por la intervención del sistema operativo en respuesta a las llamadas al sistema mount y open ejecutadas por el cliente. Este mensaje generado por mount informa a 8½ que un nuevo cliente ha accedido al fichero de servicio que proporciona; La respuesta de 8½ es un único identificador mantenido por el sistema operativo y pasado en todos los mensajes generados por I/O en los archivos derivados de ese mount. Este identificador es usado por 8½ para distinguir los diferentes clientes aunque cada uno vea un único /dev/cons; la mayoría de los servidoresn o necesitan hacer esta distinción.

Un proceso no notificado a 8½ podría crear ventanas mediante una variante de este mecanismo. Cuando 8½ arranca, usa un servicio de Plan 9 para ‘postear’ el final del conducto de comunicación del cliente en un lugar público. Un proceso pordía abrir ese conducto y mount acceder al sistema de ventana, mejor que la forma en que un cliente X podría conectar a un socket de UNIX al limitar el servidor al sistema de archivos. el argumento final para mount es pasado sin interpretar por el sistema operativo. proporciona una forma para el cliente y el servidor de intercambiar información a la vez que mount. 8½ lo interpreta como las dimensiones de la ventana a crear pro el nuevo cliente. (Como se ha visto antes, la ventana se ha durante el tiempo en que ocurre mount, y buf no lleva información.) Cuando mount retorna, el proceso puede abrir los archivos de la nueva ventana y empezar I/O para usarla.

Como la interfaz de 8½ está basada en archivos, las utilidades estándard del sistema pueden usarse para controlar sus servicios. Por ejemplo, su método de crear ventanas externamente es empaquetado en un shell script de 16 líneas, llamado window, el contenido del cual es sólo una operación mount que prefigura el directorio de 8½ para /dev y ejecuta un comando pasado en la línea como argumento:

mount -b $’8½serv’ /dev

$* < /dev/cons > /dev/cons >[2] /dev/cons &

El programa window empleado típicamente por los usuarios para sus entornos de trabajo iniciales cuando arrancan el sistema, aunque más posibilidades generales.

Otras características básicas del sistema se derivan naturalmente del modelo basado en archivos. Cuando el usuario borra una ventana, 8½ envía el equivalente de una señal de UNIX al grupo de procesos — los clientes — en la ventana, quita la ventana de la pantalla, y de niega las conexiones entrantes a los archivos que la manejen. Si un cliente ignora la señal y continúa escribiendo en la ventana, obtendrá errores de I/O. Si, por otra parte, todos los procesos en una ventana terminan espontáneamente, automáticamente cerrarán todas las conexiones a la ventana. 8½ cuenta con referencias a los archivos de la ventana; cuando no hay niguno pendiente, cierra la ventana y la borra de la pantalla. Como ejemplo diferente, cuando el usuario presiona la tecla DEL para generar una interrupción, 8½ escribe un mensaje a un archivo especial, proporcionado por la interfaz de control de procesos de Plan 9, que interrumpe todos los procesos en la ventana. En todos estos ejemplos, los trabajos de implementación se hacen entrelazadamente a través de una red.

Hay dos aspectos valorables a efectos de implementar un sistema de ventana por multiplexación de /dev/cons y otros ficheros parecidos. Primero, el problema de otorgar una completa significación para interpretar el fichero /dev/cons (/dev/tty) en cada ventana es solventado automáticamente. Proporcionar /dev/cons es la tarea fundamental del sistema de ventana, más que una torpe carga; otros sistemas deben incluso hacer arreglos especiales y si no irrelevantes para que /dev/tty se comporte como se espera en una ventana. Segundo, cualquier programa que pueda acceder al servidor, incluyendo un proceso en una máquina remota, puede acceder a los ficheros utilizando las llamadas al sistema estándares de read y wirte para comunicar con el sistema de ventana, y las llamadas estándares open y close para conectar con él. De nuevo, no se necesitan arreglso especiales para hacer que un proceso remoto utilice todas las facilidades gráficas de 8½.

Entrada en modo Gráfico

Por supuesto 8½ ofrece más que un simple ASCII I/O para sus clientes. El estado del ratón podría descubrirse mediante la lectura del archivo /dev/mouse, que retorna un mensaje de 10 bytes codificando el estado de los botones y la posición del cursor. Si el ratón no se ha movido desde la última lectura de /dev/mouse, o si la ventana asociada con la instancia de /dev/mouse no es la de ‘input focus’, entonces lee los bloques.

El formato del mensaje es:

’m’

1 byte del estado del botón

4 bytes of x, primer byte bajo

4 bytes of y, primer byte bajo

Como en todas las estructuras de datos compartidas en Plan 9, el orden de cada byte en el mensaje es definido tal que todos los clientes pueden ejecutar el mismo código para desempaquetar el mensaje dentro de una estructura de datos local.

Para la entrada de teclado, los clientes pueden leer /dev/cons o, si necesitan la entrada de caracteres en tiempo real, /dev/rcons (‘raw console’). No hay mecanismo eventual explícito para auxiliar a los clientes que necesiten leer de múltiples códigos. En su lugar, se puede usar una pequeña (365 líneas) librería de soporte externo. Ésta accede a un proceso tpara la entrada de varios bloques de código — ratón, teclado and quizá un tercer descriptor de archivo proporcionado por el usuario — y embute su entrada dentro de un conducto simple desde el cual pueden leerse los diferentes tipos de eventos en el estilo tradicional. Este paquete es un compromiso. Como discutí en una conferencia anterior [Pike89] prefiero liberar a las aplicaciones desde eventos basados en programación. desafortunadamente, creo, veo que no hay camino fácil para alcanzar ésto a través de programas en C de una vez por todas, y estoy poco dispuesto a requerir de todos los programadores que se adueñen de la conveniente programación. Debería notarse, pienso, que incluso este compromiso concluye en una interfaz pequeña y fácilmente inteligible. Un ejemplo de un programa que lo usa se presenta cerca del final de este documento.

Salida en modo Gráfico

El archivo /dev/screen puede leer desde cualquier cliente para recuperar los contenidos de la pantalla entera, así como imprimirlos (ver Fig. 1). Similarmente, /dev/window recoge los contenidos de la ventana activa. Estos ficheros son de sólo lectura.

Para manejar las operaciones gráficas en sus ventanas, los programas clientes acceden a /dev/bitblt. Éste implementa un protocolo que codifica las operaciones básicas de mapas de bits. La mayoría de lso mensajes en el protocolo (hay 23 mensaje en total, casi la mitad para manejar las fuentes multi-nivel necesarias para un manejo eficiente de los caracteres Unicode) son transmisiones (vía escritura) del cliente al sistema de ventana para manipular una operación gráfica así como un bitblt [PLR85] u operación de dibujo de caracteres; algunos incluyen información retornada (recuperada vía lectura) para el cliente. Como con /dev/mouse, el protocolo /dev/bitblt es un orden definidos de bytes. quí, como ejemplo, está el mapa del mensaje bitblt:

’b’

2 bytes de id de destino

2x4 bytes de punto de destino

2 bytes de id de código

4x4 bytes del código de rectángulo

2 bytes del código de función boolean

Figure 1. Una pantalla representativa de 8½, corriendo sobre una NeXTstation bajo Plan 9 (sin software NeXT alguno). Arriba a la derecha, un programa notifica la llegada de un correo. Arriba del todo y a la izquierda hay un navegador para bases de datos de astronomía y una imagen de una galaxia producida por el navegador. Más abajo a la izquierda hay un editor de pantalla, sam [Pike87], editando texto japonés codificado en UTF, y más abajo a la derecha un 8½ ejecutándose de forma recursiva y, dentro de la instantánea, una vista previa para la salida de troff or debajo de las caras en la ventanita se ejecuta el comando que imprime la pantalla mediante /dev/screen a la utilidad de impresión de mapas de bits.

Este mensaje es construido trivialmente desde la subrutina bitblt en la librería, definida como

void bitblt(Bitmap *dst, Point dp,

            Bitmap *src, Rectangle sr, Fcode c).

los campos ‘id’ en el mensaje indican otra propiedad de 8½: los clientes no almacenan los datos actuales localmente para ninguno de sus mapas de bits. En su lugar, el protocolo porporciona un mensaje para colocar el mapa de bits, para almacenarlo en el servidor, y devuelve al cliente un entero identificador, mejor que un descriptor de archivos de UNIX , para usarlo en las operaciones de ese mapa de bits. El mapa de bits 0 es por convención la ventana del cliente, análogo a la entrada estándard del archivo de I/O. De hecho, las operaciones gráficas de mapas de bits no son ejecutadas en el cliente en su totalidad; todas ellas son manejadas a medias en el servidor. De nuevo, usando el archivo de operaciones remotas de Plan 9, esto permite que las máquinas remotas no necesiten tener capacidad gráfica, como el CPU server, para correr aplicaciones gráficas. Características análogas al sistema de ventana original de Andrew [Gos86] y de X [Sche86] requieren mecanismos más complejos.

8½ ni siquiera opera por sí mismo directamente en los mapas de bits. En su lugar, llama a otro servidor para sus operaciones gráficas, usando un protocolo idéntico. El sistema operativo para los terminales de Plan 9 contiene un servidor interno que implementa ese protocolo, exactamente como lo hace 8½, pero para un sólo cliente. Ese servidor almacena los bytes actuales para los mapas de bits e implementa las operaciones gráficas fundamentales para mapas de bits. Para nosotros, el entorno en el que corre 8½ tiene exactamente la estructura que porporciona a sus clientes; 8½ reproduce el entorno para sus clientes, multiplexando la interfaz para mantener separados sus clientes.

Esta idea de la multiplexación por simulación se aplica a más cosas aparte de los sistemas de ventana, por supuesto, y tiene algunos aspectos en sus efectos. En el momento en que 8½ simula su propio entorno para sus clientes, puede correr en una de sus propias ventanas (see Figure 1). Una aplicación útil y común de esta técnica es conectar una ventana a una máquina remota, como un CPU server, y ejecutar el sistema de ventana allí de manera que cada subventana está automáticamente en la máquina remota. Es también una manera manejablemente fácil para depurar una nueva versión del sistema de ventana o para crear un entorno, por ejemplo, con una fuente diferente por defecto.

Implementación

Para proporcionar gráficos a sus clientes, la mayoría de las veces 8½ tan sólo multiplexa y pasa a través de su propio servidor las peticiones de los clientes, ocasionalmente rearreglando los mensajes para mantener la ficción de que el cliente tiene una única pantalla (ventanas). Para manejar la superposición de ventanas utiliza el modelo de capas, que es controlado por una librería separada [Pike83a]. Para nosotros es poco trabajo a hacer y es un programa bastante simple; está dominado por una cúpula de estamentos encaminados a interpretar el mapa de bits y los protocolos del sistema de archivos. El programa de construcción de la ventana, sus menús asociados y el soporte para el tratamiento de texto son responsables de la mayoría del código.

El servidor del sistema operativo es también compacto: la versión para el procesador 68020 de Motorola, excluyendo la implementación de media docena de operaciones gráficas de mapas de bits, es de 2295 líneas de C (de nuevo, casi la mitad a repartir con las fuentes); las operaciones gráficas son otras 2214 líneas.

8½ está estructurado como un set de corrutinas de comunicación, mejor expuestas en el documento de 1989 [Pike89]. Una corrutina maneja el ratón, otra el teclado y otra es instada a manejar el estado de cada ventana y su cliente asociado. Cuando no hay ninguna corrutina que quiera ejecutarse, 8½ lee el siguiente fichero de petición de I/O de sus clientes, que llega seguidamente por el conducto de comunicación full-duplex. Para nosotros 8½ es enteramente síncrono.

El código del programa es pequeño y compila en unos 10 segundos en nuestro entorno Plan 9. Hay diez archivos de código fuente y uno makefile totalizando 5100 líneas. Esto incluye el código fuente para el proceso de gestión de ventana, el programa del terminal de cortar-y-pegar, la ventana/servidor de archivos mismo, y una pequeña librería de corrutinas (proc.c). Ésta no incluye la librería de capas (otras 1031 líneas) o la librería para manejar el cortado y pegado de texto desplegado en una ventana (960 líneas), o la librería de soporte gráfico general que gestiona todos los los aspectos gráficos no dibujables — aritmética en puntos y rectángulos, gestión de memoria, manejo de errores, clipping, — más fuentes, eventos, y operaciones de dibujo no primitvas como círculos y elipses (un total de 3051 líneas). No todas las piezas de estas librerías son usadas por 8½ mismo; una larga parte de la librería de gráficos en particular es usada sólo por los clientes. Para nosotros es algo injusto para 8½ sumar estos números sólamente, incluyendo las 4509 líneas de soporte en el kernel y la llegada del tamaño total de implementación a 14651 líneas de código fuente para implementar todo 8½ desde los niveles más bajos a los más altos. Pero ese número da una medida justificada de la complejidad de todo el sistema.

La implementación es también eficiente. El perfeccionamiento de 8½ es competitivo al de X windows’. Comparado a usar gbench de Dunwoody y Linton en pruebas en un 68020, distribuido con la ‘‘X Test Suite’’, circulos y arcos se dibujan casi la mitad de rápido en 8½ que en X11 release 4 compilado con gcc para hardware equivalente, probablemente porque son normalmente implementados en una librería de usuario mediante llamadas a la primitiva point La velocidad dibujando líneas es casi igual entre los dos sistemas. El texto Unicode se dibuja casi a la misma velocidad en 8½ que el texto ASCII en X, y el test de bitblt corre cuatro veces más rápido para 8½. Estos números varían bastante para procurar evitar conclusiones sobre el barrido del trazado a dibujar, pero sugieren que la arquitectura de 8½ no penaliza su perfeccionamiento. Finalmente, 8½ se inicia en apenas un segundo y crea una nueva ventana aparentemente de manera instantánea.

Un ejemplo

He aquí un programa completo que corre en 8½. Imprime la cadena "hello world" donde quiera que se presione el botón izquierdo del mouse, y sale cuando se presiona el botón derecho. También imprime la cadena en el centro de su ventana, y mantiene esa cadena cuando se reconfigura el tamaño de la ventana.

#include <u.h>

#include <libc.h>

#include <libg.h>

void

ereshaped(Rectangle r)

{

    Point p;

    screen.r = r;

    bitblt(&screen, screen.r.min, &screen, r, Zero); /* clear */

    p.x = screen.r.min.x + Dx(screen.r)/2;

    p.y = screen.r.min.y + Dy(screen.r)/2;

    p = sub(p, div(strsize(font, "hello world"), 2));

    string(&screen, p, font, "hello world", S);

}

main(void)

{

    Mouse m;

    binit(0, 0, 0); /* inicializar la librería de gráficos */

    einit(Emouse);  /* inicializar la librería de eventos */

    ereshaped(screen.r);

    for(;;){

        m = emouse();

        if(m.buttons & RIGHTB)

            break;

        if(m.buttons & LEFTB){

            string(&screen, m.xy, font, "hello world", S);

            /* wait for release of button */

            do; while(emouse().buttons & LEFTB);

        }

    }

}

El binario completo cargado es un poco más de 26K bytes en un 68020. Este programa debería ser comparado a uno similar en la excelente ponencia de Rosenthal [Rose88]. (El programa en cuestión hace más: también emplea el ratón.) La parte más torpe es ereshaped, una función de nombre conocido que se llama desde al librería de eventos cuando quiera que la ventana sea reformada o movida, se ha presentado de forma poco elegante pero adecuadamente para el caso especial de un mensaje dle ratón. (Los eventos expuestos denominados simples no son eventos en su totalidad en 8½; la librería de capas cuida de ellos de manera transparente.) La lección de este programa, en deferencia a Rosenthal, es que si el sistema de ventana está limpiamente diseñado debería ser necesario un toolkit para tareas simples.

Status

Desde 1992, 8½ está en uso diario regular por casi la totalidad de las 60 personas en nuestro centro de investigación. Algunas de estas personas lo usan para acceder a Plan 9 mismo; otras lo usan como un front-end remoto para sistemas UNIX , mejor de lo que sería usar un terminal X.

Algunas cosas sobre 8½ podrían cambiar. Sería genial si sus capacidades fuesen accesibles más fácilmente desde la shell. Un compañero de este documento [Pike91] propone una manera de hacerlo, pero eso no incluye ninguna funcionalidad gráfica. Quizá una versión de texto del fichero /dev/bitblt es una forma de proceder; que seguiría, por ejemplo, por programas awk para dibujar gráficos directamente.

Puede este tipo de sistema de ventana ser construido en otros sistemas operativos? La mayor parte del diseño de 8½ depende de su estructura como un servidor de archivos. En principio, esto podría hacerlo cualquier sistema que soportase procesos de usuario que sirven archivos, como cualquier sistema que corra sobre NFS o AFS [Sun89, Kaza87]. Un requerimiento, en cualquier caso, es la necesidad de 8½ para responder a sus clientes’ peticiones fuera de orden: si un cliente lee /dev/cons en una ventana sin caracteres para leer, otros clientes deberían poder manejar I/O en sus ventanas, o incluso en la misma ventana. Otra condición es que los archivos de 8½ son como dispositivos, y no deben ser cacheados por el cliente. NFS no puede hacer honor a estos requerimientos; AFS podría ser viable. Por supuesto, otros mecanismos de comunicación interprocesales como los sockets se podrían usar como una base para un sistema de ventana. ALguien podría incluso argumentar que el modelo de X se ajusta a este esquema general. Podría probar fácilmente sus méritos para escribir un sistema tipo 8½ para sistemas comerciales de UNIX con el fin de demostrar que sus méritos se pueden ganar en otros sistemas además de Plan 9.

Conclusión

En conclusión, 8½ utiliza una arquitectura inusual en concierto con la comunicación interprocesal orientada a archivos de Plan 9 para proporcionar gráficos interactivos basados en red para programas clientes. Lo que demuestra que incluso la calidad de producción de sistemas de ventana no es larga o complicada de manera inherente y podría ser simple de usar y programar.

Reconocimientos

A los comentarios de gran ayuda en los primeros trazos de redacción de este dcumentos hechos por Doug Blewett, Stu Feldman, Chris Fraser, Brian Kernighan, Dennis Ritchie, y Phil Winterbottom. El soporte para el color de 8½ fue añadido por Howard Trickey. Muchas de estas ideas que conducen a 8½ se intentaron en antiguos, ya veces menos satisfactorios, programas. Me gustaría mostrar mi agradecimiento a aquellos usuarios que sufrieron algunos de mis previos sistemas de ventanas 7½.

Referencias

[Duff90] Tom Duff, ‘‘Rc - A Shell for Plan 9 and UNIX systems’’, Proc. of the Summer 1990 UKUUG Conf., Londres, Julio, 1990, pp. 21-33, reimpreso, en diferente formato, en este volumen.

[Far89] Far too many people, XTERM(1), Massachusetts Institute of Technology, 1989.

[Gos86] James Gosling y David Rosenthal, ‘‘A window manager for bitmapped displays and UNIX’’, en Methodology of Window Management, editado por F.R.A. Hopgood et al., Primavera, 1986.

[Kaza87] Mike Kazar, ‘‘Synchronization and Caching issues in the Andrew File System’’, Tech. Rept. CMU-ITC-058, Information Technology Center, Carnegie Mellon University, Junio, 1987.

[Kill84] Tom Killian, ‘‘Processes as Files’’, USENIX Summer Conf. Proc., Salt Lake City Junio, 1984.

[Pike83] Rob Pike, ‘‘The Blit: A Multiplexed Graphics Terminal’’, Bell Labs Tech. J., V63, #8, part 2, pp. 1607-1631.

[Pike83a] Rob Pike, ‘‘Graphics in Overlapping Bitmap Layers’’, Trans. on Graph., Vol 2, #2, 135-160, reimpreso en Proc. SIGGRAPH ’83, pp. 331-356.

[Pike87] Rob Pike, ‘‘The Text Editor sam’’, Softw. - Prac. and Exp., Nov 1987, Vol 17 #11, pp. 813-845, reimpreso en este volumen.

[Pike88] Rob Pike, ‘‘Window Systems Should Be Transparent’’, Comp. Sys., Verano de 1988, Vol 1 #3, pp. 279-296.

[Pike89] Rob Pike, ‘‘A Concurrent Window System’’, Comp. Sys., Primavera de 1989, Vol 2 #2, pp. 133-153.

[Pike91] Rob Pike, ‘‘A Minimalist Global User Interface’’, USENIX Summer Conf. Proc., Nashville, Junio, 1991.

[Pike92] Rob Pike, Dave Presotto, Ken Thompson, Howard Trickey, y Phil Winterbottom, Operating Systems Review Vol 27, #2, Abril de 1993, pp. 72-76 (reimpreso desde Proceedings of the 5th ACM SIGOPS European Workshop, Mont Saint-Michel, 1992, Documento nº 34, y reimpreso en este volumen).

[Pike94] Rob Pike y Ken Thompson, ‘‘Hello World or Καλημέρα κόσμε or こんにちは 世界’’, USENIX Winter Conf. Proc., San Diego, Enero, 1993, reimpreso en este volumen.

[PLR85] Rob Pike, Bart Locanthi y John Reiser, ‘‘Hardware/Software Tradeoffs for Bitmap Graphics on the Blit’’, Softw. - Prac. and Exp., Febrero de 1985, Vol 15 #2, pp. 131-152.

[Pres90] David L. Presotto y Dennis M. Ritchie, ‘‘Interprocess Communication in the Ninth Edition Unix System’’, Softw. - Prac. and Exp., Junio 1990, Vol 20 #S1, pp. S1/3-S1/17.

[Rose88] David Rosenthal, ‘‘A Simple X11 Client Program -or- How hard can it really be to write ‘‘Hello, World’’?’’, USENIX Winter Conf. Proc., Dallas, Enro, 1988, pp. 229-242.

[Sche86] Robert W. Scheifler y Jim Gettys, ‘‘The X Window System’’, ACM Trans. on Graph., Vol 5 #2, pp. 79-109.

[Sun89] Sun Microsystems, NFS: Network file system protocol specification, RFC 1094, Network Information Center, SRI International, Marzo, 1989.

Notes

Aparecido originalmente, en formato ligeramente diferente, en Proc. of the Summer 1991 USENIX Conf., pp. 257-265, Nashville. Nótese que ha sido reemplazado por rio (ver rio(1)).