El Protocolo base del sistema X WindowX Window System, un sistema de ventanas de red que muestra bitmaps y que permite construir interfaces gráficas de usuarios en Unix, Unix-Like y otros sistemas operativos. El sistema de ventanas X Window está basado en un modelo de Cliente-Servidor: un solo servidor controla los dispositivos hardware de entrada-salida, como el monitor, el teclado, y el ratón; todos los programas de la aplicación actúan como un solo cliente, interactuando con el usuario. Esta interacción es regulada por el protocolo del base del sistema de ventanas X Window. Existen otros protocolos relacionados con el sistema X Window, algunos utilizados en las capas superiores del protocolo X Window y otros como protocolos independientes.
es la base del protocolo deEn el protocolo base de X Window System, solo cuatro clases de paquetes son enviadas, asíncronamente, sobre la red: peticiones, respuestas, los acontecimientos, y los errores. Las “peticiones” son enviadas por un cliente al server para preguntar si puede mejorar alguna aplicación (por ejemplo crear una nueva ventana) y además son devueltos a la persona que los envió para que reciba los datos (Repuestas). Las “respuestas” son enviadas por un cliente para confirmar algún dato. Los “eventos” son enviados por un usuario para notificar a otros de que hay alguna junta de interés o trabajo. Los “errores” son enviados al usuario para notificar que ha ocurrido un error durante el proceso de peticiones. En las peticiones pueden generarse respuestas, eventos y errores; u otros, el protocolo manda una orden específica para que el usuario no mande la petición por otra red. Algunas extensiones al protocolo core existente, cada una con sus propias peticiones, respuestas, eventos y errores.
X se originó en el Instituto Tecnológico de Massachusetts en 1984 (su liberación X11 actual apareció en septiembre de 1987). Fue diseñado por Bob Scheifer y Jim Gettys, pusieron como principio primordial del proyecto “Crearemos un mecanismo, no una política”. Como resultado, el protocolo core no específica la interacción entre clientes y entre un cliente y el usuario. Estas interacciones están sujetas por especificaciones separadas, como el ICCCM y la freedesktop.org especificaciones. Son típicamente automáticos, hasta usando un dado Widget toolkit.
La comunicación entre el servidor y los clientes se hace mediante el intercambio de paquetes sobre un canal. La conexión se establece por el cliente (la forma en que el cliente se inicia no se ha especificado en el protocolo). El cliente también envía el primer paquete, que contiene el orden del byte a ser utilizado y la información sobre la versión del protocolo y el tipo de autenticación que el cliente espera que el servidor usará. La respuesta del servidor mediante el envío de un paquete de vuelta indica la aceptación o el rechazo de la conexión, o con una solicitud de una autenticación adicional. Si la conexión es aceptada, el paquete de aceptación contiene los datos que el cliente debe usar en la interacción posterior con el servidor.
Después de que se establezca la conexión, cuatro tipos de paquetes son intercambiados entre el cliente y el servidor sobre el canal de comunicación:
Los paquetes de la petición y de la respuesta tienen una longitud diversa, mientras que los paquetes de eventos y de error tienen una longitud fija de 32 bytes.
Los paquetes de petición son numerados secuencialmente por el servidor tan pronto como los recibe: la primera petición de un cliente se numera 1, la segunda 2, etc. Los 16 bits menos significativos del número secuencial de una petición se incluyen en los paquetes de la respuesta y del error, si los hay, generados por la petición. También son incluidos en los paquetes de eventos, para indicar el número secuencial de la petición que el servidor está actualmente procesando o acaba de terminar de procesar.
Lo que es usualmente llamado "ventana" en la mayoría de las interfaces gráficas de usuarios, en el X Window System se llama "ventana de nivel superior" (top-level window). El término ventana también es usado para denotar las ventanas que descansan dentro de otra ventana, es decir, subventanas de una ventana padre. Los elementos gráficos tales como los botones, menús, iconos, etc. pueden ser creados usando subventanas.
Un cliente puede solicitar la creación de una ventana. Más precisamente, puede solicitar la creación de una subventana para una ventana existente. Como resultado, las ventanas creadas por los clientes se arreglan en forma de un árbol (una jerarquía). La raíz de este árbol es la ventana raíz, que es una ventana especial creada automáticamente por el servidor en el arranque. Todas las otras ventanas son directa o indirectamente subventanas de la ventana raíz. Las ventanas de nivel superior son las subventanas directas de la ventana raíz. Visiblemente, la ventana raíz es tan grande como la pantalla, y descansa detrás del resto de las ventanas. Sin embargo la ventana raíz puede ser más grande que la pantalla, en este caso el usuario puede desplazarse alrededor del área visible.
No se garantiza que el contenido de una ventana siempre sea preservado en el tiempo. Particularmente, el contenido de la ventana puede ser destruido cuando la ventana es movida, redimensionada, cubierta por otras ventanas, y en general, hecha no visible total o parcialmente. En particular, el contenido es perdido si el servidor X no está manteniendo un almacenamiento de respaldo del contenido de la ventana. El cliente puede solicitar memoria de respaldo para que una ventana sea mantenida, pero no hay obligación para que el servidor lo haga. Por lo tanto, los clientes no pueden asumir que el almacenamiento de respaldo sea mantenido. Si una parte visible de una ventana tiene un contenido sin especificar, un evento es enviado para notificar al cliente que el contenido de la ventana tiene que ser dibujado otra vez.
Cada ventana tiene un conjunto asociado de atributos, tales como la geometría de la ventana (tamaño y posición), la imagen de fondo, si la memoria de respaldo para ella se ha pedido o no, etc. El protocolo incluye las peticiones necesarias para que un cliente pueda inspeccionar y cambiar los atributos de una ventana.
Las ventanas pueden ser de InputOutput
(entrada-salida) o de InputOnly
(solo-entrada). Las ventanas que pueden ser mostradas en la pantalla y son usadas para dibujar contenido son de la primera clase. La segunda clase de ventanas nunca son mostradas en la pantalla; son usadas solo para recibir la entrada.
El marco decorativo y la barra de título (posiblemente incluyendo botones) que son usualmente vistos alrededor de las ventanas, son creados por el manejador de ventanas, no por el cliente que crea la ventana. El manejador de ventanas también maneja la entrada relacionada con estos elementos, tales como redimensionar la ventana cuando el usuario hace clic y arrastra el marco de ventana. Los clientes usualmente operan en la ventana que ellos crearon sin hacer caso de los cambios operados por el manejador de ventanas. Un cambio que tiene que tomar en cuenta el Re-parenting window manager, que casi todos los manejadores de ventanas modernos son, es cambiar la ventana de nivel superior a una ventana que no sea la raíz. Desde el punto de vista del protocolo base, el manejador de ventanas es un cliente, no diferente de otras aplicaciones.
Los datos acerca de una ventana pueden ser obtenidos corriendo el programa xwininfo
. Pasándole el argumento de línea de comando -tree
, este programa muestra el árbol de subventanas de una ventana, junto con sus identificadores y datos de geometría.
Un pixmap es una región de memoria que puede ser usada para dibujo (drawing) de contenido. A diferencia de las ventanas, los pixmaps no se muestran automáticamente en la pantalla. Sin embargo, el contenido de un pixmap (o una parte de él) puede ser transferido a una ventana y viceversa. Esto permite técnicas tales como double buffering. La mayoría de las operaciones gráficas que se pueden hacer en ventanas, también se pueden hacer en pixmaps.
Las ventanas y los pixmaps son colectivamente llamados drawables (dibujables), y sus contenidos de datos residen en el servidor. Sin embargo, un cliente puede solicitar que el contenido de un drawable sea transferido del servidor al cliente o viceversa.
El cliente puede pedir un número de operaciones gráficas, tales como limpiar un área, copiar un área en otra, dibujar puntos, líneas, rectángulos, y texto. A menos que se diga lo contrario, todas las operaciones son posibles en todos los drawables, tanto en las ventanas como en los pixmaps.
La mayoría de los pedidos de operaciones gráficas incluyen un contexto gráfico, que es una estructura que contiene los parámetros de las operaciones gráficas. Un contexto gráfico incluye el color del primero plano, el color del fondo, la fuente del texto, y otros parámetros gráficos. Cuando se pide una operación gráfica, el cliente incluye un contexto gráfico. No todos los parámetros del contexto gráfico afectan a la operación: por ejemplo, la fuente no tiene efecto al dibujar una línea.
El protocolo base específica el uso de las fuentes del lado del servidor.sistema de archivos local o vía la red desde otro programa llamado servidor de fuente. Los clientes pueden pedir la lista de fuentes disponibles al servidor y pueden solicitar que una fuente sea cargada (si ya no lo está) o descargarla del servidor (si no es usada por otros clientes). Un cliente puede pedir la información de carácter general sobre una fuente (por ejemplo, la "subida" (ascent) de la fuente) y el espacio que una específica secuencia de caracteres (string) toma cuando es dibujada con una fuente determinada.
Tales fuentes son almacenadas como archivos, y el servidor tiene acceso directamente vía elLos nombres de las fuentes son arbitrarias secuencias de caracteres (strings) en el nivel del Protocolo base de X Window. Las convenciones del X logical font description especifican cómo las fuentes deben ser nombradas de acuerdo a sus atributos. Estas convenciones también especifican los valores de las propiedades opcionales que pueden estar adjuntas a las fuentes.
El programa xlsfonts
imprime la lista de fuentes almacenadas en el servidor. El programa xfontsel
demuestra los glyphs de las fuentes, y permite al usuario seleccionar el nombre de una fuente para pegarla en otra ventana.
Actualmente se considera desaprobado el uso de las fuentes del lado del servidor a favor de las fuentes del lado del cliente.Xft o de las bibliotecas Cairo y de la extensión de XRender. En el protocolo de base, no hay especificaciónse acerca de fuentes del lado del cliente.
Tales fuentes son renderizadas por el cliente, no por el servidor, con el soporte de las bibliotecas deTodos los datos sobre ventanas, pixmaps, fuentes, etc., son almacenados en el servidor. El cliente conoce los identificadores de estos objetos - números enteros que usa como nombres para ellos al interactuar con el servidor. Por ejemplo, si un cliente desea que sea creada una ventana, solicita al servidor crear una ventana con un identificador dado. El identificador puede ser usado posteriormente por el cliente para pedir, por ejemplo, que una secuencia de caracteres sea dibujada en la ventana. Los objetos siguientes residen en el servidor y son conocidos por el cliente vía un identificador numérico:
Estos objetos se llaman recursos. Cuando un cliente pide la creación de uno de tales recursos, también específica un identificador para el mismo. Por ejemplo, para crear una nueva ventana, el cliente específica tanto los atributos de la ventana (padre, anchura, altura, etc.) así como también el identificador a asociar con la ventana.
Los identificadores son números enteros de 32 bits con sus tres bits más significativos iguales a cero. Cada cliente tiene su propio conjunto de identificadores que puede usar para crear nuevos recursos. Este conjunto es especificado por el servidor como dos números enteros incluidos en el paquete de aceptación (el paquete que envía al cliente para informarle que la conexión es aceptada). Los clientes eligen los identificadores que están en este conjunto de tal manera que no coincidan: dos objetos entre ventanas, pixmaps, fuentes, colormaps, y contextos gráficos, no pueden tener el mismo identificador.
Una vez que se ha creado un recurso, su identificador es utilizado por el cliente para pedir operaciones sobre él al servidor. Algunas operaciones afectan al recurso dado (por ejemplo, peticiones de mover ventanas); otros piden datos del recurso almacenados en el servidor (por ejemplo, pedidos para saber las propiedades de las ventanas).
Los identificadores son únicos para el servidor, no solo para al cliente; por ejemplo, no hay dos ventanas que tengan el mismo identificador, incluso si son creadas por dos clientes diferentes. Un cliente puede acceder a cualquier objeto dado su identificador. En particular, también puede tener acceso a los recursos creados por cualquier otro cliente, incluso si sus identificadores están fuera del conjunto de identificadores que puede crear.
Como resultado, dos clientes conectados con el mismo servidor pueden usar el mismo identificador para referirse al mismo recurso. Por ejemplo, si un cliente crea una ventana con identificador 0x1e00021
y pasa este número a otra aplicación (vía cualquier medio disponible, por ejemplo almacenando este número en un archivo que es también accesible a la otra aplicación), la otra aplicación puede operar en la misma ventana. Esta posibilidad es explotada, por ejemplo, por la versión X Window de Ghostview: este programa crea una subventana, almacenando su identificador en una variable de entorno, y llama Ghostscript, el cual dibuja el contenido del archivo PostScript para mostrarlo en esta ventana.
Los recursos normalmente se destruyen cuando el cliente que los creó cierra la conexión con el servidor. Sin embargo, antes de cerrar la conexión, un cliente puede solicitar al servidor no destruirlos.
Los eventos son paquetes enviados por el servidor a un cliente para comunicar que ha sucedido algo en lo que el cliente puede estar interesado. Por ejemplo, un evento es enviado cuando el usuario pulsa una tecla o hace clic con el botón del ratón. Los eventos no solo son usados para la entrada: por ejemplo, los eventos son enviados para indicar la creación de nuevas subventanas en una ventana dada.
Cada evento es relativo a una ventana. Por ejemplo, si el usuario hace clic cuando el puntero del ratón está en una ventana, el evento será relativo a esa ventana. El paquete del evento contiene el identificador de esa ventana.
Un cliente puede solicitar al servidor que envíe un evento a otro cliente; esto es usado para la comunicación entre los clientes. Tal evento es generado, por ejemplo, cuando un cliente solicita el texto que actualmente está seleccionado: este evento es enviado al cliente que está actualmente manejando la ventana que tiene la selección.
El evento Expose
(exposición) es enviado cuando se hace visible un área de una ventana cuyo contenido se ha destruido. El contenido de una ventana puede ser destruido en algunas condiciones, por ejemplo, si la ventana es cubierta y el servidor no está manteniendo un almacenamiento de respaldo. El servidor genera un evento Expose
para notificar al cliente que una parte de la ventana tiene que ser redibujada.
La mayoría de los tipos de eventos son enviados solamente si el cliente previamente manifestó un interés en ellos. Esto es porque los clientes pueden estar interesados solamente en una cierta clase de eventos. Por ejemplo, un cliente puede estar interesado en eventos relacionados con el teclado pero no en eventos relacionados con el ratón. Sin embargo, algunos tipos de eventos son enviados a los clientes incluso si no los han pedido específicamente.
Ajustando un atributo de una ventana, los clientes especifican qué tipos de eventos quieren que se les envíen. Por ejemplo, para redibujar una ventana cuando su contenido se ha destruido, un cliente debe recibir los eventos Expose
, que le informan que la ventana necesita ser redibujada otra vez. Sin embargo, al cliente se le enviarán los eventos Expose
solamente si el cliente ha manifestado previamente su interés en estos eventos, que es hecho apropiadamente ajustando el atributo de máscara del evento de la ventana.
Diferentes clientes pueden pedir eventos en la misma ventana. Pueden incluso ajustar diferentes máscaras de evento en la misma ventana. Por ejemplo, un cliente puede solamente pedir eventos del teclado en una ventana mientras que otro cliente pide solamente eventos del ratón en la misma ventana. Esto es posible porque, para cada ventana, el servidor mantiene una máscara de evento separada por cada cliente. Sin embargo, hay algunos tipos de eventos que pueden ser seleccionados solamente por un cliente a la vez para cada ventana. En particular, los eventos que reportan los clic del botón del ratón y algunos cambios relacionados al manejo de la ventana.
El programa xev
muestra los eventos relativos a una ventana. En particular, xev -id WID
pide todos los eventos posibles relativos a la ventana del identificador WID y los imprime.
En el nivel del protocolo, un color es representado por un entero sin signo de 32 bits, llamado un pixelvalue (valor del pixel). Los elementos siguientes afectan la representación de los colores:
En el caso más fácil, el colormap es una tabla conteniendo un triple RGB en cada fila. Un pixelvalue x
representa el color contenido en la fila x
de la tabla. Si el cliente puede cambiar las entradas en el colormap, esta representación es identificada por la clase visual PseudoColor
. La clase visual StaticColor
(color estático) es similar, pero el cliente no puede cambiar las entradas en el colormap.
Hay un total de seis clases visuales posibles, cada una identificando una manera diferente para representar un triple RGB con un pixelvalue. PseudoColor
y StaticColor
son dos. El GrayScale
(escala de gris) y StaticGray
(gris estático) son otras dos, diferenciándose de las anteriores porque solamente son usadas tonalidades de gris.
Las dos clases visuales que quedan difieren de las de arriba porque dividen los pixelvalues en tres partes y usan tres tablas separadas para la intensidad del color rojo, verde y azul. De acuerdo a esta representación de color, un pixelvalue se convierte en un triple RGB como sigue:
Este mecanismo requiere que el colormap sea compuesto de tres tablas separadas, una para cada color primario. El resultado de la conversión sigue siendo un triple de valores de intensidad. Las clases visuales usando esta representación son el DirectColor
(color directo) y el TrueColor
(color verdadero), diferenciándose en si el cliente puede cambiar o no los colormaps.
Para representar colores con los pixelvalues, todos estos seis mecanismos requieren algunos parámetros adicionales para trabajar. Estos parámetros se recogen en un visual type (tipo virtual), que contiene una clase visual y otros parámetros de la representación de colores. Cada servidor tiene un conjunto fijo de visualtypes, cada uno asociado a un identificador numérico. Estos identificadores son enteros sin signo de 32 bits, pero no son necesariamente diferentes de los identificadores de recursos o de átomos.
Cuando la conexión de un cliente es aceptada, el paquete de aceptación enviado por el servidor contiene una secuencia de bloques, cada uno conteniendo información sobre una simple exhibición en pantalla. Para cada exhibición, el bloque relativo contiene una lista de otros bloques, cada uno relativo a una profundidad de color específica que es soportada por la exhibición en pantalla. Para cada profundidad soportada, esta lista contiene una lista de visualtypes. Como resultado, cada exhibición es asociada con un número de posibles profundidades, y cada profundidad de cada exhibición es asociada con un número de posibles tipos visuales. Un tipo visual dado puede ser usado para más exhibiciones y para diferentes profundidades.
Para cada tipo visual, el paquete de aceptación contiene tanto su identificador como los parámetros reales que contiene (visual class, etc). los clientes almacenan esta información, puesto que no pueden pedirla después. Por otra parte, los clientes no pueden cambiar o crear nuevos tipos visuales. Los pedidos para la creación de una nueva ventana incluyen la profundidad y el identificador del tipo visual a usar para representar los colores de esta ventana.
Los Colormaps son usados sin importar si el hardware que controla la pantalla (ej., una tarjeta gráfica), usa una paleta de colores, la cual es una tabla que también es usada para la representación de colores. Los servidores usan los colormaps incluso si el hardware no está usando una paleta de colores. Cuando el hardware usa las paletas de colores, solo un número limitado de colormaps pueden ser instalados. Particularmente, un colormap está instalado cuando el hardware muestra colores de acuerdo al mismo. Un cliente puede solicitar el servidor instalar un colormap. Sin embargo, esto puede requerir la desinstalación de otro colormap: el efecto es que las ventanas usando el colormap desinstalado no serán mostradas con el color correcto, un efecto llamado como color flashing o tecnicolor. Este problema puede ser solucionado usando los colormaps estándar, que son colormaps con una asociación predecible entre los pixelvalues y los colores. Gracias a esta característica, los colormaps estándar pueden ser usados por varias aplicaciones.
La creación de colormaps es regulada por la convención ICCCM. Los colormaps estándar son regulados por el ICCCM y por la especificación Xlib.
Una parte del sistema X Color System (Sistema de Color X) es el X Color Management System (xcms) (Sistema de Manejo de Color X). Este sistema fue introducido con el X11R6 Release 5 en 1991. Este sistema consiste en varias características adicionales en xlib, encontradas en la serie de funciones Xcms*. Este sistema define los esquemas de color independientes del dispositivo que se pueden convertir en sistemas RGB dependientes del dispositivo. El sistema consiste en las funciones Xcms* del xlib como también la X Device Color Characterization Convention (XDCCC) que describe cómo convertir los varios sistemas de color independientes del dispositivo en sistemas de color RGB dependientes del dispositivo. Este sistema soporta los sistemas de color CIE XYZ, xyY, L *u*v y L *a*b también como el TekHVC.[1], [2]
Los átomos son enteros de 32 bits representando strings. Los diseñadores del protocolo introdujeron los átomos porque representan strings en un tamaño corto y fijo: mientras que un string puede ser arbitrariamente largo, un átomo es siempre un entero de 32 bits. La brevedad del átomo fue explotada asignando por mandato su uso en las clases de paquetes que son probables de ser enviados muchas veces con los mismos strings; esto resulta en un uso más eficiente de la red. El de tamaño fijo de los átomos fue explotado especificando un de tamaño fijo para los eventos, nombrado 32 bytes: los paquetes de tamaño fijo pueden contener átomos, mientras que no pueden contener strings largos.
Precisamente, los átomos son identificadores de strings almacenados en el servidor. Son similares a los identificadores de los recursos (Windows, Pixmaps, etc.) pero se diferencian de ellos de dos maneras. Primero, los identificadores de átomos son elegidos por el servidor, no por el cliente. En otras palabras, cuando un cliente solicita la creación de un nuevo átomo, éste solamente envía el servidor el string a ser almacenado, no su identificador; este identificador es elegido por el servidor y devuelto como contestación al cliente. La segunda diferencia importante entre los recursos y los átomos es que los átomos no están asociados a los clientes. Una vez que se han creado, un átomo sobrevive hasta que el servidor termine o se resetée (éste no es el comportamiento por defecto de los recursos).
Los átomos son identificadores y son por lo tanto únicos. Sin embargo, un átomo y un identificador de recurso pueden coincidir. El string asociado con un átomo es llamado el nombre del átomo. El nombre de un átomo no puede ser cambiado después de la creación, y ninguno de dos átomos pueden tener el mismo nombre. Como resultado, el nombre de un átomo es comúnmente usado para indicar al átomo: "El átomo ABCD" significa, más precisamente, "el átomo cuyo string asociado es ABCD", o "el átomo cuyo nombre es ABC". Un cliente puede solicitar la creación de un nuevo átomo y puede solicitar para el átomo (el identificador) de un string dado. Algunos átomos están predefinidos (creado por el servidor con un identificador y string dados).
Los átomos son usados para un número de propósitos, sobre todo relacionados con la comunicación entre diversos clientes conectados con el mismo servidor. En particular, son usados en asociación con las propiedades de las ventanas, que son descritas más abajo.
La lista de todos los átomos que residiendo en un servidor puede ser impresa usando el programa xlsatoms. En particular, este programa imprime cada átomo (el identificador, es decir, un número) con su nombre (su string asociado).
Cada ventana tiene un conjunto predefinido de atributos y un conjunto de propiedades, todos almacenados en el servidor y accesible a los clientes por medio solicitudes apropiadas. Los atributos son datos acerca de una ventana, como su tamaño, posición, color de fondo, etc. Las propiedades son piezas arbitrarias de datos atados a una ventana. Al contrario de los atributos, las propiedades no tiene ningún significado a nivel del protocolo base de X Window. Un cliente puede almacenar datos arbitrarios en una propiedad de una ventana. Las propiedades son usadas sobre todo para la comunicación cliente a cliente.
Una propiedad es caracterizada por un nombre, un tipo, y un valor. Las propiedades son similares a las variables en lenguajes de programación imperativos, en que un cliente puede crear una nueva propiedad con un nombre y un tipo dados y almacenar un valor en él. Las propiedades están asociadas a las ventanas: dos propiedades con el mismo nombre pueden existir en dos diferentes ventanas mientras tengan diferentes tipos y valores.
El nombre, el tipo, y el valor de una propiedad son strings; más precisamente, son átomos, es decir, string almacenadas en el servidor y accesibles a los clientes vía identificadores. Una aplicación de cliente puede acceder a una propiedad dada usando el identificador del átomo que contiene el nombre de la propiedad.
Las propiedades son usadas sobre todo para la comunicación inter-cliente. Por ejemplo, la propiedad llamada WM_NAME
(la propiedad nombrada por el átomo cuya secuencia asociada es “WM_NAME”
) es usada para almacenar el nombre de las ventanas. Los manejadores de ventana típicamente leen esta propiedad para exhibir el nombre de las ventanas en su barra de título.
Algunos tipos de comunicación inter-cliente usan las propiedades de la ventana raíz. Por ejemplo, según la especificación del manejador de ventana de freedesktop.org, los manejadores de ventana deben almacenar el identificador de la ventana actualmente activa en la propiedad nombrada _NET_ACTIVE_WINDOW
de la ventana raíz. Los X resources, que contienen parámetros de programas, también son almacenados en las propiedades de la ventana raíz; de esta manera, todos los clientes puede tener acceso, incluso si corren en diferentes computadores.
El programa xprop imprime las propiedades de una ventana dada; xprop -root imprime el nombre, el tipo, y el valor de cada propiedad de la ventana raíz.
Escribe un comentario o lo que quieras sobre Protocolo base de X Window System (directo, no tienes que registrarte)
Comentarios
(de más nuevos a más antiguos)